Daisuke Shimamura's id3 v1/v2 + i18n patches
authorJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 11 Jul 2002 06:15:30 +0000 (06:15 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Thu, 11 Jul 2002 06:15:30 +0000 (06:15 +0000)
15 files changed:
configure.in
src/plugin_xmms/Makefile.am
src/plugin_xmms/Makefile.lite
src/plugin_xmms/charset.c [new file with mode: 0644]
src/plugin_xmms/charset.h [new file with mode: 0644]
src/plugin_xmms/configure.c [new file with mode: 0644]
src/plugin_xmms/configure.h [new file with mode: 0644]
src/plugin_xmms/fileinfo.c [new file with mode: 0644]
src/plugin_xmms/genres.h [new file with mode: 0644]
src/plugin_xmms/id3_tag.c [new file with mode: 0644]
src/plugin_xmms/id3_tag.h [new file with mode: 0644]
src/plugin_xmms/mylocale.h [new file with mode: 0644]
src/plugin_xmms/plugin.c
src/plugin_xmms/wrap_id3.c [new file with mode: 0644]
src/plugin_xmms/wrap_id3.h [new file with mode: 0644]

index 5a297c1..683584f 100644 (file)
@@ -104,6 +104,49 @@ AM_CONDITIONAL(FLaC__HAS_XMMS, test x$XMMS_INPUT_PLUGIN_DIR != x)
 
 SHARE_LIBS='$(top_builddir)/src/share/libutf8.a $(top_builddir)/src/share/libgetopt.a'
 
+dnl check for i18n(internationalization)
+AM_WITH_NLS
+AM_ICONV
+AM_LANGINFO_CODESET
+
+dnl check id3lib librairies
+LIBS_save_blah_blah_blah=$LIBS
+LIBS=""
+AC_SEARCH_LIBS(ID3Tag_Link,"id3" "id3 -lstdc++" "id3 -lz" "id3 -lz -lstdc++",
+               [have_id3lib=yes],
+               [AC_MSG_WARN([id3lib not found - ID3v2 will not be supported, internal function support only id3v1])])
+AM_CONDITIONAL(FLaC__HAS_ID3LIB, [test x$have_id3lib = xyes])
+if test x$have_id3lib = xyes ; then
+AC_DEFINE(FLAC__HAS_ID3LIB)
+ID3LIBS=$LIBS
+fi
+AC_SUBST(ID3LIBS)
+
+dnl expected version for cross compiling
+ID3LIB_MAJOR=3
+ID3LIB_MINOR=8
+ID3LIB_PATCH=0
+
+AC_MSG_CHECKING(for id3lib version)
+      AC_TRY_RUN([
+#include <id3.h>
+#include <stdio.h>
+int 
+main ()
+{
+    FILE *output;
+    output=fopen("conftest.id3","w");
+    fprintf(output,"ID3LIB_MAJOR=%d\nID3LIB_MINOR=%d\nID3LIB_PATCH=%d\n",ID3LIB_MAJOR_VERSION,ID3LIB_MINOR_VERSION,ID3LIB_PATCH_VERSION);
+    fclose(output);
+    exit(0);
+}
+], . conftest.id3; echo "${ID3LIB_MAJOR}.${ID3LIB_MINOR}.${ID3LIB_PATCH}", AC_MSG_WARN(could not determine id3lib version),[echo $ac_n "cross compiling; assuming ${ID3LIB_MAJOR}.${ID3LIB_MINOR}.${ID3LIB_PATCH} $ac_c"])
+AC_DEFINE_UNQUOTED(ID3LIB_MAJOR, $ID3LIB_MAJOR)
+AC_DEFINE_UNQUOTED(ID3LIB_MINOR, $ID3LIB_MINOR)
+AC_DEFINE_UNQUOTED(ID3LIB_PATCH, $ID3LIB_PATCH)
+
+LIBS=$LIBS_save_blah_blah_blah
+
 AC_CHECK_PROGS(NASM, nasm)
 AM_CONDITIONAL(FLaC__HAS_NASM, test -n "$NASM")
 if test -n "$NASM" ; then
index d2d3c1b..08bc019 100644 (file)
 #
 
 EXTRA_DIST = \
-       Makefile.lite
+       Makefile.lite \
+       id3_tag.c
 
 CFLAGS = @CFLAGS@ @XMMS_CFLAGS@
 xmmsinputplugindir = @XMMS_INPUT_PLUGIN_DIR@
+
 # Don't build a static library
 LIBTOOL = $(top_builddir)/libtool-disable-static
 
 xmmsinputplugin_LTLIBRARIES = libxmms-flac.la
-libxmms_flac_la_SOURCES = plugin.c
+
+plugin_sources = plugin.c wrap_id3.c configure.c charset.c
+id3v2_sources  = id3_tag.c
+
+if FLaC__HAS_ID3LIB
+libxmms_flac_la_SOURCES = $(plugin_sources) $(id3v2_sources)
+else
+libxmms_flac_la_SOURCES = $(plugin_sources)
+endif
+
 # work around the bug in libtool where its relinking fails with a different DESTDIR
 # for libtool bug info see:
 #   http://mail.gnu.org/pipermail/bug-libtool/2002-February/003018.html
@@ -37,5 +48,5 @@ libxmms_flac_la_SOURCES = plugin.c
 # for fix info see:
 #   http://lists.freshrpms.net/pipermail/rpm-list/2002-April/000746.html
 # the workaround is the extra '-L$(top_builddir)/src/libFLAC/.libs'
-libxmms_flac_la_LIBADD = $(top_builddir)/src/libFLAC/libFLAC.la -L$(top_builddir)/src/libFLAC/.libs @XMMS_LIBS@
+libxmms_flac_la_LIBADD = $(top_builddir)/src/libFLAC/libFLAC.la -L$(top_builddir)/src/libFLAC/.libs @XMMS_LIBS@ @ID3LIBS@
 libxmms_flac_la_LDFLAGS = -module -avoid-version
index 15011cd..e1c3c8d 100644 (file)
@@ -24,7 +24,11 @@ INCLUDES  = $(shell xmms-config --cflags) -I./include -I../../include
 LIBS = ../../obj/lib/libFLAC.a
 
 OBJS = \
-       plugin.o
+       plugin.o \
+       configure.o \
+       wrap_id3.o \
+       charset.o
+
 
 include ../../build/lib.mk
 
diff --git a/src/plugin_xmms/charset.c b/src/plugin_xmms/charset.c
new file mode 100644 (file)
index 0000000..d5b3e5a
--- /dev/null
@@ -0,0 +1,306 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ * Copyright (C) 2002  Daisuke Shimamura
+ *
+ * Almost from charset.c
+ *  EasyTAG - Tag editor for MP3 and OGG files
+ *  Copyright (C) 1999-2001  Håvard Kvålen <havardk@xmms.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <glib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef HAVE_ICONV
+#include <iconv.h>
+#endif
+
+#ifdef HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
+#include "charset.h"
+#include "mylocale.h"
+#include "configure.h"
+
+
+/****************
+ * Declarations *
+ ****************/
+
+#define CHARSET_TRANS_ARRAY_LEN ( sizeof(charset_trans_array) / sizeof((charset_trans_array)[0]) )
+const CharsetInfo charset_trans_array[] = { 
+    {N_("Arabic (IBM-864)"),                  "IBM864"        },
+    {N_("Arabic (ISO-8859-6)"),               "ISO-8859-6"    },
+    {N_("Arabic (Windows-1256)"),             "windows-1256"  },
+    {N_("Baltic (ISO-8859-13)"),              "ISO-8859-13"   },
+    {N_("Baltic (ISO-8859-4)"),               "ISO-8859-4"    },
+    {N_("Baltic (Windows-1257)"),             "windows-1257"  },
+    {N_("Celtic (ISO-8859-14)"),              "ISO-8859-14"   },
+    {N_("Central European (IBM-852)"),        "IBM852"        },
+    {N_("Central European (ISO-8859-2)"),     "ISO-8859-2"    },
+    {N_("Central European (Windows-1250)"),   "windows-1250"  },
+    {N_("Chinese Simplified (GB18030)"),      "gb18030"       },
+    {N_("Chinese Simplified (GB2312)"),       "GB2312"        },
+    {N_("Chinese Traditional (Big5)"),        "Big5"          },
+    {N_("Chinese Traditional (Big5-HKSCS)"),  "Big5-HKSCS"    },
+    {N_("Cyrillic (IBM-855)"),                "IBM855"        },
+    {N_("Cyrillic (ISO-8859-5)"),             "ISO-8859-5"    },
+    {N_("Cyrillic (ISO-IR-111)"),             "ISO-IR-111"    },
+    {N_("Cyrillic (KOI8-R)"),                 "KOI8-R"        },
+    {N_("Cyrillic (Windows-1251)"),           "windows-1251"  },
+    {N_("Cyrillic/Russian (CP-866)"),         "IBM866"        },
+    {N_("Cyrillic/Ukrainian (KOI8-U)"),       "KOI8-U"        },
+    {N_("English (US-ASCII)"),                "us-ascii"      },
+    {N_("Greek (ISO-8859-7)"),                "ISO-8859-7"    },
+    {N_("Greek (Windows-1253)"),              "windows-1253"  },
+    {N_("Hebrew (IBM-862)"),                  "IBM862"        },
+    {N_("Hebrew (Windows-1255)"),             "windows-1255"  },
+    {N_("Japanese (EUC-JP)"),                 "EUC-JP"        },
+    {N_("Japanese (ISO-2022-JP)"),            "ISO-2022-JP"   },
+    {N_("Japanese (Shift_JIS)"),              "Shift_JIS"     },
+    {N_("Korean (EUC-KR)"),                   "EUC-KR"        },
+    {N_("Nordic (ISO-8859-10)"),              "ISO-8859-10"   },
+    {N_("South European (ISO-8859-3)"),       "ISO-8859-3"    },
+    {N_("Thai (TIS-620)"),                    "TIS-620"       },
+    {N_("Turkish (IBM-857)"),                 "IBM857"        },
+    {N_("Turkish (ISO-8859-9)"),              "ISO-8859-9"    },
+    {N_("Turkish (Windows-1254)"),            "windows-1254"  },
+    {N_("Unicode (UTF-7)"),                   "UTF-7"         },
+    {N_("Unicode (UTF-8)"),                   "UTF-8"         },
+    {N_("Unicode (UTF-16BE)"),                "UTF-16BE"      },
+    {N_("Unicode (UTF-16LE)"),                "UTF-16LE"      },
+    {N_("Unicode (UTF-32BE)"),                "UTF-32BE"      },
+    {N_("Unicode (UTF-32LE)"),                "UTF-32LE"      },
+    {N_("Vietnamese (VISCII)"),               "VISCII"        },
+    {N_("Vietnamese (Windows-1258)"),         "windows-1258"  },
+    {N_("Visual Hebrew (ISO-8859-8)"),        "ISO-8859-8"    },
+    {N_("Western (IBM-850)"),                 "IBM850"        },
+    {N_("Western (ISO-8859-1)"),              "ISO-8859-1"    },
+    {N_("Western (ISO-8859-15)"),             "ISO-8859-15"   },
+    {N_("Western (Windows-1252)"),            "windows-1252"  }
+
+    /*
+     * From this point, character sets aren't supported by iconv
+     */
+/*    {N_("Arabic (IBM-864-I)"),                "IBM864i"              },
+    {N_("Arabic (ISO-8859-6-E)"),             "ISO-8859-6-E"         },
+    {N_("Arabic (ISO-8859-6-I)"),             "ISO-8859-6-I"         },
+    {N_("Arabic (MacArabic)"),                "x-mac-arabic"         },
+    {N_("Armenian (ARMSCII-8)"),              "armscii-8"            },
+    {N_("Central European (MacCE)"),          "x-mac-ce"             },
+    {N_("Chinese Simplified (GBK)"),          "x-gbk"                },
+    {N_("Chinese Simplified (HZ)"),           "HZ-GB-2312"           },
+    {N_("Chinese Traditional (EUC-TW)"),      "x-euc-tw"             },
+    {N_("Croatian (MacCroatian)"),            "x-mac-croatian"       },
+    {N_("Cyrillic (MacCyrillic)"),            "x-mac-cyrillic"       },
+    {N_("Cyrillic/Ukrainian (MacUkrainian)"), "x-mac-ukrainian"      },
+    {N_("Farsi (MacFarsi)"),                  "x-mac-farsi"},
+    {N_("Greek (MacGreek)"),                  "x-mac-greek"          },
+    {N_("Gujarati (MacGujarati)"),            "x-mac-gujarati"       },
+    {N_("Gurmukhi (MacGurmukhi)"),            "x-mac-gurmukhi"       },
+    {N_("Hebrew (ISO-8859-8-E)"),             "ISO-8859-8-E"         },
+    {N_("Hebrew (ISO-8859-8-I)"),             "ISO-8859-8-I"         },
+    {N_("Hebrew (MacHebrew)"),                "x-mac-hebrew"         },
+    {N_("Hindi (MacDevanagari)"),             "x-mac-devanagari"     },
+    {N_("Icelandic (MacIcelandic)"),          "x-mac-icelandic"      },
+    {N_("Korean (JOHAB)"),                    "x-johab"              },
+    {N_("Korean (UHC)"),                      "x-windows-949"        },
+    {N_("Romanian (MacRomanian)"),            "x-mac-romanian"       },
+    {N_("Turkish (MacTurkish)"),              "x-mac-turkish"        },
+    {N_("User Defined"),                      "x-user-defined"       },
+    {N_("Vietnamese (TCVN)"),                 "x-viet-tcvn5712"      },
+    {N_("Vietnamese (VPS)"),                  "x-viet-vps"           },
+    {N_("Western (MacRoman)"),                "x-mac-roman"          },
+    // charsets whithout posibly translatable names
+    {"T61.8bit",                              "T61.8bit"             },
+    {"x-imap4-modified-utf7",                 "x-imap4-modified-utf7"},
+    {"x-u-escaped",                           "x-u-escaped"          },
+    {"windows-936",                           "windows-936"          }
+*/
+};
+
+/*************
+ * Functions *
+ *************/
+
+char* get_current_charset (void)
+{
+    char *charset = getenv("CHARSET");
+
+#ifdef HAVE_LANGINFO_CODESET
+    if (!charset)
+        charset = nl_langinfo(CODESET);
+#endif
+    if (!charset)
+        charset = "ISO-8859-1";
+
+    return charset;
+}
+
+
+#ifdef HAVE_ICONV
+static char* convert_string (const char *string, char *from, char *to)
+{
+    size_t outleft, outsize, length;
+    iconv_t cd;
+    char *out, *outptr;
+    const char *input = string;
+
+    if (!string)
+        return NULL;
+
+    length = strlen(string);
+
+    /*  g_message("converting %s from %s to %s", string, from, to); */
+    if ((cd = iconv_open(to, from)) == (iconv_t)-1)
+    {
+        g_warning("convert_string(): Conversion not supported. Charsets: %s -> %s", from, to);
+        return g_strdup(string);
+    }
+
+    /* Due to a GLIBC bug, round outbuf_size up to a multiple of 4 */
+    /* + 1 for nul in case len == 1 */
+    outsize = ((length + 3) & ~3) + 1;
+    out = g_malloc(outsize);
+    outleft = outsize - 1;
+    outptr = out;
+
+ retry:
+    if (iconv(cd, &input, &length, &outptr, &outleft) == -1)
+    {
+        int used;
+        switch (errno)
+        {
+            case E2BIG:
+                used = outptr - out;
+                outsize = (outsize - 1) * 2 + 1;
+                out = g_realloc(out, outsize);
+                outptr = out + used;
+                outleft = outsize - 1 - used;
+                goto retry;
+            case EINVAL:
+                break;
+            case EILSEQ:
+                /* Invalid sequence, try to get the
+                                   rest of the string */
+                input++;
+                length = strlen(input);
+                goto retry;
+            default:
+                g_warning("convert_string(): Conversion failed. Inputstring: %s; Error: %s", string, strerror(errno));
+                break;
+        }
+    }
+    *outptr = '\0';
+
+    iconv_close(cd);
+    return out;
+}
+#else
+static char* convert_string (const char *string, char *from, char *to)
+{
+    if (!string)
+        return NULL;
+    return g_strdup(string);
+}
+#endif
+
+/*
+ * Commons conversion functions
+ */
+char* convert_from_file_to_user (const char *string)
+{
+    char *file_charset = flac_cfg.file_char_set;
+    char *user_charset = flac_cfg.user_char_set;
+
+    return convert_string(string,file_charset,user_charset);
+}
+
+char* convert_from_user_to_file (const char *string)
+{
+    char *file_charset = flac_cfg.file_char_set;
+    char *user_charset = flac_cfg.user_char_set;
+
+    return convert_string(string,user_charset,file_charset);
+}
+
+
+GList *Charset_Create_List (void)
+{
+    GList *list = NULL;
+    guint i;
+
+    for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
+        list = g_list_append(list,_(charset_trans_array[i].charset_title));
+    return list;
+}
+
+
+/*
+ * Return charset_name from charset_title
+ */
+gchar *Charset_Get_Name_From_Title (gchar *charset_title)
+{
+    guint i;
+
+    if (charset_title)
+        for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
+            if ( strcasecmp(_(charset_title),_(charset_trans_array[i].charset_title)) == 0 )
+                return charset_trans_array[i].charset_name;
+    return "";
+}
+
+
+/*
+ * Return charset_title from charset_name
+ */
+gchar *Charset_Get_Title_From_Name (gchar *charset_name)
+{
+    guint i;
+
+    if (charset_name)
+        for (i=0; i<CHARSET_TRANS_ARRAY_LEN; i++)
+            if ( strcasecmp(charset_name,charset_trans_array[i].charset_name) == 0 )
+                return _(charset_trans_array[i].charset_title);
+    return "";
+}
+
+
+
+/*
+ * Test if the conversion is supported between two character sets ('from' and 'to)
+ */
+#ifdef HAVE_ICONV
+gboolean test_conversion_charset (char *from, char *to)
+{
+    iconv_t cd;
+
+    if ((cd=iconv_open(to,from)) == (iconv_t)-1)
+    {
+        /* Conversion not supported */
+        return FALSE;
+    }
+    iconv_close(cd);
+    return TRUE;
+}
+#else
+gboolean test_conversion_charset (char *from, char *to)
+{
+    return TRUE;
+}
+#endif
diff --git a/src/plugin_xmms/charset.h b/src/plugin_xmms/charset.h
new file mode 100644 (file)
index 0000000..0a65dae
--- /dev/null
@@ -0,0 +1,57 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ * Copyright (C) 2002  Daisuke Shimamura
+ *
+ * Almost from charset.h - 2001/12/04
+ *  EasyTAG - Tag editor for MP3 and OGG files
+ *  Copyright (C) 1999-2001  H蛆ard Kv虱en <havardk@xmms.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __CHARSET_H__
+#define __CHARSET_H__
+
+
+/***************
+ * Declaration *
+ ***************/
+
+typedef struct {
+       gchar *charset_title;
+       gchar *charset_name;
+} CharsetInfo;
+
+/* translated charset titles */
+extern const CharsetInfo charset_trans_array[];
+
+/**************
+ * Prototypes *
+ **************/
+
+gchar* get_current_charset (void);
+
+gchar* convert_from_file_to_user (const gchar *string);
+gchar* convert_from_user_to_file (const gchar *string);
+
+GList *Charset_Create_List (void);
+gchar *Charset_Get_Name_From_Title (gchar *charset_title);
+gchar *Charset_Get_Title_From_Name (gchar *charset_name);
+
+gboolean test_conversion_charset (char *from, char *to);
+
+
+#endif /* __CHARSET_H__ */
+
diff --git a/src/plugin_xmms/configure.c b/src/plugin_xmms/configure.c
new file mode 100644 (file)
index 0000000..83c9ec3
--- /dev/null
@@ -0,0 +1,258 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ * Copyright (C) 2002  Daisuke Shimamura
+ *
+ * Based on mpg123 plugin
+ *          and prefs.c - 2000/05/06
+ *  EasyTAG - Tag editor for MP3 and OGG files
+ *  Copyright (C) 2000-2002  Jerome Couderc <j.couderc@ifrance.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <pthread.h>
+
+#include <xmms/configfile.h>
+#include <xmms/dirbrowser.h>
+#include <xmms/titlestring.h>
+#include <xmms/util.h>
+#include <xmms/plugin.h>
+
+#include "mylocale.h"
+#include "charset.h"
+#include "configure.h"
+
+/*
+ * Initialize Global Valueable
+ */
+flac_config_t flac_cfg = {
+       FALSE,
+       NULL,
+       FALSE,
+       NULL,
+       NULL
+};
+
+
+static GtkWidget *flac_configurewin = NULL;
+static GtkWidget *vbox, *notebook;
+
+static GtkWidget *title_tag_override, *title_tag_box, *title_tag_entry, *title_desc;
+static GtkWidget *convert_char_set, *fileCharacterSetEntry, *userCharacterSetEntry;
+
+static gchar *gtk_entry_get_text_1 (GtkWidget *widget);
+static void flac_configurewin_ok(GtkWidget * widget, gpointer data);
+static void configure_destroy(GtkWidget * w, gpointer data);
+static void title_tag_override_cb(GtkWidget * w, gpointer data);
+static void convert_char_set_cb(GtkWidget * w, gpointer data);
+
+static void flac_configurewin_ok(GtkWidget * widget, gpointer data)
+{
+       ConfigFile *cfg;
+       gchar *filename;
+
+       g_free(flac_cfg.tag_format);
+        flac_cfg.tag_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(title_tag_entry)));        
+       flac_cfg.file_char_set = Charset_Get_Name_From_Title(gtk_entry_get_text_1(fileCharacterSetEntry));
+       flac_cfg.user_char_set = Charset_Get_Name_From_Title(gtk_entry_get_text_1(userCharacterSetEntry));
+
+       filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL);
+       cfg = xmms_cfg_open_file(filename);
+       if (!cfg)
+               cfg = xmms_cfg_new();
+       xmms_cfg_write_boolean(cfg, "flac", "tag_override", flac_cfg.tag_override);
+       xmms_cfg_write_string(cfg, "flac", "tag_format", flac_cfg.tag_format);
+       xmms_cfg_write_boolean(cfg, "flac", "convert_char_set", flac_cfg.convert_char_set);
+       xmms_cfg_write_string(cfg, "flac", "file_char_set", flac_cfg.file_char_set);
+       xmms_cfg_write_string(cfg, "flac", "user_char_set", flac_cfg.user_char_set);
+       xmms_cfg_write_file(cfg, filename);
+       xmms_cfg_free(cfg);
+       g_free(filename);
+       gtk_widget_destroy(flac_configurewin);
+}
+
+static void configure_destroy(GtkWidget * w, gpointer data)
+{
+}
+
+static void title_tag_override_cb(GtkWidget * w, gpointer data)
+{
+       flac_cfg.tag_override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(title_tag_override));
+
+       gtk_widget_set_sensitive(title_tag_box, flac_cfg.tag_override);
+       gtk_widget_set_sensitive(title_desc, flac_cfg.tag_override);
+
+}
+
+static void convert_char_set_cb(GtkWidget * w, gpointer data)
+{
+       flac_cfg.convert_char_set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(convert_char_set));
+
+       gtk_widget_set_sensitive(fileCharacterSetEntry, flac_cfg.convert_char_set);
+       gtk_widget_set_sensitive(userCharacterSetEntry, flac_cfg.convert_char_set);
+}
+
+void FLAC_XMMS__configure(void)
+{
+       GtkWidget *title_frame, *title_tag_vbox, *title_tag_label;
+       GtkWidget *label, *hbox;
+       GtkWidget *bbox, *ok, *cancel;
+       GList *list;
+
+       if (flac_configurewin != NULL) {
+               gdk_window_raise(flac_configurewin->window);
+               return;
+       }
+       flac_configurewin = gtk_window_new(GTK_WINDOW_DIALOG);
+       gtk_signal_connect(GTK_OBJECT(flac_configurewin), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &flac_configurewin);
+       gtk_signal_connect(GTK_OBJECT(flac_configurewin), "destroy", GTK_SIGNAL_FUNC(configure_destroy), &flac_configurewin);
+       gtk_window_set_title(GTK_WINDOW(flac_configurewin), _("Flac Configuration"));
+       gtk_window_set_policy(GTK_WINDOW(flac_configurewin), FALSE, FALSE, FALSE);
+       gtk_container_border_width(GTK_CONTAINER(flac_configurewin), 10);
+
+       vbox = gtk_vbox_new(FALSE, 10);
+       gtk_container_add(GTK_CONTAINER(flac_configurewin), vbox);
+
+       notebook = gtk_notebook_new();
+       gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 0);
+
+       /* Title config.. */
+
+       title_frame = gtk_frame_new(_("ID3 Tags:"));
+       gtk_container_border_width(GTK_CONTAINER(title_frame), 5);
+
+       title_tag_vbox = gtk_vbox_new(FALSE, 10);
+       gtk_container_border_width(GTK_CONTAINER(title_tag_vbox), 5);
+       gtk_container_add(GTK_CONTAINER(title_frame), title_tag_vbox);
+
+       /* Convert Char Set */
+
+       convert_char_set = gtk_check_button_new_with_label(_("Convert Character Set"));
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(convert_char_set), flac_cfg.convert_char_set);
+       gtk_signal_connect(GTK_OBJECT(convert_char_set), "clicked", convert_char_set_cb, NULL);
+       gtk_box_pack_start(GTK_BOX(title_tag_vbox), convert_char_set, FALSE, FALSE, 0);
+       // Combo boxes...
+       hbox = gtk_hbox_new(FALSE,4);
+       gtk_container_add(GTK_CONTAINER(title_tag_vbox),hbox);
+       label = gtk_label_new(_("Convert character set from :"));
+       gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
+       fileCharacterSetEntry = gtk_combo_new();
+       gtk_box_pack_start(GTK_BOX(hbox),fileCharacterSetEntry,TRUE,TRUE,0);
+
+       label = gtk_label_new (_("to :"));
+       gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,0);
+       userCharacterSetEntry = gtk_combo_new();
+       gtk_box_pack_start(GTK_BOX(hbox),userCharacterSetEntry,TRUE,TRUE,0);
+
+       gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(fileCharacterSetEntry)->entry),FALSE);
+       gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(userCharacterSetEntry)->entry),FALSE);
+       gtk_combo_set_value_in_list(GTK_COMBO(fileCharacterSetEntry),TRUE,FALSE);
+       gtk_combo_set_value_in_list(GTK_COMBO(userCharacterSetEntry),TRUE,FALSE);
+
+       list = Charset_Create_List();
+       gtk_combo_set_popdown_strings(GTK_COMBO(fileCharacterSetEntry),list);
+       gtk_combo_set_popdown_strings(GTK_COMBO(userCharacterSetEntry),list);
+       gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(fileCharacterSetEntry)->entry),Charset_Get_Title_From_Name(flac_cfg.file_char_set));
+       gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(userCharacterSetEntry)->entry),Charset_Get_Title_From_Name(flac_cfg.user_char_set));
+       gtk_widget_set_sensitive(fileCharacterSetEntry, flac_cfg.convert_char_set);
+       gtk_widget_set_sensitive(userCharacterSetEntry, flac_cfg.convert_char_set);
+
+       /* Override Tagging Format */
+
+       title_tag_override = gtk_check_button_new_with_label(_("Override generic titles"));
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(title_tag_override), flac_cfg.tag_override);
+       gtk_signal_connect(GTK_OBJECT(title_tag_override), "clicked", title_tag_override_cb, NULL);
+       gtk_box_pack_start(GTK_BOX(title_tag_vbox), title_tag_override, FALSE, FALSE, 0);
+
+        title_tag_box = gtk_hbox_new(FALSE, 5);
+       gtk_widget_set_sensitive(title_tag_box, flac_cfg.tag_override);
+       gtk_box_pack_start(GTK_BOX(title_tag_vbox), title_tag_box, FALSE, FALSE, 0);
+       
+       title_tag_label = gtk_label_new(_("Title format:"));
+       gtk_box_pack_start(GTK_BOX(title_tag_box), title_tag_label, FALSE, FALSE, 0);
+       
+       title_tag_entry = gtk_entry_new();
+       gtk_entry_set_text(GTK_ENTRY(title_tag_entry), flac_cfg.tag_format);
+       gtk_box_pack_start(GTK_BOX(title_tag_box), title_tag_entry, TRUE, TRUE, 0);
+
+       title_desc = xmms_titlestring_descriptions("pafFetnygc", 2);
+       gtk_widget_set_sensitive(title_desc, flac_cfg.tag_override);
+       gtk_box_pack_start(GTK_BOX(title_tag_vbox), title_desc, FALSE, FALSE, 0);
+
+       gtk_notebook_append_page(GTK_NOTEBOOK(notebook), title_frame, gtk_label_new(_("Title")));
+
+       /* Buttons */
+
+       bbox = gtk_hbutton_box_new();
+       gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+       gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+       gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
+
+       ok = gtk_button_new_with_label(_("Ok"));
+       gtk_signal_connect(GTK_OBJECT(ok), "clicked", GTK_SIGNAL_FUNC(flac_configurewin_ok), NULL);
+       GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT);
+       gtk_box_pack_start(GTK_BOX(bbox), ok, TRUE, TRUE, 0);
+       gtk_widget_grab_default(ok);
+
+       cancel = gtk_button_new_with_label(_("Cancel"));
+       gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(flac_configurewin));
+       GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
+       gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
+
+       gtk_widget_show_all(flac_configurewin);
+}
+
+void FLAC_XMMS__aboutbox()
+{
+       static GtkWidget *about_window;
+
+       if (about_window)
+               gdk_window_raise(about_window->window);
+
+       about_window = xmms_show_message(
+               _("About Flac Plugin"),
+               _("Flac Plugin by Josh Coalson\n"
+                 "contributions by\n"
+                 "......\n"
+                 "......\n"
+                 "and\n"
+                 "Daisuke Shimamura\n"
+                 "Visit http://flac.sourceforge.net/"),
+               _("Ok"), FALSE, NULL, NULL);
+       gtk_signal_connect(GTK_OBJECT(about_window), "destroy",
+                          GTK_SIGNAL_FUNC(gtk_widget_destroyed),
+                          &about_window);
+}
+
+/*
+ * Get text of an Entry or a ComboBox
+ */
+static gchar *gtk_entry_get_text_1 (GtkWidget *widget)
+{
+    if (GTK_IS_COMBO(widget))
+    {
+        return gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(widget)->entry));
+    }else if (GTK_IS_ENTRY(widget))
+    {
+        return gtk_entry_get_text(GTK_ENTRY(widget));
+    }else
+    {
+        return NULL;
+    }
+}
+
diff --git a/src/plugin_xmms/configure.h b/src/plugin_xmms/configure.h
new file mode 100644 (file)
index 0000000..1b03050
--- /dev/null
@@ -0,0 +1,42 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ * Copyright (C) 2002  Daisuke Shimamura
+ *
+ * Based on mpg123 plugin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __CONFIGURE_H__
+#define __CONFIGURE_H__
+
+#include <glib.h>
+
+typedef struct {
+       gboolean tag_override;
+       gchar *tag_format;
+       gboolean convert_char_set;
+       gchar *file_char_set;
+       gchar *user_char_set;
+} flac_config_t;
+
+extern flac_config_t flac_cfg;
+
+extern void FLAC_XMMS__configure(void);
+extern void FLAC_XMMS__aboutbox();
+
+#endif
+
+
+
diff --git a/src/plugin_xmms/fileinfo.c b/src/plugin_xmms/fileinfo.c
new file mode 100644 (file)
index 0000000..3017073
--- /dev/null
@@ -0,0 +1,325 @@
+/*  XMMS - Cross-platform multimedia player
+ *  Copyright (C) 1998-2000  Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
+ *  Copyright (C) 1999,2000  Håvard Kvålen
+ *  Copyright (C) 2002  Daisuke Shimamura
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include "FLAC/all.h"
+#include "id3_tag.h"
+#include "configure.h"
+
+gboolean get_file_info(char *filename, flac_file_info_struct *tmp_file_info)
+{
+       FLAC__StreamMetadata streaminfo;
+
+       if(0 == filename)
+               filename = "";
+
+       if(!FLAC__metadata_get_streaminfo(filename, &streaminfo)) {
+               return FALSE;
+       }
+
+        tmp_file_info->sample_rate     = streaminfo.data.stream_info.sample_rate;
+        tmp_file_info->channels                = streaminfo.data.stream_info.channels;
+        tmp_file_info->bits_per_sample = streaminfo.data.stream_info.bits_per_sample;
+        tmp_file_info->total_samples   = streaminfo.data.stream_info.total_samples;
+
+       tmp_file_info->length_in_msec   = streaminfo.data.stream_info.total_samples * 10 / (streaminfo.data.stream_info.sample_rate / 100);
+
+       return TRUE;
+}
+
+static GtkWidget *window = NULL;
+static GtkWidget *filename_entry, *id3_frame;
+static GtkWidget *title_entry, *artist_entry, *album_entry, *year_entry, *tracknum_entry, *comment_entry;
+static GtkWidget *genre_combo;
+static GtkWidget *flac_level, *flac_bitrate, *flac_samplerate, *flac_flags;
+static GtkWidget *flac_fileinfo, *flac_genre;
+
+static gchar *current_filename = NULL;
+
+extern gchar *flac_filename;
+extern gint flac_bitrate, flac_frequency, flac_layer, flac_lsf, flac_mode;
+extern gboolean flac_stereo, flac_flac25;
+
+#define MAX_STR_LEN 100
+
+static void set_entry_tag(GtkEntry * entry, gchar * tag, gint length)
+{
+       gint stripped_len;
+       gchar *text;
+
+       stripped_len = flac_strip_spaces(tag, length);
+       text = g_strdup_printf("%-*.*s", stripped_len, stripped_len, tag);
+       gtk_entry_set_text(entry, text);
+       g_free(text);
+}
+
+static void get_entry_tag(GtkEntry * entry, gchar * tag, gint length)
+{
+       gchar *text;
+
+       text = gtk_entry_get_text(entry);
+       memset(tag, ' ', length);
+       memcpy(tag, text, strlen(text) > length ? length : strlen(text));
+}
+
+static gint genre_comp_func(gconstpointer a, gconstpointer b)
+{
+       return strcasecmp(a, b);
+}
+
+static gchar* channel_mode_name(int mode)
+{
+       static const gchar *channel_mode[] =
+               {N_("Mono"), N_("Stereo")};
+       if (mode < 1 || mode > 2)
+               return "";
+       return gettext(channel_mode[mode]);
+}
+
+void FLAC_XMMS__file_info_box(char *filename)
+{
+       gint i;
+       FILE *fh;
+       gchar *tmp, *title;
+
+       gboolean rc;
+
+#ifdef FLAC__HAS_ID3LIB
+       File_Tag tag;
+       Initialize_File_Tag_Item (&tag);
+       rc = Id3tag_Read_File_Tag (filename, &tag);
+#else
+       id3v2_struct tag;
+       memset(&tag, 0, sizeof(tag));
+       rc = get_id3v1_tag_as_v2_(filename, &tag);
+#endif
+
+       if (!window)
+       {
+               GtkWidget *vbox, *hbox, *left_vbox, *table;
+               GtkWidget *flac_frame, *flac_box;
+               GtkWidget *label, *filename_hbox;
+               GtkWidget *bbox, *save, *remove_id3, *cancel;
+               
+               window = gtk_window_new(GTK_WINDOW_DIALOG);
+               gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE);
+               gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window);
+               gtk_container_set_border_width(GTK_CONTAINER(window), 10);
+
+               vbox = gtk_vbox_new(FALSE, 10);
+               gtk_container_add(GTK_CONTAINER(window), vbox);
+
+               filename_hbox = gtk_hbox_new(FALSE, 5);
+               gtk_box_pack_start(GTK_BOX(vbox), filename_hbox, FALSE, TRUE, 0);
+
+               label = gtk_label_new(_("Filename:"));
+               gtk_box_pack_start(GTK_BOX(filename_hbox), label, FALSE, TRUE, 0);
+               filename_entry = gtk_entry_new();
+               gtk_editable_set_editable(GTK_EDITABLE(filename_entry), FALSE);
+               gtk_box_pack_start(GTK_BOX(filename_hbox), filename_entry, TRUE, TRUE, 0);
+               
+               hbox = gtk_hbox_new(FALSE, 10);
+               gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0);
+               
+               left_vbox = gtk_vbox_new(FALSE, 10);
+               gtk_box_pack_start(GTK_BOX(hbox), left_vbox, FALSE, FALSE, 0);
+
+               id3_frame = gtk_frame_new(_("ID3 Tag:"));
+               gtk_box_pack_start(GTK_BOX(left_vbox), id3_frame, FALSE, FALSE, 0);
+
+               table = gtk_table_new(5, 5, FALSE);
+               gtk_container_set_border_width(GTK_CONTAINER(table), 5);
+               gtk_container_add(GTK_CONTAINER(id3_frame), table);
+
+               label = gtk_label_new(_("Title:"));
+               gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+               gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, GTK_FILL, GTK_FILL, 5, 5);
+
+               title_entry = gtk_entry_new_with_max_length(30);
+               gtk_table_attach(GTK_TABLE(table), title_entry, 1, 4, 0, 1, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
+
+               label = gtk_label_new(_("Artist:"));
+               gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+               gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 5);
+
+               artist_entry = gtk_entry_new_with_max_length(30);
+               gtk_table_attach(GTK_TABLE(table), artist_entry, 1, 4, 1, 2, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
+
+               label = gtk_label_new(_("Album:"));
+               gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+               gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, GTK_FILL, GTK_FILL, 5, 5);
+
+               album_entry = gtk_entry_new_with_max_length(30);
+               gtk_table_attach(GTK_TABLE(table), album_entry, 1, 4, 2, 3, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
+
+               label = gtk_label_new(_("Comment:"));
+               gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+               gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, GTK_FILL, GTK_FILL, 5, 5);
+
+               comment_entry = gtk_entry_new_with_max_length(30);
+               gtk_table_attach(GTK_TABLE(table), comment_entry, 1, 4, 3, 4, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
+
+               label = gtk_label_new(_("Year:"));
+               gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+               gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5, GTK_FILL, GTK_FILL, 5, 5);
+
+               year_entry = gtk_entry_new_with_max_length(4);
+               gtk_widget_set_usize(year_entry, 40, -1);
+               gtk_table_attach(GTK_TABLE(table), year_entry, 1, 2, 4, 5, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
+
+               label = gtk_label_new(_("Track number:"));
+               gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+               gtk_table_attach(GTK_TABLE(table), label, 2, 3, 4, 5, GTK_FILL, GTK_FILL, 5, 5);
+
+               tracknum_entry = gtk_entry_new_with_max_length(3);
+               gtk_widget_set_usize(tracknum_entry, 40, -1);
+               gtk_table_attach(GTK_TABLE(table), tracknum_entry, 3, 4, 4, 5, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
+
+               label = gtk_label_new(_("Genre:"));
+               gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5);
+               gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6, GTK_FILL, GTK_FILL, 5, 5);
+
+               genre_combo = gtk_combo_new();
+               gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(genre_combo)->entry), FALSE);
+               if (!genre_list)
+               {
+                       for (i = 0; i < GENRE_MAX; i++)
+                               genre_list = g_list_prepend(genre_list, (char *) flac_id3_genres[i]);
+                       genre_list = g_list_prepend(genre_list, "");
+                       genre_list = g_list_sort(genre_list, genre_comp_func);
+               }
+               gtk_combo_set_popdown_strings(GTK_COMBO(genre_combo), genre_list);
+
+               gtk_table_attach(GTK_TABLE(table), genre_combo, 1, 4, 5, 6, GTK_FILL | GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5);
+
+               bbox = gtk_hbutton_box_new();
+               gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
+               gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
+               gtk_box_pack_start(GTK_BOX(left_vbox), bbox, FALSE, FALSE, 0);
+
+               save = gtk_button_new_with_label(_("Save"));
+               gtk_signal_connect(GTK_OBJECT(save), "clicked", GTK_SIGNAL_FUNC(save_cb), NULL);
+               GTK_WIDGET_SET_FLAGS(save, GTK_CAN_DEFAULT);
+               gtk_box_pack_start(GTK_BOX(bbox), save, TRUE, TRUE, 0);
+               gtk_widget_grab_default(save);
+
+               remove_id3 = gtk_button_new_with_label(_("Remove ID3"));
+               gtk_signal_connect(GTK_OBJECT(remove_id3), "clicked", GTK_SIGNAL_FUNC(remove_id3_cb), NULL);
+               GTK_WIDGET_SET_FLAGS(remove_id3, GTK_CAN_DEFAULT);
+               gtk_box_pack_start(GTK_BOX(bbox), remove_id3, TRUE, TRUE, 0);
+
+               cancel = gtk_button_new_with_label(_("Cancel"));
+               gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window));
+               GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT);
+               gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0);
+
+               flac_frame = gtk_frame_new(_("FLAC Info:"));
+               gtk_box_pack_start(GTK_BOX(hbox), flac_frame, FALSE, FALSE, 0);
+
+               flac_box = gtk_vbox_new(FALSE, 5);
+               gtk_container_add(GTK_CONTAINER(flac_frame), flac_box);
+               gtk_container_set_border_width(GTK_CONTAINER(flac_box), 10);
+               gtk_box_set_spacing(GTK_BOX(flac_box), 0);
+
+               flac_level = gtk_label_new("");
+               gtk_widget_set_usize(flac_level, 120, -2);
+               gtk_misc_set_alignment(GTK_MISC(flac_level), 0, 0);
+               gtk_box_pack_start(GTK_BOX(flac_box), flac_level, FALSE, FALSE, 0);
+
+               flac_bitrate = gtk_label_new("");
+               gtk_misc_set_alignment(GTK_MISC(flac_bitrate), 0, 0);
+               gtk_label_set_justify(GTK_LABEL(flac_bitrate), GTK_JUSTIFY_LEFT);
+               gtk_box_pack_start(GTK_BOX(flac_box), flac_bitrate, FALSE, FALSE, 0);
+
+               flac_samplerate = gtk_label_new("");
+               gtk_misc_set_alignment(GTK_MISC(flac_samplerate), 0, 0);
+               gtk_box_pack_start(GTK_BOX(flac_box), flac_samplerate, FALSE, FALSE, 0);
+
+               flac_flags = gtk_label_new("");
+               gtk_misc_set_alignment(GTK_MISC(flac_flags), 0, 0);
+               gtk_label_set_justify(GTK_LABEL(flac_flags), GTK_JUSTIFY_LEFT);
+               gtk_box_pack_start(GTK_BOX(flac_box), flac_flags, FALSE, FALSE, 0);
+
+               flac_fileinfo = gtk_label_new("");
+               gtk_misc_set_alignment(GTK_MISC(flac_fileinfo), 0, 0);
+               gtk_label_set_justify(GTK_LABEL(flac_fileinfo), GTK_JUSTIFY_LEFT);
+               gtk_box_pack_start(GTK_BOX(flac_box), flac_fileinfo, FALSE, FALSE, 0);
+
+               gtk_widget_show_all(window);
+       }
+
+       if (current_filename)
+               g_free(current_filename);
+       current_filename = g_strdup(filename);
+
+       title = g_strdup_printf(_("File Info - %s"), g_basename(filename));
+       gtk_window_set_title(GTK_WINDOW(window), title);
+       g_free(title);
+
+       gtk_entry_set_text(GTK_ENTRY(filename_entry), filename);
+       gtk_editable_set_position(GTK_EDITABLE(filename_entry), -1);
+
+       if (tag.title != NULL && strlen(tag.title) > 0)
+       {
+               gtk_entry_set_text(GTK_ENTRY(title_entry), tag.title);
+       }
+       else
+       {
+               title = g_strdup(g_basename(filename));
+               if ((tmp = strrchr(title, '.')) != NULL)
+                       *tmp = '\0';
+               gtk_entry_set_text(GTK_ENTRY(title_entry), title);
+               g_free(title);
+       }
+
+       gtk_entry_set_text(GTK_ENTRY(artist_entry), tag.artist);
+       gtk_entry_set_text(GTK_ENTRY(album_entry), tag.album);
+       gtk_entry_set_text(GTK_ENTRY(year_entry), tag.year);
+       gtk_entry_set_text(GTK_ENTRY(tracknum_entry), tag.track);
+       gtk_entry_set_text(GTK_ENTRY(comment_entry), tag.comment);
+       gtk_entry_set_text(GTK_ENTRY(genre_entry), tag.genre);
+
+       gtk_label_set_text(GTK_LABEL(flac_level), "");
+       gtk_label_set_text(GTK_LABEL(flac_bitrate), "");
+       gtk_label_set_text(GTK_LABEL(flac_samplerate), "");
+       gtk_label_set_text(GTK_LABEL(flac_flags), "");
+       gtk_label_set_text(GTK_LABEL(flac_fileinfo), "");
+
+       if (!strncasecmp(filename, "http://", 7))
+       {
+               file_info_http(filename);
+               return;
+       }
+
+       gtk_widget_set_sensitive(id3_frame, TRUE);
+
+       label_set_text(flac_bitrate, _("Bits/Samples: %d"), tmp_file_info->bits_per_sample);
+       /* tmp_file_info->length_in_msec */
+
+       label_set_text(flac_samplerate, _("Samplerate: %ld Hz"),         tmp_file_info->sample_rate);
+       label_set_text(flac_channel, _("Channel: %s"), channel_mode_name(tmp_file_info->channel);
+#if 0
+       label_set_text(flac_fileinfo, _("%d frames\nFilesize: %lu B"), num_frames, ftell(fh));
+#endif
+}
+
+
diff --git a/src/plugin_xmms/genres.h b/src/plugin_xmms/genres.h
new file mode 100644 (file)
index 0000000..7dc2aea
--- /dev/null
@@ -0,0 +1,187 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ * Copyright (C) 2002  Daisuke Shimamura
+ *
+ * Based on genres.h - EasyTAG - Jerome Couderc 2000/05/29
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+
+#ifndef __GENRES_H__
+#define __GENRES_H__
+
+
+/* GENRE_MAX is the last genre number that can be used */
+#define GENRE_MAX ( sizeof(id3_genres)/sizeof(id3_genres[0]) - 1 )
+#define ID3_INVALID_GENRE 255
+
+
+/* 
+ * Do not sort genres!!
+ * Last Update: 2000/04/30
+ */
+static char *id3_genres[] =
+{
+       "Blues",                /* 0 */
+       "Classic Rock",
+       "Country",
+       "Dance",
+       "Disco",
+       "Funk",                 /* 5 */
+       "Grunge",
+       "Hip-Hop", 
+       "Jazz",
+       "Metal",
+       "New Age",              /* 10 */                
+       "Oldies",
+       "Other", 
+       "Pop",
+       "R&B",
+       "Rap",                  /* 15 */
+       "Reggae", 
+       "Rock",
+       "Techno",
+       "Industrial",
+       "Alternative",          /* 20 */
+       "Ska",
+       "Death Metal", 
+       "Pranks",
+       "Soundtrack",
+       "Euro-Techno",          /* 25 */
+       "Ambient",
+       "Trip-Hop", 
+       "Vocal",
+       "Jazz+Funk", 
+       "Fusion",               /* 30 */
+       "Trance",
+       "Classical",
+       "Instrumental", 
+       "Acid",
+       "House",                /* 35 */
+       "Game",
+       "Sound Clip", 
+       "Gospel",
+       "Noise",
+       "Altern Rock",          /* 40 */
+       "Bass",
+       "Soul",
+       "Punk",
+       "Space",
+       "Meditative",           /* 45 */
+       "Instrumental Pop",
+       "Instrumental Rock", 
+       "Ethnic",
+       "Gothic",
+       "Darkwave",             /* 50 */
+       "Techno-Industrial", 
+       "Electronic", 
+       "Pop-Folk",
+       "Eurodance", 
+       "Dream",                /* 55 */
+       "Southern Rock", 
+       "Comedy", 
+       "Cult",
+       "Gangsta",
+       "Top 40",               /* 60 */
+       "Christian Rap", 
+       "Pop/Funk", 
+       "Jungle",
+       "Native American", 
+       "Cabaret",              /* 65 */
+       "New Wave",
+       "Psychadelic", 
+       "Rave",
+       "Showtunes", 
+       "Trailer",              /* 70 */
+       "Lo-Fi",
+       "Tribal",
+       "Acid Punk",
+       "Acid Jazz", 
+       "Polka",                /* 75 */
+       "Retro",
+       "Musical",
+       "Rock & Roll", 
+       "Hard Rock", 
+       "Folk",                 /* 80 */
+       "Folk/Rock",
+       "National Folk", 
+       "Fast Fusion",
+       "Swing",
+       "Bebob",                /* 85 */
+       "Latin",
+       "Revival",
+       "Celtic",
+       "Bluegrass",
+       "Avantgarde",           /* 90 */
+       "Gothic Rock",
+       "Progressive Rock",
+       "Psychedelic Rock", 
+       "Symphonic Rock", 
+       "Slow Rock",            /* 95 */
+       "Big Band", 
+       "Chorus",
+       "Easy Listening", 
+       "Acoustic", 
+       "Humour",               /* 100 */
+       "Speech",
+       "Chanson", 
+       "Opera",
+       "Chamber Music", 
+       "Sonata",               /* 105 */
+       "Symphony",
+       "Booty Bass", 
+       "Primus",
+       "Porn Groove", 
+       "Satire",               /* 110 */
+       "Slow Jam", 
+       "Club",
+       "Tango",
+       "Samba",
+       "Folklore",             /* 115 */
+       "Ballad",
+       "Power Ballad",
+       "Rhythmic Soul",
+       "Freestyle",
+       "Duet",                 /* 120 */
+       "Punk Rock",
+       "Drum Solo",
+       "A Capella",
+       "Euro-House",
+       "Dance Hall",           /* 125 */
+       "Goa",
+       "Drum & Bass",
+       "Club-House",
+       "Hardcore",
+       "Terror",               /* 130 */
+       "Indie",
+       "BritPop",
+       "Negerpunk",
+       "Polsk Punk",
+       "Beat",                 /* 135 */
+       "Christian Gangsta Rap",
+       "Heavy Metal",
+       "Black Metal",
+       "Crossover",
+       "Contemporary Christian",/* 140 */
+       "Christian Rock",
+       "Merengue",
+       "Salsa",
+       "Thrash Metal",
+       "Anime",                /* 145 */
+       "JPop",
+       "Synthpop"
+};
+
+#endif /* __GENRES_H__ */
diff --git a/src/plugin_xmms/id3_tag.c b/src/plugin_xmms/id3_tag.c
new file mode 100644 (file)
index 0000000..c47e4be
--- /dev/null
@@ -0,0 +1,508 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ * Copyright (C) 2002  Daisuke Shimamura
+ *
+ * Almost from id3_tag.c - 2001/02/16
+ *  EasyTAG - Tag editor for MP3 and OGG files
+ *  Copyright (C) 2001-2002  Jerome Couderc <j.couderc@ifrance.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <id3.h>
+#include <gtk/gtk.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "configure.h"
+#include "genres.h"
+#include "charset.h"
+#include "mylocale.h"
+#include "id3_tag.h"
+
+/****************
+ * Declarations *
+ ****************/
+#define ID3V2_MAX_STRING_LEN 4096
+#define NUMBER_TRACK_FORMATED 1
+
+/**************
+ * Prototypes *
+ **************/
+static size_t ID3Tag_Link_1       (ID3Tag *id3tag, const char *filename);
+static size_t ID3Field_GetASCII_1 (const ID3Field *field, char *buffer, size_t maxChars, index_t itemNum);
+
+static gchar  *Id3tag_Genre_To_String (unsigned char genre_code);
+static void Strip_String (gchar *string);
+
+/*************
+ * Functions *
+ *************/
+/*
+ * Read id3v1.x / id3v2 tag and load data into the File_Tag structure using id3lib functions.
+ * Returns TRUE on success, else FALSE.
+ * If a tag entry exists (ex: title), we allocate memory, else value stays to NULL
+ */
+gboolean Id3tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
+{
+    FILE *file;
+    ID3Tag *id3_tag = NULL;    /* Tag defined by the id3lib */
+    gchar *string, *string1, *string2;
+    gboolean USE_CHARACTER_SET_TRANSLATION;
+
+    USE_CHARACTER_SET_TRANSLATION = flac_cfg.convert_char_set;
+
+    if (!filename || !FileTag)
+        return FALSE;
+
+    if ( (file=fopen(filename,"r"))==NULL )
+    {
+        g_print(_("ERROR while opening file: '%s' (%s).\n\a"),filename,g_strerror(errno));
+        return FALSE;
+    }
+    fclose(file); // We close it cause id3lib opens/closes file itself
+
+
+    /* Get data from tag */
+    if ( (id3_tag = ID3Tag_New()) )
+    {
+        ID3Frame *id3_frame;
+        ID3Field *id3_field;
+        luint frm_size;
+        luint num_chars;
+        guint field_num = 0; // First field
+
+        /* Link the file to the tag */
+        frm_size = ID3Tag_Link_1(id3_tag,filename);
+
+        string = g_malloc(ID3V2_MAX_STRING_LEN+1);
+
+        /*********
+         * Title *
+         *********/
+        if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_TITLE)) )
+        {
+            if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
+            {
+                // Note: if 'num_chars' is equal to 0, then the field is empty or corrupted!
+                if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
+                     && string != NULL )
+                {
+                    if (USE_CHARACTER_SET_TRANSLATION)
+                    {
+                        string1 = convert_from_file_to_user(string);
+                        Strip_String(string1);
+                        FileTag->title = g_strdup(string1);
+                        g_free(string1);
+                    }else
+                    {
+                        Strip_String(string);
+                        FileTag->title = g_strdup(string);
+                    }
+                }
+            }
+        }
+
+
+        /**********
+         * Artist *
+         **********/
+        if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_LEADARTIST)) )
+        {
+            if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
+            {
+                if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
+                     && string != NULL )
+                {
+                    if (USE_CHARACTER_SET_TRANSLATION)
+                    {
+                        string1 = convert_from_file_to_user(string);
+                        Strip_String(string1);
+                        FileTag->artist = g_strdup(string1);
+                        g_free(string1);
+                    }else
+                    {
+                        Strip_String(string);
+                        FileTag->artist = g_strdup(string);
+                    }
+                }
+            }
+        }
+
+
+        /*********
+         * Album *
+         *********/
+        if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_ALBUM)) )
+        {
+            if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
+            {
+                if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
+                     && string != NULL )
+                {
+                    if (USE_CHARACTER_SET_TRANSLATION)
+                    {
+                        string1 = convert_from_file_to_user(string);
+                        Strip_String(string1);
+                        FileTag->album = g_strdup(string1);
+                        g_free(string1);
+                    }else
+                    {
+                        Strip_String(string);
+                        FileTag->album = g_strdup(string);
+                    }
+                }
+            }
+        }
+
+
+        /********
+         * Year *
+         ********/
+        if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_YEAR)) )
+        {
+            if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
+            {
+                if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
+                     && string != NULL )
+                {
+                    gchar *tmp_str;
+
+                    Strip_String(string);
+
+                    /* Fix for id3lib 3.7.x: if the id3v1.x tag was filled with spaces
+                     * instead of zeroes, then the year field contains garbages! */
+                    tmp_str = string;
+                    while (isdigit(*tmp_str)) tmp_str++;
+                    *tmp_str = 0;
+                    /* End of fix for id3lib 3.7.x */
+
+                    if (USE_CHARACTER_SET_TRANSLATION)
+                    {
+                        string1 = convert_from_file_to_user(string);
+                        Strip_String(string1);
+                        FileTag->year = g_strdup(string1);
+                        g_free(string1);
+                    }else
+                    {
+                        Strip_String(string);
+                        FileTag->year = g_strdup(string);
+                    }
+                }
+            }
+        }
+
+
+        /*************************
+         * Track and Total Track *
+         *************************/
+        if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_TRACKNUM)) )
+        {
+            if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
+            {
+                if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
+                     && string != NULL )
+                {
+                    
+                    Strip_String(string);
+
+                    if (USE_CHARACTER_SET_TRANSLATION)
+                    {
+                        string1 = convert_from_file_to_user(string);
+                        string2 = strchr(string1,'/');
+                        if (NUMBER_TRACK_FORMATED)
+                        {
+                            if (string2)
+                            {
+                                FileTag->track_total = g_strdup_printf("%.2d",atoi(string2+1)); // Just to have numbers like this : '01', '05', '12', ...
+                                *string2 = '\0';
+                            }
+                            FileTag->track = g_strdup_printf("%.2d",atoi(string1)); // Just to have numbers like this : '01', '05', '12', ...
+                        }else
+                        {
+                            if (string2)
+                            {
+                                FileTag->track_total = g_strdup(string2+1);
+                                *string2 = '\0';
+                            }
+                            FileTag->track = g_strdup(string1);
+                        }
+                        g_free(string1);
+                    }else
+                    {
+                        string2 = strchr(string,'/');
+                        if (NUMBER_TRACK_FORMATED)
+                        {
+                            if (string2)
+                            {
+                                FileTag->track_total = g_strdup_printf("%.2d",atoi(string2+1)); // Just to have numbers like this : '01', '05', '12', ...
+                                *string2 = '\0';
+                            }
+                            FileTag->track = g_strdup_printf("%.2d",atoi(string)); // Just to have numbers like this : '01', '05', '12', ...
+                        }else
+                            {
+                            if (string2)
+                            {
+                                FileTag->track_total = g_strdup(string2+1);
+                                *string2 = '\0';
+                            }
+                            FileTag->track = g_strdup(string);
+                        }
+                    }
+                }
+            }
+        }
+
+
+        /*********
+         * Genre *
+         *********/
+        if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_CONTENTTYPE)) )
+        {
+            if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
+            {
+                /*
+                 * We manipulate only the name of the genre
+                 */
+                if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
+                     && string != NULL )
+                {
+                    gchar *tmp;
+
+                    Strip_String(string);
+
+                    if ( (string[0]=='(') && (tmp=strchr(string,')')) && (strlen((tmp+1))>0) )
+                    {
+    
+                        /* Convert a genre written as '(3)Dance' into 'Dance' */
+                        if (USE_CHARACTER_SET_TRANSLATION)
+                        {
+                            string1 = convert_from_file_to_user(tmp+1);
+                            FileTag->genre = g_strdup(string1);
+                            g_free(string1);
+                        }else
+                        {
+                            FileTag->genre = g_strdup(tmp+1);
+                        }
+
+                    }else if ( (string[0]=='(') && (tmp=strchr(string,')')) )
+                    {
+    
+                        /* Convert a genre written as '(3)' into 'Dance' */
+                        *tmp = 0;
+                        if (USE_CHARACTER_SET_TRANSLATION)
+                        {
+                            string1 = convert_from_file_to_user(Id3tag_Genre_To_String(atoi(string+1)));
+                            FileTag->genre = g_strdup(string1);
+                            g_free(string1);
+                        }else
+                        {
+                            FileTag->genre = g_strdup(Id3tag_Genre_To_String(atoi(string+1)));
+                        }
+
+                    }else
+                    {
+
+                        /* Genre is already written as 'Dance' */
+                            if (USE_CHARACTER_SET_TRANSLATION)
+                        {
+                            string1 = convert_from_file_to_user(string);
+                            FileTag->genre = g_strdup(string1);
+                            g_free(string1);
+                        }else
+                        {
+                            FileTag->genre = g_strdup(string);
+                        }
+
+                    }
+                }
+            }
+        }
+
+
+        /***********
+         * Comment *
+         ***********/
+        if ( (id3_frame = ID3Tag_FindFrameWithID(id3_tag,ID3FID_COMMENT)) )
+        {
+            if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_TEXT)) )
+            {
+                if ( (num_chars=ID3Field_GetASCII_1(id3_field,string,ID3V2_MAX_STRING_LEN,field_num)) > 0
+                     && string != NULL )
+                {
+                    if (USE_CHARACTER_SET_TRANSLATION)
+                    {
+                        string1 = convert_from_file_to_user(string);
+                        Strip_String(string1);
+                        FileTag->comment = g_strdup(string1);
+                        g_free(string1);
+                    }else
+                    {
+                        Strip_String(string);
+                        FileTag->comment = g_strdup(string);
+                    }
+                }
+            }
+            /*if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_DESCRIPTION)) )
+            {
+                gchar *comment1 = g_malloc0(MAX_STRING_LEN+1);
+                num_chars = ID3Field_GetASCII(id3_field,comment1,MAX_STRING_LEN,Item_Num);
+                g_free(comment1);
+            }
+            if ( (id3_field = ID3Frame_GetField(id3_frame,ID3FN_LANGUAGE)) )
+            {
+                gchar *comment2 = g_malloc0(MAX_STRING_LEN+1);
+                num_chars = ID3Field_GetASCII(id3_field,comment2,MAX_STRING_LEN,Item_Num);
+                g_free(comment2);
+            }*/
+        }
+        g_free(string);
+
+        /* Free allocated data */
+        ID3Tag_Delete(id3_tag);
+    }
+
+    return TRUE;
+}
+
+void Initialize_File_Tag_Item (File_Tag *FileTag)
+{
+    if (FileTag)
+    {
+        FileTag->key         = 0;
+        FileTag->saved       = FALSE;    
+        FileTag->title       = NULL;
+        FileTag->artist      = NULL;
+        FileTag->album       = NULL;
+        FileTag->track       = NULL;
+        FileTag->track_total = NULL;
+        FileTag->year        = NULL;
+        FileTag->genre       = NULL;
+        FileTag->comment     = NULL;
+    }
+}
+
+/*
+ * Frees a File_Tag item.
+ */
+gboolean Free_File_Tag_Item (File_Tag *FileTag)
+{
+    if (!FileTag) return FALSE;
+
+    if (FileTag->title)       g_free(FileTag->title);
+    if (FileTag->artist)      g_free(FileTag->artist);
+    if (FileTag->album)       g_free(FileTag->album);
+    if (FileTag->year)        g_free(FileTag->year);
+    if (FileTag->track)       g_free(FileTag->track);
+    if (FileTag->track_total) g_free(FileTag->track_total);
+    if (FileTag->genre)       g_free(FileTag->genre);
+    if (FileTag->comment)     g_free(FileTag->comment);
+
+    return TRUE;
+}
+
+/*
+ * Returns the name of a genre code if found
+ * Three states for genre code :
+ *    - defined (0 to GENRE_MAX)
+ *    - undefined/unknown (GENRE_MAX+1 to ID3_INVALID_GENRE-1)
+ *    - invalid (>ID3_INVALID_GENRE)
+ */
+static gchar *Id3tag_Genre_To_String (unsigned char genre_code)
+{
+    if (genre_code>=ID3_INVALID_GENRE)    /* empty */
+        return "";
+    else if (genre_code>GENRE_MAX)        /* unknown tag */
+        return "Unknown";
+    else                                  /* known tag */
+        return id3_genres[genre_code];
+}
+
+
+
+/*
+ * As the ID3Tag_Link function of id3lib-3.8.0pre2 returns the ID3v1 tags
+ * when a file has both ID3v1 and ID3v2 tags, we first try to explicitely
+ * get the ID3v2 tags with ID3Tag_LinkWithFlags and, if we cannot get them,
+ * fall back to the ID3v1 tags.
+ * (Written by Holger Schemel).
+ */
+static size_t ID3Tag_Link_1 (ID3Tag *id3tag, const char *filename)
+{
+    size_t offset;
+
+#   if ( (ID3LIB_MAJOR >= 3) && (ID3LIB_MINOR >= 8)  )
+        /* First, try to get the ID3v2 tags */
+        offset = ID3Tag_LinkWithFlags(id3tag,filename,ID3TT_ID3V2);
+        if (offset == 0)
+        {
+            /* No ID3v2 tags available => try to get the ID3v1 tags */
+            offset = ID3Tag_LinkWithFlags(id3tag,filename,ID3TT_ID3V1);
+        }
+#   else
+        /* Function 'ID3Tag_LinkWithFlags' is not defined up to id3lib-.3.7.13 */
+        offset = ID3Tag_Link(id3tag,filename);
+#   endif
+    //g_print("ID3 TAG SIZE: %d\t%s\n",offset,g_basename(filename));
+    return offset;
+}
+
+
+/*
+ * As the ID3Field_GetASCII function differs with the version of id3lib, we must redefine it.
+ */
+static size_t ID3Field_GetASCII_1(const ID3Field *field, char *buffer, size_t maxChars, index_t itemNum)
+{
+
+    /* Defined by id3lib:   ID3LIB_MAJOR_VERSION, ID3LIB_MINOR_VERSION, ID3LIB_PATCH_VERSION
+     * Defined by autoconf: ID3LIB_MAJOR,         ID3LIB_MINOR,         ID3LIB_PATCH
+     *
+     * <= 3.7.12 : first item num is 1 for ID3Field_GetASCII
+     *  = 3.7.13 : first item num is 0 for ID3Field_GetASCII
+     * >= 3.8.0  : doesn't need item num for ID3Field_GetASCII
+     */
+     //g_print("id3lib version: %d.%d.%d\n",ID3LIB_MAJOR,ID3LIB_MINOR,ID3LIB_PATCH);
+#    if (ID3LIB_MAJOR >= 3)
+         // (>= 3.x.x)
+#        if (ID3LIB_MINOR <= 7)
+             // (3.0.0 to 3.7.x)
+#            if (ID3LIB_PATCH >= 13)
+                 // (>= 3.7.13)
+                 return ID3Field_GetASCII(field,buffer,maxChars,itemNum);
+#            else
+                 return ID3Field_GetASCII(field,buffer,maxChars,itemNum+1);
+#            endif
+#        else
+             // (>= to 3.8.0)
+             //return ID3Field_GetASCII(field,buffer,maxChars);
+             return ID3Field_GetASCIIItem(field,buffer,maxChars,itemNum);
+#        endif
+#    else
+         // Not tested (< 3.x.x)
+         return ID3Field_GetASCII(field,buffer,maxChars,itemNum+1);
+#    endif
+}
+
+/*
+ * Delete spaces at the end and the beginning of the string 
+ */
+static void Strip_String (gchar *string)
+{
+    if (!string) return;
+    string = g_strstrip(string);
+}
+
diff --git a/src/plugin_xmms/id3_tag.h b/src/plugin_xmms/id3_tag.h
new file mode 100644 (file)
index 0000000..605e9dc
--- /dev/null
@@ -0,0 +1,67 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ * Copyright (C) 2002  Daisuke Shimamura
+ *
+ *  Based on id3_tag.h - 2001/02/16
+ *           et_core.h - 2001/10/21
+ *  EasyTAG - Tag editor for MP3 and OGG files
+ *  Copyright (C) 2001-2002  Jerome Couderc <j.couderc@ifrance.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __ID3TAG_H__
+#define __ID3TAG_H__
+
+#include <glib.h>
+
+/***************
+ * Declaration *
+ ***************/
+
+#ifndef MAX
+#    define MAX(a,b) ((a) > (b) ? (a) : (b))
+#endif
+
+#ifndef MIN
+#    define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+
+/*
+ * Description of each item of the TagList list
+ */
+typedef struct _File_Tag File_Tag;
+struct _File_Tag
+{
+    gulong key;            /* Incremented value */
+    gboolean saved;        /* Set to TRUE if this tag had been saved */
+    gchar *title;          /* Title of track */
+    gchar *artist;         /* Artist name */
+    gchar *album;          /* Album name */
+    gchar *year;           /* Year of track */
+    gchar *track;          /* Position of track in the album */
+    gchar *track_total;    /* The number of tracks for the album (ex: 12/20) */
+    gchar *genre;          /* Genre of song */
+    gchar *comment;        /* Comment */
+};
+
+/**************
+ * Prototypes *
+ **************/
+void Initialize_File_Tag_Item (File_Tag *FileTag);
+gboolean Free_File_Tag_Item (File_Tag *FileTag);
+gboolean Id3tag_Read_File_Tag  (gchar *filename, File_Tag *FileTag);
+
+#endif /* __ID3TAG_H__ */
diff --git a/src/plugin_xmms/mylocale.h b/src/plugin_xmms/mylocale.h
new file mode 100644 (file)
index 0000000..4bed7f8
--- /dev/null
@@ -0,0 +1,55 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ *
+ * locale.h - 2000/05/05 13:10 Jerome Couderc
+ *  EasyTAG - Tag editor for MP3 and OGG files
+ *  Copyright (C) 1999-2001  H蛆ard Kv虱en <havardk@xmms.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+/*
+ * Gettext support for EasyTAG
+ */
+
+
+
+#ifndef __MY_LOCALE_H__
+#define __MY_LOCALE_H__
+
+
+#include <locale.h>
+
+/*
+ * Standard gettext macros.
+ */
+#ifdef ENABLE_NLS
+#  include <libintl.h>
+#  define _(String) gettext (String)
+#  ifdef gettext_noop
+#    define N_(String) gettext_noop (String)
+#  else
+#    define N_(String) (String)
+#  endif
+#else
+#  define textdomain(String) (String)
+#  define gettext(String) (String)
+#  define dgettext(Domain,Message) (Message)
+#  define dcgettext(Domain,Message,Type) (Message)
+#  define bindtextdomain(Domain,Directory) (Domain)
+#  define _(String) (String)
+#  define N_(String) (String)
+#endif
+
+
+#endif /* __MY_LOCALE_H__ */
index 6052182..f4e40c8 100644 (file)
 #include <stdio.h>
 #include <glib.h>
 
-#include "xmms/plugin.h"
-#include "xmms/util.h"
+#include <xmms/plugin.h>
+#include <xmms/util.h>
+#include <xmms/configfile.h>
+#include <xmms/titlestring.h>
+
+#ifdef HAVE_LANGINFO_CODESET
+#include <langinfo.h>
+#endif
+
 #include "FLAC/all.h"
+#include "configure.h"
+#include "wrap_id3.h"
+#include "charset.h"
 
 #ifdef min
 #undef min
 #define min(x,y) ((x)<(y)?(x):(y))
 
 typedef struct {
-       FLAC__byte raw[128];
-       char title[31];
-       char artist[31];
-       char album[31];
-       char comment[31];
-       unsigned year;
-       unsigned track; /* may be 0 if v1 (not v1.1) tag */
-       unsigned genre;
-       char description[1024]; /* the formatted description passed to xmms */
-} id3v1_struct;
-
-typedef struct {
        FLAC__bool abort_flag;
        FLAC__bool is_playing;
        FLAC__bool eof;
@@ -67,7 +65,6 @@ static int  FLAC_XMMS__get_time();
 static void FLAC_XMMS__cleanup();
 static void FLAC_XMMS__get_song_info(char *filename, char **title, int *length);
 
-static FLAC__bool get_id3v1_tag_(const char *filename, id3v1_struct *tag);
 static void *play_loop_(void *arg);
 static FLAC__bool safe_decoder_init_(const char *filename, FLAC__FileDecoder *decoder);
 static void safe_decoder_finish_(FLAC__FileDecoder *decoder);
@@ -76,15 +73,14 @@ static FLAC__StreamDecoderWriteStatus write_callback_(const FLAC__FileDecoder *d
 static void metadata_callback_(const FLAC__FileDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data);
 static void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data);
 
-
 InputPlugin flac_ip =
 {
        NULL,
        NULL,
        "FLAC Player v" FLAC__VERSION_STRING,
        FLAC_XMMS__init,
-       NULL,
-       NULL,
+       FLAC_XMMS__aboutbox,
+       FLAC_XMMS__configure,
        FLAC_XMMS__is_our_file,
        NULL,
        FLAC_XMMS__play_file,
@@ -101,7 +97,7 @@ InputPlugin flac_ip =
        NULL,
        NULL,
        FLAC_XMMS__get_song_info,
-       NULL,                   /* file_info_box */
+       NULL,           /* file_info_box */
        NULL
 };
 
@@ -122,6 +118,30 @@ InputPlugin *get_iplugin_info()
 
 void FLAC_XMMS__init()
 {
+       ConfigFile *cfg;
+
+       flac_cfg.tag_override = FALSE;
+       g_free(flac_cfg.tag_format);
+       flac_cfg.convert_char_set = FALSE;
+               
+       cfg = xmms_cfg_open_default_file();
+       xmms_cfg_read_boolean(cfg, "flac", "tag_override", &flac_cfg.tag_override);
+       if (!xmms_cfg_read_string(cfg, "flac", "tag_format",
+                                 &flac_cfg.tag_format))
+               flac_cfg.tag_format = g_strdup("%p - %t");
+
+       xmms_cfg_read_boolean(cfg, "flac", "convert_char_set", &flac_cfg.convert_char_set);
+       if (!xmms_cfg_read_string(cfg, "flac", "file_char_set",
+                                 &flac_cfg.file_char_set))
+       {
+               flac_cfg.file_char_set = get_current_charset();
+       }
+       if (!xmms_cfg_read_string(cfg, "flac", "user_char_set",
+                                 &flac_cfg.user_char_set))
+       {
+               flac_cfg.user_char_set = get_current_charset();
+       }
+
        decoder_ = FLAC__file_decoder_new();
 }
 
@@ -139,7 +159,7 @@ int FLAC_XMMS__is_our_file(char *filename)
 void FLAC_XMMS__play_file(char *filename)
 {
        FILE *f;
-       id3v1_struct tag;
+       gchar *ret;
 
        reservoir_samples_ = 0;
        audio_error_ = false;
@@ -166,8 +186,10 @@ void FLAC_XMMS__play_file(char *filename)
                return;
        }
 
-       (void)get_id3v1_tag_(filename, &tag);
-       flac_ip.set_info(tag.description, file_info_.length_in_msec, file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample, file_info_.sample_rate, file_info_.channels);
+       ret = flac_format_song_title(filename);
+       flac_ip.set_info(ret, file_info_.length_in_msec, file_info_.sample_rate * file_info_.channels * file_info_.bits_per_sample, file_info_.sample_rate, file_info_.channels);
+
+       g_free(ret);
 
        file_info_.seek_to_in_sec = -1;
        file_info_.play_thread_open = true;
@@ -219,7 +241,6 @@ void FLAC_XMMS__cleanup()
 
 void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec)
 {
-       id3v1_struct tag;
        FLAC__StreamMetadata streaminfo;
 
        if(0 == filename)
@@ -238,9 +259,7 @@ void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec)
        }
 
        if(title) {
-               (void)get_id3v1_tag_(filename, &tag);
-               *title = g_malloc(strlen(tag.description)+1);
-               strcpy(*title, tag.description);
+               *title = flac_format_song_title(filename);
        }
        if(length_in_msec)
                *length_in_msec = streaminfo.data.stream_info.total_samples * 10 / (streaminfo.data.stream_info.sample_rate / 100);
@@ -250,52 +269,6 @@ void FLAC_XMMS__get_song_info(char *filename, char **title, int *length_in_msec)
  * local routines
  **********************************************************************/
 
-FLAC__bool get_id3v1_tag_(const char *filename, id3v1_struct *tag)
-{
-       const char *temp;
-       FILE *f = fopen(filename, "rb");
-       memset(tag, 0, sizeof(id3v1_struct));
-
-       /* set the title and description to the filename by default */
-       temp = strrchr(filename, '/');
-       if(!temp)
-               temp = filename;
-       else
-               temp++;
-       strcpy(tag->description, temp);
-       *strrchr(tag->description, '.') = '\0';
-       strncpy(tag->title, tag->description, 30); tag->title[30] = '\0';
-
-       if(0 == f)
-               return false;
-       if(-1 == fseek(f, -128, SEEK_END)) {
-               fclose(f);
-               return false;
-       }
-       if(fread(tag->raw, 1, 128, f) < 128) {
-               fclose(f);
-               return false;
-       }
-       fclose(f);
-       if(strncmp(tag->raw, "TAG", 3))
-               return false;
-       else {
-               char year_str[5];
-
-               memcpy(tag->title, tag->raw+3, 30);
-               memcpy(tag->artist, tag->raw+33, 30);
-               memcpy(tag->album, tag->raw+63, 30);
-               memcpy(year_str, tag->raw+93, 4); year_str[4] = '\0'; tag->year = atoi(year_str);
-               memcpy(tag->comment, tag->raw+97, 30);
-               tag->genre = (unsigned)((FLAC__byte)tag->raw[127]);
-               tag->track = (unsigned)((FLAC__byte)tag->raw[126]);
-
-               sprintf(tag->description, "%s - %s", tag->artist, tag->title);
-
-               return true;
-       }
-}
-
 void *play_loop_(void *arg)
 {
        (void)arg;
@@ -463,3 +436,4 @@ void error_callback_(const FLAC__FileDecoder *decoder, FLAC__StreamDecoderErrorS
        if(status != FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC)
                file_info->abort_flag = true;
 }
+
diff --git a/src/plugin_xmms/wrap_id3.c b/src/plugin_xmms/wrap_id3.c
new file mode 100644 (file)
index 0000000..b158531
--- /dev/null
@@ -0,0 +1,272 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ * Copyright (C) 2000,2001,2002  Josh Coalson
+ * Copyright (C) 2002  Daisuke Shimamura
+ *
+ * Based on FLAC plugin.c and mpg123 plugin
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <glib.h>
+#include <xmms/plugin.h>
+#include <xmms/util.h>
+#include <xmms/configfile.h>
+#include <xmms/titlestring.h>
+
+#include "mylocale.h"
+#include "configure.h"
+
+#ifdef FLAC__HAS_ID3LIB
+#include <id3.h>
+#include "id3_tag.h"
+
+#else
+#include "charset.h"
+#include "genres.h"
+
+typedef struct id3v1tag_t {
+       char tag[3]; /* always "TAG": defines ID3v1 tag 128 bytes before EOF */
+       char title[30];
+       char artist[30];
+       char album[30];
+       char year[4];
+       union {
+               struct {
+                       char comment[30];
+               } v1_0;
+               struct {
+                       char comment[28];
+                       char __zero;
+                       unsigned char track;
+               } v1_1;
+       } u;
+       unsigned char genre;
+} id3v1_struct;
+
+typedef struct id3tag_t {
+       char title[64];
+       char artist[64];
+       char album[64];
+       char comment[256];
+       char genre[256];
+       char year[16];
+       char track[16];
+} id3v2_struct;
+
+static gboolean get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *tag);
+static void flac_id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2);
+static const char *flac_get_id3_genre(unsigned char genre_code);
+#endif /* FLAC__HAS_ID3LIB */
+
+static gchar *extname(const char *filename);
+static char* flac_getstr(char* str);
+static int flac_getnum(char* str);
+
+/*
+ * Function flac_format_song_title (tag, filename)
+ *
+ *    Create song title according to `tag' and/or `filename' and
+ *    return it.  The title must be subsequently freed using g_free().
+ *
+ */
+gchar *flac_format_song_title(gchar * filename)
+{
+       gchar *ret = NULL;
+       TitleInput *input = NULL;
+       gboolean rc;
+
+#ifdef FLAC__HAS_ID3LIB
+       File_Tag tag;
+       Initialize_File_Tag_Item (&tag);
+       rc = Id3tag_Read_File_Tag (filename, &tag);
+#else
+       id3v2_struct tag;
+       memset(&tag, 0, sizeof(tag));
+       rc = get_id3v1_tag_as_v2_(filename, &tag);
+#endif
+       XMMS_NEW_TITLEINPUT(input);
+
+       if (rc)
+       {
+               input->performer = flac_getstr(tag.artist);
+               input->album_name = flac_getstr(tag.album);
+               input->track_name = flac_getstr(tag.title);
+               input->track_number = flac_getnum(tag.track);
+               input->year = flac_getnum(tag.year);
+               input->genre = flac_getstr(tag.genre);
+               input->comment = flac_getstr(tag.comment);
+       }
+       input->file_name = g_basename(filename);
+       input->file_path = filename;
+       input->file_ext = extname(filename);
+       ret = xmms_get_titlestring(flac_cfg.tag_override ?
+                                  flac_cfg.tag_format :
+                                  xmms_get_gentitle_format(), input);
+       g_free(input);
+
+       if (!ret)
+       {
+               /*
+                * Format according to filename.
+                */
+               ret = g_strdup(g_basename(filename));
+               if (extname(ret) != NULL)
+                       *(extname(ret) - 1) = '\0';     /* removes period */
+       }
+
+#ifdef FLAC__HAS_ID3LIB
+       Free_File_Tag_Item  (&tag);
+#endif
+       return ret;
+}
+
+/*
+ * Function extname (filename)
+ *
+ *    Return pointer within filename to its extenstion, or NULL if
+ *    filename has no extension.
+ *
+ */
+static gchar *extname(const char *filename)
+{
+       gchar *ext = strrchr(filename, '.');
+
+       if (ext != NULL)
+               ++ext;
+
+       return ext;
+}
+
+static char* flac_getstr(char* str)
+{
+       if (str && strlen(str) > 0)
+               return str;
+       return NULL;
+}
+
+static int flac_getnum(char* str)
+{
+       if (str && strlen(str) > 0)
+               return atoi(str);
+       return 0;
+}
+
+#ifndef FLAC__HAS_ID3LIB
+/*
+ * Function get_idv2_tag_(filename, ID3v2tag)
+ *
+ *    Get ID3v2 tag from file.
+ *
+ */
+static gboolean get_id3v1_tag_as_v2_(const char *filename, id3v2_struct *id3v2tag)
+{
+       FILE *file;
+       id3v1_struct id3v1tag;
+
+       memset(id3v2tag, 0, sizeof(id3v2_struct));
+
+       if ((file = fopen(filename, "rb")) != 0)
+       {
+               if ((fseek(file, -1 * sizeof (id3v1tag), SEEK_END) == 0) &&
+                   (fread(&id3v1tag, 1, sizeof (id3v1tag), file) == sizeof (id3v1tag)) &&
+                   (strncmp(id3v1tag.tag, "TAG", 3) == 0))
+               {
+                       flac_id3v1_to_id3v2(&id3v1tag, id3v2tag);
+
+                       if (flac_cfg.convert_char_set)
+                       {
+                               gchar *string;
+
+                               string = convert_from_file_to_user(id3v2tag->title);
+                               strcpy(id3v2tag->title, string);
+                               g_free(string);
+
+                               string = convert_from_file_to_user(id3v2tag->artist);
+                               strcpy(id3v2tag->artist, string);
+                               g_free(string);
+
+                               string = convert_from_file_to_user(id3v2tag->album);
+                               strcpy(id3v2tag->album, string);
+                               g_free(string);
+
+                               string = convert_from_file_to_user(id3v2tag->comment);
+                               strcpy(id3v2tag->comment, string);
+                               g_free(string);
+
+                               string = convert_from_file_to_user(id3v2tag->genre);
+                               strcpy(id3v2tag->genre, string);
+                               g_free(string);
+
+                               string = convert_from_file_to_user(id3v2tag->year);
+                               strcpy(id3v2tag->year, string);
+                               g_free(string);
+
+                               string = convert_from_file_to_user(id3v2tag->track);
+                               strcpy(id3v2tag->track, string);
+                               g_free(string);
+                       }
+               }
+
+       }
+       else
+       {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+/*
+ * Function flac_id3v1_to_id3v2 (v1, v2)
+ *
+ *    Convert ID3v1 tag `v1' to ID3v2 tag `v2'.
+ *
+ */
+static void flac_id3v1_to_id3v2(id3v1_struct *v1, id3v2_struct *v2)
+{
+       memset(v2,0,sizeof(id3v2_struct));
+       strncpy(v2->title, v1->title, 30);
+       strncpy(v2->artist, v1->artist, 30);
+       strncpy(v2->album, v1->album, 30);
+       strncpy(v2->comment, v1->u.v1_0.comment, 30);
+       strncpy(v2->genre, flac_get_id3_genre(v1->genre), sizeof (v2->genre));
+       strncpy(v2->year, v1->year, 4);
+
+       /* Check for v1.1 tags. */
+       if (v1->u.v1_1.__zero == 0)
+               sprintf(v2->track, "%d", v1->u.v1_1.track);
+       else
+               strcpy(v2->track, "0");
+
+       g_strstrip(v2->title);
+       g_strstrip(v2->artist);
+       g_strstrip(v2->album);
+       g_strstrip(v2->comment);
+       g_strstrip(v2->genre);
+       g_strstrip(v2->year);
+       g_strstrip(v2->track);
+}
+
+static const char *flac_get_id3_genre(unsigned char genre_code)
+{
+       if (genre_code < GENRE_MAX)
+               return gettext(id3_genres[genre_code]);
+
+       return "";
+}
+#endif /* ifndef FLAC__HAS_ID3LIB */
diff --git a/src/plugin_xmms/wrap_id3.h b/src/plugin_xmms/wrap_id3.h
new file mode 100644 (file)
index 0000000..9ee4c2a
--- /dev/null
@@ -0,0 +1,24 @@
+/* libxmms-flac - XMMS FLAC input plugin
+ * Copyright (C) 2002  Daisuke Shimamura
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ */
+
+#ifndef __FLAC_ID3_H__
+#define __FLAC_ID3_H__
+
+gchar *flac_format_song_title(gchar * filename);
+
+#endif