From 448f6f91c7bd14d9e4ad26ac4793a9d59845c0cd Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Sat, 27 Mar 2021 03:05:19 +0100 Subject: Restructure to make XMMS just one of the patches --- 3rdparty/mpg123/0050_all_libxmms-charset.patch | 191 -- 3rdparty/mpg123/2011_all_mpg123-http-seek.patch | 201 -- 3rdparty/mpg123/2012_all_mpg123-id3convert.patch | 41 - 3rdparty/mpg123/2013_all_mpg123-latin-id3.patch | 128 -- .../mpg123/2014_all_mpg123-encode-override.patch | 130 -- 3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch | 2247 -------------------- 3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch | 766 ------- ReadMe | 70 +- VERSION | 1 + apply.sh | 50 - misc/brokentags.c | 16 - patches/xmms-plugins/xmms-wma-csa1.tar.bz2 | Bin 20480 -> 0 bytes .../3rdparty/mpg123/0050_all_libxmms-charset.patch | 191 ++ .../mpg123/2011_all_mpg123-http-seek.patch | 201 ++ .../mpg123/2012_all_mpg123-id3convert.patch | 41 + .../mpg123/2013_all_mpg123-latin-id3.patch | 128 ++ .../mpg123/2014_all_mpg123-encode-override.patch | 130 ++ .../mpg123/2015_all_mpg123-id3v2edit.patch | 2247 ++++++++++++++++++++ .../mpg123/2020_all_mpg123-vorbis-ssl.patch | 766 +++++++ patches/xmms/ReadMe | 86 + patches/xmms/apply.sh | 50 + .../xmms/extra/xmms-ds-mpg123-wrongencoding.patch | 157 -- .../extra/xmms-ds-mpg123-wrongencoding.patch | 157 ++ .../plugins/xmms-ds-mpg123-editor-keys.patch | 164 ++ .../patches/plugins/xmms-ds-mpg123-editor.patch | 202 ++ patches/xmms/patches/plugins/xmms-ds-mpg123.patch | 20 + .../plugins/xmms-ds-vorbis-editor-keys.patch | 78 + .../patches/plugins/xmms-ds-vorbis-editor.patch | 51 + patches/xmms/patches/xmms-ds-playlist.patch | 526 +++++ patches/xmms/patches/xmms-ds-rusxmms-charset.patch | 87 + patches/xmms/patches/xmms-ds-rusxmms.patch | 172 ++ patches/xmms/patches/xmms-ds-shade.patch | 194 ++ patches/xmms/patches/xmms-ds-textbox.patch | 31 + .../xmms/plugins/xmms-ds-mpg123-editor-keys.patch | 164 -- patches/xmms/plugins/xmms-ds-mpg123-editor.patch | 202 -- patches/xmms/plugins/xmms-ds-mpg123.patch | 20 - .../xmms/plugins/xmms-ds-vorbis-editor-keys.patch | 78 - patches/xmms/plugins/xmms-ds-vorbis-editor.patch | 51 - patches/xmms/plugins/xmms-wma-csa1.tar.bz2 | Bin 0 -> 20480 bytes patches/xmms/source/rcc.c | 185 ++ patches/xmms/source/rcc.h | 32 + patches/xmms/source/rcc_langs.h | 120 ++ patches/xmms/xmms-ds-playlist.patch | 526 ----- patches/xmms/xmms-ds-rusxmms-charset.patch | 87 - patches/xmms/xmms-ds-rusxmms.patch | 172 -- patches/xmms/xmms-ds-shade.patch | 194 -- patches/xmms/xmms-ds-textbox.patch | 31 - release | 38 + source/rcc.c | 185 -- source/rcc.h | 32 - source/rcc_langs.h | 120 -- 51 files changed, 5903 insertions(+), 5854 deletions(-) delete mode 100644 3rdparty/mpg123/0050_all_libxmms-charset.patch delete mode 100644 3rdparty/mpg123/2011_all_mpg123-http-seek.patch delete mode 100644 3rdparty/mpg123/2012_all_mpg123-id3convert.patch delete mode 100644 3rdparty/mpg123/2013_all_mpg123-latin-id3.patch delete mode 100644 3rdparty/mpg123/2014_all_mpg123-encode-override.patch delete mode 100644 3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch delete mode 100644 3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch create mode 100644 VERSION delete mode 100755 apply.sh delete mode 100644 misc/brokentags.c delete mode 100644 patches/xmms-plugins/xmms-wma-csa1.tar.bz2 create mode 100644 patches/xmms/3rdparty/mpg123/0050_all_libxmms-charset.patch create mode 100644 patches/xmms/3rdparty/mpg123/2011_all_mpg123-http-seek.patch create mode 100644 patches/xmms/3rdparty/mpg123/2012_all_mpg123-id3convert.patch create mode 100644 patches/xmms/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch create mode 100644 patches/xmms/3rdparty/mpg123/2014_all_mpg123-encode-override.patch create mode 100644 patches/xmms/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch create mode 100644 patches/xmms/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch create mode 100644 patches/xmms/ReadMe create mode 100755 patches/xmms/apply.sh delete mode 100644 patches/xmms/extra/xmms-ds-mpg123-wrongencoding.patch create mode 100644 patches/xmms/patches/extra/xmms-ds-mpg123-wrongencoding.patch create mode 100644 patches/xmms/patches/plugins/xmms-ds-mpg123-editor-keys.patch create mode 100644 patches/xmms/patches/plugins/xmms-ds-mpg123-editor.patch create mode 100644 patches/xmms/patches/plugins/xmms-ds-mpg123.patch create mode 100644 patches/xmms/patches/plugins/xmms-ds-vorbis-editor-keys.patch create mode 100644 patches/xmms/patches/plugins/xmms-ds-vorbis-editor.patch create mode 100644 patches/xmms/patches/xmms-ds-playlist.patch create mode 100644 patches/xmms/patches/xmms-ds-rusxmms-charset.patch create mode 100644 patches/xmms/patches/xmms-ds-rusxmms.patch create mode 100644 patches/xmms/patches/xmms-ds-shade.patch create mode 100644 patches/xmms/patches/xmms-ds-textbox.patch delete mode 100644 patches/xmms/plugins/xmms-ds-mpg123-editor-keys.patch delete mode 100644 patches/xmms/plugins/xmms-ds-mpg123-editor.patch delete mode 100644 patches/xmms/plugins/xmms-ds-mpg123.patch delete mode 100644 patches/xmms/plugins/xmms-ds-vorbis-editor-keys.patch delete mode 100644 patches/xmms/plugins/xmms-ds-vorbis-editor.patch create mode 100644 patches/xmms/plugins/xmms-wma-csa1.tar.bz2 create mode 100644 patches/xmms/source/rcc.c create mode 100644 patches/xmms/source/rcc.h create mode 100644 patches/xmms/source/rcc_langs.h delete mode 100644 patches/xmms/xmms-ds-playlist.patch delete mode 100644 patches/xmms/xmms-ds-rusxmms-charset.patch delete mode 100644 patches/xmms/xmms-ds-rusxmms.patch delete mode 100644 patches/xmms/xmms-ds-shade.patch delete mode 100644 patches/xmms/xmms-ds-textbox.patch create mode 100755 release delete mode 100644 source/rcc.c delete mode 100644 source/rcc.h delete mode 100644 source/rcc_langs.h diff --git a/3rdparty/mpg123/0050_all_libxmms-charset.patch b/3rdparty/mpg123/0050_all_libxmms-charset.patch deleted file mode 100644 index 94416dd..0000000 --- a/3rdparty/mpg123/0050_all_libxmms-charset.patch +++ /dev/null @@ -1,191 +0,0 @@ -diff -Naur xmms-1.2.10-20041012/libxmms/charset.c xmms-1.2.10-20041012.convert/libxmms/charset.c ---- xmms-1.2.10-20041012/libxmms/charset.c 2004-10-13 01:03:03.258234924 -0700 -+++ xmms-1.2.10-20041012.convert/libxmms/charset.c 2004-10-24 23:49:42.083591275 -0700 -@@ -22,7 +22,6 @@ - - #include "charset.h" - -- - char* xmms_charset_get_current(void) - { - char *charset = getenv("CHARSET"); -@@ -38,6 +37,18 @@ - return charset; - } - -+static size_t utf16_strlen(const char *string) -+{ -+ size_t len = 0; -+ -+ if (!string) -+ return 0; -+ -+ while (*(string + len) != 0 || *(string + len + 1) != 0) -+ len += 2; -+ -+ return len; -+} - - #ifdef HAVE_ICONV - char* xmms_charset_convert(const char *string, size_t insize, char *from, char *to) -@@ -108,15 +119,55 @@ - { - if (!string) - return NULL; -+ - return xmms_charset_convert(string, strlen(string), "UTF-8", NULL); - } - -+char *xmms_charset_from_utf16(const unsigned char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return xmms_charset_convert(string, utf16_strlen(string), "UTF-16", NULL); -+} -+ -+char *xmms_charset_from_utf16be(const unsigned char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return xmms_charset_convert(string, utf16_strlen(string), "UTF-16BE", NULL); -+} -+ -+char* xmms_charset_from_latin1(const char *string) -+{ -+ char *to = xmms_charset_get_current(); -+ -+ if (!string) -+ return NULL; -+ -+ if (!strcmp(to, "UTF-8")) -+ return xmms_charset_convert(string, strlen(string), "ISO-8859-1", to); -+ else -+ return g_strdup(string); -+} -+ - #else - - char* xmms_charset_convert(const char *string, size_t insize, char *from, char *to) - { -+ if (!string) -+ return NULL; -+ - if (!strcmp(from, "UTF-8") && !to) - return xmms_charset_from_utf8(string); -+ -+ if (!strcmp(from, "UTF-16") && !to) -+ return xmms_charset_from_utf16(string); -+ -+ if (!strcmp(from, "UTF-16BE") && !to) -+ return xmms_charset_from_utf16be(string); -+ - return g_strdup(string); - } - -@@ -155,11 +206,83 @@ - return ascii; - } - -+static char* utf16_to_ascii(const unsigned char *utf16, int le) -+{ -+ char *ascii; -+ unsigned int i, len, c; -+ -+ if (!utf16) -+ return NULL; -+ -+ len = utf16_strlen(utf16) / 2 + 1; -+ -+ ascii = g_malloc(len + 1); -+ -+ for (i = 0, c = 0; i < len; i++) -+ { -+ guint16 uc; -+ int o = i << 1; -+ -+ if (le) -+ uc = *(utf16 + o) | *(utf16 + o + 1) << 8; -+ else -+ uc = *(utf16 + o) << 8 | *(utf16 + o + 1); -+ -+ /* Skip BOM and surrogate pairs */ -+ if (uc == 0xfeff || (uc >= 0xd800 && uc <= 0xdfff)) -+ continue; -+ -+ if (uc < 0x80) -+ ascii[c] = uc; -+ else -+ ascii[c] = '?'; -+ c++; -+ } -+ -+ ascii[c] = 0; -+ return ascii; -+} -+ -+char *xmms_charset_from_utf16(const unsigned char *string) -+{ -+ int le = FALSE; -+ guint16 bom; -+ -+ if (!string) -+ return NULL; -+ -+ bom = *string << 8 | *(string + 1); -+ -+ if (bom == 0xfffe) -+ le = TRUE; -+ else if (bom != 0xfeff) -+ return g_strdup(""); -+ -+ return utf16_to_ascii(string, le); -+} -+ -+char *xmms_charset_from_utf16be(const unsigned char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return utf16_to_ascii(string, FALSE); -+} -+ -+char* xmms_charset_from_latin1(const char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return g_strdup(string); -+} -+ - #endif - - char* xmms_charset_to_utf8(const char *string) - { - if (!string) - return NULL; -+ - return xmms_charset_convert(string, strlen(string), NULL, "UTF-8"); - } -diff -Naur xmms-1.2.10-20041012/libxmms/charset.h xmms-1.2.10-20041012.convert/libxmms/charset.h ---- xmms-1.2.10-20041012/libxmms/charset.h 2004-10-13 01:03:03.260234595 -0700 -+++ xmms-1.2.10-20041012.convert/libxmms/charset.h 2004-10-23 08:54:11.421220833 -0700 -@@ -5,11 +5,16 @@ - * - */ - -+#ifndef XMMS_CHARSET_H -+#define XMMS_CHARSET_H - - char* xmms_charset_get_current(void); - char* xmms_charset_convert(const char *string, size_t insize, char *from, char *to); - char* xmms_charset_to_utf8(const char *string); - char* xmms_charset_from_utf8(const char *string); -+char* xmms_charset_from_utf16(const unsigned char *string); -+char* xmms_charset_from_utf16be(const unsigned char *string); -+char* xmms_charset_from_latin1(const char *string); - -- -+#endif /* XMMS_CHARSET_H */ - diff --git a/3rdparty/mpg123/2011_all_mpg123-http-seek.patch b/3rdparty/mpg123/2011_all_mpg123-http-seek.patch deleted file mode 100644 index 67ab4f5..0000000 --- a/3rdparty/mpg123/2011_all_mpg123-http-seek.patch +++ /dev/null @@ -1,201 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/mpg123/common.c xmms-1.2.11-new/Input/mpg123/common.c ---- xmms-1.2.11/Input/mpg123/common.c 2005-05-15 02:01:19.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/common.c 2007-11-24 23:52:01.000000000 +0100 -@@ -148,19 +148,34 @@ - int mpg123_stream_jump_to_frame(struct frame *fr, int frame) - { - if (!filept) -- return -1; -- mpg123_read_frame_init(); -- fseek(filept, frame * (fr->framesize + 4), SEEK_SET); -- mpg123_read_frame(fr); -+ { -+ unsigned long r; -+ -+ r = frame * (fr->framesize + 4); -+ mpg123_stream_close(); -+ mpg123_open_stream(mpg123_filename, -1, r); -+ } -+ else -+ { -+ mpg123_read_frame_init(); -+ fseek(filept, frame * (fr->framesize + 4), SEEK_SET); -+ mpg123_read_frame(fr); -+ } - return 0; - } - - int mpg123_stream_jump_to_byte(struct frame *fr, int byte) - { - if (!filept) -- return -1; -- fseek(filept, byte, SEEK_SET); -- mpg123_read_frame(fr); -+ { -+ mpg123_stream_close(); -+ mpg123_open_stream(mpg123_filename, -1, (unsigned long)byte); -+ } -+ else -+ { -+ fseek(filept, byte, SEEK_SET); -+ mpg123_read_frame(fr); -+ } - return 0; - } - -@@ -446,14 +461,14 @@ - return 1; - } - --void mpg123_open_stream(char *bs_filenam, int fd) -+void mpg123_open_stream(char *bs_filenam, int fd, unsigned long range) - { - filept_opened = 1; - if (!strncasecmp(bs_filenam, "http://", 7)) - { - filept = NULL; -- mpg123_http_open(bs_filenam); - mpg123_info->filesize = 0; -+ mpg123_http_open(bs_filenam, range); - mpg123_info->network_stream = TRUE; - } - else -diff -dPNur xmms-1.2.11/Input/mpg123/http.c xmms-1.2.11-new/Input/mpg123/http.c ---- xmms-1.2.11/Input/mpg123/http.c 2007-11-16 22:51:24.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/http.c 2007-11-24 23:52:01.000000000 +0100 -@@ -50,6 +50,7 @@ - extern gboolean mpg123_stereo; - - static gboolean prebuffering, going, eof = FALSE; -+static unsigned long range; - static gint sock, rd_index, wr_index, buffer_length, prebuffer_length; - static guint64 buffer_read = 0; - static gchar *buffer; -@@ -326,7 +327,7 @@ - static void *http_buffer_loop(void *arg) - { - gchar line[1024], *user, *pass, *host, *filename, -- *status, *url, *temp, *file; -+ *status, *url, *temp, *temp2, *file; - gchar *chost; - gint cnt, written, error, port, cport; - socklen_t err_len; -@@ -495,15 +496,22 @@ - } - else - file = g_strconcat("/", filename, NULL); -- temp = g_strdup_printf("GET %s HTTP/1.0\r\n" -+ if (range) -+ { -+ temp2 = g_strdup_printf("Range: bytes=%lu-\r\n", range); -+ } else -+ temp2 = NULL; -+ temp = g_strdup_printf("GET %s HTTP/1.1\r\n" - "Host: %s\r\n" - "User-Agent: %s/%s\r\n" -- "%s%s%s%s\r\n", -+ "%s%s%s%s%s\r\n", - file, host, PACKAGE, VERSION, - proxy_auth ? proxy_auth : "", auth ? auth : "", - mpg123_cfg.cast_title_streaming ? "Icy-MetaData:1\r\n" : "", -- mpg123_cfg.use_udp_channel ? udpspace : ""); -- -+ mpg123_cfg.use_udp_channel ? udpspace : "", -+ range ? temp2 : ""); -+ -+ g_free(temp2); - g_free(file); - if(proxy_auth) - g_free(proxy_auth); -@@ -587,7 +595,9 @@ - #endif - /* udp_serverport = atoi (line + 20); */ - } -- -+ if (!strncasecmp(line, "content-length:", 15)) { -+ mpg123_info->filesize = atoi(line + 15); -+ } - } - else - { -@@ -719,7 +729,7 @@ - pthread_exit(NULL); - } - --int mpg123_http_open(gchar * _url) -+int mpg123_http_open(gchar * _url, unsigned long rng) - { - gchar *url; - -@@ -735,6 +745,7 @@ - going = TRUE; - eof = FALSE; - buffer = g_malloc(buffer_length); -+ range = rng; - - pthread_create(&thread, NULL, http_buffer_loop, url); - -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2006-07-25 05:18:51.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:52:01.000000000 +0100 -@@ -857,7 +857,7 @@ - - mpg123_read_frame_init(); - -- mpg123_open_stream(filename, -1); -+ mpg123_open_stream(filename, -1, 0); - if (mpg123_info->eof || !mpg123_read_frame(&fr)) - mpg123_info->eof = TRUE; - if (!mpg123_info->eof && mpg123_info->going) -@@ -906,7 +906,7 @@ - break; - } - -- if (!have_xing_header && strncasecmp(filename, "http://", 7)) -+ if(!have_xing_header && mpg123_info->filesize != 0) - mpg123_info->num_frames = mpg123_calc_numframes(&fr); - - memcpy(&fr, &temp_fr, sizeof(struct frame)); -@@ -918,11 +918,10 @@ - mpg123_lsf = fr.lsf; - mpg123_mpeg25 = fr.mpeg25; - mpg123_mode = fr.mode; -- -+ mpg123_length = mpg123_info->num_frames * mpg123_info->tpf * 1000; -+ - if (strncasecmp(filename, "http://", 7)) - { -- mpg123_length = -- mpg123_info->num_frames * mpg123_info->tpf * 1000; - if (!mpg123_title) - mpg123_title = get_song_title(NULL,filename); - } -@@ -930,7 +929,6 @@ - { - if (!mpg123_title) - mpg123_title = mpg123_http_get_title(filename); -- mpg123_length = -1; - } - mpg123_ip.set_info(mpg123_title, mpg123_length, - mpg123_bitrate * 1000, -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.h xmms-1.2.11-new/Input/mpg123/mpg123.h ---- xmms-1.2.11/Input/mpg123/mpg123.h 2006-07-24 00:32:44.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.h 2007-11-24 23:52:01.000000000 +0100 -@@ -176,7 +176,7 @@ - - /* ------ Declarations from "http.c" ------ */ - --extern int mpg123_http_open(char *url); -+extern int mpg123_http_open(char *url, unsigned long rng); - int mpg123_http_read(gpointer data, gint length); - void mpg123_http_close(void); - char *mpg123_http_get_title(char * url); -@@ -188,7 +188,7 @@ - extern unsigned int mpg123_getbits(int); - extern unsigned int mpg123_getbits_fast(int); - --extern void mpg123_open_stream(char *bs_filenam, int fd); -+extern void mpg123_open_stream(char *bs_filenam, int fd, unsigned long range); - extern int mpg123_head_check(unsigned long); - extern void mpg123_stream_close(void); - diff --git a/3rdparty/mpg123/2012_all_mpg123-id3convert.patch b/3rdparty/mpg123/2012_all_mpg123-id3convert.patch deleted file mode 100644 index 8c1b76b..0000000 --- a/3rdparty/mpg123/2012_all_mpg123-id3convert.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:53:33.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:55:43.000000000 +0100 -@@ -2,6 +2,7 @@ - #include "id3_header.h" - #include "libxmms/configfile.h" - #include "libxmms/titlestring.h" -+#include "libxmms/charset.h" - #include - #include - #include -@@ -400,6 +401,14 @@ - return ext; - } - -+static char *convert_id3v1_field(const char *v1field, unsigned len) -+{ -+ char *tmp = g_strndup(v1field, len); -+ char *v2field = xmms_charset_from_latin1(g_strstrip(tmp)); -+ g_free(tmp); -+ return v2field; -+} -+ - /* - * Function id3v1_to_id3v2 (v1, v2) - * -@@ -411,10 +420,10 @@ - char *year; - struct id3v2tag_t *v2 = g_malloc0(sizeof (struct id3v2tag_t)); - -- v2->title = g_strstrip(g_strndup(v1->title, 30)); -- v2->artist = g_strstrip(g_strndup(v1->artist, 30)); -- v2->album = g_strstrip(g_strndup(v1->album, 30)); -- v2->comment = g_strstrip(g_strndup(v1->u.v1_0.comment, 30)); -+ v2->title = convert_id3v1_field(v1->title, 30); -+ v2->artist = convert_id3v1_field(v1->artist, 30); -+ v2->album = convert_id3v1_field(v1->album, 30); -+ v2->comment = convert_id3v1_field(v1->u.v1_0.comment, 30); - v2->genre = g_strstrip(g_strdup(mpg123_get_id3_genre(v1->genre))); - - year = g_strndup(v1->year, 4); diff --git a/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch b/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch deleted file mode 100644 index b1d33cd..0000000 --- a/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch +++ /dev/null @@ -1,128 +0,0 @@ -diff -Naur xmms-1.2.10-20041012/Input/mpg123/Makefile.am xmms-1.2.10-20041012.id3latin/Input/mpg123/Makefile.am ---- xmms-1.2.10-20041012/Input/mpg123/Makefile.am 2004-10-13 01:03:03.186246768 -0700 -+++ xmms-1.2.10-20041012.id3latin/Input/mpg123/Makefile.am 2004-10-23 08:52:23.370409147 -0700 -@@ -15,7 +15,7 @@ - dxhead.c dxhead.h \ - id3.c id3.h \ - id3_frame.c id3_frame_content.c id3_frame_text.c id3_frame_url.c \ --id3_header.h id3_tag.c unicode.c -+id3_header.h id3_tag.c - - if ARCH_X86 - -diff -Naur xmms-1.2.10-20041012/Input/mpg123/id3_frame_text.c xmms-1.2.10-20041012.id3latin/Input/mpg123/id3_frame_text.c ---- xmms-1.2.10-20041012/Input/mpg123/id3_frame_text.c 2004-10-13 01:03:03.201244300 -0700 -+++ xmms-1.2.10-20041012.id3latin/Input/mpg123/id3_frame_text.c 2004-10-23 09:15:29.117825260 -0700 -@@ -60,13 +60,13 @@ - switch (encoding) - { - case ID3_ENCODING_ISO_8859_1: -- return g_strdup(text); -+ return xmms_charset_from_latin1(text); - case ID3_ENCODING_UTF8: - return xmms_charset_from_utf8(text); - case ID3_ENCODING_UTF16: -- return convert_from_utf16(text); -+ return xmms_charset_from_utf16(text); - case ID3_ENCODING_UTF16BE: -- return convert_from_utf16be(text); -+ return xmms_charset_from_utf16be(text); - default: - return NULL; - } -diff -Naur xmms-1.2.10-20041012/Input/mpg123/unicode.c xmms-1.2.10-20041012.id3latin/Input/mpg123/unicode.c ---- xmms-1.2.10-20041012/Input/mpg123/unicode.c 2004-10-13 01:03:03.215241997 -0700 -+++ xmms-1.2.10-20041012.id3latin/Input/mpg123/unicode.c 1969-12-31 16:00:00.000000000 -0800 -@@ -1,92 +0,0 @@ --/* -- * Copyright (C) 2004 Haavard Kvaalen -- * -- * Licensed under GNU GPL version 2. -- * -- */ --#include "config.h" -- --#include --#include -- --#include "libxmms/charset.h" -- --size_t utf16_strlen(const char *string) --{ -- size_t len = 0; -- -- while (*(string + len) != 0 || *(string + len + 1) != 0) -- len += 2; -- -- return len; --} -- --#ifdef HAVE_ICONV -- --char *convert_from_utf16(const unsigned char *utf16) --{ -- return xmms_charset_convert(utf16, utf16_strlen(utf16), "UTF-16", NULL); --} -- --char *convert_from_utf16be(const unsigned char *utf16) --{ -- return xmms_charset_convert(utf16, utf16_strlen(utf16), "UTF-16BE", NULL); --} -- -- --#else -- -- --static char* to_ascii(const unsigned char *utf16, int le) --{ -- char *ascii; -- unsigned int i, len, c; -- -- len = utf16_strlen(utf16) / 2 + 1; -- -- ascii = g_malloc(len + 1); -- -- for (i = 0, c = 0; i < len; i++) -- { -- guint16 uc; -- int o = i << 1; -- -- if (le) -- uc = *(utf16 + o) | *(utf16 + o + 1) << 8; -- else -- uc = *(utf16 + o) << 8 | *(utf16 + o + 1); -- -- /* Skip BOM and surrogate pairs */ -- if (uc == 0xfeff || (uc >= 0xd800 && uc <= 0xdfff)) -- continue; -- -- if (uc < 0x80) -- ascii[c] = uc; -- else -- ascii[c] = '?'; -- c++; -- } -- -- ascii[c] = 0; -- return ascii; --} -- --char *convert_from_utf16(const unsigned char *utf16) --{ -- int le = FALSE; -- guint16 bom = *utf16 << 8 | *(utf16 + 1); -- -- if (bom == 0xfffe) -- le = TRUE; -- else if (bom != 0xfeff) -- return g_strdup(""); -- -- return to_ascii(utf16, le); --} -- --char *convert_from_utf16be(const unsigned char *utf16) --{ -- return to_ascii(utf16, FALSE); --} -- --#endif diff --git a/3rdparty/mpg123/2014_all_mpg123-encode-override.patch b/3rdparty/mpg123/2014_all_mpg123-encode-override.patch deleted file mode 100644 index 5c27f66..0000000 --- a/3rdparty/mpg123/2014_all_mpg123-encode-override.patch +++ /dev/null @@ -1,130 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/mpg123/configure.c xmms-1.2.11-new/Input/mpg123/configure.c ---- xmms-1.2.11/Input/mpg123/configure.c 2005-05-15 02:01:19.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/configure.c 2007-11-24 23:57:29.000000000 +0100 -@@ -27,6 +27,7 @@ - static GtkWidget *streaming_proxy_hbox, *streaming_proxy_auth_hbox, *streaming_save_dirbrowser; - static GtkWidget *streaming_save_hbox, *title_id3_box, *title_tag_desc; - static GtkWidget *title_override, *title_id3_entry, *title_id3v2_disable; -+static GtkWidget *id3v2_encoding_override, *id3v2_encoding_box, *encoding_entry; - - MPG123Config mpg123_cfg; - -@@ -105,6 +106,8 @@ - mpg123_cfg.disable_id3v2 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(title_id3v2_disable)); - g_free(mpg123_cfg.id3_format); - mpg123_cfg.id3_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(title_id3_entry))); -+ mpg123_cfg.id3v2_encoding_override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(id3v2_encoding_override)); -+ mpg123_cfg.id3v2_default_encoding = g_strdup(gtk_entry_get_text(GTK_ENTRY(encoding_entry))); - - filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); - cfg = xmms_cfg_open_file(filename); -@@ -134,6 +137,8 @@ - xmms_cfg_write_boolean(cfg, "MPG123", "title_override", mpg123_cfg.title_override); - xmms_cfg_write_boolean(cfg, "MPG123", "disable_id3v2", mpg123_cfg.disable_id3v2); - xmms_cfg_write_string(cfg, "MPG123", "id3_format", mpg123_cfg.id3_format); -+ xmms_cfg_write_boolean(cfg, "MPG123", "id3v2_encoding_override", mpg123_cfg.id3v2_encoding_override); -+ xmms_cfg_write_string(cfg, "MPG123", "id3v2_default_encoding", mpg123_cfg.id3v2_default_encoding); - xmms_cfg_write_int(cfg, "MPG123", "detect_by", mpg123_cfg.detect_by); - #ifdef USE_SIMD - xmms_cfg_write_int(cfg, "MPG123", "default_synth", mpg123_cfg.default_synth); -@@ -212,6 +217,13 @@ - gtk_widget_set_sensitive(title_tag_desc, override); - } - -+static void id3v2_encoding_override_cb(GtkWidget * w, gpointer data) -+{ -+ gboolean override; -+ override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(id3v2_encoding_override)); -+ gtk_widget_set_sensitive(id3v2_encoding_box, override); -+} -+ - static void configure_destroy(GtkWidget * w, gpointer data) - { - if (streaming_save_dirbrowser) -@@ -230,6 +242,7 @@ - GtkWidget *streaming_save_label, *streaming_save_browse; - GtkWidget *streaming_cast_frame, *streaming_cast_vbox; - GtkWidget *title_frame, *title_id3_vbox, *title_id3_label; -+ GtkWidget *title_id3_label2; - GtkWidget *bbox, *ok, *cancel; - - char *temp; -@@ -576,6 +589,23 @@ - title_tag_desc = xmms_titlestring_descriptions("pafFetnygc", 2); - gtk_widget_set_sensitive(title_tag_desc, mpg123_cfg.title_override); - gtk_box_pack_start(GTK_BOX(title_id3_vbox), title_tag_desc, FALSE, FALSE, 0); -+ -+ id3v2_encoding_override = gtk_check_button_new_with_label(_("Override default ID3V2 encoding")); -+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(id3v2_encoding_override), mpg123_cfg.id3v2_encoding_override); -+ gtk_signal_connect(GTK_OBJECT(id3v2_encoding_override), "clicked", id3v2_encoding_override_cb, NULL); -+ gtk_box_pack_start(GTK_BOX(title_id3_vbox), id3v2_encoding_override, FALSE, FALSE, 0); -+ -+ id3v2_encoding_box = gtk_hbox_new(FALSE, 5); -+ gtk_widget_set_sensitive(id3v2_encoding_box, mpg123_cfg.id3v2_encoding_override); -+ gtk_box_pack_start(GTK_BOX(title_id3_vbox), id3v2_encoding_box, FALSE, FALSE, 0); -+ -+ title_id3_label2 = gtk_label_new(_("Encoding name:")); -+ gtk_box_pack_start(GTK_BOX(id3v2_encoding_box), title_id3_label2, FALSE, FALSE, 0); -+ -+ encoding_entry = gtk_entry_new(); -+ gtk_entry_set_text(GTK_ENTRY(encoding_entry), mpg123_cfg.id3v2_default_encoding); -+ gtk_box_pack_start(GTK_BOX(id3v2_encoding_box), encoding_entry, TRUE, TRUE, 0); -+ - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), title_frame, gtk_label_new(_("Title"))); - - bbox = gtk_hbutton_box_new(); -diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame_text.c xmms-1.2.11-new/Input/mpg123/id3_frame_text.c ---- xmms-1.2.11/Input/mpg123/id3_frame_text.c 2007-11-24 23:57:15.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/id3_frame_text.c 2007-11-24 23:57:29.000000000 +0100 -@@ -29,6 +29,8 @@ - - #include "libxmms/charset.h" - -+/* For extern mpg123_cfg */ -+#include "mpg123.h" - - /* Get size of string in bytes including null. */ - guint id3_string_size(guint8 encoding, const char* text) -@@ -60,6 +62,9 @@ - switch (encoding) - { - case ID3_ENCODING_ISO_8859_1: -+ if (mpg123_cfg.id3v2_encoding_override) { -+ return xmms_charset_convert(text, strlen(text), mpg123_cfg.id3v2_default_encoding, NULL); -+ } - return xmms_charset_from_latin1(text); - case ID3_ENCODING_UTF8: - return xmms_charset_from_utf8(text); -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:56:41.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:57:29.000000000 +0100 -@@ -171,6 +171,7 @@ - mpg123_cfg.use_udp_channel = FALSE; - mpg123_cfg.title_override = FALSE; - mpg123_cfg.disable_id3v2 = FALSE; -+ mpg123_cfg.id3v2_encoding_override = FALSE; - mpg123_cfg.detect_by = DETECT_EXTENSION; - mpg123_cfg.default_synth = SYNTH_AUTO; - -@@ -199,6 +200,9 @@ - xmms_cfg_read_boolean(cfg, "MPG123", "disable_id3v2", &mpg123_cfg.disable_id3v2); - if (!xmms_cfg_read_string(cfg, "MPG123", "id3_format", &mpg123_cfg.id3_format)) - mpg123_cfg.id3_format = g_strdup("%p - %t"); -+ xmms_cfg_read_boolean(cfg, "MPG123", "id3v2_encoding_override", &mpg123_cfg.id3v2_encoding_override); -+ if (!xmms_cfg_read_string(cfg, "MPG123", "id3v2_default_encoding", &mpg123_cfg.id3v2_default_encoding)) -+ mpg123_cfg.id3_format = g_strdup("ISO-8859-1"); - xmms_cfg_read_int(cfg, "MPG123", "detect_by", &mpg123_cfg.detect_by); - xmms_cfg_read_int(cfg, "MPG123", "default_synth", &mpg123_cfg.default_synth); - -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.h xmms-1.2.11-new/Input/mpg123/mpg123.h ---- xmms-1.2.11/Input/mpg123/mpg123.h 2007-11-24 23:53:33.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.h 2007-11-24 23:57:29.000000000 +0100 -@@ -159,6 +159,8 @@ - gboolean use_udp_channel; - gchar *id3_format; - gboolean title_override, disable_id3v2; -+ gboolean id3v2_encoding_override; -+ gchar *id3v2_default_encoding; - int detect_by; - int default_synth; - } diff --git a/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch b/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch deleted file mode 100644 index b1d47a2..0000000 --- a/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch +++ /dev/null @@ -1,2247 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/mpg123/common.c xmms-1.2.11-new/Input/mpg123/common.c ---- xmms-1.2.11/Input/mpg123/common.c 2007-11-24 23:53:33.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/common.c 2007-11-24 23:58:41.000000000 +0100 -@@ -303,8 +303,8 @@ - mpg123_id3v2_destroy(tag); - id3_close(id3d); - } -- g_free(id3buf); - -+ g_free(id3buf); - return TRUE; - } - -diff -dPNur xmms-1.2.11/Input/mpg123/fileinfo.c xmms-1.2.11-new/Input/mpg123/fileinfo.c ---- xmms-1.2.11/Input/mpg123/fileinfo.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/fileinfo.c 2007-11-24 23:58:41.000000000 +0100 -@@ -27,42 +27,96 @@ - #include - #include "mpg123.h" - -+#define MAX_STR_LEN 100 -+#define MAX_ENTRY_LEN2 1023 -+ - static GtkWidget *window = NULL; --static GtkWidget *filename_entry, *id3_frame; --static GtkWidget *title_entry, *artist_entry, *album_entry, *year_entry; --static GtkWidget *tracknum_entry, *comment_entry, *genre_combo; -+static GtkWidget *notebook = NULL; -+static GtkWidget *filename_entry, *id3v1_frame, *id3v2_frame; -+static GtkWidget *v1_checkbox, *v2_checkbox; -+static GtkWidget *v1_title_entry, *v1_artist_entry, *v1_album_entry, *v1_year_entry, *v1_tracknum_entry, *v1_comment_entry; -+static GtkWidget *v2_title_entry, *v2_artist_entry, *v2_album_entry, *v2_year_entry, *v2_tracknum_entry, *v2_comment_entry, -+ *v2_composer_entry, *v2_orig_artist_entry, *v2_url_entry, *v2_encoded_by_entry; -+static GtkWidget *v1_genre_combo, *v2_genre_combo; - static GtkWidget *mpeg_level, *mpeg_bitrate, *mpeg_samplerate, *mpeg_flags; - static GtkWidget *mpeg_fileinfo; - -+static GPtrArray *v1_labels_list = NULL, *v2_labels_list = NULL; // TODO: Where will these be freed? - static GList *genre_list; - struct genre_item { - const char *name; - int id; - }; --static int current_genre; -+static int v1_current_genre; -+static int v2_current_genre; - static char *current_filename; - - extern char *mpg123_filename; - extern int mpg123_bitrate, mpg123_frequency, mpg123_layer, mpg123_lsf, mpg123_mode; - extern gboolean mpg123_stereo, mpg123_mpeg25; - --#define MAX_STR_LEN 100 -- --static void label_set_text(GtkWidget * label, char *str, ...) -+static void label_set_text(GtkWidget * label, const char *str, ...) - G_GNUC_PRINTF(2, 3); - --static void set_entry_tag(GtkEntry * entry, char * tag, int length) -+static void set_entry_tag_v1(GtkEntry * entry, const char * tag, int length) - { - char *text = g_strchomp(g_strndup(tag, length)); - gtk_entry_set_text(entry, text); - g_free(text); - } - --static void get_entry_tag(GtkEntry * entry, char * tag, int length) -+static void get_entry_tag_v1(GtkEntry * entry, char * tag, int length) - { - strncpy(tag, gtk_entry_get_text(entry), length); - } - -+void copy_entry_tag_v1(GtkEntry * src, GtkEntry * dest, int length) -+{ -+ set_entry_tag_v1(dest, gtk_entry_get_text(src), length); -+ return; -+} -+ -+static void set_entry_tag_v2(GtkEntry * entry, struct id3_tag* id3, guint32 frame_type) -+{ -+ struct id3_frame* frame; -+ -+ frame = id3_get_frame(id3, frame_type, 1); -+ if (frame != NULL) -+ { -+ char *text, *url, *comment; -+ -+ text = id3_get_text(frame); -+ if (text != NULL) -+ { -+ gtk_entry_set_text(entry, text); -+ g_free(text); -+ return; -+ } -+ -+ url = id3_get_url(frame); -+ if (url != NULL) -+ { -+ gtk_entry_set_text(entry, url); -+ g_free(url); -+ return; -+ } -+ -+ comment = id3_get_comment(frame); -+ if (comment != NULL) -+ { -+ gtk_entry_set_text(entry, comment); -+ g_free(url); -+ return; -+ } -+ } -+} -+ -+void copy_entry_tag_v2(GtkEntry * src, GtkEntry * dest) -+{ -+ gtk_entry_set_text(dest, gtk_entry_get_text(src)); -+ return; -+} -+ - static int genre_find_index(GList *genre_list, int id) - { - int idx = 0; -@@ -74,6 +128,24 @@ - idx++; - genre_list = genre_list->next; - } -+ if (!genre_list) -+ return 0; -+ return idx; -+} -+ -+static int genre_find_index_str(GList *genre_list, const char* str) -+{ -+ int idx = 0; -+ while (genre_list) -+ { -+ struct genre_item *item = genre_list->data; -+ if (strcmp(item->name, str) == 0) -+ break; -+ idx++; -+ genre_list = genre_list->next; -+ } -+ if (!genre_list) -+ return 0; - return idx; - } - -@@ -83,9 +155,9 @@ - return strcasecmp(ga->name, gb->name); - } - --static void save_cb(GtkWidget * w, gpointer data) -+static void remove_id3v1(void) - { -- int fd; -+ int fd, len; - struct id3v1tag_t tag; - char *msg = NULL; - -@@ -94,71 +166,36 @@ - - if ((fd = open(current_filename, O_RDWR)) != -1) - { -- int tracknum; -- -- lseek(fd, -128, SEEK_END); -+ len = lseek(fd, -128, SEEK_END); - read(fd, &tag, sizeof (struct id3v1tag_t)); - - if (!strncmp(tag.tag, "TAG", 3)) -- lseek(fd, -128, SEEK_END); -- else -- lseek(fd, 0, SEEK_END); -- tag.tag[0] = 'T'; -- tag.tag[1] = 'A'; -- tag.tag[2] = 'G'; -- get_entry_tag(GTK_ENTRY(title_entry), tag.title, 30); -- get_entry_tag(GTK_ENTRY(artist_entry), tag.artist, 30); -- get_entry_tag(GTK_ENTRY(album_entry), tag.album, 30); -- get_entry_tag(GTK_ENTRY(year_entry), tag.year, 4); -- tracknum = atoi(gtk_entry_get_text(GTK_ENTRY(tracknum_entry))); -- if (tracknum > 0) - { -- get_entry_tag(GTK_ENTRY(comment_entry), -- tag.u.v1_1.comment, 28); -- tag.u.v1_1.__zero = 0; -- tag.u.v1_1.track_number = MIN(tracknum, 255); -+ if (ftruncate(fd, len)) -+ msg = g_strdup_printf(_("%s\n" -+ "Unable to truncate file: %s"), -+ _("Couldn't remove tag!"), -+ strerror(errno)); - } -- else -- get_entry_tag(GTK_ENTRY(comment_entry), -- tag.u.v1_0.comment, 30); -- tag.genre = current_genre; -- if (write(fd, &tag, sizeof (tag)) != sizeof (tag)) -- msg = g_strdup_printf(_("%s\nUnable to write to file: %s"), -- _("Couldn't write tag!"), -- strerror(errno)); - close(fd); - } - else - msg = g_strdup_printf(_("%s\nUnable to open file: %s"), -- _("Couldn't write tag!"), -+ _("Couldn't remove tag!"), - strerror(errno)); - if (msg) - { -- GtkWidget *mwin = xmms_show_message(_("File Info"), msg, -- _("OK"), FALSE, NULL, NULL); -+ GtkWidget *mwin = xmms_show_message(_("File Info"), msg, _("OK"), -+ FALSE, NULL, NULL); - gtk_window_set_transient_for(GTK_WINDOW(mwin), - GTK_WINDOW(window)); - g_free(msg); - } -- else -- gtk_widget_destroy(window); --} -- --static void label_set_text(GtkWidget * label, char *str, ...) --{ -- va_list args; -- char tempstr[MAX_STR_LEN]; -- -- va_start(args, str); -- g_vsnprintf(tempstr, MAX_STR_LEN, str, args); -- va_end(args); -- -- gtk_label_set_text(GTK_LABEL(label), tempstr); - } - --static void remove_id3_cb(GtkWidget * w, gpointer data) -+static void save_cb(GtkWidget * w, gpointer data) - { -- int fd, len; -+ int fd; - struct id3v1tag_t tag; - char *msg = NULL; - -@@ -167,36 +204,112 @@ - - if ((fd = open(current_filename, O_RDWR)) != -1) - { -- len = lseek(fd, -128, SEEK_END); -- read(fd, &tag, sizeof (struct id3v1tag_t)); -+ if (!GTK_TOGGLE_BUTTON(v1_checkbox)->active) { -+ /* Try to save id3v1 tag */ -+ int tracknum; - -- if (!strncmp(tag.tag, "TAG", 3)) -- { -- if (ftruncate(fd, len)) -- msg = g_strdup_printf( -- _("%s\n" -- "Unable to truncate file: %s"), -- _("Couldn't remove tag!"), -- strerror(errno)); -+ lseek(fd, -128, SEEK_END); -+ read(fd, &tag, sizeof (struct id3v1tag_t)); -+ -+ if (!strncmp(tag.tag, "TAG", 3)) -+ lseek(fd, -128, SEEK_END); -+ else -+ lseek(fd, 0, SEEK_END); -+ tag.tag[0] = 'T'; -+ tag.tag[1] = 'A'; -+ tag.tag[2] = 'G'; -+ get_entry_tag_v1(GTK_ENTRY(v1_title_entry), tag.title, 30); -+ get_entry_tag_v1(GTK_ENTRY(v1_artist_entry), tag.artist, 30); -+ get_entry_tag_v1(GTK_ENTRY(v1_album_entry), tag.album, 30); -+ get_entry_tag_v1(GTK_ENTRY(v1_year_entry), tag.year, 4); -+ tracknum = atoi(gtk_entry_get_text(GTK_ENTRY(v1_tracknum_entry))); -+ if (tracknum > 0) -+ { -+ get_entry_tag_v1(GTK_ENTRY(v1_comment_entry), tag.u.v1_1.comment, 28); -+ tag.u.v1_1.__zero = 0; -+ tag.u.v1_1.track_number = MIN(tracknum, 255); -+ } -+ else -+ get_entry_tag_v1(GTK_ENTRY(v1_comment_entry), -+ tag.u.v1_0.comment, 30); -+ tag.genre = v1_current_genre; -+ if (write(fd, &tag, sizeof (tag)) != sizeof (tag)) -+ msg = g_strdup_printf(_("%s\nUnable to write to file: %s"), -+ _("Couldn't write tag!"), -+ strerror(errno)); -+ } else { -+ /* Remove the id3v1 tag from the file */ -+ remove_id3v1(); - } -- else -- msg = strdup(_("No tag to remove!")); -- close(fd); -+ -+ if (!GTK_TOGGLE_BUTTON(v2_checkbox)->active) { -+ struct id3_tag* id3; -+ -+ lseek(fd, SEEK_SET, 0); -+ id3 = id3_open_fd(fd, 0); -+ if (id3 == NULL) -+ id3 = id3_new(); -+ -+ if (id3 != NULL) -+ { -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TIT2), gtk_entry_get_text(GTK_ENTRY(v2_title_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TPE1), gtk_entry_get_text(GTK_ENTRY(v2_artist_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TALB), gtk_entry_get_text(GTK_ENTRY(v2_album_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TYER), gtk_entry_get_text(GTK_ENTRY(v2_year_entry))); -+ id3_set_comment(id3_get_or_add_frame(id3, ID3_COMM), gtk_entry_get_text(GTK_ENTRY(v2_comment_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TRCK), gtk_entry_get_text(GTK_ENTRY(v2_tracknum_entry))); -+ if (v2_current_genre != 0xff) -+ { -+ /* Essentially the same behavior as Winamp2's ID3v2 tagger */ -+ char genre[255]; -+ snprintf(genre, sizeof(genre), "(%d)%s", -+ v2_current_genre, -+ gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TCON), genre); -+ } -+ else -+ { -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TCON), gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry))); -+ } -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TCOM), gtk_entry_get_text(GTK_ENTRY(v2_composer_entry))); -+ id3_set_url(id3_get_or_add_frame(id3, ID3_WCOM), gtk_entry_get_text(GTK_ENTRY(v2_url_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TOPE), gtk_entry_get_text(GTK_ENTRY(v2_orig_artist_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TENC), gtk_entry_get_text(GTK_ENTRY(v2_encoded_by_entry))); -+ -+ id3_write_tag_filename(id3, current_filename); -+ } -+ -+ } else { -+ id3_remove_tag_filename(current_filename); -+ } -+ -+ if (fd) -+ close(fd); - } - else - msg = g_strdup_printf(_("%s\nUnable to open file: %s"), -- _("Couldn't remove tag!"), -+ _("Couldn't write tag!"), - strerror(errno)); - if (msg) - { -- GtkWidget *mwin = xmms_show_message(_("File Info"), msg, -- _("OK"), FALSE, NULL, NULL); -+ GtkWidget *mwin = xmms_show_message(_("File Info"), msg, _("OK"), -+ FALSE, NULL, NULL); - gtk_window_set_transient_for(GTK_WINDOW(mwin), - GTK_WINDOW(window)); - g_free(msg); - } -- else -- gtk_widget_destroy(window); -+} -+ -+static void label_set_text(GtkWidget * label, const char *str, ...) -+{ -+ va_list args; -+ char tempstr[MAX_STR_LEN]; -+ -+ va_start(args, str); -+ g_vsnprintf(tempstr, MAX_STR_LEN, str, args); -+ va_end(args); -+ -+ gtk_label_set_text(GTK_LABEL(label), tempstr); - } - - static void set_mpeg_level_label(gboolean mpeg25, int lsf, int layer) -@@ -219,28 +332,141 @@ - - static void file_info_http(char *filename) - { -- gtk_widget_set_sensitive(id3_frame, FALSE); -+ gtk_widget_set_sensitive(id3v1_frame, FALSE); -+ gtk_widget_set_sensitive(id3v2_frame, FALSE); - if (mpg123_filename && !strcmp(filename, mpg123_filename) && - mpg123_bitrate != 0) - { -- set_mpeg_level_label(mpg123_mpeg25, mpg123_lsf, mpg123_layer); -+ set_mpeg_level_label(mpg123_mpeg25, mpg123_lsf, -+ mpg123_layer); - label_set_text(mpeg_bitrate, _("Bitrate: %d kb/s"), -- mpg123_bitrate); -+ mpg123_bitrate); - label_set_text(mpeg_samplerate, _("Samplerate: %d Hz"), -- mpg123_frequency); -+ mpg123_frequency); - label_set_text(mpeg_flags, "%s", -- channel_mode_name(mpg123_mode)); -+ channel_mode_name(mpg123_mode)); - } - } - --static void genre_selected(GtkList *list, GtkWidget *w, gpointer data) -+void copy_v2_to_v1_cb(GtkButton *button, gpointer user_data) -+{ -+ copy_entry_tag_v1(GTK_ENTRY(v2_title_entry), GTK_ENTRY(v1_title_entry), 30); -+ copy_entry_tag_v1(GTK_ENTRY(v2_artist_entry), GTK_ENTRY(v1_artist_entry), 30); -+ copy_entry_tag_v1(GTK_ENTRY(v2_album_entry), GTK_ENTRY(v1_album_entry), 30); -+ copy_entry_tag_v1(GTK_ENTRY(v2_year_entry), GTK_ENTRY(v1_year_entry), 4); -+ copy_entry_tag_v1(GTK_ENTRY(v2_comment_entry), GTK_ENTRY(v1_comment_entry), 30); -+ copy_entry_tag_v1(GTK_ENTRY(v2_tracknum_entry), GTK_ENTRY(v1_tracknum_entry), 3); -+ -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v1_genre_combo)->list), genre_find_index(genre_list, v2_current_genre)); -+ return; -+} -+ -+void copy_v1_to_v2_cb(GtkButton *button, gpointer user_data) -+{ -+ copy_entry_tag_v2(GTK_ENTRY(v1_title_entry), GTK_ENTRY(v2_title_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_artist_entry), GTK_ENTRY(v2_artist_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_album_entry), GTK_ENTRY(v2_album_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_year_entry), GTK_ENTRY(v2_year_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_comment_entry), GTK_ENTRY(v2_comment_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_tracknum_entry), GTK_ENTRY(v2_tracknum_entry)); -+ -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v2_genre_combo)->list), genre_find_index(genre_list, v1_current_genre)); -+ return; -+} -+ -+void v1_toggle_cb (GtkWidget *widget, gpointer data) -+{ -+ int i = 0; -+ if (GTK_TOGGLE_BUTTON (widget)->active) -+ { -+ // If control reaches here, the toggle button is down -+ // Gray out labels -+ for (i = 0; i < v1_labels_list->len; i++) { -+ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v1_labels_list, i) ), FALSE); -+ } -+ gtk_widget_set_sensitive(v1_title_entry, FALSE); -+ gtk_widget_set_sensitive(v1_artist_entry, FALSE); -+ gtk_widget_set_sensitive(v1_album_entry, FALSE); -+ gtk_widget_set_sensitive(v1_year_entry, FALSE); -+ gtk_widget_set_sensitive(v1_tracknum_entry, FALSE); -+ gtk_widget_set_sensitive(v1_comment_entry, FALSE); -+ gtk_widget_set_sensitive(v1_genre_combo, FALSE); -+ } else { -+ -+ // If control reaches here, the toggle button is up -+ // Enable labels -+ for (i = 0; i < v1_labels_list->len; i++) { -+ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v1_labels_list, i) ), TRUE); -+ } -+ gtk_widget_set_sensitive(v1_title_entry, TRUE); -+ gtk_widget_set_sensitive(v1_artist_entry, TRUE); -+ gtk_widget_set_sensitive(v1_album_entry, TRUE); -+ gtk_widget_set_sensitive(v1_year_entry, TRUE); -+ gtk_widget_set_sensitive(v1_tracknum_entry, TRUE); -+ gtk_widget_set_sensitive(v1_comment_entry, TRUE); -+ gtk_widget_set_sensitive(v1_genre_combo, TRUE); -+ } -+} -+ -+void v2_toggle_cb (GtkWidget *widget, gpointer data) -+{ -+ int i = 0; -+ if (GTK_TOGGLE_BUTTON (widget)->active) -+ { -+ // If control reaches here, the toggle button is down -+ // Gray out labels -+ for (i = 0; i < v2_labels_list->len; i++) { -+ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v2_labels_list, i) ), FALSE); -+ } -+ gtk_widget_set_sensitive(v2_title_entry, FALSE); -+ gtk_widget_set_sensitive(v2_artist_entry, FALSE); -+ gtk_widget_set_sensitive(v2_album_entry, FALSE); -+ gtk_widget_set_sensitive(v2_year_entry, FALSE); -+ gtk_widget_set_sensitive(v2_tracknum_entry, FALSE); -+ gtk_widget_set_sensitive(v2_comment_entry, FALSE); -+ gtk_widget_set_sensitive(v2_composer_entry, FALSE); -+ gtk_widget_set_sensitive(v2_orig_artist_entry, FALSE); -+ gtk_widget_set_sensitive(v2_url_entry, FALSE); -+ gtk_widget_set_sensitive(v2_encoded_by_entry, FALSE); -+ gtk_widget_set_sensitive(v2_genre_combo, FALSE); -+ } else { -+ -+ // If control reaches here, the toggle button is up -+ // Enable labels -+ for (i = 0; i < v2_labels_list->len; i++) { -+ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v2_labels_list, i) ), TRUE); -+ } -+ gtk_widget_set_sensitive(v2_title_entry, TRUE); -+ gtk_widget_set_sensitive(v2_artist_entry, TRUE); -+ gtk_widget_set_sensitive(v2_album_entry, TRUE); -+ gtk_widget_set_sensitive(v2_year_entry, TRUE); -+ gtk_widget_set_sensitive(v2_tracknum_entry, TRUE); -+ gtk_widget_set_sensitive(v2_comment_entry, TRUE); -+ gtk_widget_set_sensitive(v2_composer_entry, TRUE); -+ gtk_widget_set_sensitive(v2_orig_artist_entry, TRUE); -+ gtk_widget_set_sensitive(v2_url_entry, TRUE); -+ gtk_widget_set_sensitive(v2_encoded_by_entry, TRUE); -+ gtk_widget_set_sensitive(v2_genre_combo, TRUE); -+ } -+} -+static void v1_genre_selected(GtkList *list, GtkWidget *w, gpointer data) - { - void * p; - p = gtk_object_get_data(GTK_OBJECT(w), "genre_id"); - if (p != NULL) -- current_genre = GPOINTER_TO_INT(p); -+ v1_current_genre = GPOINTER_TO_INT(p); - else -- current_genre = 0; -+ v1_current_genre = 0; -+} -+ -+static void v2_genre_selected(GtkList *list, GtkWidget *w, gpointer data) -+{ -+ void * p; -+ p = gtk_object_get_data(GTK_OBJECT(w), "genre_id"); -+ if (p != NULL) -+ v2_current_genre = GPOINTER_TO_INT(p); -+ else -+ v2_current_genre = 0; - } - - static void genre_set_popdown(GtkWidget *combo, GList *genres) -@@ -269,7 +495,7 @@ - void mpg123_file_info_box(char *filename) - { - int i; -- struct id3v1tag_t tag; -+ struct id3v1tag_t id3v1tag; - FILE *fh; - char *tmp, *title; - const char *emphasis[4]; -@@ -284,205 +510,397 @@ - - if (!window) - { -- GtkWidget *vbox, *hbox, *left_vbox, *table; -- GtkWidget *mpeg_frame, *mpeg_box; -- GtkWidget *label, *filename_hbox; -- GtkWidget *bbox, *save, *remove_id3, *cancel; -- -+ GtkWidget *window_vbox, -+ *id3v1_vbox, *id3v2_vbox, *id3v1_frame_vbox, *id3v2_frame_vbox, -+ *mpeg_lvbox, *mpeg_rvbox, *mpeg_hbox, *mpeg_box, *mpeg_frame, -+ *bbox, *save, *close, *copy_to, *copy_from, -+ *table, *label, *filename_hbox; -+ -+ v1_labels_list = g_ptr_array_new(); -+ v2_labels_list = g_ptr_array_new(); -+ - 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_widget_destroyed, &window); -- gtk_signal_connect(GTK_OBJECT(window), "key_press_event", -- file_info_box_keypress_cb, NULL); -+ gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window); -+ gtk_signal_connect(GTK_OBJECT(window), "key_press_event", file_info_box_keypress_cb, NULL); - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - -- vbox = gtk_vbox_new(FALSE, 10); -- gtk_container_add(GTK_CONTAINER(window), vbox); -- -+ window_vbox = gtk_vbox_new(FALSE,10); - filename_hbox = gtk_hbox_new(FALSE, 5); -- gtk_box_pack_start(GTK_BOX(vbox), filename_hbox, -- FALSE, TRUE, 0); -+ gtk_box_pack_start(GTK_BOX(window_vbox), filename_hbox, FALSE, TRUE, 0); - - label = gtk_label_new(_("Filename:")); -- gtk_box_pack_start(GTK_BOX(filename_hbox), label, -- FALSE, TRUE, 0); -+ gtk_box_pack_start(GTK_BOX(filename_hbox), label, FALSE, TRUE, 0); - filename_entry = xmms_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); -+ gtk_box_pack_start(GTK_BOX(filename_hbox), filename_entry, TRUE, TRUE, 0); - -- id3_frame = gtk_frame_new(_("ID3 Tag:")); -- gtk_box_pack_start(GTK_BOX(left_vbox), id3_frame, -- FALSE, FALSE, 0); -+ /* Set up the genres list */ - -- table = gtk_table_new(5, 5, FALSE); -+ if (!genre_list) -+ { -+ struct genre_item *item; -+ -+ for (i = 0; i < GENRE_MAX; i++) -+ { -+ item = g_malloc(sizeof (*item)); -+ item->name = gettext(mpg123_id3_genres[i]); -+ item->id = i; -+ genre_list = g_list_prepend(genre_list, item); -+ } -+ item = g_malloc(sizeof (*item)); -+ item->name = ""; -+ item->id = 0xff; -+ genre_list = g_list_prepend(genre_list, item); -+ genre_list = g_list_sort(genre_list, genre_comp_func); -+ } -+ -+ notebook = gtk_notebook_new (); -+ gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP); -+ -+ /* ID3v2 page */ -+ -+ id3v2_vbox = gtk_vbox_new(FALSE, 0); -+ -+ id3v2_frame = gtk_frame_new("ID3v2 Information"); -+ gtk_box_pack_start(GTK_BOX(id3v2_vbox), id3v2_frame, FALSE, FALSE, 0); -+ -+ id3v2_frame_vbox = gtk_vbox_new(FALSE, 0); -+ gtk_container_add(GTK_CONTAINER(id3v2_frame), id3v2_frame_vbox); -+ -+ table = gtk_table_new(6, 6, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(table), 5); -- gtk_container_add(GTK_CONTAINER(id3_frame), table); -+ gtk_widget_set_usize(GTK_WIDGET(table), 400, -1); -+ gtk_box_pack_start(GTK_BOX(id3v2_frame_vbox), table, FALSE, FALSE, 0); - -- label = gtk_label_new(_("Title:")); -+ v2_checkbox = gtk_check_button_new_with_label ("Disable ID3v2 Tag"); -+ gtk_signal_connect(GTK_OBJECT(v2_checkbox), "toggled", GTK_SIGNAL_FUNC(v2_toggle_cb), NULL); -+ gtk_table_attach(GTK_TABLE(table), v2_checkbox, 1, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 2); -+ -+ label = gtk_label_new("Track number:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - 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); -+ gtk_table_attach(GTK_TABLE(table), label, 3, 4, 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); -+ v2_tracknum_entry = gtk_entry_new_with_max_length(3); -+ gtk_widget_set_usize(v2_tracknum_entry, 20, -1); -+ gtk_table_attach(GTK_TABLE(table), v2_tracknum_entry, 4, 5, 0, 1, -+ GTK_FILL, GTK_FILL, 0, 2); - -- label = gtk_label_new(_("Artist:")); -+ label = gtk_label_new("Title:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - 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); -+ 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); -+ v2_title_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_title_entry, 1, 5, 1, 2, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); - -- label = gtk_label_new(_("Album:")); -+ label = gtk_label_new("Artist:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - 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); -+ 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); -+ v2_artist_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_artist_entry, 1, 5, 2, 3, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); - -- label = gtk_label_new(_("Comment:")); -+ label = gtk_label_new("Album:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - 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); -+ 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); -+ v2_album_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_album_entry, 1, 5, 3, 4, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); - -- label = gtk_label_new(_("Year:")); -+ label = gtk_label_new("Comment:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - 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); -+ 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); -+ v2_comment_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_comment_entry, 1, 5, 4, 5, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); - -- label = gtk_label_new(_("Track number:")); -+ label = gtk_label_new("Year:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - 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); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6, -+ 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); -+ v2_year_entry = gtk_entry_new_with_max_length(4); -+ gtk_widget_set_usize(v2_year_entry, 45, -1); -+ gtk_table_attach(GTK_TABLE(table), v2_year_entry, 1, 2, 5, 6, -+ GTK_FILL, GTK_FILL, 0, 2); - -- label = gtk_label_new(_("Genre:")); -+ label = gtk_label_new("Genre:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 2, 3, 5, 6, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_genre_combo = gtk_combo_new(); -+ gtk_combo_set_value_in_list(GTK_COMBO(v2_genre_combo), FALSE, TRUE); -+ -+ genre_set_popdown(v2_genre_combo, genre_list); -+ gtk_signal_connect(GTK_OBJECT(GTK_COMBO(v2_genre_combo)->list), -+ "select-child", v2_genre_selected, NULL); -+ -+ gtk_table_attach(GTK_TABLE(table), v2_genre_combo, 3, 5, 5, 6, -+ GTK_FILL | GTK_SHRINK, GTK_FILL | -+ GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Composer:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 6, 7, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_composer_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_composer_entry, 1, 5, 6, 7, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Orig. Artist:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 7, 8, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_orig_artist_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_orig_artist_entry, 1, 5, 7, 8, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("URL:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 8, 9, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_url_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_url_entry, 1, 5, 8, 9, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ label = gtk_label_new("Encoded By:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 9, 10, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_encoded_by_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_encoded_by_entry, 1, 5, 9, 10, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ bbox = gtk_hbutton_box_new(); -+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START); -+ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 0); -+ gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); -+ gtk_box_pack_start(GTK_BOX(id3v2_frame_vbox), bbox, FALSE, FALSE, 0); -+ -+ copy_to = gtk_button_new_with_label("ID3v2 to ID3v1"); -+ gtk_signal_connect(GTK_OBJECT(copy_to), "clicked", GTK_SIGNAL_FUNC(copy_v2_to_v1_cb), NULL); -+ /* remove the next line to thicken the button width */ -+ GTK_WIDGET_SET_FLAGS(copy_to, GTK_CAN_DEFAULT); -+ gtk_box_pack_start(GTK_BOX(bbox), copy_to, FALSE, TRUE, 0); -+ -+ label = gtk_label_new ("ID3v2"); -+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), id3v2_vbox, label); -+ -+ /* ID3v1 page */ -+ -+ id3v1_vbox = gtk_vbox_new(FALSE, 10); -+ id3v1_frame = gtk_frame_new("ID3v1 Information"); -+ gtk_box_pack_start(GTK_BOX(id3v1_vbox), id3v1_frame, TRUE, TRUE, 0); -+ -+ id3v1_frame_vbox = gtk_vbox_new(FALSE,10); -+ gtk_container_add(GTK_CONTAINER(id3v1_frame), id3v1_frame_vbox); -+ -+ table = gtk_table_new(6, 6, FALSE); -+ gtk_container_set_border_width(GTK_CONTAINER(table), 5); -+ //gtk_widget_set_usize(GTK_WIDGET(table), 325, -1); -+ //gtk_container_add(GTK_CONTAINER(id3v1_frame), table); -+ gtk_box_pack_start(GTK_BOX(id3v1_frame_vbox), table, FALSE, FALSE, 0); -+ -+ v1_checkbox = gtk_check_button_new_with_label ("Disable ID3v1 Tag"); -+ gtk_signal_connect(GTK_OBJECT(v1_checkbox), "toggled", GTK_SIGNAL_FUNC(v1_toggle_cb), NULL); -+ gtk_table_attach(GTK_TABLE(table), v1_checkbox, 1, 3, 0, 1, -+ GTK_FILL, GTK_FILL, 0, 2); -+ -+ label = gtk_label_new("Track number:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 3, 4, 0, 1, -+ GTK_FILL, GTK_FILL, 5,5); -+ -+ v1_tracknum_entry = gtk_entry_new_with_max_length(3); -+ gtk_widget_set_usize(v1_tracknum_entry, 20, -1); -+ gtk_table_attach(GTK_TABLE(table), v1_tracknum_entry, 4, 5, 0, 1, -+ GTK_FILL, GTK_FILL, 0, 2); -+ -+ label = gtk_label_new("Title:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ 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); -+ -+ v1_title_entry = gtk_entry_new_with_max_length(30); -+ gtk_table_attach(GTK_TABLE(table), v1_title_entry, 1, 5, 1, 2, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Artist:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ 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); -+ -+ v1_artist_entry = gtk_entry_new_with_max_length(30); -+ gtk_table_attach(GTK_TABLE(table), v1_artist_entry, 1, 5, 2, 3, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Album:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ 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); -+ -+ v1_album_entry = gtk_entry_new_with_max_length(30); -+ gtk_table_attach(GTK_TABLE(table), v1_album_entry, 1, 5, 3, 4, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Comment:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ 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); -+ -+ v1_comment_entry = gtk_entry_new_with_max_length(30); -+ gtk_table_attach(GTK_TABLE(table), v1_comment_entry, 1, 5, 4, 5, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Year:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); - 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); -+ 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) -- { -- struct genre_item *item; -+ v1_year_entry = gtk_entry_new_with_max_length(4); -+ gtk_widget_set_usize(v1_year_entry, 45, -1); -+ gtk_table_attach(GTK_TABLE(table), v1_year_entry, 1, 2, 5, 6, -+ GTK_FILL, GTK_FILL, 0, 2); - -- for (i = 0; i < GENRE_MAX; i++) -- { -- item = g_malloc(sizeof (*item)); -- item->name = gettext(mpg123_id3_genres[i]); -- item->id = i; -- genre_list = g_list_prepend(genre_list, item); -- } -- item = g_malloc(sizeof (*item)); -- item->name = ""; -- item->id = 0xff; -- genre_list = g_list_prepend(genre_list, item); -- genre_list = g_list_sort(genre_list, genre_comp_func); -- } -- genre_set_popdown(genre_combo, genre_list); -- gtk_signal_connect(GTK_OBJECT(GTK_COMBO(genre_combo)->list), -- "select-child", genre_selected, NULL); -+ label = gtk_label_new("Genre:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 2, 3, 5, 6, -+ GTK_FILL, GTK_FILL, 5, 5); - -- 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); -+ v1_genre_combo = gtk_combo_new(); -+ gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(v1_genre_combo)->entry), FALSE); -+ genre_set_popdown(v1_genre_combo, genre_list); -+ gtk_signal_connect(GTK_OBJECT(GTK_COMBO(v1_genre_combo)->list), -+ "select-child", v1_genre_selected, NULL); -+ -+ gtk_table_attach(GTK_TABLE(table), v1_genre_combo, 3, 5, 5, 6, -+ GTK_FILL | GTK_SHRINK, GTK_FILL | -+ GTK_SHRINK, 0, 2); - - 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); -+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START); -+ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 0); -+ gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); -+ gtk_box_pack_start(GTK_BOX(id3v1_frame_vbox), bbox, FALSE, FALSE, 0); - -- save = gtk_button_new_with_label(_("Save")); -- gtk_signal_connect(GTK_OBJECT(save), "clicked", 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); -+ copy_from = gtk_button_new_with_label("ID3v1 to ID3v2"); -+ gtk_signal_connect(GTK_OBJECT(copy_from), "clicked", GTK_SIGNAL_FUNC(copy_v1_to_v2_cb), NULL); -+ // remove the next line to thicken the button width -+ GTK_WIDGET_SET_FLAGS(copy_from, GTK_CAN_DEFAULT); -+ gtk_box_pack_start(GTK_BOX(bbox), copy_from, FALSE, TRUE, 0); - -- remove_id3 = gtk_button_new_with_label(_("Remove ID3")); -- gtk_signal_connect(GTK_OBJECT(remove_id3), "clicked", -- 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); -+ label = gtk_label_new ("ID3v1"); -+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), id3v1_vbox, label); - -- cancel = gtk_button_new_with_label(_("Cancel")); -- gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked", -- 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); -+ /* MPEG info page */ - -- mpeg_frame = gtk_frame_new(_("MPEG Info:")); -- gtk_box_pack_start(GTK_BOX(hbox), mpeg_frame, FALSE, FALSE, 0); -+ mpeg_frame = gtk_frame_new("MPEG Information"); -+ mpeg_hbox = gtk_hbox_new(FALSE,50); -+ gtk_container_add(GTK_CONTAINER(mpeg_frame), mpeg_hbox); -+ -+ mpeg_lvbox = gtk_vbox_new(FALSE, 5); -+ gtk_container_set_border_width(GTK_CONTAINER(mpeg_lvbox), 10); -+ gtk_box_pack_start(GTK_BOX(mpeg_hbox), mpeg_lvbox, FALSE, FALSE, 0); - - mpeg_box = gtk_vbox_new(FALSE, 5); -- gtk_container_add(GTK_CONTAINER(mpeg_frame), mpeg_box); -+ gtk_box_pack_start(GTK_BOX(mpeg_hbox), mpeg_box, FALSE, FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(mpeg_box), 10); - gtk_box_set_spacing(GTK_BOX(mpeg_box), 0); - - mpeg_level = gtk_label_new(""); -- gtk_widget_set_usize(mpeg_level, 120, -2); -- gtk_misc_set_alignment(GTK_MISC(mpeg_level), 0, 0); -- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_level, FALSE, FALSE, 0); -- -- mpeg_bitrate = gtk_label_new(""); -- gtk_misc_set_alignment(GTK_MISC(mpeg_bitrate), 0, 0); -- gtk_label_set_justify(GTK_LABEL(mpeg_bitrate), -- GTK_JUSTIFY_LEFT); -- gtk_box_pack_start(GTK_BOX(mpeg_box), -- mpeg_bitrate, FALSE, FALSE, 0); -+ //gtk_widget_set_usize(mpeg_level, 120, -2); -+ gtk_label_set_justify (GTK_LABEL(mpeg_level), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_level), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_lvbox), mpeg_level, FALSE, FALSE, 0); - - mpeg_samplerate = gtk_label_new(""); -- gtk_misc_set_alignment(GTK_MISC(mpeg_samplerate), 0, 0); -- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_samplerate, -- FALSE, FALSE, 0); -+ gtk_label_set_justify (GTK_LABEL(mpeg_samplerate), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_samplerate), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_lvbox), mpeg_samplerate, FALSE, FALSE, 0); -+ -+ mpeg_fileinfo = gtk_label_new(""); -+ gtk_label_set_justify (GTK_LABEL(mpeg_fileinfo), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_fileinfo), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_lvbox), mpeg_fileinfo, FALSE, FALSE, 0); -+ -+ mpeg_rvbox = gtk_vbox_new(FALSE, 5); -+ gtk_box_pack_start(GTK_BOX(mpeg_hbox), mpeg_rvbox, FALSE, FALSE, 0); -+ gtk_container_set_border_width(GTK_CONTAINER(mpeg_rvbox), 10); -+ -+ mpeg_bitrate = gtk_label_new(""); -+ gtk_label_set_justify (GTK_LABEL(mpeg_bitrate), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_bitrate), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_rvbox), mpeg_bitrate, FALSE, FALSE, 0); - - mpeg_flags = gtk_label_new(""); -- gtk_misc_set_alignment(GTK_MISC(mpeg_flags), 0, 0); -- gtk_label_set_justify(GTK_LABEL(mpeg_flags), GTK_JUSTIFY_LEFT); -- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_flags, -- FALSE, FALSE, 0); -+ gtk_label_set_justify (GTK_LABEL(mpeg_flags), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_flags), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_rvbox), mpeg_flags, FALSE, FALSE, 0); - -- mpeg_fileinfo = gtk_label_new(""); -- gtk_misc_set_alignment(GTK_MISC(mpeg_fileinfo), 0, 0); -- gtk_label_set_justify(GTK_LABEL(mpeg_fileinfo), -- GTK_JUSTIFY_LEFT); -- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_fileinfo, -- FALSE, FALSE, 0); -+ label = gtk_label_new ("MPEG"); -+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), mpeg_frame, label); -+ -+ /* add notebook to window vbox */ -+ gtk_box_pack_start(GTK_BOX(window_vbox), notebook, FALSE, FALSE, 0); -+ -+ /* add button box to window vbox */ -+ bbox = gtk_hbutton_box_new(); -+ gtk_box_pack_start(GTK_BOX(window_vbox), bbox, FALSE, FALSE, 0); - -+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END); -+ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 5); -+ -+ save = gtk_button_new_with_label("Save"); -+ gtk_signal_connect(GTK_OBJECT(save), "clicked", GTK_SIGNAL_FUNC(save_cb), NULL); -+ gtk_box_pack_start(GTK_BOX(bbox), save, TRUE, TRUE, 5); -+ -+ close = gtk_button_new_with_label("Close"); -+ gtk_signal_connect_object(GTK_OBJECT(close), "clicked", -+ GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window)); -+ gtk_box_pack_start(GTK_BOX(bbox), close, TRUE, TRUE, 5); -+ -+ gtk_container_add(GTK_CONTAINER(window), window_vbox); - gtk_widget_show_all(window); - } - -@@ -500,73 +918,128 @@ - title = g_strdup(g_basename(filename)); - if ((tmp = strrchr(title, '.')) != NULL) - *tmp = '\0'; -- gtk_entry_set_text(GTK_ENTRY(title_entry), title); -+ gtk_entry_set_text(GTK_ENTRY(v1_title_entry), title); -+ gtk_entry_set_text(GTK_ENTRY(v2_title_entry), title); - g_free(title); - -- gtk_entry_set_text(GTK_ENTRY(artist_entry), ""); -- gtk_entry_set_text(GTK_ENTRY(album_entry), ""); -- gtk_entry_set_text(GTK_ENTRY(year_entry), ""); -- gtk_entry_set_text(GTK_ENTRY(tracknum_entry), ""); -- gtk_entry_set_text(GTK_ENTRY(comment_entry), ""); -- gtk_list_select_item(GTK_LIST(GTK_COMBO(genre_combo)->list), -+ gtk_entry_set_text(GTK_ENTRY(v1_artist_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v1_album_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v1_year_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v1_tracknum_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v1_comment_entry), ""); -+ -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v1_genre_combo)->list), - genre_find_index(genre_list, 0xff)); -+ -+ gtk_entry_set_text(GTK_ENTRY(v2_artist_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_album_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_year_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_tracknum_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_comment_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_composer_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_orig_artist_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_url_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_encoded_by_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry), ""); -+ - gtk_label_set_text(GTK_LABEL(mpeg_level), "MPEG ?, layer ?"); - gtk_label_set_text(GTK_LABEL(mpeg_bitrate), ""); - gtk_label_set_text(GTK_LABEL(mpeg_samplerate), ""); - gtk_label_set_text(GTK_LABEL(mpeg_flags), ""); - gtk_label_set_text(GTK_LABEL(mpeg_fileinfo), ""); -- - if (!strncasecmp(filename, "http://", 7)) - { - file_info_http(filename); - return; - } - -- gtk_widget_set_sensitive(id3_frame, TRUE); -+ gtk_widget_set_sensitive(id3v1_frame, TRUE); -+ gtk_widget_set_sensitive(id3v2_frame, TRUE); - - if ((fh = fopen(current_filename, "rb")) != NULL) - { - struct frame frm; - gboolean id3_found = FALSE; -+ struct id3_tag *id3 = NULL; - guint8 *buf; - double tpf; - int pos; - xing_header_t xing_header; - guint32 num_frames; -- -- fseek(fh, -sizeof (tag), SEEK_END); -- if (fread(&tag, 1, sizeof (tag), fh) == sizeof (tag)) -+ /* -+ * Try reading ID3v2 tag. -+ */ -+ fseek(fh, 0, SEEK_SET); -+ id3 = id3_open_fp(fh, 0); -+ if (id3 != NULL) - { -- if (!strncmp(tag.tag, "TAG", 3)) -+ struct id3_frame* frame; -+ -+ set_entry_tag_v2(GTK_ENTRY(v2_title_entry), id3, ID3_TIT2); -+ set_entry_tag_v2(GTK_ENTRY(v2_artist_entry), id3, ID3_TPE1); -+ set_entry_tag_v2(GTK_ENTRY(v2_album_entry), id3, ID3_TALB); -+ set_entry_tag_v2(GTK_ENTRY(v2_comment_entry), id3, ID3_COMM); -+ set_entry_tag_v2(GTK_ENTRY(v2_composer_entry), id3, ID3_TCOM); -+ set_entry_tag_v2(GTK_ENTRY(v2_orig_artist_entry), id3, ID3_TOPE); -+ set_entry_tag_v2(GTK_ENTRY(v2_url_entry), id3, ID3_WCOM); -+ set_entry_tag_v2(GTK_ENTRY(v2_encoded_by_entry), id3, ID3_TENC); -+ set_entry_tag_v2(GTK_ENTRY(v2_tracknum_entry), id3, ID3_TRCK); -+ set_entry_tag_v2(GTK_ENTRY(v2_year_entry), id3, ID3_TYER); -+ -+ frame = id3_get_frame(id3, ID3_TCON, 1); -+ if (frame != NULL) - { -- id3_found = TRUE; -- set_entry_tag(GTK_ENTRY(title_entry), -- tag.title, 30); -- set_entry_tag(GTK_ENTRY(artist_entry), -- tag.artist, 30); -- set_entry_tag(GTK_ENTRY(album_entry), -- tag.album, 30); -- set_entry_tag(GTK_ENTRY(year_entry), -- tag.year, 4); -- /* Check for v1.1 tags */ -- if (tag.u.v1_1.__zero == 0 && tag.u.v1_1.track_number > 0) -- { -- char *temp = g_strdup_printf("%d", tag.u.v1_1.track_number); -- set_entry_tag(GTK_ENTRY(comment_entry), -- tag.u.v1_1.comment, 28); -- gtk_entry_set_text(GTK_ENTRY(tracknum_entry), temp); -- g_free(temp); -- } -- else -+ char* genre = id3_get_content(frame); -+ if (genre != NULL) - { -- set_entry_tag(GTK_ENTRY(comment_entry), -- tag.u.v1_0.comment, 30); -- gtk_entry_set_text(GTK_ENTRY(tracknum_entry), ""); -+ int genre_idx = genre_find_index_str(genre_list, genre); -+ if (genre_idx > 0) -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v2_genre_combo)->list), genre_idx); -+ else -+ gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry), genre); - } -- -- gtk_list_select_item(GTK_LIST(GTK_COMBO(genre_combo)->list), genre_find_index(genre_list, tag.genre)); - } -+ -+ id3_close(id3); -+ } -+ else -+ { -+ /* Grey out the id3v2 tab */ -+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(v2_checkbox), TRUE); -+ } -+ -+ /* -+ * Try reading ID3v1 tag. -+ */ -+ fseek(fh, -sizeof (id3v1tag), SEEK_END); -+ if ( (fread(&id3v1tag, 1, sizeof (id3v1tag), fh) == sizeof (id3v1tag)) && !strncmp(id3v1tag.tag, "TAG", 3)) -+ { -+ id3_found = TRUE; -+ set_entry_tag_v1(GTK_ENTRY(v1_title_entry), id3v1tag.title, 30); -+ set_entry_tag_v1(GTK_ENTRY(v1_artist_entry), id3v1tag.artist, 30); -+ set_entry_tag_v1(GTK_ENTRY(v1_album_entry), id3v1tag.album, 30); -+ set_entry_tag_v1(GTK_ENTRY(v1_year_entry), id3v1tag.year, 4); -+ /* Check for v1.1 tags */ -+ if (id3v1tag.u.v1_1.__zero == 0 && id3v1tag.u.v1_1.track_number > 0) -+ { -+ char *temp = g_strdup_printf("%d", id3v1tag.u.v1_1.track_number); -+ set_entry_tag_v1(GTK_ENTRY(v1_comment_entry), id3v1tag.u.v1_1.comment, 28); -+ gtk_entry_set_text(GTK_ENTRY(v1_tracknum_entry), temp); -+ g_free(temp); -+ } -+ else -+ { -+ set_entry_tag_v1(GTK_ENTRY(v1_comment_entry), id3v1tag.u.v1_0.comment, 30); -+ gtk_entry_set_text(GTK_ENTRY(v1_tracknum_entry), ""); - } -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v1_genre_combo)->list), genre_find_index(genre_list, id3v1tag.genre)); -+ } -+ else -+ { -+ // Grey out id3v1 tab -+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(v1_checkbox), TRUE); -+ } -+ - rewind(fh); - - if (!mpg123_get_first_frame(fh, &frm, &buf)) -diff -dPNur xmms-1.2.11/Input/mpg123/id3.c xmms-1.2.11-new/Input/mpg123/id3.c ---- xmms-1.2.11/Input/mpg123/id3.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3.c 2007-11-24 23:58:41.000000000 +0100 -@@ -22,6 +22,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -49,7 +50,7 @@ - */ - static int id3_seek_mem(struct id3_tag *id3, int offset) - { -- if (id3->id3_pos + offset > id3->id3_tagsize || -+ if (id3->id3_pos + offset > id3->id3_totalsize || - id3->id3_pos + offset < 0) - { - id3_error(id3, "seeking beyond tag boundary"); -@@ -77,7 +78,7 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + size > id3->id3_tagsize) -+ if (id3->id3_pos + size > id3->id3_totalsize) - return NULL; - - /* -@@ -118,7 +119,7 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + offset > id3->id3_tagsize || -+ if (id3->id3_pos + offset > id3->id3_totalsize || - id3->id3_pos + offset < 0) - return -1; - -@@ -148,8 +149,8 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + size > id3->id3_tagsize) -- return NULL; -+ if (id3->id3_pos + size > id3->id3_totalsize) -+ size = id3->id3_totalsize - id3->id3_pos; - - /* - * If buffer is NULL, we use the default buffer. -@@ -205,7 +206,7 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + offset > id3->id3_tagsize || -+ if (id3->id3_pos + offset > id3->id3_totalsize || - id3->id3_pos + offset < 0) - return -1; - -@@ -263,8 +264,8 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + size > id3->id3_tagsize) -- size = id3->id3_tagsize - id3->id3_pos; -+ if (id3->id3_pos + size > id3->id3_totalsize) -+ size = id3->id3_totalsize - id3->id3_pos; - - /* - * If buffer is NULL, we use the default buffer. -@@ -338,6 +339,32 @@ - return NULL; - } - -+/* -+ * Function id3_new() -+ * -+ * Creates a new ID3 tag structure. Useful for creating -+ * a new tag. -+ * -+ */ -+struct id3_tag *id3_new() -+{ -+ struct id3_tag *id3; -+ -+ /* -+ * Allocate ID3 structure. -+ */ -+ id3 = g_malloc0( sizeof(struct id3_tag) ); -+ -+ if (id3 != NULL) -+ { -+ id3_init_tag ( id3 ); -+ id3->id3_type = ID3_TYPE_NONE; -+ id3->id3_seek = NULL; -+ id3->id3_read = NULL; -+ } -+ -+ return id3; -+} - - /* - * Function id3_open_fd (fd, flags) -@@ -493,7 +520,7 @@ - if (id3->id3_newtag) - return 0; - else -- return id3->id3_tagsize + 3 + sizeof(id3_taghdr_t); -+ return id3->id3_totalsize + 3 + sizeof(id3_taghdr_t); - } - #endif - -@@ -560,6 +587,81 @@ - return 0; - } - -+/* -+ * Function id3_remove_tag_filename(filename) -+ * -+ * Remove the ID3v2 tag from the file indicated by filename. Takes care of resizing -+ * the file, if needed. Returns 0 upon success, or -1 if an error occured. -+ * -+ */ -+int id3_remove_tag_filename(const char* filename) -+{ -+ struct id3_tag *current_id3; -+ int fd; -+ int current_totalsize; -+ struct stat stat_buf; -+ -+ fd = open(filename, O_RDWR); -+ if (fd == -1) -+ return -1; -+ -+ /* -+ * Figure out how large the current tag is. -+ */ -+ current_id3 = id3_open_fd(fd, 0); -+ if (current_id3 != NULL) -+ { -+ /* We use MAX to make sure an erroneous tag doesn't confuse us */ -+ current_totalsize = MAX(current_id3->id3_totalsize, 0); -+ id3_close(current_id3); -+ } -+ else -+ { -+ current_totalsize = 0; -+ } -+ -+ if (current_totalsize <= 0) -+ return 0; -+ -+ /* -+ * Rewrite the file. -+ */ -+ -+ stat(filename, &stat_buf); -+ -+ /* Re-position all the data current_totalsize bytes backwards */ -+ { -+ int read_pos, write_pos; -+ size_t read_size; -+ char buf[4096]; -+ -+ /* TODO: Add error handling to IO operations */ -+ -+ /* We reposition the data by going forwards, each time reading -+ a block and copying it backward. That way, we never write -+ over a block which we intend to read later. */ -+ write_pos = 0; -+ read_pos = write_pos + current_totalsize; -+ -+ do -+ { -+ lseek(fd, read_pos, SEEK_SET); -+ read_size = read(fd, buf, sizeof(buf)); -+ read_pos += read_size; -+ -+ /* Write whatever block we've got */ -+ lseek(fd, write_pos, SEEK_SET); -+ write(fd, buf, read_size); -+ write_pos += read_size; -+ } -+ while (read_size > 0); -+ -+ ftruncate(fd, stat_buf.st_size - current_totalsize); -+ } -+ -+ close(fd); -+ return 0; -+} - - /* - * Function id3_write_tag (id3, fd) -@@ -567,30 +669,25 @@ - * Wrtite the ID3 tag to the indicated file descriptor. Return 0 - * upon success, or -1 if an error occured. - * -+ * Warning: This function is called by id3_write_tag_filename and should -+ * not be called standalone, as it doesn't perform seeking -+ * and doesn't enlarge the file as necessary, and thus might -+ * OVERWRITE THE AUDIO DATA. -+ * - */ - int id3_write_tag(struct id3_tag *id3, int fd) - { - struct id3_frame *fr; - GList *node; -- int size = 0; - char buf[ID3_TAGHDR_SIZE]; - - /* -- * Calculate size of ID3 tag. -- */ -- for (node = id3->id3_frame; node != NULL; node = node->next) -- { -- fr = node->data; -- size += fr->fr_size + ID3_FRAMEHDR_SIZE; -- } -- -- /* - * Write tag header. - */ - buf[0] = id3->id3_version; - buf[1] = id3->id3_revision; - buf[2] = id3->id3_flags; -- ID3_SET_SIZE28(size, buf[3], buf[4], buf[5], buf[6]); -+ ID3_SET_SIZE28(id3->id3_size, buf[3], buf[4], buf[5], buf[6]); - - if (safe_write(fd, "ID3", 3) == -1) - return -1; -@@ -617,19 +714,203 @@ - * TODO: Support compressed headers, encoded - * headers, and grouping info. - */ -- /* fhdr.fh_id = fr->fr_desc ? g_htonl(fr->fr_desc->fd_id) : 0; */ -- fhdr[3] = (fr->fr_size >> 24) & 0xff; -- fhdr[4] = (fr->fr_size >> 16) & 0xff; -- fhdr[5] = (fr->fr_size >> 8) & 0xff; -- fhdr[6] = fr->fr_size & 0xff; -- fhdr[7] = (fr->fr_flags >> 8) & 0xff; -- fhdr[8] = fr->fr_flags & 0xff; -+ fhdr[0] = fr->fr_desc->fd_idstr[0]; -+ fhdr[1] = fr->fr_desc->fd_idstr[1]; -+ fhdr[2] = fr->fr_desc->fd_idstr[2]; -+ fhdr[3] = fr->fr_desc->fd_idstr[3]; -+ fhdr[4] = (fr->fr_raw_size >> 24) & 0xff; -+ fhdr[5] = (fr->fr_raw_size >> 16) & 0xff; -+ fhdr[6] = (fr->fr_raw_size >> 8) & 0xff; -+ fhdr[7] = fr->fr_raw_size & 0xff; -+ fhdr[8] = (fr->fr_flags >> 8) & 0xff; -+ fhdr[9] = fr->fr_flags & 0xff; - - if (safe_write(fd, fhdr, sizeof(fhdr)) == -1) - return -1; - -- if (safe_write(fd, fr->fr_data, fr->fr_size) == -1) -+ if (safe_write(fd, fr->fr_raw_data, fr->fr_raw_size) == -1) - return -1; - } - return 0; - } -+ -+ -+/* -+ * Function id3_write_tag_file(id3, filename) -+ * -+ * Write the ID3 tag to the file indicated by filename. Takes care of enlarging -+ * the file, if needed. Returns 0 upon success, or -1 if an error occured. -+ * -+ */ -+int id3_write_tag_filename(struct id3_tag *id3, const char* filename) -+{ -+ struct id3_tag *current_id3; -+ int fd; -+ int current_totalsize, new_totalsize; -+ GList* node; -+ -+ fd = open(filename, O_RDWR); -+ if (fd == -1) -+ return -1; -+ -+ /* -+ * Figure out how large the current tag is. -+ */ -+ current_id3 = id3_open_fd(fd, 0); -+ if (current_id3 != NULL) -+ { -+ /* We use MAX to make sure an erroneous tag doesn't confuse us */ -+ current_totalsize = MAX(current_id3->id3_totalsize, 0); -+ id3_close(current_id3); -+ } -+ else -+ { -+ current_totalsize = 0; -+ } -+ -+ /* -+ * Figure out how large the new tag will be. -+ */ -+ new_totalsize = 10; -+ node = id3->id3_frame; -+ while (node != NULL) -+ { -+ struct id3_frame* fr = node->data; -+ -+ { -+ char* text = id3_get_text(fr); -+ if (text != NULL) -+ { -+ int len = strlen(text); -+ g_free(text); -+ -+ if (len == 0) -+ { -+ /* We skip over frames with empty text */ -+ node = node->next; -+ id3_delete_frame(fr); -+ continue; -+ } -+ } -+ } -+ -+ { -+ char* url = id3_get_url(fr); -+ if (url != NULL) -+ { -+ int len = strlen(url); -+ g_free(url); -+ -+ if (len == 0) -+ { -+ /* We skip over frames with empty URLs */ -+ node = node->next; -+ id3_delete_frame(fr); -+ continue; -+ } -+ } -+ } -+ -+ new_totalsize += fr->fr_raw_size + ID3_FRAMEHDR_SIZE; -+ node = node->next; -+ } -+ new_totalsize += 0; /* no extended header, no footer, no padding */ -+ id3->id3_flags = 0; -+ -+ /* -+ * Determine whether we need to rewrite the file to make place for the new tag. -+ */ -+ if (new_totalsize > current_totalsize) -+ { -+ struct stat stat_buf; -+ int grow_size; -+ -+ stat(filename, &stat_buf); -+ grow_size = new_totalsize - current_totalsize; -+ ftruncate(fd, stat_buf.st_size + grow_size); -+ -+ /* truncate adds "sparse" zeros; we'll turn them into real ones, -+ which occupy space on disk, to make sure we actually have -+ the disk space before we start enlarging the file */ -+ { -+ int remaining = grow_size; -+ char buf[1024] = { 0 }; -+ lseek(fd, stat_buf.st_size, SEEK_SET); -+ while (remaining > 0) -+ { -+ int ret = write(fd, buf, MIN(sizeof(buf), remaining)); -+ if (ret >= 0) -+ remaining -= ret; -+ else -+ { -+ id3_error(id3, "Unable to enlarge file for the new tag"); -+ ftruncate(fd, stat_buf.st_size); -+ close(fd); -+ return -1; -+ } -+ } -+ } -+ -+ /* and now, re-position all the data grow_size bytes forward */ -+ { -+ int area_to_move_size = stat_buf.st_size - current_totalsize; -+ int read_pos, write_pos; -+ size_t read_size, read_size_desired; -+ char buf[4096]; -+ -+ /* TODO: Add error handling to IO operations */ -+ -+ /* We reposition the data by going backwards, each time reading -+ a block and copying it forward. That way, we never write -+ over a block which we intend to read later. */ -+ write_pos = lseek(fd, 0, SEEK_END); -+ read_pos = write_pos - grow_size; -+ -+ /* While we still have bytes to move... */ -+ while(area_to_move_size > 0) -+ { -+ /* Get 1 block or the remaining bytes -- the smallest of the two */ -+ read_size_desired = MIN(area_to_move_size, sizeof(buf)); -+ read_pos -= read_size_desired; -+ lseek(fd, read_pos, SEEK_SET); -+ read_size = read(fd, buf, read_size_desired); -+ -+ /* Write whatever block we've got */ -+ write_pos -= read_size; -+ lseek(fd, write_pos, SEEK_SET); -+ write(fd, buf, read_size); -+ -+ area_to_move_size -= read_size; -+ } -+ } -+ } -+ else -+ { -+ new_totalsize = current_totalsize; -+ } -+ -+ id3->id3_size = new_totalsize - 10; -+ -+ /* Zero-out the ID3v2 tag area */ -+ { -+ char buf[1024] = {0}; -+ size_t remaining; -+ -+ lseek(fd, 0, SEEK_SET); -+ for(remaining = new_totalsize; remaining > 0; remaining -= MIN(remaining,sizeof(buf))) -+ { -+ write(fd, buf, MIN(remaining,sizeof(buf))); -+ } -+ } -+ -+ /* Write the new tag */ -+ lseek(fd, 0, SEEK_SET); -+ if (id3_write_tag(id3, fd) == -1) -+ { -+ close(fd); -+ return -1; -+ } -+ -+ close(fd); -+ return 0; -+} -diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame.c xmms-1.2.11-new/Input/mpg123/id3_frame.c ---- xmms-1.2.11/Input/mpg123/id3_frame.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3_frame.c 2007-11-24 23:58:41.000000000 +0100 -@@ -283,7 +283,7 @@ - */ - if (!((buf[0] >= '0' && buf[0] <= '9') || (buf[0] >= 'A' && buf[0] <= 'Z'))) - { -- id3->id3_seek(id3, id3->id3_tagsize - id3->id3_pos); -+ id3->id3_seek(id3, id3->id3_totalsize - id3->id3_pos); - return 0; - } - id = ID3_FRAME_ID(buf[0], buf[1], buf[2], buf[3]); -@@ -308,7 +308,7 @@ - */ - - frame->fr_desc = find_frame_description(id); -- -+ - /* - * Check if frame had a valid id. - */ -@@ -385,6 +385,29 @@ - } - - /* -+ * Function id3_get_or_add_frame (id3, type) -+ * -+ * Search in the list of frames for the ID3-tag, and return the first frame -+ * of the indicated type. If no frame of the indicated type exists yet, -+ * it will add one and return it. -+ * -+ */ -+struct id3_frame *id3_get_or_add_frame(struct id3_tag *id3, guint32 type) -+{ -+ struct id3_frame* fr; -+ -+ fr = id3_get_frame(id3, type, 1); -+ if (fr != NULL) -+ { -+ return fr; -+ } -+ else -+ { -+ return id3_add_frame(id3, type); -+ } -+} -+ -+/* - * Function decompress_frame(frame) - * - * Uncompress the indicated frame. Return 0 upon success, or -1 if -@@ -517,27 +540,26 @@ - */ - int id3_delete_frame(struct id3_frame *frame) - { -- GList *list = frame->fr_owner->id3_frame; -+ struct id3_tag* id3 = frame->fr_owner; -+ GList *list = id3->id3_frame; - int ret; - - /* - * Search for frame in list. - */ -- if (g_list_find(list, frame) != NULL) -- { -- /* -- * Frame does not exist in frame list. -- */ -- ret = -1; -- } -- else -- { -+ if (g_list_find(list, frame) != NULL) { - /* - * Remove frame from frame list. - */ - list = g_list_remove(list, frame); -- frame->fr_owner->id3_altered = 1; -- ret = 0; -+ id3->id3_frame = list; -+ id3->id3_altered = 1; -+ ret = 0; -+ } else { -+ /* -+ * Frame does not exist in frame list. -+ */ -+ ret = -1; - } - - /* -@@ -704,7 +726,7 @@ - */ - if (!((buf[0] >= '0' && buf[0] <= '9') || (buf[0] >= 'A' && buf[0] <= 'Z'))) - { -- id3->id3_seek(id3, id3->id3_tagsize - id3->id3_pos); -+ id3->id3_seek(id3, id3->id3_size - id3->id3_pos); - return 0; - } - -diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame_text.c xmms-1.2.11-new/Input/mpg123/id3_frame_text.c ---- xmms-1.2.11/Input/mpg123/id3_frame_text.c 2007-11-24 23:58:20.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/id3_frame_text.c 2007-11-24 23:58:41.000000000 +0100 -@@ -155,6 +155,11 @@ - char *id3_get_text(struct id3_frame *frame) - { - int offset = 0; -+ -+ /* Do we even have data for this frame */ -+ if (!frame->fr_data) -+ return NULL; -+ - /* Type check */ - if (frame->fr_desc->fd_idstr[0] != 'T') - return NULL; -@@ -374,3 +379,54 @@ - return id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), - ID3_TEXT_FRAME_PTR(frame) + offset); - } -+ -+/* -+ * Function id3_set_comment (frame, text) -+ * -+ * Set text for the indicated frame. Return 0 upon -+ * success, or -1 if an error occured. -+ * -+ */ -+int id3_set_comment(struct id3_frame *frame, char *text) -+{ -+ int *intp; -+ -+ /* Type check */ -+ if (frame->fr_desc->fd_id != ID3_COMM) -+ return -1; -+ -+ /* -+ * Release memory occupied by previous data. -+ */ -+ id3_frame_clear_data(frame); -+ -+ /* -+ * Allocate memory for new data. -+ */ -+ frame->fr_raw_size = 13 + strlen(text); -+ frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); /* XXXComments\0<\0> -+ -+ /* Save time... we just need to zero out the start, not the whole -+ * block, so don't waste time with a calloc() -+ */ -+ -+ ((guint8 *)frame->fr_raw_data)[0] = ID3_ENCODING_ISO_8859_1; -+ ((guint8 *)frame->fr_raw_data)[1] = 0x58; -+ ((guint8 *)frame->fr_raw_data)[2] = 0x58; -+ ((guint8 *)frame->fr_raw_data)[3] = 0x58; -+ -+ memcpy((char *) frame->fr_raw_data + 4, "Comments", 9); -+ -+ /* -+ * Copy contents. -+ */ -+ memcpy((char *) frame->fr_raw_data + 13, text, strlen(text) + 1); -+ -+ frame->fr_altered = 1; -+ frame->fr_owner->id3_altered = 1; -+ -+ frame->fr_data = frame->fr_raw_data; -+ frame->fr_size = frame->fr_raw_size; -+ -+ return 0; -+} -diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame_url.c xmms-1.2.11-new/Input/mpg123/id3_frame_url.c ---- xmms-1.2.11/Input/mpg123/id3_frame_url.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3_frame_url.c 2007-11-24 23:58:41.000000000 +0100 -@@ -34,6 +34,11 @@ - char *id3_get_url(struct id3_frame *frame) - { - int offset = 0; -+ -+ /* Do we even have data for this frame */ -+ if (!frame->fr_data) -+ return NULL; -+ - /* Type check */ - if (frame->fr_desc->fd_idstr[0] != 'W') - return NULL; -@@ -80,3 +85,32 @@ - return id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), - ID3_TEXT_FRAME_PTR(frame)); - } -+ -+/* -+ * Function id3_set_url (frame) -+ * -+ * Sets URL of frame. -+ * -+ */ -+void id3_set_url(struct id3_frame *frame, const char* url) -+{ -+ /* Type check */ -+ if ( frame->fr_desc->fd_idstr[0] != 'W' ) -+ return; -+ -+ /* Check if frame is compressed */ -+ if (id3_decompress_frame(frame) == -1) -+ return; -+ -+ /* -+ * Allocate memory for new data. -+ */ -+ frame->fr_raw_size = strlen(url) + 1; -+ frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); -+ -+ /* -+ * Copy contents. -+ */ -+ *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1; -+ memcpy((char *) frame->fr_raw_data + 1, url, frame->fr_raw_size); -+} -diff -dPNur xmms-1.2.11/Input/mpg123/id3.h xmms-1.2.11-new/Input/mpg123/id3.h ---- xmms-1.2.11/Input/mpg123/id3.h 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3.h 2007-11-24 23:58:41.000000000 +0100 -@@ -22,6 +22,7 @@ - #define ID3_H - - #include -+#include - - /* - * Option flags to id3_open_*(). -@@ -49,8 +50,9 @@ - - int id3_version; /* Major ID3 version number */ - int id3_revision; /* ID3 revision number */ -+ int id3_size; /* Size of ID3 tag (as dictated by header) */ - -- int id3_tagsize; /* Total size of ID3 tag */ -+ int id3_totalsize; /* Total size of ID3 tag (including header, footer and padding) */ - int id3_pos; /* Current position within tag */ - - char *id3_error_msg; /* Last error message */ -@@ -140,8 +142,6 @@ - #define ID3_ENCODING_UTF16BE 0x02 - #define ID3_ENCODING_UTF8 0x03 - -- -- - /* - * ID3 frame id numbers. - */ -@@ -322,50 +322,51 @@ - */ - - /* From id3.c */ --struct id3_tag *id3_open_mem(void *, int); --struct id3_tag *id3_open_fd(int, int); --struct id3_tag *id3_open_fp(FILE *, int); --int id3_set_output(struct id3_tag *, char *); --int id3_close(struct id3_tag *); --int id3_tell(struct id3_tag *); --int id3_alter_file(struct id3_tag *); --int id3_write_tag(struct id3_tag *, int); -+struct id3_tag *id3_new(); -+struct id3_tag *id3_open_mem(void *ptr, int flags); -+struct id3_tag *id3_open_fd(int fd, int flags); -+struct id3_tag *id3_open_fp(FILE *fp, int flags); -+int id3_close(struct id3_tag *id3); -+int id3_tell(struct id3_tag *id3); -+int id3_alter_file(struct id3_tag *id3); -+int id3_write_tag(struct id3_tag *id3, int fd); -+int id3_write_tag_filename(struct id3_tag *id3, const char* filename); -+int id3_remove_tag_filename(const char* filename); - - /* From id3_frame.c */ - int id3_read_frame(struct id3_tag *id3); --struct id3_frame *id3_get_frame(struct id3_tag *, guint32, int); -+struct id3_frame *id3_get_frame(struct id3_tag *id3, guint32 type, int num); - int id3_delete_frame(struct id3_frame *frame); --struct id3_frame *id3_add_frame(struct id3_tag *, guint32); --int id3_decompress_frame(struct id3_frame *); --void id3_destroy_frames(struct id3_tag *id); -+struct id3_frame *id3_add_frame(struct id3_tag *id3, guint32 type); -+struct id3_frame *id3_get_or_add_frame(struct id3_tag *id3, guint32 type); -+int id3_decompress_frame(struct id3_frame *frame); -+void id3_destroy_frames(struct id3_tag *id3); - void id3_frame_clear_data(struct id3_frame *frame); - - /* From id3_frame_text.c */ - guint id3_string_size(guint8 encoding, const char* text); - char* id3_string_decode(guint8 encoding, const char* text); --gint8 id3_get_encoding(struct id3_frame *); --int id3_set_encoding(struct id3_frame *, gint8); --char *id3_get_text(struct id3_frame *); --char *id3_get_comment(struct id3_frame *); --char *id3_get_text_desc(struct id3_frame *); --int id3_get_text_number(struct id3_frame *); --int id3_set_text(struct id3_frame *, char *); --int id3_set_text_number(struct id3_frame *, int); -+gint8 id3_get_encoding(struct id3_frame *frame); -+int id3_set_encoding(struct id3_frame *frame, gint8 encoding); -+char *id3_get_text(struct id3_frame *frame); -+char *id3_get_comment(struct id3_frame *frame); -+char *id3_get_text_desc(struct id3_frame *frame); -+int id3_get_text_number(struct id3_frame *frame); -+int id3_set_text(struct id3_frame *frame, char *text); -+int id3_set_comment(struct id3_frame *frame, char *comment); -+int id3_set_text_number(struct id3_frame *frame, int number); - gboolean id3_frame_is_text(struct id3_frame *frame); - - /* From id3_frame_content.c */ --char *id3_get_content(struct id3_frame *); -+char *id3_get_content(struct id3_frame *frame); - - /* From id3_frame_url.c */ --char *id3_get_url(struct id3_frame *); --char *id3_get_url_desc(struct id3_frame *); -+char *id3_get_url(struct id3_frame *frame); -+char *id3_get_url_desc(struct id3_frame *frame); -+void id3_set_url(struct id3_frame *frame, const char* url); - - /* From id3_tag.c */ - void id3_init_tag(struct id3_tag *id3); - int id3_read_tag(struct id3_tag *id3); - --char *convert_from_utf16(const unsigned char *utf16); --char *convert_from_utf16be(const unsigned char *utf16); -- -- - #endif /* ID3_H */ -diff -dPNur xmms-1.2.11/Input/mpg123/id3_header.h xmms-1.2.11-new/Input/mpg123/id3_header.h ---- xmms-1.2.11/Input/mpg123/id3_header.h 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3_header.h 2007-11-24 23:58:41.000000000 +0100 -@@ -39,22 +39,21 @@ - #define ID3_THFLAG_USYNC 0x80 - #define ID3_THFLAG_EXT 0x40 - #define ID3_THFLAG_EXP 0x20 -+#define ID3_THFLAG_FOOTER 0x10 - - #define ID3_SET_SIZE28(size, a, b, c, d) \ --do { \ -- a = (size >> (24 + 3)) & 0x7f; \ -- b = (size >> (16 + 2)) & 0x7f; \ -- c = (size >> ( 8 + 1)) & 0x7f; \ -+{ \ -+ a = (size >> (24 - 3)) & 0x7f; \ -+ b = (size >> (16 - 2)) & 0x7f; \ -+ c = (size >> ( 8 - 1)) & 0x7f; \ - d = size & 0x7f; \ --} while (0) -+} - - #define ID3_GET_SIZE28(a, b, c, d) \ --(((a & 0x7f) << (24 - 3)) | \ -- ((b & 0x7f) << (16 - 2)) | \ -- ((c & 0x7f) << ( 8 - 1)) | \ -- ((d & 0x7f))) -- -- -+ (((a & 0x7f) << (24 - 3)) | \ -+ ((b & 0x7f) << (16 - 2)) | \ -+ ((c & 0x7f) << ( 8 - 1)) | \ -+ ((d & 0x7f))) \ - - /* - * Layout for the extended header. -diff -dPNur xmms-1.2.11/Input/mpg123/id3_tag.c xmms-1.2.11-new/Input/mpg123/id3_tag.c ---- xmms-1.2.11/Input/mpg123/id3_tag.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3_tag.c 2007-11-24 23:58:41.000000000 +0100 -@@ -39,7 +39,8 @@ - id3->id3_version = 3; - id3->id3_revision = 0; - id3->id3_flags = ID3_THFLAG_USYNC | ID3_THFLAG_EXP; -- id3->id3_tagsize = 0; -+ id3->id3_size = 0; -+ id3->id3_totalsize = 0; - - id3->id3_altered = 1; - id3->id3_newtag = 1; -@@ -63,13 +64,14 @@ - int id3_read_tag(struct id3_tag *id3) - { - char *buf; -+ guint8 padding; - - /* - * We know that the tag will be at least this big. - * - * tag header + "ID3" - */ -- id3->id3_tagsize = ID3_TAGHDR_SIZE + 3; -+ id3->id3_totalsize = ID3_TAGHDR_SIZE + 3; - - if (!(id3->id3_oflags & ID3_OPENF_NOCHK)) - { -@@ -100,9 +102,11 @@ - id3->id3_version = buf[0]; - id3->id3_revision = buf[1]; - id3->id3_flags = buf[2]; -- id3->id3_tagsize = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]); -+ id3->id3_size = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]); -+ id3->id3_totalsize += id3->id3_size; -+ if (id3->id3_flags & ID3_THFLAG_FOOTER) -+ id3->id3_totalsize += 10; - id3->id3_newtag = 0; -- id3->id3_pos = 0; - - if (id3->id3_version < 2 || id3->id3_version > 4) - return -1; -@@ -120,14 +124,34 @@ - /* - * Parse frames. - */ -- while (id3->id3_pos < id3->id3_tagsize) -+ while (id3->id3_pos < id3->id3_size) - { - if (id3_read_frame(id3) == -1) - return -1; - } - -- if (id3->id3_frame == NULL) -- return -1; -+ /* -+ * Like id3lib, we try to find unstandard padding (not within -+ * the tag size). This is important to know when we strip -+ * the tag or replace it. -+ * Another option might be looking for an MPEG sync, but we don't do it. -+ */ -+ -+ id3->id3_seek(id3, id3->id3_totalsize - id3->id3_pos); -+ -+ /* Temporarily increase totalsize, to try reading beyong the boundary */ -+ ++id3->id3_totalsize; -+ -+ while (id3->id3_read(id3, &padding, sizeof(padding)) != NULL) -+ { -+ if (padding == 0) -+ ++id3->id3_totalsize; -+ else -+ break; -+ } -+ -+ /* Decrease totalsize after we temporarily increased it */ -+ --id3->id3_totalsize; - - return 0; - } -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:58:20.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:58:41.000000000 +0100 -@@ -129,9 +129,9 @@ - - #ifdef USE_SIMD - fr->dct36 = funcs_dct36[0]; -- -+ - if (CPU_HAS_3DNOW() && !p8 && -- (mpg123_cfg.default_synth == SYNTH_3DNOW || -+ (mpg123_cfg.default_synth == SYNTH_3DNOW || - mpg123_cfg.default_synth == SYNTH_AUTO)) - { - fr->synth = funcs[3][ds]; /* 3DNow! optimized synth_1to1() */ -@@ -320,11 +320,11 @@ - if (!strncasecmp(filename, "http://", 7)) - { /* We assume all http:// (except those ending in .ogg) are mpeg -- why do we do that? */ - ext = strrchr(filename, '.'); -- if (ext) -+ if (ext) - { -- if (!strncasecmp(ext, ".ogg", 4)) -+ if (!strncasecmp(ext, ".ogg", 4)) - return FALSE; -- if (!strncasecmp(ext, ".rm", 3) || -+ if (!strncasecmp(ext, ".rm", 3) || - !strncasecmp(ext, ".ra", 3) || - !strncasecmp(ext, ".rpm", 4) || - !strncasecmp(ext, ".fla", 4) || -@@ -534,7 +534,7 @@ - * Function mpg123_get_id3v2 (id3d, tag) - * - * Get desired contents from the indicated id3tag and store it in -- * `tag'. -+ * `tag'. - * - */ - struct id3v2tag_t* mpg123_id3v2_get(struct id3_tag *id3d) -@@ -550,6 +550,10 @@ - tag->track_number = id3v2_get_num(id3d, ID3_TRCK); - tag->comment = id3v2_get_text(id3d, ID3_COMM); - tag->genre = id3v2_get_text(id3d, ID3_TCON); -+ tag->composer = id3v2_get_text(id3d, ID3_TCOM); -+ tag->orig_artist = id3v2_get_text(id3d, ID3_TOPE); -+ tag->url = id3v2_get_text(id3d, ID3_WCOM); -+ tag->encoded_by = id3v2_get_text(id3d, ID3_TENC); - - return tag; - } -@@ -829,7 +833,7 @@ - static int mpg123_seek(struct frame *fr, xing_header_t *xh, gboolean vbr, int time) - { - int jumped = -1; -- -+ - if (xh) - { - int percent = ((double) time * 100.0) / -@@ -995,7 +999,7 @@ - mpg123_info->output_audio = FALSE; - continue; - } -- -+ - } - } - if(mpg123_freqs[fr.sampling_frequency] != mpg123_frequency || mpg123_stereo != fr.stereo) -@@ -1033,12 +1037,12 @@ - mpg123_info->output_audio = FALSE; - continue; - } -- } -+ } - } -- -+ - if (tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index] != mpg123_bitrate) - mpg123_bitrate = tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index]; -- -+ - if (!disp_count) - { - disp_count = 20; -@@ -1154,7 +1158,7 @@ - - if (aboutbox != NULL) - return; -- -+ - aboutbox = xmms_show_message( - _("About MPEG Layer 1/2/3 plugin"), - _("mpg123 decoding engine by Michael Hipp \n" -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.h xmms-1.2.11-new/Input/mpg123/mpg123.h ---- xmms-1.2.11/Input/mpg123/mpg123.h 2007-11-24 23:58:20.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.h 2007-11-24 23:58:41.000000000 +0100 -@@ -1,5 +1,5 @@ - /* -- * mpg123 defines -+ * mpg123 defines - * used source: musicout.h from mpegaudio package - */ - -@@ -79,6 +79,10 @@ - char *album; - char *comment; - char *genre; -+ char *composer; -+ char *orig_artist; -+ char *url; -+ char *encoded_by; - int year; - int track_number; - }; -@@ -300,7 +304,6 @@ - int mpg123_decode_header(struct frame *fr, unsigned long newhead); - double mpg123_compute_bpf(struct frame *fr); - double mpg123_compute_tpf(struct frame *fr); --guint mpg123_strip_spaces(char *src, size_t n); - struct id3v2tag_t* mpg123_id3v2_get(struct id3_tag *id3d); - void mpg123_id3v2_destroy(struct id3v2tag_t* tag); - char *mpg123_format_song_title(struct id3v2tag_t *tag, char *filename); diff --git a/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch b/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch deleted file mode 100644 index 453c91b..0000000 --- a/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch +++ /dev/null @@ -1,766 +0,0 @@ -diff -dPNur xmms-1.2.11/configure.in xmms-1.2.11-new/configure.in ---- xmms-1.2.11/configure.in 2007-11-16 22:52:30.000000000 +0100 -+++ xmms-1.2.11-new/configure.in 2007-11-25 00:00:09.000000000 +0100 -@@ -144,6 +144,22 @@ - fi - AC_SUBST([PTHREAD_LIBS]) - -+dnl *** OpenSSL support -+AC_ARG_ENABLE( ssl, -+[ --disable-ssl Disable HTTP SSL in plugin(s) [default=enabled]],, -+ enable_ssl="yes") -+ -+if test "x$enable_ssl" = xyes; then -+ SSL_LIBS="" -+ AC_CHECK_LIB(ssl, SSL_read, [SSL_LIBS="-lssl" -+ AC_DEFINE(HTTP_SSL,,[Define if OpenSSL is available]) -+ AC_DEFINE(OPENSSL_NO_KRB5,,[Define if OpenSSL is available])], -+ echo "*** SSL support requires openssl and openssl-devel packages ***") -+ LIBS="$LIBS $SSL_LIBS" -+else -+ AC_MSG_RESULT([*** Disabling SSL in plugin(s) per user request ***]) -+ have_ssl=no -+fi - - dnl *** - dnl *** OpenGL -diff -dPNur xmms-1.2.11/Input/mpg123/common.c xmms-1.2.11-new/Input/mpg123/common.c ---- xmms-1.2.11/Input/mpg123/common.c 2007-11-24 23:59:35.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/common.c 2007-11-25 00:00:09.000000000 +0100 -@@ -464,7 +464,11 @@ - void mpg123_open_stream(char *bs_filenam, int fd, unsigned long range) - { - filept_opened = 1; -+#ifdef HTTP_SSL -+ if (!strncasecmp(bs_filenam, "http://", 7) || !strncasecmp(bs_filenam, "https://", 8)) -+#else - if (!strncasecmp(bs_filenam, "http://", 7)) -+#endif - { - filept = NULL; - mpg123_info->filesize = 0; -diff -dPNur xmms-1.2.11/Input/mpg123/http.c xmms-1.2.11-new/Input/mpg123/http.c ---- xmms-1.2.11/Input/mpg123/http.c 2007-11-24 23:53:33.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/http.c 2007-11-25 00:00:09.000000000 +0100 -@@ -33,6 +33,14 @@ - #include "mpg123.h" - #include "libxmms/util.h" - -+#ifdef HTTP_SSL -+#include -+#include -+#include -+#include -+#include -+#endif -+ - #define min(x,y) ((x)<(y)?(x):(y)) - #define min3(x,y,z) (min(x,y)<(z)?min(x,y):(z)) - #define min4(x,y,z,w) (min3(x,y,z)<(w)?min3(x,y,z):(w)) -@@ -117,7 +125,11 @@ - return res; - } - -+#ifdef HTTP_SSL -+static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename, int *ssl) -+#else - static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename) -+#endif - { - gchar *h, *p, *pt, *f, *temp, *ptr; - -@@ -126,6 +138,14 @@ - - if (!strncasecmp("http://", ptr, 7)) - ptr += 7; -+#ifdef HTTP_SSL -+ if (!strncasecmp("https://", ptr, 8)) { -+ ptr += 8; -+ *ssl = 1; -+ } else -+ *ssl = 0; -+#endif -+ - h = strchr(ptr, '@'); - f = strchr(ptr, '/'); - if (h != NULL && (!f || h < f)) -@@ -160,7 +180,12 @@ - { - if (f) - *f = '\0'; -- *port = 80; -+#ifdef HTTP_SSL -+ if (*ssl) -+ *port = 443; -+ else -+#endif -+ *port = 80; - } - *host = g_strdup(h); - -@@ -302,16 +327,27 @@ - return FALSE; - } - -+#ifdef HTTP_SSL -+gint mpg123_http_read_line(gchar * buf, gint size, SSL *ssl_c) -+#else - gint mpg123_http_read_line(gchar * buf, gint size) -+#endif - { -- gint i = 0; -+ gint i = 0, rc; - - while (going && i < size - 1) - { - if (http_check_for_data()) - { -- if (read(sock, buf + i, 1) <= 0) -- return -1; -+#ifdef HTTP_SSL -+ if (ssl_c) { -+ while ((rc = SSL_read(ssl_c, buf + i, 1)) == -1); -+ if (rc <= 0) -+ return -1; -+ } else -+#endif -+ if (read(sock, buf + i, 1) <= 0) -+ return -1; - if (buf[i] == '\n') - break; - if (buf[i] != '\r') -@@ -342,7 +378,13 @@ - struct sockaddr_in address; - #endif - struct timeval tv; -- -+#ifdef HTTP_SSL -+ SSL *ssl_c = NULL; -+ SSL_CTX *ssl_ctx = NULL; -+ BIO *b = NULL; -+ gint ssl=0; -+#endif -+ - url = (gchar *) arg; - do - { -@@ -350,7 +392,11 @@ - - g_strstrip(url); - -+#ifdef HTTP_SSL -+ parse_url(url, &user, &pass, &host, &port, &filename, &ssl); -+#else - parse_url(url, &user, &pass, &host, &port, &filename); -+#endif - - if ((!filename || !*filename) && url[strlen(url) - 1] != '/') - temp = g_strconcat(url, "/", NULL); -@@ -362,6 +408,26 @@ - chost = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_host : host; - cport = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_port : port; - -+#ifdef HTTP_SSL -+ if (ssl) { -+ SSL_library_init(); -+ OpenSSL_add_ssl_algorithms(); -+ SSL_load_error_strings(); -+ -+ ssl_ctx = SSL_CTX_new(SSLv23_client_method()); -+ if (ssl_ctx == NULL) { -+ fprintf(stderr, "SSL_CTX_new() failed."); -+ eof = TRUE; -+ } -+ -+ ssl_c = SSL_new(ssl_ctx); -+ if (ssl_c == NULL) { -+ fprintf(stderr, "SSL_new() failed.\n"); -+ eof = TRUE; -+ } -+ } -+#endif -+ - #ifdef USE_IPV6 - g_snprintf(service, 6, "%d", cport); - memset(&hints, 0, sizeof(hints)); -@@ -441,7 +507,20 @@ - eof = TRUE; - } - } -+#ifdef HTTP_SSL -+ if (ssl) { -+ b = BIO_new_socket(sock, BIO_NOCLOSE); -+ if (b == NULL) { -+ printf("BIO_new_socket() failed.\n"); -+ eof = TRUE; -+ } -+ -+ // cannot fail -+ SSL_set_bio(ssl_c, b, b); -+ } -+#endif - #endif -+ - while (going) - { - tv.tv_sec = 0; -@@ -466,6 +545,24 @@ - break; - } - } -+#ifdef HTTP_SSL -+ if (ssl) { -+ int rc; -+ -+ SSL_set_connect_state(ssl_c); -+ -+ while ((rc = SSL_connect(ssl_c)) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_connect() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ } -+ while ((rc = SSL_do_handshake(ssl_c)) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_do_handshake() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ } -+ } -+#endif - if (!eof) - { - gchar *auth = NULL, *proxy_auth = NULL; -@@ -517,14 +614,30 @@ - g_free(proxy_auth); - if(auth) - g_free(auth); -- write(sock, temp, strlen(temp)); -+#ifdef HTTP_SSL -+ if (ssl) { -+ int rc; -+ while ((rc = SSL_write(ssl_c, temp, strlen(temp))) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_write() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ eof = TRUE; -+ } -+ } else -+#endif -+ write(sock, temp, strlen(temp)); -+ - g_free(temp); - mpg123_ip.set_info_text(_("CONNECTED: WAITING FOR REPLY")); - while (going && !eof) - { - if (http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if (mpg123_http_read_line(line, 1024, ssl_c)) -+#else - if (mpg123_http_read_line(line, 1024)) -+#endif - { - status = strchr(line, ' '); - if (status) -@@ -537,7 +650,11 @@ - { - if(http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if((cnt = mpg123_http_read_line(line, 1024, ssl_c)) != -1) -+#else - if((cnt = mpg123_http_read_line(line, 1024)) != -1) -+#endif - { - if(!cnt) - break; -@@ -579,7 +696,11 @@ - { - if (http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if ((cnt = mpg123_http_read_line(line, 1024, ssl_c)) != -1) -+#else - if ((cnt = mpg123_http_read_line(line, 1024)) != -1) -+#endif - { - if (!cnt) - break; -@@ -617,6 +738,10 @@ - fclose(output_file); - output_file = NULL; - } -+#ifdef HTTP_SSL -+ if (ssl) -+ SSL_shutdown(ssl_c); -+#endif - close(sock); - g_free(user); - g_free(pass); -@@ -634,6 +759,10 @@ - fname = file; - if (!strncasecmp(fname, "http://", 7)) - fname += 7; -+#ifdef HTTP_SSL -+ if (!strncasecmp(fname, "https://", 8)) -+ fname += 8; -+#endif - temp = strrchr(fname, '.'); - if (temp && !strcasecmp(temp, ".mp3")) - *temp = '\0'; -@@ -668,7 +797,12 @@ - cnt = min(http_free(), buffer_length - wr_index); - if (cnt > 1024) - cnt = 1024; -- written = read(sock, buffer + wr_index, cnt); -+#ifdef HTTP_SSL -+ if (ssl) -+ while ((written = SSL_read(ssl_c, buffer + wr_index, cnt)) == -1); -+ else -+#endif -+ written = read(sock, buffer + wr_index, cnt); - if (written <= 0) - { - eof = TRUE; -@@ -715,6 +849,10 @@ - fclose(output_file); - output_file = NULL; - } -+#ifdef HTTP_SSL -+ if (ssl) -+ SSL_shutdown(ssl_c); -+#endif - close(sock); - if (udp_sock != 0) - close(udp_sock); -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:59:35.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-25 00:00:09.000000000 +0100 -@@ -317,7 +317,11 @@ - char *ext; - guint16 wavid; - -+#ifdef HTTP_SSL -+ if (!strncasecmp(filename, "http://", 7) || !strncasecmp(filename, "https://", 8)) -+#else - if (!strncasecmp(filename, "http://", 7)) -+#endif - { /* We assume all http:// (except those ending in .ogg) are mpeg -- why do we do that? */ - ext = strrchr(filename, '.'); - if (ext) -@@ -801,7 +805,11 @@ - /* - * TODO: Getting song info from http streams. - */ -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) && strncasecmp(filename, "https://", 8)) -+#else - if (strncasecmp(filename, "http://", 7)) -+#endif - { - if ((file = fopen(filename, "rb")) != NULL) - { -@@ -890,7 +898,12 @@ - mpg123_init_layer3(fr.down_sample_sblimit); - - mpg123_info->tpf = mpg123_compute_tpf(&fr); -+ -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) && strncasecmp(filename, "https://", 8)) -+#else - if (strncasecmp(filename, "http://", 7)) -+#endif - { - if (mpg123_stream_check_for_xing_header(&fr, &xing_header)) - { -@@ -937,7 +950,11 @@ - mpg123_mode = fr.mode; - mpg123_length = mpg123_info->num_frames * mpg123_info->tpf * 1000; - -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) && strncasecmp(filename, "https://", 8)) -+#else - if (strncasecmp(filename, "http://", 7)) -+#endif - { - if (!mpg123_title) - mpg123_title = get_song_title(NULL,filename); -@@ -1050,7 +1067,11 @@ - { - /* FIXME networks streams */ - disp_bitrate = mpg123_bitrate; -+#ifdef HTTP_SSL -+ if(!have_xing_header && strncasecmp(filename,"http://",7) && strncasecmp(filename, "https://", 8)) -+#else - if(!have_xing_header && strncasecmp(filename,"http://",7)) -+#endif - { - double rel = mpg123_relative_pos(); - if (rel) -diff -dPNur xmms-1.2.11/Input/vorbis/fileinfo.c xmms-1.2.11-new/Input/vorbis/fileinfo.c ---- xmms-1.2.11/Input/vorbis/fileinfo.c 2005-05-15 02:01:20.000000000 +0200 -+++ xmms-1.2.11-new/Input/vorbis/fileinfo.c 2007-11-25 00:00:09.000000000 +0100 -@@ -227,7 +227,12 @@ - vcedit_state *state; - vorbis_comment *comment; - -+#ifdef HTTP_SSL -+ if (!g_strncasecmp(vte.filename, "http://", 7) || -+ !g_strncasecmp(vte.filename, "https://", 8)) -+#else - if (!g_strncasecmp(vte.filename, "http://", 7)) -+#endif - return; - - state = vcedit_new_state(); -@@ -303,7 +308,12 @@ - vcedit_state *state; - vorbis_comment *comment; - -+#ifdef HTTP_SSL -+ if (!g_strncasecmp(vte.filename, "http://", 7) || -+ !g_strncasecmp(vte.filename, "https://", 8)) -+#else - if (!g_strncasecmp(vte.filename, "http://", 7)) -+#endif - return; - - state = vcedit_new_state(); -@@ -800,7 +810,12 @@ - } else - gdk_window_raise(window->window); - -+#ifdef HTTP_SSL -+ if (!g_strncasecmp(vte.filename, "http://", 7) || -+ !g_strncasecmp(vte.filename, "https://", 8)) -+#else - if (!g_strncasecmp(vte.filename, "http://", 7)) -+#endif - gtk_widget_set_sensitive(tag_frame, FALSE); - else - gtk_widget_set_sensitive(tag_frame, TRUE); -diff -dPNur xmms-1.2.11/Input/vorbis/http.c xmms-1.2.11-new/Input/vorbis/http.c ---- xmms-1.2.11/Input/vorbis/http.c 2007-11-16 22:51:24.000000000 +0100 -+++ xmms-1.2.11-new/Input/vorbis/http.c 2007-11-25 00:03:11.000000000 +0100 -@@ -39,6 +39,10 @@ - #include "xmms/plugin.h" - #include "xmms/i18n.h" - -+#ifdef HTTP_SSL -+#include -+#endif -+ - #define min(x,y) ((x)<(y)?(x):(y)) - #define min3(x,y,z) (min(x,y)<(z)?min(x,y):(z)) - #define min4(x,y,z,w) (min3(x,y,z)<(w)?min3(x,y,z):(w)) -@@ -116,7 +120,11 @@ - return res; - } - -+#ifdef HTTP_SSL -+static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename, int *ssl) -+#else - static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename) -+#endif - { - gchar *h, *p, *pt, *f, *temp, *ptr; - -@@ -125,6 +133,14 @@ - - if (!strncasecmp("http://", ptr, 7)) - ptr += 7; -+#ifdef HTTP_SSL -+ if (!strncasecmp("https://", ptr, 8)) { -+ ptr += 8; -+ *ssl = 1; -+ } else -+ *ssl = 0; -+#endif -+ - h = strchr(ptr, '@'); - f = strchr(ptr, '/'); - if (h != NULL && (!f || h < f)) -@@ -159,7 +175,12 @@ - { - if (f) - *f = '\0'; -- *port = 80; -+#ifdef HTTP_SSL -+ if (*ssl) -+ *port = 443; -+ else -+#endif -+ *port = 80; - } - *host = g_strdup(h); - -@@ -257,16 +278,27 @@ - return FALSE; - } - -+#ifdef HTTP_SSL -+gint vorbis_http_read_line(gchar * buf, gint size, SSL *ssl_c) -+#else - gint vorbis_http_read_line(gchar * buf, gint size) -+#endif - { -- gint i = 0; -+ gint i = 0, rc; - - while (going && i < size - 1) - { - if (http_check_for_data()) - { -- if (read(sock, buf + i, 1) <= 0) -- return -1; -+#ifdef HTTP_SSL -+ if (ssl_c) { -+ while ((rc = SSL_read(ssl_c, buf + i, 1)) == -1); -+ if (rc <= 0) -+ return -1; -+ } else -+#endif -+ if (read(sock, buf + i, 1) <= 0) -+ return -1; - if (buf[i] == '\n') - break; - if (buf[i] != '\r') -@@ -296,6 +328,12 @@ - struct sockaddr_in address; - #endif - struct timeval tv; -+#ifdef HTTP_SSL -+ SSL *ssl_c = NULL; -+ SSL_CTX *ssl_ctx = NULL; -+ BIO *b = NULL; -+ gint ssl=0; -+#endif - - url = (gchar *) arg; - do -@@ -304,7 +342,11 @@ - - g_strstrip(url); - -+#ifdef HTTP_SSL -+ parse_url(url, &user, &pass, &host, &port, &filename, &ssl); -+#else - parse_url(url, &user, &pass, &host, &port, &filename); -+#endif - - if ((!filename || !*filename) && url[strlen(url) - 1] != '/') - temp = g_strconcat(url, "/", NULL); -@@ -316,6 +358,26 @@ - chost = vorbis_cfg.use_proxy ? vorbis_cfg.proxy_host : host; - cport = vorbis_cfg.use_proxy ? vorbis_cfg.proxy_port : port; - -+#ifdef HTTP_SSL -+ if (ssl) { -+ SSL_library_init(); -+ OpenSSL_add_ssl_algorithms(); -+ SSL_load_error_strings(); -+ -+ ssl_ctx = SSL_CTX_new(SSLv23_client_method()); -+ if (ssl_ctx == NULL) { -+ fprintf(stderr, "SSL_CTX_new() failed."); -+ eof = TRUE; -+ } -+ -+ ssl_c = SSL_new(ssl_ctx); -+ if (ssl_c == NULL) { -+ fprintf(stderr, "SSL_new() failed.\n"); -+ eof = TRUE; -+ } -+ } -+#endif -+ - #ifdef USE_IPV6 - g_snprintf(service, 6, "%d", cport); - memset(&hints, 0, sizeof(hints)); -@@ -394,6 +456,18 @@ - eof = TRUE; - } - } -+#ifdef HTTP_SSL -+ if (ssl) { -+ b = BIO_new_socket(sock, BIO_NOCLOSE); -+ if (b == NULL) { -+ printf("BIO_new_socket() failed.\n"); -+ eof = TRUE; -+ } -+ -+ // cannot fail -+ SSL_set_bio(ssl_c, b, b); -+ } -+#endif - #endif - while (going) - { -@@ -419,6 +493,24 @@ - break; - } - } -+#ifdef HTTP_SSL -+ if (ssl) { -+ int rc; -+ -+ SSL_set_connect_state(ssl_c); -+ -+ while ((rc = SSL_connect(ssl_c)) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_connect() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ } -+ while ((rc = SSL_do_handshake(ssl_c)) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_do_handshake() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ } -+ } -+#endif - if (!eof) - { - gchar *auth = NULL, *proxy_auth = NULL; -@@ -449,14 +541,30 @@ - g_free(proxy_auth); - if(auth) - g_free(auth); -- write(sock, temp, strlen(temp)); -+#ifdef HTTP_SSL -+ if (ssl) { -+ int rc; -+ while ((rc = SSL_write(ssl_c, temp, strlen(temp))) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_write() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ eof = TRUE; -+ } -+ } else -+#endif -+ write(sock, temp, strlen(temp)); -+ - g_free(temp); - vorbis_ip.set_info_text(_("CONNECTED: WAITING FOR REPLY")); - while (going && !eof) - { - if (http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if (vorbis_http_read_line(line, 1024, ssl_c)) -+#else - if (vorbis_http_read_line(line, 1024)) -+#endif - { - status = strchr(line, ' '); - if (status) -@@ -469,7 +577,11 @@ - { - if(http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if((cnt = vorbis_http_read_line(line, 1024, ssl_c)) != -1) -+#else - if((cnt = vorbis_http_read_line(line, 1024)) != -1) -+#endif - { - if(!cnt) - break; -@@ -511,7 +623,11 @@ - { - if (http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if ((cnt = vorbis_http_read_line(line, 1024, ssl_c)) != -1) -+#else - if ((cnt = vorbis_http_read_line(line, 1024)) != -1) -+#endif - { - if (!cnt) - break; -@@ -537,6 +653,10 @@ - fclose(output_file); - output_file = NULL; - } -+#ifdef HTTP_SSL -+ if (ssl) -+ SSL_shutdown(ssl_c); -+#endif - close(sock); - g_free(user); - g_free(pass); -@@ -554,6 +674,9 @@ - fname = file; - if (!strncasecmp(fname, "http://", 7)) - fname += 7; -+ if (!strncasecmp(fname, "https://", 8)) -+ fname += 8; -+ - temp = strrchr(fname, '.'); - if (temp && !strcasecmp(temp, ".ogg")) - *temp = '\0'; -@@ -588,7 +711,12 @@ - cnt = min(http_free(), buffer_length - wr_index); - if (cnt > 1024) - cnt = 1024; -- written = read(sock, buffer + wr_index, cnt); -+#ifdef HTTP_SSL -+ if (ssl) -+ while ((written = SSL_read(ssl_c, buffer + wr_index, cnt)) == -1); -+ else -+#endif -+ written = read(sock, buffer + wr_index, cnt); - if (written <= 0) - { - eof = TRUE; -@@ -629,6 +757,10 @@ - fclose(output_file); - output_file = NULL; - } -+#ifdef HTTP_SSL -+ if (ssl) -+ SSL_shutdown(ssl_c); -+#endif - close(sock); - - -diff -dPNur xmms-1.2.11/Input/vorbis/vorbis.c xmms-1.2.11-new/Input/vorbis/vorbis.c ---- xmms-1.2.11/Input/vorbis/vorbis.c 2006-07-16 15:40:04.000000000 +0200 -+++ xmms-1.2.11-new/Input/vorbis/vorbis.c 2007-11-25 00:00:09.000000000 +0100 -@@ -138,7 +138,12 @@ - char *ext; - - /* is this our http resource? */ -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) == 0 || -+ strncasecmp(filename, "https://", 8) == 0) { -+#else - if (strncasecmp(filename, "http://", 7) == 0) { -+#endif - ext = strrchr(filename, '.'); - if (ext) { - if (!strncasecmp(ext, ".ogg", 4)) { -@@ -332,7 +337,12 @@ - - memset(&vf, 0, sizeof(vf)); - -+#ifdef HTTP_SSL -+ if (strncasecmp("http://", filename, 7) && -+ strncasecmp("https://", filename, 8)) { -+#else - if (strncasecmp("http://", filename, 7) != 0) { -+#endif - /* file is a real file */ - if ((stream = fopen(filename, "r")) == NULL) { - vorbis_eos = TRUE; -@@ -536,7 +546,12 @@ - FILE *stream; - OggVorbis_File vf; /* avoid thread interaction */ - -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) && -+ strncasecmp(filename, "https://", 8)) { -+#else - if (strncasecmp(filename, "http://", 7)) { -+#endif - if ((stream = fopen(filename, "r")) == NULL) - return; - diff --git a/ReadMe b/ReadMe index 93308cf..d6697de 100644 --- a/ReadMe +++ b/ReadMe @@ -1,10 +1,10 @@ Prerequisites ------------- - The patched XMMS can be compiled without any additional dependency, + The patched applications can be compiled without additional dependency, but to get recoding on you will need LibRCC (http://rusxmms.sf.net). - The LibRCC (Russian Charset Conversion Library) supports several - ways of encoding autodetection. To get this feature on the LibRCD, - Enca, db4 libraries should be installed prior to LibRCC compilation. + The LibRCC (RusXMMS Charset Conversion Library) supports several + ways of encoding autodetection. This depend on LibRCD, Enca, and DB4 + libraries which should be installed prior to LibRCC compilation. Starting from version 0.2.0 LibRCC supports language autodetection using aspell and language translation using libtranslate (the internet connection @@ -22,65 +22,5 @@ Prerequisites To get language translation: 7. Libtranslate + Internet Connection -Compilation ------------ -1. Copy RusXMMS into the root of xmms source distribution - Run 'apply.sh' to get RusXMMS with ID3v2 enabled mpg123 - * Patches from Gentoo XMMS Distribution is used to provide ID3v2 - Custom: Just apply patches you need - * all files from source/*.[ch] should be copied into the - libxmms directory -2. Run 'aclocal && automake && autoconf' in the root of XMMS source tree in - order to regenerate Makefiles. -3. configure, compile and install as usual - -Patches -------- - xmms-ds-rusxmms: Base RusXMMS patch (required!) - xmms-ds-rusxmms-charset: UTF16/RCC for libxmms/charset.c. - * Required by Id3v2 tag editor. - xmms-ds-playlist: PlayList Recoding (Save/Load/Display) - * Recodes file names from playlist files - * Recodes titles from playlist files - * Recodes titles from plugins if AutoEngine enabled - xmms-ds-shade: Enables font selection for Shade Windows - * After applying the non-English titles will be - displayed correctly in the shade window - xmms-ds-textbox: Corrects UTF-8 displaying in xmms 'TextBox' - - xmms-ds-mpg123: Recodes mpg123 titles - editor: Enables editing of ID3 tags (v.1 and v.2) - keys: Enables fast keys - Esc, Enter: Cancel, Save and Exit - Ctrl+Left, Ctrl+Right: Navigate tabs - Ctrl+PgDn, Ctrl+PgUp: Navigate records - xmms-ds-vorbis-*: The same functionalities for vorbis plugin - ( No recoding patch is required ) - -Extra Patches -------------- - Some extra functionality, which is not included in default "apply.sh" - scripts and could be considered a bad or/and dangerous idea. - - xmms-ds-mpg123-wrongencoding.patch: - The ID3 v.2 defines 4 types of encodings: Latin1, UTF16, UTF16BE, UTF8. - Original version of XMMS assumes the tag broken if other encoding is - specified. This patch, assumes Latin1 for such encodings. - -Minimal Configurations: - xmms-ds-rusxmms + xmms-ds-playlist: - In the case then the autoengine is available, this solution will - give completely recoded playlist window. The recoding of plugins - will work as well. - xmms-ds-rusxmms + xmms-ds-mpg123(no editor and keys): - This solution will give completely recoded playlist even if no - autoengine is available, but playlists are unsupported. - -Notes ------ - * Edited ID3 tags and playlists will be saved in the corresponded - encodings selected using 'RusXMMS' preference page. - - Project Page: http://rusxmms.sf.net -Author: Suren A. Chilingaryan +Author: Suren A. Chilingaryan diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..6093485 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +csa45 diff --git a/apply.sh b/apply.sh deleted file mode 100755 index 69c4ea4..0000000 --- a/apply.sh +++ /dev/null @@ -1,50 +0,0 @@ -#! /bin/bash - -TOP_DIR=`pwd | sed -e s/\\\/RusXMMS2$//` -if [ ! -d $TOP_DIR/RusXMMS2 ]; then - PATCH_DIR=$TOP_DIR/../ - if [ ! -d $PATCH_DIR/RusXMMS2 ]; then - exit 1 - fi -else - PATCH_DIR=$TOP_DIR -fi - -if [ ! -d $TOP_DIR/libxmms ]; then - exit 1 -fi - -echo "Patching: $TOP_DIR" - -cp $PATCH_DIR/RusXMMS2/source/* $TOP_DIR/libxmms/ - -# ID3 fixes -cat $PATCH_DIR/RusXMMS2/3rdparty/mpg123/*.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** gentoo mpg123 patches ***"; exit 1; fi - -# RusXMMS core -cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-rusxmms.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-rusxmms ***"; exit 1; fi -cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-rusxmms-charset.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-rusxmms-charset ***"; exit 1; fi - -# RusXMMS plugins -cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-mpg123.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-mpg123 ***"; exit 1; fi -cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-mpg123-editor.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-mpg123-editor ***"; exit 1; fi -cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-mpg123-editor-keys.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-mpg123-editor-keys ***"; exit 1; fi -cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-vorbis-editor.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-vorbis-editor ***"; exit 1; fi -cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-vorbis-editor-keys.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-vorbis-editor-keys ***"; exit 1; fi - -# RusXMMS extra -cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-playlist.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-playlist ***"; exit 1; fi -cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-shade.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-shade ***"; exit 1; fi -cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-textbox.patch | patch -d $TOP_DIR -p1 -if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-textbox ***"; exit 1; fi - diff --git a/misc/brokentags.c b/misc/brokentags.c deleted file mode 100644 index e850057..0000000 --- a/misc/brokentags.c +++ /dev/null @@ -1,16 +0,0 @@ -/* I tried to use it to fix broken tags (call id3_get_text), but -it really didn't help much (half of title tag, instead of one fourth) */ -void id3_fix_text(struct id3_frame *frame, int offset) { - int i, size; - char *string; - - size = frame->fr_size - offset - 1; - string = ID3_TEXT_FRAME_PTR(frame) + offset; - - for (offset=0, i=0;i0;offset--) string[i-offset]=0; -} diff --git a/patches/xmms-plugins/xmms-wma-csa1.tar.bz2 b/patches/xmms-plugins/xmms-wma-csa1.tar.bz2 deleted file mode 100644 index de6968c..0000000 Binary files a/patches/xmms-plugins/xmms-wma-csa1.tar.bz2 and /dev/null differ diff --git a/patches/xmms/3rdparty/mpg123/0050_all_libxmms-charset.patch b/patches/xmms/3rdparty/mpg123/0050_all_libxmms-charset.patch new file mode 100644 index 0000000..94416dd --- /dev/null +++ b/patches/xmms/3rdparty/mpg123/0050_all_libxmms-charset.patch @@ -0,0 +1,191 @@ +diff -Naur xmms-1.2.10-20041012/libxmms/charset.c xmms-1.2.10-20041012.convert/libxmms/charset.c +--- xmms-1.2.10-20041012/libxmms/charset.c 2004-10-13 01:03:03.258234924 -0700 ++++ xmms-1.2.10-20041012.convert/libxmms/charset.c 2004-10-24 23:49:42.083591275 -0700 +@@ -22,7 +22,6 @@ + + #include "charset.h" + +- + char* xmms_charset_get_current(void) + { + char *charset = getenv("CHARSET"); +@@ -38,6 +37,18 @@ + return charset; + } + ++static size_t utf16_strlen(const char *string) ++{ ++ size_t len = 0; ++ ++ if (!string) ++ return 0; ++ ++ while (*(string + len) != 0 || *(string + len + 1) != 0) ++ len += 2; ++ ++ return len; ++} + + #ifdef HAVE_ICONV + char* xmms_charset_convert(const char *string, size_t insize, char *from, char *to) +@@ -108,15 +119,55 @@ + { + if (!string) + return NULL; ++ + return xmms_charset_convert(string, strlen(string), "UTF-8", NULL); + } + ++char *xmms_charset_from_utf16(const unsigned char *string) ++{ ++ if (!string) ++ return NULL; ++ ++ return xmms_charset_convert(string, utf16_strlen(string), "UTF-16", NULL); ++} ++ ++char *xmms_charset_from_utf16be(const unsigned char *string) ++{ ++ if (!string) ++ return NULL; ++ ++ return xmms_charset_convert(string, utf16_strlen(string), "UTF-16BE", NULL); ++} ++ ++char* xmms_charset_from_latin1(const char *string) ++{ ++ char *to = xmms_charset_get_current(); ++ ++ if (!string) ++ return NULL; ++ ++ if (!strcmp(to, "UTF-8")) ++ return xmms_charset_convert(string, strlen(string), "ISO-8859-1", to); ++ else ++ return g_strdup(string); ++} ++ + #else + + char* xmms_charset_convert(const char *string, size_t insize, char *from, char *to) + { ++ if (!string) ++ return NULL; ++ + if (!strcmp(from, "UTF-8") && !to) + return xmms_charset_from_utf8(string); ++ ++ if (!strcmp(from, "UTF-16") && !to) ++ return xmms_charset_from_utf16(string); ++ ++ if (!strcmp(from, "UTF-16BE") && !to) ++ return xmms_charset_from_utf16be(string); ++ + return g_strdup(string); + } + +@@ -155,11 +206,83 @@ + return ascii; + } + ++static char* utf16_to_ascii(const unsigned char *utf16, int le) ++{ ++ char *ascii; ++ unsigned int i, len, c; ++ ++ if (!utf16) ++ return NULL; ++ ++ len = utf16_strlen(utf16) / 2 + 1; ++ ++ ascii = g_malloc(len + 1); ++ ++ for (i = 0, c = 0; i < len; i++) ++ { ++ guint16 uc; ++ int o = i << 1; ++ ++ if (le) ++ uc = *(utf16 + o) | *(utf16 + o + 1) << 8; ++ else ++ uc = *(utf16 + o) << 8 | *(utf16 + o + 1); ++ ++ /* Skip BOM and surrogate pairs */ ++ if (uc == 0xfeff || (uc >= 0xd800 && uc <= 0xdfff)) ++ continue; ++ ++ if (uc < 0x80) ++ ascii[c] = uc; ++ else ++ ascii[c] = '?'; ++ c++; ++ } ++ ++ ascii[c] = 0; ++ return ascii; ++} ++ ++char *xmms_charset_from_utf16(const unsigned char *string) ++{ ++ int le = FALSE; ++ guint16 bom; ++ ++ if (!string) ++ return NULL; ++ ++ bom = *string << 8 | *(string + 1); ++ ++ if (bom == 0xfffe) ++ le = TRUE; ++ else if (bom != 0xfeff) ++ return g_strdup(""); ++ ++ return utf16_to_ascii(string, le); ++} ++ ++char *xmms_charset_from_utf16be(const unsigned char *string) ++{ ++ if (!string) ++ return NULL; ++ ++ return utf16_to_ascii(string, FALSE); ++} ++ ++char* xmms_charset_from_latin1(const char *string) ++{ ++ if (!string) ++ return NULL; ++ ++ return g_strdup(string); ++} ++ + #endif + + char* xmms_charset_to_utf8(const char *string) + { + if (!string) + return NULL; ++ + return xmms_charset_convert(string, strlen(string), NULL, "UTF-8"); + } +diff -Naur xmms-1.2.10-20041012/libxmms/charset.h xmms-1.2.10-20041012.convert/libxmms/charset.h +--- xmms-1.2.10-20041012/libxmms/charset.h 2004-10-13 01:03:03.260234595 -0700 ++++ xmms-1.2.10-20041012.convert/libxmms/charset.h 2004-10-23 08:54:11.421220833 -0700 +@@ -5,11 +5,16 @@ + * + */ + ++#ifndef XMMS_CHARSET_H ++#define XMMS_CHARSET_H + + char* xmms_charset_get_current(void); + char* xmms_charset_convert(const char *string, size_t insize, char *from, char *to); + char* xmms_charset_to_utf8(const char *string); + char* xmms_charset_from_utf8(const char *string); ++char* xmms_charset_from_utf16(const unsigned char *string); ++char* xmms_charset_from_utf16be(const unsigned char *string); ++char* xmms_charset_from_latin1(const char *string); + +- ++#endif /* XMMS_CHARSET_H */ + diff --git a/patches/xmms/3rdparty/mpg123/2011_all_mpg123-http-seek.patch b/patches/xmms/3rdparty/mpg123/2011_all_mpg123-http-seek.patch new file mode 100644 index 0000000..67ab4f5 --- /dev/null +++ b/patches/xmms/3rdparty/mpg123/2011_all_mpg123-http-seek.patch @@ -0,0 +1,201 @@ +diff -dPNur xmms-1.2.11/Input/mpg123/common.c xmms-1.2.11-new/Input/mpg123/common.c +--- xmms-1.2.11/Input/mpg123/common.c 2005-05-15 02:01:19.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/common.c 2007-11-24 23:52:01.000000000 +0100 +@@ -148,19 +148,34 @@ + int mpg123_stream_jump_to_frame(struct frame *fr, int frame) + { + if (!filept) +- return -1; +- mpg123_read_frame_init(); +- fseek(filept, frame * (fr->framesize + 4), SEEK_SET); +- mpg123_read_frame(fr); ++ { ++ unsigned long r; ++ ++ r = frame * (fr->framesize + 4); ++ mpg123_stream_close(); ++ mpg123_open_stream(mpg123_filename, -1, r); ++ } ++ else ++ { ++ mpg123_read_frame_init(); ++ fseek(filept, frame * (fr->framesize + 4), SEEK_SET); ++ mpg123_read_frame(fr); ++ } + return 0; + } + + int mpg123_stream_jump_to_byte(struct frame *fr, int byte) + { + if (!filept) +- return -1; +- fseek(filept, byte, SEEK_SET); +- mpg123_read_frame(fr); ++ { ++ mpg123_stream_close(); ++ mpg123_open_stream(mpg123_filename, -1, (unsigned long)byte); ++ } ++ else ++ { ++ fseek(filept, byte, SEEK_SET); ++ mpg123_read_frame(fr); ++ } + return 0; + } + +@@ -446,14 +461,14 @@ + return 1; + } + +-void mpg123_open_stream(char *bs_filenam, int fd) ++void mpg123_open_stream(char *bs_filenam, int fd, unsigned long range) + { + filept_opened = 1; + if (!strncasecmp(bs_filenam, "http://", 7)) + { + filept = NULL; +- mpg123_http_open(bs_filenam); + mpg123_info->filesize = 0; ++ mpg123_http_open(bs_filenam, range); + mpg123_info->network_stream = TRUE; + } + else +diff -dPNur xmms-1.2.11/Input/mpg123/http.c xmms-1.2.11-new/Input/mpg123/http.c +--- xmms-1.2.11/Input/mpg123/http.c 2007-11-16 22:51:24.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/http.c 2007-11-24 23:52:01.000000000 +0100 +@@ -50,6 +50,7 @@ + extern gboolean mpg123_stereo; + + static gboolean prebuffering, going, eof = FALSE; ++static unsigned long range; + static gint sock, rd_index, wr_index, buffer_length, prebuffer_length; + static guint64 buffer_read = 0; + static gchar *buffer; +@@ -326,7 +327,7 @@ + static void *http_buffer_loop(void *arg) + { + gchar line[1024], *user, *pass, *host, *filename, +- *status, *url, *temp, *file; ++ *status, *url, *temp, *temp2, *file; + gchar *chost; + gint cnt, written, error, port, cport; + socklen_t err_len; +@@ -495,15 +496,22 @@ + } + else + file = g_strconcat("/", filename, NULL); +- temp = g_strdup_printf("GET %s HTTP/1.0\r\n" ++ if (range) ++ { ++ temp2 = g_strdup_printf("Range: bytes=%lu-\r\n", range); ++ } else ++ temp2 = NULL; ++ temp = g_strdup_printf("GET %s HTTP/1.1\r\n" + "Host: %s\r\n" + "User-Agent: %s/%s\r\n" +- "%s%s%s%s\r\n", ++ "%s%s%s%s%s\r\n", + file, host, PACKAGE, VERSION, + proxy_auth ? proxy_auth : "", auth ? auth : "", + mpg123_cfg.cast_title_streaming ? "Icy-MetaData:1\r\n" : "", +- mpg123_cfg.use_udp_channel ? udpspace : ""); +- ++ mpg123_cfg.use_udp_channel ? udpspace : "", ++ range ? temp2 : ""); ++ ++ g_free(temp2); + g_free(file); + if(proxy_auth) + g_free(proxy_auth); +@@ -587,7 +595,9 @@ + #endif + /* udp_serverport = atoi (line + 20); */ + } +- ++ if (!strncasecmp(line, "content-length:", 15)) { ++ mpg123_info->filesize = atoi(line + 15); ++ } + } + else + { +@@ -719,7 +729,7 @@ + pthread_exit(NULL); + } + +-int mpg123_http_open(gchar * _url) ++int mpg123_http_open(gchar * _url, unsigned long rng) + { + gchar *url; + +@@ -735,6 +745,7 @@ + going = TRUE; + eof = FALSE; + buffer = g_malloc(buffer_length); ++ range = rng; + + pthread_create(&thread, NULL, http_buffer_loop, url); + +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c +--- xmms-1.2.11/Input/mpg123/mpg123.c 2006-07-25 05:18:51.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:52:01.000000000 +0100 +@@ -857,7 +857,7 @@ + + mpg123_read_frame_init(); + +- mpg123_open_stream(filename, -1); ++ mpg123_open_stream(filename, -1, 0); + if (mpg123_info->eof || !mpg123_read_frame(&fr)) + mpg123_info->eof = TRUE; + if (!mpg123_info->eof && mpg123_info->going) +@@ -906,7 +906,7 @@ + break; + } + +- if (!have_xing_header && strncasecmp(filename, "http://", 7)) ++ if(!have_xing_header && mpg123_info->filesize != 0) + mpg123_info->num_frames = mpg123_calc_numframes(&fr); + + memcpy(&fr, &temp_fr, sizeof(struct frame)); +@@ -918,11 +918,10 @@ + mpg123_lsf = fr.lsf; + mpg123_mpeg25 = fr.mpeg25; + mpg123_mode = fr.mode; +- ++ mpg123_length = mpg123_info->num_frames * mpg123_info->tpf * 1000; ++ + if (strncasecmp(filename, "http://", 7)) + { +- mpg123_length = +- mpg123_info->num_frames * mpg123_info->tpf * 1000; + if (!mpg123_title) + mpg123_title = get_song_title(NULL,filename); + } +@@ -930,7 +929,6 @@ + { + if (!mpg123_title) + mpg123_title = mpg123_http_get_title(filename); +- mpg123_length = -1; + } + mpg123_ip.set_info(mpg123_title, mpg123_length, + mpg123_bitrate * 1000, +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.h xmms-1.2.11-new/Input/mpg123/mpg123.h +--- xmms-1.2.11/Input/mpg123/mpg123.h 2006-07-24 00:32:44.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.h 2007-11-24 23:52:01.000000000 +0100 +@@ -176,7 +176,7 @@ + + /* ------ Declarations from "http.c" ------ */ + +-extern int mpg123_http_open(char *url); ++extern int mpg123_http_open(char *url, unsigned long rng); + int mpg123_http_read(gpointer data, gint length); + void mpg123_http_close(void); + char *mpg123_http_get_title(char * url); +@@ -188,7 +188,7 @@ + extern unsigned int mpg123_getbits(int); + extern unsigned int mpg123_getbits_fast(int); + +-extern void mpg123_open_stream(char *bs_filenam, int fd); ++extern void mpg123_open_stream(char *bs_filenam, int fd, unsigned long range); + extern int mpg123_head_check(unsigned long); + extern void mpg123_stream_close(void); + diff --git a/patches/xmms/3rdparty/mpg123/2012_all_mpg123-id3convert.patch b/patches/xmms/3rdparty/mpg123/2012_all_mpg123-id3convert.patch new file mode 100644 index 0000000..8c1b76b --- /dev/null +++ b/patches/xmms/3rdparty/mpg123/2012_all_mpg123-id3convert.patch @@ -0,0 +1,41 @@ +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c +--- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:53:33.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:55:43.000000000 +0100 +@@ -2,6 +2,7 @@ + #include "id3_header.h" + #include "libxmms/configfile.h" + #include "libxmms/titlestring.h" ++#include "libxmms/charset.h" + #include + #include + #include +@@ -400,6 +401,14 @@ + return ext; + } + ++static char *convert_id3v1_field(const char *v1field, unsigned len) ++{ ++ char *tmp = g_strndup(v1field, len); ++ char *v2field = xmms_charset_from_latin1(g_strstrip(tmp)); ++ g_free(tmp); ++ return v2field; ++} ++ + /* + * Function id3v1_to_id3v2 (v1, v2) + * +@@ -411,10 +420,10 @@ + char *year; + struct id3v2tag_t *v2 = g_malloc0(sizeof (struct id3v2tag_t)); + +- v2->title = g_strstrip(g_strndup(v1->title, 30)); +- v2->artist = g_strstrip(g_strndup(v1->artist, 30)); +- v2->album = g_strstrip(g_strndup(v1->album, 30)); +- v2->comment = g_strstrip(g_strndup(v1->u.v1_0.comment, 30)); ++ v2->title = convert_id3v1_field(v1->title, 30); ++ v2->artist = convert_id3v1_field(v1->artist, 30); ++ v2->album = convert_id3v1_field(v1->album, 30); ++ v2->comment = convert_id3v1_field(v1->u.v1_0.comment, 30); + v2->genre = g_strstrip(g_strdup(mpg123_get_id3_genre(v1->genre))); + + year = g_strndup(v1->year, 4); diff --git a/patches/xmms/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch b/patches/xmms/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch new file mode 100644 index 0000000..b1d33cd --- /dev/null +++ b/patches/xmms/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch @@ -0,0 +1,128 @@ +diff -Naur xmms-1.2.10-20041012/Input/mpg123/Makefile.am xmms-1.2.10-20041012.id3latin/Input/mpg123/Makefile.am +--- xmms-1.2.10-20041012/Input/mpg123/Makefile.am 2004-10-13 01:03:03.186246768 -0700 ++++ xmms-1.2.10-20041012.id3latin/Input/mpg123/Makefile.am 2004-10-23 08:52:23.370409147 -0700 +@@ -15,7 +15,7 @@ + dxhead.c dxhead.h \ + id3.c id3.h \ + id3_frame.c id3_frame_content.c id3_frame_text.c id3_frame_url.c \ +-id3_header.h id3_tag.c unicode.c ++id3_header.h id3_tag.c + + if ARCH_X86 + +diff -Naur xmms-1.2.10-20041012/Input/mpg123/id3_frame_text.c xmms-1.2.10-20041012.id3latin/Input/mpg123/id3_frame_text.c +--- xmms-1.2.10-20041012/Input/mpg123/id3_frame_text.c 2004-10-13 01:03:03.201244300 -0700 ++++ xmms-1.2.10-20041012.id3latin/Input/mpg123/id3_frame_text.c 2004-10-23 09:15:29.117825260 -0700 +@@ -60,13 +60,13 @@ + switch (encoding) + { + case ID3_ENCODING_ISO_8859_1: +- return g_strdup(text); ++ return xmms_charset_from_latin1(text); + case ID3_ENCODING_UTF8: + return xmms_charset_from_utf8(text); + case ID3_ENCODING_UTF16: +- return convert_from_utf16(text); ++ return xmms_charset_from_utf16(text); + case ID3_ENCODING_UTF16BE: +- return convert_from_utf16be(text); ++ return xmms_charset_from_utf16be(text); + default: + return NULL; + } +diff -Naur xmms-1.2.10-20041012/Input/mpg123/unicode.c xmms-1.2.10-20041012.id3latin/Input/mpg123/unicode.c +--- xmms-1.2.10-20041012/Input/mpg123/unicode.c 2004-10-13 01:03:03.215241997 -0700 ++++ xmms-1.2.10-20041012.id3latin/Input/mpg123/unicode.c 1969-12-31 16:00:00.000000000 -0800 +@@ -1,92 +0,0 @@ +-/* +- * Copyright (C) 2004 Haavard Kvaalen +- * +- * Licensed under GNU GPL version 2. +- * +- */ +-#include "config.h" +- +-#include +-#include +- +-#include "libxmms/charset.h" +- +-size_t utf16_strlen(const char *string) +-{ +- size_t len = 0; +- +- while (*(string + len) != 0 || *(string + len + 1) != 0) +- len += 2; +- +- return len; +-} +- +-#ifdef HAVE_ICONV +- +-char *convert_from_utf16(const unsigned char *utf16) +-{ +- return xmms_charset_convert(utf16, utf16_strlen(utf16), "UTF-16", NULL); +-} +- +-char *convert_from_utf16be(const unsigned char *utf16) +-{ +- return xmms_charset_convert(utf16, utf16_strlen(utf16), "UTF-16BE", NULL); +-} +- +- +-#else +- +- +-static char* to_ascii(const unsigned char *utf16, int le) +-{ +- char *ascii; +- unsigned int i, len, c; +- +- len = utf16_strlen(utf16) / 2 + 1; +- +- ascii = g_malloc(len + 1); +- +- for (i = 0, c = 0; i < len; i++) +- { +- guint16 uc; +- int o = i << 1; +- +- if (le) +- uc = *(utf16 + o) | *(utf16 + o + 1) << 8; +- else +- uc = *(utf16 + o) << 8 | *(utf16 + o + 1); +- +- /* Skip BOM and surrogate pairs */ +- if (uc == 0xfeff || (uc >= 0xd800 && uc <= 0xdfff)) +- continue; +- +- if (uc < 0x80) +- ascii[c] = uc; +- else +- ascii[c] = '?'; +- c++; +- } +- +- ascii[c] = 0; +- return ascii; +-} +- +-char *convert_from_utf16(const unsigned char *utf16) +-{ +- int le = FALSE; +- guint16 bom = *utf16 << 8 | *(utf16 + 1); +- +- if (bom == 0xfffe) +- le = TRUE; +- else if (bom != 0xfeff) +- return g_strdup(""); +- +- return to_ascii(utf16, le); +-} +- +-char *convert_from_utf16be(const unsigned char *utf16) +-{ +- return to_ascii(utf16, FALSE); +-} +- +-#endif diff --git a/patches/xmms/3rdparty/mpg123/2014_all_mpg123-encode-override.patch b/patches/xmms/3rdparty/mpg123/2014_all_mpg123-encode-override.patch new file mode 100644 index 0000000..5c27f66 --- /dev/null +++ b/patches/xmms/3rdparty/mpg123/2014_all_mpg123-encode-override.patch @@ -0,0 +1,130 @@ +diff -dPNur xmms-1.2.11/Input/mpg123/configure.c xmms-1.2.11-new/Input/mpg123/configure.c +--- xmms-1.2.11/Input/mpg123/configure.c 2005-05-15 02:01:19.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/configure.c 2007-11-24 23:57:29.000000000 +0100 +@@ -27,6 +27,7 @@ + static GtkWidget *streaming_proxy_hbox, *streaming_proxy_auth_hbox, *streaming_save_dirbrowser; + static GtkWidget *streaming_save_hbox, *title_id3_box, *title_tag_desc; + static GtkWidget *title_override, *title_id3_entry, *title_id3v2_disable; ++static GtkWidget *id3v2_encoding_override, *id3v2_encoding_box, *encoding_entry; + + MPG123Config mpg123_cfg; + +@@ -105,6 +106,8 @@ + mpg123_cfg.disable_id3v2 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(title_id3v2_disable)); + g_free(mpg123_cfg.id3_format); + mpg123_cfg.id3_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(title_id3_entry))); ++ mpg123_cfg.id3v2_encoding_override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(id3v2_encoding_override)); ++ mpg123_cfg.id3v2_default_encoding = g_strdup(gtk_entry_get_text(GTK_ENTRY(encoding_entry))); + + filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); + cfg = xmms_cfg_open_file(filename); +@@ -134,6 +137,8 @@ + xmms_cfg_write_boolean(cfg, "MPG123", "title_override", mpg123_cfg.title_override); + xmms_cfg_write_boolean(cfg, "MPG123", "disable_id3v2", mpg123_cfg.disable_id3v2); + xmms_cfg_write_string(cfg, "MPG123", "id3_format", mpg123_cfg.id3_format); ++ xmms_cfg_write_boolean(cfg, "MPG123", "id3v2_encoding_override", mpg123_cfg.id3v2_encoding_override); ++ xmms_cfg_write_string(cfg, "MPG123", "id3v2_default_encoding", mpg123_cfg.id3v2_default_encoding); + xmms_cfg_write_int(cfg, "MPG123", "detect_by", mpg123_cfg.detect_by); + #ifdef USE_SIMD + xmms_cfg_write_int(cfg, "MPG123", "default_synth", mpg123_cfg.default_synth); +@@ -212,6 +217,13 @@ + gtk_widget_set_sensitive(title_tag_desc, override); + } + ++static void id3v2_encoding_override_cb(GtkWidget * w, gpointer data) ++{ ++ gboolean override; ++ override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(id3v2_encoding_override)); ++ gtk_widget_set_sensitive(id3v2_encoding_box, override); ++} ++ + static void configure_destroy(GtkWidget * w, gpointer data) + { + if (streaming_save_dirbrowser) +@@ -230,6 +242,7 @@ + GtkWidget *streaming_save_label, *streaming_save_browse; + GtkWidget *streaming_cast_frame, *streaming_cast_vbox; + GtkWidget *title_frame, *title_id3_vbox, *title_id3_label; ++ GtkWidget *title_id3_label2; + GtkWidget *bbox, *ok, *cancel; + + char *temp; +@@ -576,6 +589,23 @@ + title_tag_desc = xmms_titlestring_descriptions("pafFetnygc", 2); + gtk_widget_set_sensitive(title_tag_desc, mpg123_cfg.title_override); + gtk_box_pack_start(GTK_BOX(title_id3_vbox), title_tag_desc, FALSE, FALSE, 0); ++ ++ id3v2_encoding_override = gtk_check_button_new_with_label(_("Override default ID3V2 encoding")); ++ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(id3v2_encoding_override), mpg123_cfg.id3v2_encoding_override); ++ gtk_signal_connect(GTK_OBJECT(id3v2_encoding_override), "clicked", id3v2_encoding_override_cb, NULL); ++ gtk_box_pack_start(GTK_BOX(title_id3_vbox), id3v2_encoding_override, FALSE, FALSE, 0); ++ ++ id3v2_encoding_box = gtk_hbox_new(FALSE, 5); ++ gtk_widget_set_sensitive(id3v2_encoding_box, mpg123_cfg.id3v2_encoding_override); ++ gtk_box_pack_start(GTK_BOX(title_id3_vbox), id3v2_encoding_box, FALSE, FALSE, 0); ++ ++ title_id3_label2 = gtk_label_new(_("Encoding name:")); ++ gtk_box_pack_start(GTK_BOX(id3v2_encoding_box), title_id3_label2, FALSE, FALSE, 0); ++ ++ encoding_entry = gtk_entry_new(); ++ gtk_entry_set_text(GTK_ENTRY(encoding_entry), mpg123_cfg.id3v2_default_encoding); ++ gtk_box_pack_start(GTK_BOX(id3v2_encoding_box), encoding_entry, TRUE, TRUE, 0); ++ + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), title_frame, gtk_label_new(_("Title"))); + + bbox = gtk_hbutton_box_new(); +diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame_text.c xmms-1.2.11-new/Input/mpg123/id3_frame_text.c +--- xmms-1.2.11/Input/mpg123/id3_frame_text.c 2007-11-24 23:57:15.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/id3_frame_text.c 2007-11-24 23:57:29.000000000 +0100 +@@ -29,6 +29,8 @@ + + #include "libxmms/charset.h" + ++/* For extern mpg123_cfg */ ++#include "mpg123.h" + + /* Get size of string in bytes including null. */ + guint id3_string_size(guint8 encoding, const char* text) +@@ -60,6 +62,9 @@ + switch (encoding) + { + case ID3_ENCODING_ISO_8859_1: ++ if (mpg123_cfg.id3v2_encoding_override) { ++ return xmms_charset_convert(text, strlen(text), mpg123_cfg.id3v2_default_encoding, NULL); ++ } + return xmms_charset_from_latin1(text); + case ID3_ENCODING_UTF8: + return xmms_charset_from_utf8(text); +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c +--- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:56:41.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:57:29.000000000 +0100 +@@ -171,6 +171,7 @@ + mpg123_cfg.use_udp_channel = FALSE; + mpg123_cfg.title_override = FALSE; + mpg123_cfg.disable_id3v2 = FALSE; ++ mpg123_cfg.id3v2_encoding_override = FALSE; + mpg123_cfg.detect_by = DETECT_EXTENSION; + mpg123_cfg.default_synth = SYNTH_AUTO; + +@@ -199,6 +200,9 @@ + xmms_cfg_read_boolean(cfg, "MPG123", "disable_id3v2", &mpg123_cfg.disable_id3v2); + if (!xmms_cfg_read_string(cfg, "MPG123", "id3_format", &mpg123_cfg.id3_format)) + mpg123_cfg.id3_format = g_strdup("%p - %t"); ++ xmms_cfg_read_boolean(cfg, "MPG123", "id3v2_encoding_override", &mpg123_cfg.id3v2_encoding_override); ++ if (!xmms_cfg_read_string(cfg, "MPG123", "id3v2_default_encoding", &mpg123_cfg.id3v2_default_encoding)) ++ mpg123_cfg.id3_format = g_strdup("ISO-8859-1"); + xmms_cfg_read_int(cfg, "MPG123", "detect_by", &mpg123_cfg.detect_by); + xmms_cfg_read_int(cfg, "MPG123", "default_synth", &mpg123_cfg.default_synth); + +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.h xmms-1.2.11-new/Input/mpg123/mpg123.h +--- xmms-1.2.11/Input/mpg123/mpg123.h 2007-11-24 23:53:33.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.h 2007-11-24 23:57:29.000000000 +0100 +@@ -159,6 +159,8 @@ + gboolean use_udp_channel; + gchar *id3_format; + gboolean title_override, disable_id3v2; ++ gboolean id3v2_encoding_override; ++ gchar *id3v2_default_encoding; + int detect_by; + int default_synth; + } diff --git a/patches/xmms/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch b/patches/xmms/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch new file mode 100644 index 0000000..b1d47a2 --- /dev/null +++ b/patches/xmms/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch @@ -0,0 +1,2247 @@ +diff -dPNur xmms-1.2.11/Input/mpg123/common.c xmms-1.2.11-new/Input/mpg123/common.c +--- xmms-1.2.11/Input/mpg123/common.c 2007-11-24 23:53:33.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/common.c 2007-11-24 23:58:41.000000000 +0100 +@@ -303,8 +303,8 @@ + mpg123_id3v2_destroy(tag); + id3_close(id3d); + } +- g_free(id3buf); + ++ g_free(id3buf); + return TRUE; + } + +diff -dPNur xmms-1.2.11/Input/mpg123/fileinfo.c xmms-1.2.11-new/Input/mpg123/fileinfo.c +--- xmms-1.2.11/Input/mpg123/fileinfo.c 2005-05-21 20:05:56.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/fileinfo.c 2007-11-24 23:58:41.000000000 +0100 +@@ -27,42 +27,96 @@ + #include + #include "mpg123.h" + ++#define MAX_STR_LEN 100 ++#define MAX_ENTRY_LEN2 1023 ++ + static GtkWidget *window = NULL; +-static GtkWidget *filename_entry, *id3_frame; +-static GtkWidget *title_entry, *artist_entry, *album_entry, *year_entry; +-static GtkWidget *tracknum_entry, *comment_entry, *genre_combo; ++static GtkWidget *notebook = NULL; ++static GtkWidget *filename_entry, *id3v1_frame, *id3v2_frame; ++static GtkWidget *v1_checkbox, *v2_checkbox; ++static GtkWidget *v1_title_entry, *v1_artist_entry, *v1_album_entry, *v1_year_entry, *v1_tracknum_entry, *v1_comment_entry; ++static GtkWidget *v2_title_entry, *v2_artist_entry, *v2_album_entry, *v2_year_entry, *v2_tracknum_entry, *v2_comment_entry, ++ *v2_composer_entry, *v2_orig_artist_entry, *v2_url_entry, *v2_encoded_by_entry; ++static GtkWidget *v1_genre_combo, *v2_genre_combo; + static GtkWidget *mpeg_level, *mpeg_bitrate, *mpeg_samplerate, *mpeg_flags; + static GtkWidget *mpeg_fileinfo; + ++static GPtrArray *v1_labels_list = NULL, *v2_labels_list = NULL; // TODO: Where will these be freed? + static GList *genre_list; + struct genre_item { + const char *name; + int id; + }; +-static int current_genre; ++static int v1_current_genre; ++static int v2_current_genre; + static char *current_filename; + + extern char *mpg123_filename; + extern int mpg123_bitrate, mpg123_frequency, mpg123_layer, mpg123_lsf, mpg123_mode; + extern gboolean mpg123_stereo, mpg123_mpeg25; + +-#define MAX_STR_LEN 100 +- +-static void label_set_text(GtkWidget * label, char *str, ...) ++static void label_set_text(GtkWidget * label, const char *str, ...) + G_GNUC_PRINTF(2, 3); + +-static void set_entry_tag(GtkEntry * entry, char * tag, int length) ++static void set_entry_tag_v1(GtkEntry * entry, const char * tag, int length) + { + char *text = g_strchomp(g_strndup(tag, length)); + gtk_entry_set_text(entry, text); + g_free(text); + } + +-static void get_entry_tag(GtkEntry * entry, char * tag, int length) ++static void get_entry_tag_v1(GtkEntry * entry, char * tag, int length) + { + strncpy(tag, gtk_entry_get_text(entry), length); + } + ++void copy_entry_tag_v1(GtkEntry * src, GtkEntry * dest, int length) ++{ ++ set_entry_tag_v1(dest, gtk_entry_get_text(src), length); ++ return; ++} ++ ++static void set_entry_tag_v2(GtkEntry * entry, struct id3_tag* id3, guint32 frame_type) ++{ ++ struct id3_frame* frame; ++ ++ frame = id3_get_frame(id3, frame_type, 1); ++ if (frame != NULL) ++ { ++ char *text, *url, *comment; ++ ++ text = id3_get_text(frame); ++ if (text != NULL) ++ { ++ gtk_entry_set_text(entry, text); ++ g_free(text); ++ return; ++ } ++ ++ url = id3_get_url(frame); ++ if (url != NULL) ++ { ++ gtk_entry_set_text(entry, url); ++ g_free(url); ++ return; ++ } ++ ++ comment = id3_get_comment(frame); ++ if (comment != NULL) ++ { ++ gtk_entry_set_text(entry, comment); ++ g_free(url); ++ return; ++ } ++ } ++} ++ ++void copy_entry_tag_v2(GtkEntry * src, GtkEntry * dest) ++{ ++ gtk_entry_set_text(dest, gtk_entry_get_text(src)); ++ return; ++} ++ + static int genre_find_index(GList *genre_list, int id) + { + int idx = 0; +@@ -74,6 +128,24 @@ + idx++; + genre_list = genre_list->next; + } ++ if (!genre_list) ++ return 0; ++ return idx; ++} ++ ++static int genre_find_index_str(GList *genre_list, const char* str) ++{ ++ int idx = 0; ++ while (genre_list) ++ { ++ struct genre_item *item = genre_list->data; ++ if (strcmp(item->name, str) == 0) ++ break; ++ idx++; ++ genre_list = genre_list->next; ++ } ++ if (!genre_list) ++ return 0; + return idx; + } + +@@ -83,9 +155,9 @@ + return strcasecmp(ga->name, gb->name); + } + +-static void save_cb(GtkWidget * w, gpointer data) ++static void remove_id3v1(void) + { +- int fd; ++ int fd, len; + struct id3v1tag_t tag; + char *msg = NULL; + +@@ -94,71 +166,36 @@ + + if ((fd = open(current_filename, O_RDWR)) != -1) + { +- int tracknum; +- +- lseek(fd, -128, SEEK_END); ++ len = lseek(fd, -128, SEEK_END); + read(fd, &tag, sizeof (struct id3v1tag_t)); + + if (!strncmp(tag.tag, "TAG", 3)) +- lseek(fd, -128, SEEK_END); +- else +- lseek(fd, 0, SEEK_END); +- tag.tag[0] = 'T'; +- tag.tag[1] = 'A'; +- tag.tag[2] = 'G'; +- get_entry_tag(GTK_ENTRY(title_entry), tag.title, 30); +- get_entry_tag(GTK_ENTRY(artist_entry), tag.artist, 30); +- get_entry_tag(GTK_ENTRY(album_entry), tag.album, 30); +- get_entry_tag(GTK_ENTRY(year_entry), tag.year, 4); +- tracknum = atoi(gtk_entry_get_text(GTK_ENTRY(tracknum_entry))); +- if (tracknum > 0) + { +- get_entry_tag(GTK_ENTRY(comment_entry), +- tag.u.v1_1.comment, 28); +- tag.u.v1_1.__zero = 0; +- tag.u.v1_1.track_number = MIN(tracknum, 255); ++ if (ftruncate(fd, len)) ++ msg = g_strdup_printf(_("%s\n" ++ "Unable to truncate file: %s"), ++ _("Couldn't remove tag!"), ++ strerror(errno)); + } +- else +- get_entry_tag(GTK_ENTRY(comment_entry), +- tag.u.v1_0.comment, 30); +- tag.genre = current_genre; +- if (write(fd, &tag, sizeof (tag)) != sizeof (tag)) +- msg = g_strdup_printf(_("%s\nUnable to write to file: %s"), +- _("Couldn't write tag!"), +- strerror(errno)); + close(fd); + } + else + msg = g_strdup_printf(_("%s\nUnable to open file: %s"), +- _("Couldn't write tag!"), ++ _("Couldn't remove tag!"), + strerror(errno)); + if (msg) + { +- GtkWidget *mwin = xmms_show_message(_("File Info"), msg, +- _("OK"), FALSE, NULL, NULL); ++ GtkWidget *mwin = xmms_show_message(_("File Info"), msg, _("OK"), ++ FALSE, NULL, NULL); + gtk_window_set_transient_for(GTK_WINDOW(mwin), + GTK_WINDOW(window)); + g_free(msg); + } +- else +- gtk_widget_destroy(window); +-} +- +-static void label_set_text(GtkWidget * label, char *str, ...) +-{ +- va_list args; +- char tempstr[MAX_STR_LEN]; +- +- va_start(args, str); +- g_vsnprintf(tempstr, MAX_STR_LEN, str, args); +- va_end(args); +- +- gtk_label_set_text(GTK_LABEL(label), tempstr); + } + +-static void remove_id3_cb(GtkWidget * w, gpointer data) ++static void save_cb(GtkWidget * w, gpointer data) + { +- int fd, len; ++ int fd; + struct id3v1tag_t tag; + char *msg = NULL; + +@@ -167,36 +204,112 @@ + + if ((fd = open(current_filename, O_RDWR)) != -1) + { +- len = lseek(fd, -128, SEEK_END); +- read(fd, &tag, sizeof (struct id3v1tag_t)); ++ if (!GTK_TOGGLE_BUTTON(v1_checkbox)->active) { ++ /* Try to save id3v1 tag */ ++ int tracknum; + +- if (!strncmp(tag.tag, "TAG", 3)) +- { +- if (ftruncate(fd, len)) +- msg = g_strdup_printf( +- _("%s\n" +- "Unable to truncate file: %s"), +- _("Couldn't remove tag!"), +- strerror(errno)); ++ lseek(fd, -128, SEEK_END); ++ read(fd, &tag, sizeof (struct id3v1tag_t)); ++ ++ if (!strncmp(tag.tag, "TAG", 3)) ++ lseek(fd, -128, SEEK_END); ++ else ++ lseek(fd, 0, SEEK_END); ++ tag.tag[0] = 'T'; ++ tag.tag[1] = 'A'; ++ tag.tag[2] = 'G'; ++ get_entry_tag_v1(GTK_ENTRY(v1_title_entry), tag.title, 30); ++ get_entry_tag_v1(GTK_ENTRY(v1_artist_entry), tag.artist, 30); ++ get_entry_tag_v1(GTK_ENTRY(v1_album_entry), tag.album, 30); ++ get_entry_tag_v1(GTK_ENTRY(v1_year_entry), tag.year, 4); ++ tracknum = atoi(gtk_entry_get_text(GTK_ENTRY(v1_tracknum_entry))); ++ if (tracknum > 0) ++ { ++ get_entry_tag_v1(GTK_ENTRY(v1_comment_entry), tag.u.v1_1.comment, 28); ++ tag.u.v1_1.__zero = 0; ++ tag.u.v1_1.track_number = MIN(tracknum, 255); ++ } ++ else ++ get_entry_tag_v1(GTK_ENTRY(v1_comment_entry), ++ tag.u.v1_0.comment, 30); ++ tag.genre = v1_current_genre; ++ if (write(fd, &tag, sizeof (tag)) != sizeof (tag)) ++ msg = g_strdup_printf(_("%s\nUnable to write to file: %s"), ++ _("Couldn't write tag!"), ++ strerror(errno)); ++ } else { ++ /* Remove the id3v1 tag from the file */ ++ remove_id3v1(); + } +- else +- msg = strdup(_("No tag to remove!")); +- close(fd); ++ ++ if (!GTK_TOGGLE_BUTTON(v2_checkbox)->active) { ++ struct id3_tag* id3; ++ ++ lseek(fd, SEEK_SET, 0); ++ id3 = id3_open_fd(fd, 0); ++ if (id3 == NULL) ++ id3 = id3_new(); ++ ++ if (id3 != NULL) ++ { ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TIT2), gtk_entry_get_text(GTK_ENTRY(v2_title_entry))); ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TPE1), gtk_entry_get_text(GTK_ENTRY(v2_artist_entry))); ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TALB), gtk_entry_get_text(GTK_ENTRY(v2_album_entry))); ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TYER), gtk_entry_get_text(GTK_ENTRY(v2_year_entry))); ++ id3_set_comment(id3_get_or_add_frame(id3, ID3_COMM), gtk_entry_get_text(GTK_ENTRY(v2_comment_entry))); ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TRCK), gtk_entry_get_text(GTK_ENTRY(v2_tracknum_entry))); ++ if (v2_current_genre != 0xff) ++ { ++ /* Essentially the same behavior as Winamp2's ID3v2 tagger */ ++ char genre[255]; ++ snprintf(genre, sizeof(genre), "(%d)%s", ++ v2_current_genre, ++ gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry))); ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TCON), genre); ++ } ++ else ++ { ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TCON), gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry))); ++ } ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TCOM), gtk_entry_get_text(GTK_ENTRY(v2_composer_entry))); ++ id3_set_url(id3_get_or_add_frame(id3, ID3_WCOM), gtk_entry_get_text(GTK_ENTRY(v2_url_entry))); ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TOPE), gtk_entry_get_text(GTK_ENTRY(v2_orig_artist_entry))); ++ id3_set_text(id3_get_or_add_frame(id3, ID3_TENC), gtk_entry_get_text(GTK_ENTRY(v2_encoded_by_entry))); ++ ++ id3_write_tag_filename(id3, current_filename); ++ } ++ ++ } else { ++ id3_remove_tag_filename(current_filename); ++ } ++ ++ if (fd) ++ close(fd); + } + else + msg = g_strdup_printf(_("%s\nUnable to open file: %s"), +- _("Couldn't remove tag!"), ++ _("Couldn't write tag!"), + strerror(errno)); + if (msg) + { +- GtkWidget *mwin = xmms_show_message(_("File Info"), msg, +- _("OK"), FALSE, NULL, NULL); ++ GtkWidget *mwin = xmms_show_message(_("File Info"), msg, _("OK"), ++ FALSE, NULL, NULL); + gtk_window_set_transient_for(GTK_WINDOW(mwin), + GTK_WINDOW(window)); + g_free(msg); + } +- else +- gtk_widget_destroy(window); ++} ++ ++static void label_set_text(GtkWidget * label, const char *str, ...) ++{ ++ va_list args; ++ char tempstr[MAX_STR_LEN]; ++ ++ va_start(args, str); ++ g_vsnprintf(tempstr, MAX_STR_LEN, str, args); ++ va_end(args); ++ ++ gtk_label_set_text(GTK_LABEL(label), tempstr); + } + + static void set_mpeg_level_label(gboolean mpeg25, int lsf, int layer) +@@ -219,28 +332,141 @@ + + static void file_info_http(char *filename) + { +- gtk_widget_set_sensitive(id3_frame, FALSE); ++ gtk_widget_set_sensitive(id3v1_frame, FALSE); ++ gtk_widget_set_sensitive(id3v2_frame, FALSE); + if (mpg123_filename && !strcmp(filename, mpg123_filename) && + mpg123_bitrate != 0) + { +- set_mpeg_level_label(mpg123_mpeg25, mpg123_lsf, mpg123_layer); ++ set_mpeg_level_label(mpg123_mpeg25, mpg123_lsf, ++ mpg123_layer); + label_set_text(mpeg_bitrate, _("Bitrate: %d kb/s"), +- mpg123_bitrate); ++ mpg123_bitrate); + label_set_text(mpeg_samplerate, _("Samplerate: %d Hz"), +- mpg123_frequency); ++ mpg123_frequency); + label_set_text(mpeg_flags, "%s", +- channel_mode_name(mpg123_mode)); ++ channel_mode_name(mpg123_mode)); + } + } + +-static void genre_selected(GtkList *list, GtkWidget *w, gpointer data) ++void copy_v2_to_v1_cb(GtkButton *button, gpointer user_data) ++{ ++ copy_entry_tag_v1(GTK_ENTRY(v2_title_entry), GTK_ENTRY(v1_title_entry), 30); ++ copy_entry_tag_v1(GTK_ENTRY(v2_artist_entry), GTK_ENTRY(v1_artist_entry), 30); ++ copy_entry_tag_v1(GTK_ENTRY(v2_album_entry), GTK_ENTRY(v1_album_entry), 30); ++ copy_entry_tag_v1(GTK_ENTRY(v2_year_entry), GTK_ENTRY(v1_year_entry), 4); ++ copy_entry_tag_v1(GTK_ENTRY(v2_comment_entry), GTK_ENTRY(v1_comment_entry), 30); ++ copy_entry_tag_v1(GTK_ENTRY(v2_tracknum_entry), GTK_ENTRY(v1_tracknum_entry), 3); ++ ++ gtk_list_select_item(GTK_LIST(GTK_COMBO(v1_genre_combo)->list), genre_find_index(genre_list, v2_current_genre)); ++ return; ++} ++ ++void copy_v1_to_v2_cb(GtkButton *button, gpointer user_data) ++{ ++ copy_entry_tag_v2(GTK_ENTRY(v1_title_entry), GTK_ENTRY(v2_title_entry)); ++ copy_entry_tag_v2(GTK_ENTRY(v1_artist_entry), GTK_ENTRY(v2_artist_entry)); ++ copy_entry_tag_v2(GTK_ENTRY(v1_album_entry), GTK_ENTRY(v2_album_entry)); ++ copy_entry_tag_v2(GTK_ENTRY(v1_year_entry), GTK_ENTRY(v2_year_entry)); ++ copy_entry_tag_v2(GTK_ENTRY(v1_comment_entry), GTK_ENTRY(v2_comment_entry)); ++ copy_entry_tag_v2(GTK_ENTRY(v1_tracknum_entry), GTK_ENTRY(v2_tracknum_entry)); ++ ++ gtk_list_select_item(GTK_LIST(GTK_COMBO(v2_genre_combo)->list), genre_find_index(genre_list, v1_current_genre)); ++ return; ++} ++ ++void v1_toggle_cb (GtkWidget *widget, gpointer data) ++{ ++ int i = 0; ++ if (GTK_TOGGLE_BUTTON (widget)->active) ++ { ++ // If control reaches here, the toggle button is down ++ // Gray out labels ++ for (i = 0; i < v1_labels_list->len; i++) { ++ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v1_labels_list, i) ), FALSE); ++ } ++ gtk_widget_set_sensitive(v1_title_entry, FALSE); ++ gtk_widget_set_sensitive(v1_artist_entry, FALSE); ++ gtk_widget_set_sensitive(v1_album_entry, FALSE); ++ gtk_widget_set_sensitive(v1_year_entry, FALSE); ++ gtk_widget_set_sensitive(v1_tracknum_entry, FALSE); ++ gtk_widget_set_sensitive(v1_comment_entry, FALSE); ++ gtk_widget_set_sensitive(v1_genre_combo, FALSE); ++ } else { ++ ++ // If control reaches here, the toggle button is up ++ // Enable labels ++ for (i = 0; i < v1_labels_list->len; i++) { ++ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v1_labels_list, i) ), TRUE); ++ } ++ gtk_widget_set_sensitive(v1_title_entry, TRUE); ++ gtk_widget_set_sensitive(v1_artist_entry, TRUE); ++ gtk_widget_set_sensitive(v1_album_entry, TRUE); ++ gtk_widget_set_sensitive(v1_year_entry, TRUE); ++ gtk_widget_set_sensitive(v1_tracknum_entry, TRUE); ++ gtk_widget_set_sensitive(v1_comment_entry, TRUE); ++ gtk_widget_set_sensitive(v1_genre_combo, TRUE); ++ } ++} ++ ++void v2_toggle_cb (GtkWidget *widget, gpointer data) ++{ ++ int i = 0; ++ if (GTK_TOGGLE_BUTTON (widget)->active) ++ { ++ // If control reaches here, the toggle button is down ++ // Gray out labels ++ for (i = 0; i < v2_labels_list->len; i++) { ++ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v2_labels_list, i) ), FALSE); ++ } ++ gtk_widget_set_sensitive(v2_title_entry, FALSE); ++ gtk_widget_set_sensitive(v2_artist_entry, FALSE); ++ gtk_widget_set_sensitive(v2_album_entry, FALSE); ++ gtk_widget_set_sensitive(v2_year_entry, FALSE); ++ gtk_widget_set_sensitive(v2_tracknum_entry, FALSE); ++ gtk_widget_set_sensitive(v2_comment_entry, FALSE); ++ gtk_widget_set_sensitive(v2_composer_entry, FALSE); ++ gtk_widget_set_sensitive(v2_orig_artist_entry, FALSE); ++ gtk_widget_set_sensitive(v2_url_entry, FALSE); ++ gtk_widget_set_sensitive(v2_encoded_by_entry, FALSE); ++ gtk_widget_set_sensitive(v2_genre_combo, FALSE); ++ } else { ++ ++ // If control reaches here, the toggle button is up ++ // Enable labels ++ for (i = 0; i < v2_labels_list->len; i++) { ++ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v2_labels_list, i) ), TRUE); ++ } ++ gtk_widget_set_sensitive(v2_title_entry, TRUE); ++ gtk_widget_set_sensitive(v2_artist_entry, TRUE); ++ gtk_widget_set_sensitive(v2_album_entry, TRUE); ++ gtk_widget_set_sensitive(v2_year_entry, TRUE); ++ gtk_widget_set_sensitive(v2_tracknum_entry, TRUE); ++ gtk_widget_set_sensitive(v2_comment_entry, TRUE); ++ gtk_widget_set_sensitive(v2_composer_entry, TRUE); ++ gtk_widget_set_sensitive(v2_orig_artist_entry, TRUE); ++ gtk_widget_set_sensitive(v2_url_entry, TRUE); ++ gtk_widget_set_sensitive(v2_encoded_by_entry, TRUE); ++ gtk_widget_set_sensitive(v2_genre_combo, TRUE); ++ } ++} ++static void v1_genre_selected(GtkList *list, GtkWidget *w, gpointer data) + { + void * p; + p = gtk_object_get_data(GTK_OBJECT(w), "genre_id"); + if (p != NULL) +- current_genre = GPOINTER_TO_INT(p); ++ v1_current_genre = GPOINTER_TO_INT(p); + else +- current_genre = 0; ++ v1_current_genre = 0; ++} ++ ++static void v2_genre_selected(GtkList *list, GtkWidget *w, gpointer data) ++{ ++ void * p; ++ p = gtk_object_get_data(GTK_OBJECT(w), "genre_id"); ++ if (p != NULL) ++ v2_current_genre = GPOINTER_TO_INT(p); ++ else ++ v2_current_genre = 0; + } + + static void genre_set_popdown(GtkWidget *combo, GList *genres) +@@ -269,7 +495,7 @@ + void mpg123_file_info_box(char *filename) + { + int i; +- struct id3v1tag_t tag; ++ struct id3v1tag_t id3v1tag; + FILE *fh; + char *tmp, *title; + const char *emphasis[4]; +@@ -284,205 +510,397 @@ + + if (!window) + { +- GtkWidget *vbox, *hbox, *left_vbox, *table; +- GtkWidget *mpeg_frame, *mpeg_box; +- GtkWidget *label, *filename_hbox; +- GtkWidget *bbox, *save, *remove_id3, *cancel; +- ++ GtkWidget *window_vbox, ++ *id3v1_vbox, *id3v2_vbox, *id3v1_frame_vbox, *id3v2_frame_vbox, ++ *mpeg_lvbox, *mpeg_rvbox, *mpeg_hbox, *mpeg_box, *mpeg_frame, ++ *bbox, *save, *close, *copy_to, *copy_from, ++ *table, *label, *filename_hbox; ++ ++ v1_labels_list = g_ptr_array_new(); ++ v2_labels_list = g_ptr_array_new(); ++ + 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_widget_destroyed, &window); +- gtk_signal_connect(GTK_OBJECT(window), "key_press_event", +- file_info_box_keypress_cb, NULL); ++ gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window); ++ gtk_signal_connect(GTK_OBJECT(window), "key_press_event", file_info_box_keypress_cb, NULL); + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + +- vbox = gtk_vbox_new(FALSE, 10); +- gtk_container_add(GTK_CONTAINER(window), vbox); +- ++ window_vbox = gtk_vbox_new(FALSE,10); + filename_hbox = gtk_hbox_new(FALSE, 5); +- gtk_box_pack_start(GTK_BOX(vbox), filename_hbox, +- FALSE, TRUE, 0); ++ gtk_box_pack_start(GTK_BOX(window_vbox), filename_hbox, FALSE, TRUE, 0); + + label = gtk_label_new(_("Filename:")); +- gtk_box_pack_start(GTK_BOX(filename_hbox), label, +- FALSE, TRUE, 0); ++ gtk_box_pack_start(GTK_BOX(filename_hbox), label, FALSE, TRUE, 0); + filename_entry = xmms_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); ++ gtk_box_pack_start(GTK_BOX(filename_hbox), filename_entry, TRUE, TRUE, 0); + +- id3_frame = gtk_frame_new(_("ID3 Tag:")); +- gtk_box_pack_start(GTK_BOX(left_vbox), id3_frame, +- FALSE, FALSE, 0); ++ /* Set up the genres list */ + +- table = gtk_table_new(5, 5, FALSE); ++ if (!genre_list) ++ { ++ struct genre_item *item; ++ ++ for (i = 0; i < GENRE_MAX; i++) ++ { ++ item = g_malloc(sizeof (*item)); ++ item->name = gettext(mpg123_id3_genres[i]); ++ item->id = i; ++ genre_list = g_list_prepend(genre_list, item); ++ } ++ item = g_malloc(sizeof (*item)); ++ item->name = ""; ++ item->id = 0xff; ++ genre_list = g_list_prepend(genre_list, item); ++ genre_list = g_list_sort(genre_list, genre_comp_func); ++ } ++ ++ notebook = gtk_notebook_new (); ++ gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP); ++ ++ /* ID3v2 page */ ++ ++ id3v2_vbox = gtk_vbox_new(FALSE, 0); ++ ++ id3v2_frame = gtk_frame_new("ID3v2 Information"); ++ gtk_box_pack_start(GTK_BOX(id3v2_vbox), id3v2_frame, FALSE, FALSE, 0); ++ ++ id3v2_frame_vbox = gtk_vbox_new(FALSE, 0); ++ gtk_container_add(GTK_CONTAINER(id3v2_frame), id3v2_frame_vbox); ++ ++ table = gtk_table_new(6, 6, FALSE); + gtk_container_set_border_width(GTK_CONTAINER(table), 5); +- gtk_container_add(GTK_CONTAINER(id3_frame), table); ++ gtk_widget_set_usize(GTK_WIDGET(table), 400, -1); ++ gtk_box_pack_start(GTK_BOX(id3v2_frame_vbox), table, FALSE, FALSE, 0); + +- label = gtk_label_new(_("Title:")); ++ v2_checkbox = gtk_check_button_new_with_label ("Disable ID3v2 Tag"); ++ gtk_signal_connect(GTK_OBJECT(v2_checkbox), "toggled", GTK_SIGNAL_FUNC(v2_toggle_cb), NULL); ++ gtk_table_attach(GTK_TABLE(table), v2_checkbox, 1, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 2); ++ ++ label = gtk_label_new("Track number:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); + 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); ++ gtk_table_attach(GTK_TABLE(table), label, 3, 4, 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); ++ v2_tracknum_entry = gtk_entry_new_with_max_length(3); ++ gtk_widget_set_usize(v2_tracknum_entry, 20, -1); ++ gtk_table_attach(GTK_TABLE(table), v2_tracknum_entry, 4, 5, 0, 1, ++ GTK_FILL, GTK_FILL, 0, 2); + +- label = gtk_label_new(_("Artist:")); ++ label = gtk_label_new("Title:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); + 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); ++ 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); ++ v2_title_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); ++ gtk_table_attach(GTK_TABLE(table), v2_title_entry, 1, 5, 1, 2, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); + +- label = gtk_label_new(_("Album:")); ++ label = gtk_label_new("Artist:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); + 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); ++ 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); ++ v2_artist_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); ++ gtk_table_attach(GTK_TABLE(table), v2_artist_entry, 1, 5, 2, 3, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); + +- label = gtk_label_new(_("Comment:")); ++ label = gtk_label_new("Album:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); + 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); ++ 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); ++ v2_album_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); ++ gtk_table_attach(GTK_TABLE(table), v2_album_entry, 1, 5, 3, 4, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); + +- label = gtk_label_new(_("Year:")); ++ label = gtk_label_new("Comment:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); + 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); ++ 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); ++ v2_comment_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); ++ gtk_table_attach(GTK_TABLE(table), v2_comment_entry, 1, 5, 4, 5, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); + +- label = gtk_label_new(_("Track number:")); ++ label = gtk_label_new("Year:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); + 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); ++ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6, ++ 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); ++ v2_year_entry = gtk_entry_new_with_max_length(4); ++ gtk_widget_set_usize(v2_year_entry, 45, -1); ++ gtk_table_attach(GTK_TABLE(table), v2_year_entry, 1, 2, 5, 6, ++ GTK_FILL, GTK_FILL, 0, 2); + +- label = gtk_label_new(_("Genre:")); ++ label = gtk_label_new("Genre:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); ++ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); ++ gtk_table_attach(GTK_TABLE(table), label, 2, 3, 5, 6, ++ GTK_FILL, GTK_FILL, 5, 5); ++ ++ v2_genre_combo = gtk_combo_new(); ++ gtk_combo_set_value_in_list(GTK_COMBO(v2_genre_combo), FALSE, TRUE); ++ ++ genre_set_popdown(v2_genre_combo, genre_list); ++ gtk_signal_connect(GTK_OBJECT(GTK_COMBO(v2_genre_combo)->list), ++ "select-child", v2_genre_selected, NULL); ++ ++ gtk_table_attach(GTK_TABLE(table), v2_genre_combo, 3, 5, 5, 6, ++ GTK_FILL | GTK_SHRINK, GTK_FILL | ++ GTK_SHRINK, 0, 2); ++ ++ label = gtk_label_new("Composer:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); ++ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); ++ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 6, 7, ++ GTK_FILL, GTK_FILL, 5, 5); ++ ++ v2_composer_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); ++ gtk_table_attach(GTK_TABLE(table), v2_composer_entry, 1, 5, 6, 7, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); ++ ++ label = gtk_label_new("Orig. Artist:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); ++ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); ++ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 7, 8, ++ GTK_FILL, GTK_FILL, 5, 5); ++ ++ v2_orig_artist_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); ++ gtk_table_attach(GTK_TABLE(table), v2_orig_artist_entry, 1, 5, 7, 8, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); ++ ++ label = gtk_label_new("URL:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); ++ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); ++ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 8, 9, ++ GTK_FILL, GTK_FILL, 5, 5); ++ ++ v2_url_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); ++ gtk_table_attach(GTK_TABLE(table), v2_url_entry, 1, 5, 8, 9, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); ++ label = gtk_label_new("Encoded By:"); ++ g_ptr_array_add(v2_labels_list, (gpointer)label); ++ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); ++ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 9, 10, ++ GTK_FILL, GTK_FILL, 5, 5); ++ ++ v2_encoded_by_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); ++ gtk_table_attach(GTK_TABLE(table), v2_encoded_by_entry, 1, 5, 9, 10, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); ++ ++ bbox = gtk_hbutton_box_new(); ++ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START); ++ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 0); ++ gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); ++ gtk_box_pack_start(GTK_BOX(id3v2_frame_vbox), bbox, FALSE, FALSE, 0); ++ ++ copy_to = gtk_button_new_with_label("ID3v2 to ID3v1"); ++ gtk_signal_connect(GTK_OBJECT(copy_to), "clicked", GTK_SIGNAL_FUNC(copy_v2_to_v1_cb), NULL); ++ /* remove the next line to thicken the button width */ ++ GTK_WIDGET_SET_FLAGS(copy_to, GTK_CAN_DEFAULT); ++ gtk_box_pack_start(GTK_BOX(bbox), copy_to, FALSE, TRUE, 0); ++ ++ label = gtk_label_new ("ID3v2"); ++ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), id3v2_vbox, label); ++ ++ /* ID3v1 page */ ++ ++ id3v1_vbox = gtk_vbox_new(FALSE, 10); ++ id3v1_frame = gtk_frame_new("ID3v1 Information"); ++ gtk_box_pack_start(GTK_BOX(id3v1_vbox), id3v1_frame, TRUE, TRUE, 0); ++ ++ id3v1_frame_vbox = gtk_vbox_new(FALSE,10); ++ gtk_container_add(GTK_CONTAINER(id3v1_frame), id3v1_frame_vbox); ++ ++ table = gtk_table_new(6, 6, FALSE); ++ gtk_container_set_border_width(GTK_CONTAINER(table), 5); ++ //gtk_widget_set_usize(GTK_WIDGET(table), 325, -1); ++ //gtk_container_add(GTK_CONTAINER(id3v1_frame), table); ++ gtk_box_pack_start(GTK_BOX(id3v1_frame_vbox), table, FALSE, FALSE, 0); ++ ++ v1_checkbox = gtk_check_button_new_with_label ("Disable ID3v1 Tag"); ++ gtk_signal_connect(GTK_OBJECT(v1_checkbox), "toggled", GTK_SIGNAL_FUNC(v1_toggle_cb), NULL); ++ gtk_table_attach(GTK_TABLE(table), v1_checkbox, 1, 3, 0, 1, ++ GTK_FILL, GTK_FILL, 0, 2); ++ ++ label = gtk_label_new("Track number:"); ++ g_ptr_array_add(v1_labels_list, (gpointer)label); ++ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); ++ gtk_table_attach(GTK_TABLE(table), label, 3, 4, 0, 1, ++ GTK_FILL, GTK_FILL, 5,5); ++ ++ v1_tracknum_entry = gtk_entry_new_with_max_length(3); ++ gtk_widget_set_usize(v1_tracknum_entry, 20, -1); ++ gtk_table_attach(GTK_TABLE(table), v1_tracknum_entry, 4, 5, 0, 1, ++ GTK_FILL, GTK_FILL, 0, 2); ++ ++ label = gtk_label_new("Title:"); ++ g_ptr_array_add(v1_labels_list, (gpointer)label); ++ 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); ++ ++ v1_title_entry = gtk_entry_new_with_max_length(30); ++ gtk_table_attach(GTK_TABLE(table), v1_title_entry, 1, 5, 1, 2, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); ++ ++ label = gtk_label_new("Artist:"); ++ g_ptr_array_add(v1_labels_list, (gpointer)label); ++ 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); ++ ++ v1_artist_entry = gtk_entry_new_with_max_length(30); ++ gtk_table_attach(GTK_TABLE(table), v1_artist_entry, 1, 5, 2, 3, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); ++ ++ label = gtk_label_new("Album:"); ++ g_ptr_array_add(v1_labels_list, (gpointer)label); ++ 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); ++ ++ v1_album_entry = gtk_entry_new_with_max_length(30); ++ gtk_table_attach(GTK_TABLE(table), v1_album_entry, 1, 5, 3, 4, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); ++ ++ label = gtk_label_new("Comment:"); ++ g_ptr_array_add(v1_labels_list, (gpointer)label); ++ 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); ++ ++ v1_comment_entry = gtk_entry_new_with_max_length(30); ++ gtk_table_attach(GTK_TABLE(table), v1_comment_entry, 1, 5, 4, 5, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, ++ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); ++ ++ label = gtk_label_new("Year:"); ++ g_ptr_array_add(v1_labels_list, (gpointer)label); + 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); ++ 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) +- { +- struct genre_item *item; ++ v1_year_entry = gtk_entry_new_with_max_length(4); ++ gtk_widget_set_usize(v1_year_entry, 45, -1); ++ gtk_table_attach(GTK_TABLE(table), v1_year_entry, 1, 2, 5, 6, ++ GTK_FILL, GTK_FILL, 0, 2); + +- for (i = 0; i < GENRE_MAX; i++) +- { +- item = g_malloc(sizeof (*item)); +- item->name = gettext(mpg123_id3_genres[i]); +- item->id = i; +- genre_list = g_list_prepend(genre_list, item); +- } +- item = g_malloc(sizeof (*item)); +- item->name = ""; +- item->id = 0xff; +- genre_list = g_list_prepend(genre_list, item); +- genre_list = g_list_sort(genre_list, genre_comp_func); +- } +- genre_set_popdown(genre_combo, genre_list); +- gtk_signal_connect(GTK_OBJECT(GTK_COMBO(genre_combo)->list), +- "select-child", genre_selected, NULL); ++ label = gtk_label_new("Genre:"); ++ g_ptr_array_add(v1_labels_list, (gpointer)label); ++ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); ++ gtk_table_attach(GTK_TABLE(table), label, 2, 3, 5, 6, ++ GTK_FILL, GTK_FILL, 5, 5); + +- 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); ++ v1_genre_combo = gtk_combo_new(); ++ gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(v1_genre_combo)->entry), FALSE); ++ genre_set_popdown(v1_genre_combo, genre_list); ++ gtk_signal_connect(GTK_OBJECT(GTK_COMBO(v1_genre_combo)->list), ++ "select-child", v1_genre_selected, NULL); ++ ++ gtk_table_attach(GTK_TABLE(table), v1_genre_combo, 3, 5, 5, 6, ++ GTK_FILL | GTK_SHRINK, GTK_FILL | ++ GTK_SHRINK, 0, 2); + + 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); ++ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START); ++ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 0); ++ gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); ++ gtk_box_pack_start(GTK_BOX(id3v1_frame_vbox), bbox, FALSE, FALSE, 0); + +- save = gtk_button_new_with_label(_("Save")); +- gtk_signal_connect(GTK_OBJECT(save), "clicked", 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); ++ copy_from = gtk_button_new_with_label("ID3v1 to ID3v2"); ++ gtk_signal_connect(GTK_OBJECT(copy_from), "clicked", GTK_SIGNAL_FUNC(copy_v1_to_v2_cb), NULL); ++ // remove the next line to thicken the button width ++ GTK_WIDGET_SET_FLAGS(copy_from, GTK_CAN_DEFAULT); ++ gtk_box_pack_start(GTK_BOX(bbox), copy_from, FALSE, TRUE, 0); + +- remove_id3 = gtk_button_new_with_label(_("Remove ID3")); +- gtk_signal_connect(GTK_OBJECT(remove_id3), "clicked", +- 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); ++ label = gtk_label_new ("ID3v1"); ++ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), id3v1_vbox, label); + +- cancel = gtk_button_new_with_label(_("Cancel")); +- gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked", +- 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); ++ /* MPEG info page */ + +- mpeg_frame = gtk_frame_new(_("MPEG Info:")); +- gtk_box_pack_start(GTK_BOX(hbox), mpeg_frame, FALSE, FALSE, 0); ++ mpeg_frame = gtk_frame_new("MPEG Information"); ++ mpeg_hbox = gtk_hbox_new(FALSE,50); ++ gtk_container_add(GTK_CONTAINER(mpeg_frame), mpeg_hbox); ++ ++ mpeg_lvbox = gtk_vbox_new(FALSE, 5); ++ gtk_container_set_border_width(GTK_CONTAINER(mpeg_lvbox), 10); ++ gtk_box_pack_start(GTK_BOX(mpeg_hbox), mpeg_lvbox, FALSE, FALSE, 0); + + mpeg_box = gtk_vbox_new(FALSE, 5); +- gtk_container_add(GTK_CONTAINER(mpeg_frame), mpeg_box); ++ gtk_box_pack_start(GTK_BOX(mpeg_hbox), mpeg_box, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(mpeg_box), 10); + gtk_box_set_spacing(GTK_BOX(mpeg_box), 0); + + mpeg_level = gtk_label_new(""); +- gtk_widget_set_usize(mpeg_level, 120, -2); +- gtk_misc_set_alignment(GTK_MISC(mpeg_level), 0, 0); +- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_level, FALSE, FALSE, 0); +- +- mpeg_bitrate = gtk_label_new(""); +- gtk_misc_set_alignment(GTK_MISC(mpeg_bitrate), 0, 0); +- gtk_label_set_justify(GTK_LABEL(mpeg_bitrate), +- GTK_JUSTIFY_LEFT); +- gtk_box_pack_start(GTK_BOX(mpeg_box), +- mpeg_bitrate, FALSE, FALSE, 0); ++ //gtk_widget_set_usize(mpeg_level, 120, -2); ++ gtk_label_set_justify (GTK_LABEL(mpeg_level), GTK_JUSTIFY_LEFT); ++ gtk_misc_set_alignment(GTK_MISC(mpeg_level), 0, 0.5); ++ gtk_box_pack_start(GTK_BOX(mpeg_lvbox), mpeg_level, FALSE, FALSE, 0); + + mpeg_samplerate = gtk_label_new(""); +- gtk_misc_set_alignment(GTK_MISC(mpeg_samplerate), 0, 0); +- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_samplerate, +- FALSE, FALSE, 0); ++ gtk_label_set_justify (GTK_LABEL(mpeg_samplerate), GTK_JUSTIFY_LEFT); ++ gtk_misc_set_alignment(GTK_MISC(mpeg_samplerate), 0, 0.5); ++ gtk_box_pack_start(GTK_BOX(mpeg_lvbox), mpeg_samplerate, FALSE, FALSE, 0); ++ ++ mpeg_fileinfo = gtk_label_new(""); ++ gtk_label_set_justify (GTK_LABEL(mpeg_fileinfo), GTK_JUSTIFY_LEFT); ++ gtk_misc_set_alignment(GTK_MISC(mpeg_fileinfo), 0, 0.5); ++ gtk_box_pack_start(GTK_BOX(mpeg_lvbox), mpeg_fileinfo, FALSE, FALSE, 0); ++ ++ mpeg_rvbox = gtk_vbox_new(FALSE, 5); ++ gtk_box_pack_start(GTK_BOX(mpeg_hbox), mpeg_rvbox, FALSE, FALSE, 0); ++ gtk_container_set_border_width(GTK_CONTAINER(mpeg_rvbox), 10); ++ ++ mpeg_bitrate = gtk_label_new(""); ++ gtk_label_set_justify (GTK_LABEL(mpeg_bitrate), GTK_JUSTIFY_LEFT); ++ gtk_misc_set_alignment(GTK_MISC(mpeg_bitrate), 0, 0.5); ++ gtk_box_pack_start(GTK_BOX(mpeg_rvbox), mpeg_bitrate, FALSE, FALSE, 0); + + mpeg_flags = gtk_label_new(""); +- gtk_misc_set_alignment(GTK_MISC(mpeg_flags), 0, 0); +- gtk_label_set_justify(GTK_LABEL(mpeg_flags), GTK_JUSTIFY_LEFT); +- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_flags, +- FALSE, FALSE, 0); ++ gtk_label_set_justify (GTK_LABEL(mpeg_flags), GTK_JUSTIFY_LEFT); ++ gtk_misc_set_alignment(GTK_MISC(mpeg_flags), 0, 0.5); ++ gtk_box_pack_start(GTK_BOX(mpeg_rvbox), mpeg_flags, FALSE, FALSE, 0); + +- mpeg_fileinfo = gtk_label_new(""); +- gtk_misc_set_alignment(GTK_MISC(mpeg_fileinfo), 0, 0); +- gtk_label_set_justify(GTK_LABEL(mpeg_fileinfo), +- GTK_JUSTIFY_LEFT); +- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_fileinfo, +- FALSE, FALSE, 0); ++ label = gtk_label_new ("MPEG"); ++ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), mpeg_frame, label); ++ ++ /* add notebook to window vbox */ ++ gtk_box_pack_start(GTK_BOX(window_vbox), notebook, FALSE, FALSE, 0); ++ ++ /* add button box to window vbox */ ++ bbox = gtk_hbutton_box_new(); ++ gtk_box_pack_start(GTK_BOX(window_vbox), bbox, FALSE, FALSE, 0); + ++ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END); ++ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 5); ++ ++ save = gtk_button_new_with_label("Save"); ++ gtk_signal_connect(GTK_OBJECT(save), "clicked", GTK_SIGNAL_FUNC(save_cb), NULL); ++ gtk_box_pack_start(GTK_BOX(bbox), save, TRUE, TRUE, 5); ++ ++ close = gtk_button_new_with_label("Close"); ++ gtk_signal_connect_object(GTK_OBJECT(close), "clicked", ++ GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window)); ++ gtk_box_pack_start(GTK_BOX(bbox), close, TRUE, TRUE, 5); ++ ++ gtk_container_add(GTK_CONTAINER(window), window_vbox); + gtk_widget_show_all(window); + } + +@@ -500,73 +918,128 @@ + title = g_strdup(g_basename(filename)); + if ((tmp = strrchr(title, '.')) != NULL) + *tmp = '\0'; +- gtk_entry_set_text(GTK_ENTRY(title_entry), title); ++ gtk_entry_set_text(GTK_ENTRY(v1_title_entry), title); ++ gtk_entry_set_text(GTK_ENTRY(v2_title_entry), title); + g_free(title); + +- gtk_entry_set_text(GTK_ENTRY(artist_entry), ""); +- gtk_entry_set_text(GTK_ENTRY(album_entry), ""); +- gtk_entry_set_text(GTK_ENTRY(year_entry), ""); +- gtk_entry_set_text(GTK_ENTRY(tracknum_entry), ""); +- gtk_entry_set_text(GTK_ENTRY(comment_entry), ""); +- gtk_list_select_item(GTK_LIST(GTK_COMBO(genre_combo)->list), ++ gtk_entry_set_text(GTK_ENTRY(v1_artist_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v1_album_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v1_year_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v1_tracknum_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v1_comment_entry), ""); ++ ++ gtk_list_select_item(GTK_LIST(GTK_COMBO(v1_genre_combo)->list), + genre_find_index(genre_list, 0xff)); ++ ++ gtk_entry_set_text(GTK_ENTRY(v2_artist_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v2_album_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v2_year_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v2_tracknum_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v2_comment_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v2_composer_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v2_orig_artist_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v2_url_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(v2_encoded_by_entry), ""); ++ gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry), ""); ++ + gtk_label_set_text(GTK_LABEL(mpeg_level), "MPEG ?, layer ?"); + gtk_label_set_text(GTK_LABEL(mpeg_bitrate), ""); + gtk_label_set_text(GTK_LABEL(mpeg_samplerate), ""); + gtk_label_set_text(GTK_LABEL(mpeg_flags), ""); + gtk_label_set_text(GTK_LABEL(mpeg_fileinfo), ""); +- + if (!strncasecmp(filename, "http://", 7)) + { + file_info_http(filename); + return; + } + +- gtk_widget_set_sensitive(id3_frame, TRUE); ++ gtk_widget_set_sensitive(id3v1_frame, TRUE); ++ gtk_widget_set_sensitive(id3v2_frame, TRUE); + + if ((fh = fopen(current_filename, "rb")) != NULL) + { + struct frame frm; + gboolean id3_found = FALSE; ++ struct id3_tag *id3 = NULL; + guint8 *buf; + double tpf; + int pos; + xing_header_t xing_header; + guint32 num_frames; +- +- fseek(fh, -sizeof (tag), SEEK_END); +- if (fread(&tag, 1, sizeof (tag), fh) == sizeof (tag)) ++ /* ++ * Try reading ID3v2 tag. ++ */ ++ fseek(fh, 0, SEEK_SET); ++ id3 = id3_open_fp(fh, 0); ++ if (id3 != NULL) + { +- if (!strncmp(tag.tag, "TAG", 3)) ++ struct id3_frame* frame; ++ ++ set_entry_tag_v2(GTK_ENTRY(v2_title_entry), id3, ID3_TIT2); ++ set_entry_tag_v2(GTK_ENTRY(v2_artist_entry), id3, ID3_TPE1); ++ set_entry_tag_v2(GTK_ENTRY(v2_album_entry), id3, ID3_TALB); ++ set_entry_tag_v2(GTK_ENTRY(v2_comment_entry), id3, ID3_COMM); ++ set_entry_tag_v2(GTK_ENTRY(v2_composer_entry), id3, ID3_TCOM); ++ set_entry_tag_v2(GTK_ENTRY(v2_orig_artist_entry), id3, ID3_TOPE); ++ set_entry_tag_v2(GTK_ENTRY(v2_url_entry), id3, ID3_WCOM); ++ set_entry_tag_v2(GTK_ENTRY(v2_encoded_by_entry), id3, ID3_TENC); ++ set_entry_tag_v2(GTK_ENTRY(v2_tracknum_entry), id3, ID3_TRCK); ++ set_entry_tag_v2(GTK_ENTRY(v2_year_entry), id3, ID3_TYER); ++ ++ frame = id3_get_frame(id3, ID3_TCON, 1); ++ if (frame != NULL) + { +- id3_found = TRUE; +- set_entry_tag(GTK_ENTRY(title_entry), +- tag.title, 30); +- set_entry_tag(GTK_ENTRY(artist_entry), +- tag.artist, 30); +- set_entry_tag(GTK_ENTRY(album_entry), +- tag.album, 30); +- set_entry_tag(GTK_ENTRY(year_entry), +- tag.year, 4); +- /* Check for v1.1 tags */ +- if (tag.u.v1_1.__zero == 0 && tag.u.v1_1.track_number > 0) +- { +- char *temp = g_strdup_printf("%d", tag.u.v1_1.track_number); +- set_entry_tag(GTK_ENTRY(comment_entry), +- tag.u.v1_1.comment, 28); +- gtk_entry_set_text(GTK_ENTRY(tracknum_entry), temp); +- g_free(temp); +- } +- else ++ char* genre = id3_get_content(frame); ++ if (genre != NULL) + { +- set_entry_tag(GTK_ENTRY(comment_entry), +- tag.u.v1_0.comment, 30); +- gtk_entry_set_text(GTK_ENTRY(tracknum_entry), ""); ++ int genre_idx = genre_find_index_str(genre_list, genre); ++ if (genre_idx > 0) ++ gtk_list_select_item(GTK_LIST(GTK_COMBO(v2_genre_combo)->list), genre_idx); ++ else ++ gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry), genre); + } +- +- gtk_list_select_item(GTK_LIST(GTK_COMBO(genre_combo)->list), genre_find_index(genre_list, tag.genre)); + } ++ ++ id3_close(id3); ++ } ++ else ++ { ++ /* Grey out the id3v2 tab */ ++ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(v2_checkbox), TRUE); ++ } ++ ++ /* ++ * Try reading ID3v1 tag. ++ */ ++ fseek(fh, -sizeof (id3v1tag), SEEK_END); ++ if ( (fread(&id3v1tag, 1, sizeof (id3v1tag), fh) == sizeof (id3v1tag)) && !strncmp(id3v1tag.tag, "TAG", 3)) ++ { ++ id3_found = TRUE; ++ set_entry_tag_v1(GTK_ENTRY(v1_title_entry), id3v1tag.title, 30); ++ set_entry_tag_v1(GTK_ENTRY(v1_artist_entry), id3v1tag.artist, 30); ++ set_entry_tag_v1(GTK_ENTRY(v1_album_entry), id3v1tag.album, 30); ++ set_entry_tag_v1(GTK_ENTRY(v1_year_entry), id3v1tag.year, 4); ++ /* Check for v1.1 tags */ ++ if (id3v1tag.u.v1_1.__zero == 0 && id3v1tag.u.v1_1.track_number > 0) ++ { ++ char *temp = g_strdup_printf("%d", id3v1tag.u.v1_1.track_number); ++ set_entry_tag_v1(GTK_ENTRY(v1_comment_entry), id3v1tag.u.v1_1.comment, 28); ++ gtk_entry_set_text(GTK_ENTRY(v1_tracknum_entry), temp); ++ g_free(temp); ++ } ++ else ++ { ++ set_entry_tag_v1(GTK_ENTRY(v1_comment_entry), id3v1tag.u.v1_0.comment, 30); ++ gtk_entry_set_text(GTK_ENTRY(v1_tracknum_entry), ""); + } ++ gtk_list_select_item(GTK_LIST(GTK_COMBO(v1_genre_combo)->list), genre_find_index(genre_list, id3v1tag.genre)); ++ } ++ else ++ { ++ // Grey out id3v1 tab ++ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(v1_checkbox), TRUE); ++ } ++ + rewind(fh); + + if (!mpg123_get_first_frame(fh, &frm, &buf)) +diff -dPNur xmms-1.2.11/Input/mpg123/id3.c xmms-1.2.11-new/Input/mpg123/id3.c +--- xmms-1.2.11/Input/mpg123/id3.c 2005-05-21 20:05:56.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/id3.c 2007-11-24 23:58:41.000000000 +0100 +@@ -22,6 +22,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -49,7 +50,7 @@ + */ + static int id3_seek_mem(struct id3_tag *id3, int offset) + { +- if (id3->id3_pos + offset > id3->id3_tagsize || ++ if (id3->id3_pos + offset > id3->id3_totalsize || + id3->id3_pos + offset < 0) + { + id3_error(id3, "seeking beyond tag boundary"); +@@ -77,7 +78,7 @@ + /* + * Check boundary. + */ +- if (id3->id3_pos + size > id3->id3_tagsize) ++ if (id3->id3_pos + size > id3->id3_totalsize) + return NULL; + + /* +@@ -118,7 +119,7 @@ + /* + * Check boundary. + */ +- if (id3->id3_pos + offset > id3->id3_tagsize || ++ if (id3->id3_pos + offset > id3->id3_totalsize || + id3->id3_pos + offset < 0) + return -1; + +@@ -148,8 +149,8 @@ + /* + * Check boundary. + */ +- if (id3->id3_pos + size > id3->id3_tagsize) +- return NULL; ++ if (id3->id3_pos + size > id3->id3_totalsize) ++ size = id3->id3_totalsize - id3->id3_pos; + + /* + * If buffer is NULL, we use the default buffer. +@@ -205,7 +206,7 @@ + /* + * Check boundary. + */ +- if (id3->id3_pos + offset > id3->id3_tagsize || ++ if (id3->id3_pos + offset > id3->id3_totalsize || + id3->id3_pos + offset < 0) + return -1; + +@@ -263,8 +264,8 @@ + /* + * Check boundary. + */ +- if (id3->id3_pos + size > id3->id3_tagsize) +- size = id3->id3_tagsize - id3->id3_pos; ++ if (id3->id3_pos + size > id3->id3_totalsize) ++ size = id3->id3_totalsize - id3->id3_pos; + + /* + * If buffer is NULL, we use the default buffer. +@@ -338,6 +339,32 @@ + return NULL; + } + ++/* ++ * Function id3_new() ++ * ++ * Creates a new ID3 tag structure. Useful for creating ++ * a new tag. ++ * ++ */ ++struct id3_tag *id3_new() ++{ ++ struct id3_tag *id3; ++ ++ /* ++ * Allocate ID3 structure. ++ */ ++ id3 = g_malloc0( sizeof(struct id3_tag) ); ++ ++ if (id3 != NULL) ++ { ++ id3_init_tag ( id3 ); ++ id3->id3_type = ID3_TYPE_NONE; ++ id3->id3_seek = NULL; ++ id3->id3_read = NULL; ++ } ++ ++ return id3; ++} + + /* + * Function id3_open_fd (fd, flags) +@@ -493,7 +520,7 @@ + if (id3->id3_newtag) + return 0; + else +- return id3->id3_tagsize + 3 + sizeof(id3_taghdr_t); ++ return id3->id3_totalsize + 3 + sizeof(id3_taghdr_t); + } + #endif + +@@ -560,6 +587,81 @@ + return 0; + } + ++/* ++ * Function id3_remove_tag_filename(filename) ++ * ++ * Remove the ID3v2 tag from the file indicated by filename. Takes care of resizing ++ * the file, if needed. Returns 0 upon success, or -1 if an error occured. ++ * ++ */ ++int id3_remove_tag_filename(const char* filename) ++{ ++ struct id3_tag *current_id3; ++ int fd; ++ int current_totalsize; ++ struct stat stat_buf; ++ ++ fd = open(filename, O_RDWR); ++ if (fd == -1) ++ return -1; ++ ++ /* ++ * Figure out how large the current tag is. ++ */ ++ current_id3 = id3_open_fd(fd, 0); ++ if (current_id3 != NULL) ++ { ++ /* We use MAX to make sure an erroneous tag doesn't confuse us */ ++ current_totalsize = MAX(current_id3->id3_totalsize, 0); ++ id3_close(current_id3); ++ } ++ else ++ { ++ current_totalsize = 0; ++ } ++ ++ if (current_totalsize <= 0) ++ return 0; ++ ++ /* ++ * Rewrite the file. ++ */ ++ ++ stat(filename, &stat_buf); ++ ++ /* Re-position all the data current_totalsize bytes backwards */ ++ { ++ int read_pos, write_pos; ++ size_t read_size; ++ char buf[4096]; ++ ++ /* TODO: Add error handling to IO operations */ ++ ++ /* We reposition the data by going forwards, each time reading ++ a block and copying it backward. That way, we never write ++ over a block which we intend to read later. */ ++ write_pos = 0; ++ read_pos = write_pos + current_totalsize; ++ ++ do ++ { ++ lseek(fd, read_pos, SEEK_SET); ++ read_size = read(fd, buf, sizeof(buf)); ++ read_pos += read_size; ++ ++ /* Write whatever block we've got */ ++ lseek(fd, write_pos, SEEK_SET); ++ write(fd, buf, read_size); ++ write_pos += read_size; ++ } ++ while (read_size > 0); ++ ++ ftruncate(fd, stat_buf.st_size - current_totalsize); ++ } ++ ++ close(fd); ++ return 0; ++} + + /* + * Function id3_write_tag (id3, fd) +@@ -567,30 +669,25 @@ + * Wrtite the ID3 tag to the indicated file descriptor. Return 0 + * upon success, or -1 if an error occured. + * ++ * Warning: This function is called by id3_write_tag_filename and should ++ * not be called standalone, as it doesn't perform seeking ++ * and doesn't enlarge the file as necessary, and thus might ++ * OVERWRITE THE AUDIO DATA. ++ * + */ + int id3_write_tag(struct id3_tag *id3, int fd) + { + struct id3_frame *fr; + GList *node; +- int size = 0; + char buf[ID3_TAGHDR_SIZE]; + + /* +- * Calculate size of ID3 tag. +- */ +- for (node = id3->id3_frame; node != NULL; node = node->next) +- { +- fr = node->data; +- size += fr->fr_size + ID3_FRAMEHDR_SIZE; +- } +- +- /* + * Write tag header. + */ + buf[0] = id3->id3_version; + buf[1] = id3->id3_revision; + buf[2] = id3->id3_flags; +- ID3_SET_SIZE28(size, buf[3], buf[4], buf[5], buf[6]); ++ ID3_SET_SIZE28(id3->id3_size, buf[3], buf[4], buf[5], buf[6]); + + if (safe_write(fd, "ID3", 3) == -1) + return -1; +@@ -617,19 +714,203 @@ + * TODO: Support compressed headers, encoded + * headers, and grouping info. + */ +- /* fhdr.fh_id = fr->fr_desc ? g_htonl(fr->fr_desc->fd_id) : 0; */ +- fhdr[3] = (fr->fr_size >> 24) & 0xff; +- fhdr[4] = (fr->fr_size >> 16) & 0xff; +- fhdr[5] = (fr->fr_size >> 8) & 0xff; +- fhdr[6] = fr->fr_size & 0xff; +- fhdr[7] = (fr->fr_flags >> 8) & 0xff; +- fhdr[8] = fr->fr_flags & 0xff; ++ fhdr[0] = fr->fr_desc->fd_idstr[0]; ++ fhdr[1] = fr->fr_desc->fd_idstr[1]; ++ fhdr[2] = fr->fr_desc->fd_idstr[2]; ++ fhdr[3] = fr->fr_desc->fd_idstr[3]; ++ fhdr[4] = (fr->fr_raw_size >> 24) & 0xff; ++ fhdr[5] = (fr->fr_raw_size >> 16) & 0xff; ++ fhdr[6] = (fr->fr_raw_size >> 8) & 0xff; ++ fhdr[7] = fr->fr_raw_size & 0xff; ++ fhdr[8] = (fr->fr_flags >> 8) & 0xff; ++ fhdr[9] = fr->fr_flags & 0xff; + + if (safe_write(fd, fhdr, sizeof(fhdr)) == -1) + return -1; + +- if (safe_write(fd, fr->fr_data, fr->fr_size) == -1) ++ if (safe_write(fd, fr->fr_raw_data, fr->fr_raw_size) == -1) + return -1; + } + return 0; + } ++ ++ ++/* ++ * Function id3_write_tag_file(id3, filename) ++ * ++ * Write the ID3 tag to the file indicated by filename. Takes care of enlarging ++ * the file, if needed. Returns 0 upon success, or -1 if an error occured. ++ * ++ */ ++int id3_write_tag_filename(struct id3_tag *id3, const char* filename) ++{ ++ struct id3_tag *current_id3; ++ int fd; ++ int current_totalsize, new_totalsize; ++ GList* node; ++ ++ fd = open(filename, O_RDWR); ++ if (fd == -1) ++ return -1; ++ ++ /* ++ * Figure out how large the current tag is. ++ */ ++ current_id3 = id3_open_fd(fd, 0); ++ if (current_id3 != NULL) ++ { ++ /* We use MAX to make sure an erroneous tag doesn't confuse us */ ++ current_totalsize = MAX(current_id3->id3_totalsize, 0); ++ id3_close(current_id3); ++ } ++ else ++ { ++ current_totalsize = 0; ++ } ++ ++ /* ++ * Figure out how large the new tag will be. ++ */ ++ new_totalsize = 10; ++ node = id3->id3_frame; ++ while (node != NULL) ++ { ++ struct id3_frame* fr = node->data; ++ ++ { ++ char* text = id3_get_text(fr); ++ if (text != NULL) ++ { ++ int len = strlen(text); ++ g_free(text); ++ ++ if (len == 0) ++ { ++ /* We skip over frames with empty text */ ++ node = node->next; ++ id3_delete_frame(fr); ++ continue; ++ } ++ } ++ } ++ ++ { ++ char* url = id3_get_url(fr); ++ if (url != NULL) ++ { ++ int len = strlen(url); ++ g_free(url); ++ ++ if (len == 0) ++ { ++ /* We skip over frames with empty URLs */ ++ node = node->next; ++ id3_delete_frame(fr); ++ continue; ++ } ++ } ++ } ++ ++ new_totalsize += fr->fr_raw_size + ID3_FRAMEHDR_SIZE; ++ node = node->next; ++ } ++ new_totalsize += 0; /* no extended header, no footer, no padding */ ++ id3->id3_flags = 0; ++ ++ /* ++ * Determine whether we need to rewrite the file to make place for the new tag. ++ */ ++ if (new_totalsize > current_totalsize) ++ { ++ struct stat stat_buf; ++ int grow_size; ++ ++ stat(filename, &stat_buf); ++ grow_size = new_totalsize - current_totalsize; ++ ftruncate(fd, stat_buf.st_size + grow_size); ++ ++ /* truncate adds "sparse" zeros; we'll turn them into real ones, ++ which occupy space on disk, to make sure we actually have ++ the disk space before we start enlarging the file */ ++ { ++ int remaining = grow_size; ++ char buf[1024] = { 0 }; ++ lseek(fd, stat_buf.st_size, SEEK_SET); ++ while (remaining > 0) ++ { ++ int ret = write(fd, buf, MIN(sizeof(buf), remaining)); ++ if (ret >= 0) ++ remaining -= ret; ++ else ++ { ++ id3_error(id3, "Unable to enlarge file for the new tag"); ++ ftruncate(fd, stat_buf.st_size); ++ close(fd); ++ return -1; ++ } ++ } ++ } ++ ++ /* and now, re-position all the data grow_size bytes forward */ ++ { ++ int area_to_move_size = stat_buf.st_size - current_totalsize; ++ int read_pos, write_pos; ++ size_t read_size, read_size_desired; ++ char buf[4096]; ++ ++ /* TODO: Add error handling to IO operations */ ++ ++ /* We reposition the data by going backwards, each time reading ++ a block and copying it forward. That way, we never write ++ over a block which we intend to read later. */ ++ write_pos = lseek(fd, 0, SEEK_END); ++ read_pos = write_pos - grow_size; ++ ++ /* While we still have bytes to move... */ ++ while(area_to_move_size > 0) ++ { ++ /* Get 1 block or the remaining bytes -- the smallest of the two */ ++ read_size_desired = MIN(area_to_move_size, sizeof(buf)); ++ read_pos -= read_size_desired; ++ lseek(fd, read_pos, SEEK_SET); ++ read_size = read(fd, buf, read_size_desired); ++ ++ /* Write whatever block we've got */ ++ write_pos -= read_size; ++ lseek(fd, write_pos, SEEK_SET); ++ write(fd, buf, read_size); ++ ++ area_to_move_size -= read_size; ++ } ++ } ++ } ++ else ++ { ++ new_totalsize = current_totalsize; ++ } ++ ++ id3->id3_size = new_totalsize - 10; ++ ++ /* Zero-out the ID3v2 tag area */ ++ { ++ char buf[1024] = {0}; ++ size_t remaining; ++ ++ lseek(fd, 0, SEEK_SET); ++ for(remaining = new_totalsize; remaining > 0; remaining -= MIN(remaining,sizeof(buf))) ++ { ++ write(fd, buf, MIN(remaining,sizeof(buf))); ++ } ++ } ++ ++ /* Write the new tag */ ++ lseek(fd, 0, SEEK_SET); ++ if (id3_write_tag(id3, fd) == -1) ++ { ++ close(fd); ++ return -1; ++ } ++ ++ close(fd); ++ return 0; ++} +diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame.c xmms-1.2.11-new/Input/mpg123/id3_frame.c +--- xmms-1.2.11/Input/mpg123/id3_frame.c 2005-05-21 20:05:56.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/id3_frame.c 2007-11-24 23:58:41.000000000 +0100 +@@ -283,7 +283,7 @@ + */ + if (!((buf[0] >= '0' && buf[0] <= '9') || (buf[0] >= 'A' && buf[0] <= 'Z'))) + { +- id3->id3_seek(id3, id3->id3_tagsize - id3->id3_pos); ++ id3->id3_seek(id3, id3->id3_totalsize - id3->id3_pos); + return 0; + } + id = ID3_FRAME_ID(buf[0], buf[1], buf[2], buf[3]); +@@ -308,7 +308,7 @@ + */ + + frame->fr_desc = find_frame_description(id); +- ++ + /* + * Check if frame had a valid id. + */ +@@ -385,6 +385,29 @@ + } + + /* ++ * Function id3_get_or_add_frame (id3, type) ++ * ++ * Search in the list of frames for the ID3-tag, and return the first frame ++ * of the indicated type. If no frame of the indicated type exists yet, ++ * it will add one and return it. ++ * ++ */ ++struct id3_frame *id3_get_or_add_frame(struct id3_tag *id3, guint32 type) ++{ ++ struct id3_frame* fr; ++ ++ fr = id3_get_frame(id3, type, 1); ++ if (fr != NULL) ++ { ++ return fr; ++ } ++ else ++ { ++ return id3_add_frame(id3, type); ++ } ++} ++ ++/* + * Function decompress_frame(frame) + * + * Uncompress the indicated frame. Return 0 upon success, or -1 if +@@ -517,27 +540,26 @@ + */ + int id3_delete_frame(struct id3_frame *frame) + { +- GList *list = frame->fr_owner->id3_frame; ++ struct id3_tag* id3 = frame->fr_owner; ++ GList *list = id3->id3_frame; + int ret; + + /* + * Search for frame in list. + */ +- if (g_list_find(list, frame) != NULL) +- { +- /* +- * Frame does not exist in frame list. +- */ +- ret = -1; +- } +- else +- { ++ if (g_list_find(list, frame) != NULL) { + /* + * Remove frame from frame list. + */ + list = g_list_remove(list, frame); +- frame->fr_owner->id3_altered = 1; +- ret = 0; ++ id3->id3_frame = list; ++ id3->id3_altered = 1; ++ ret = 0; ++ } else { ++ /* ++ * Frame does not exist in frame list. ++ */ ++ ret = -1; + } + + /* +@@ -704,7 +726,7 @@ + */ + if (!((buf[0] >= '0' && buf[0] <= '9') || (buf[0] >= 'A' && buf[0] <= 'Z'))) + { +- id3->id3_seek(id3, id3->id3_tagsize - id3->id3_pos); ++ id3->id3_seek(id3, id3->id3_size - id3->id3_pos); + return 0; + } + +diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame_text.c xmms-1.2.11-new/Input/mpg123/id3_frame_text.c +--- xmms-1.2.11/Input/mpg123/id3_frame_text.c 2007-11-24 23:58:20.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/id3_frame_text.c 2007-11-24 23:58:41.000000000 +0100 +@@ -155,6 +155,11 @@ + char *id3_get_text(struct id3_frame *frame) + { + int offset = 0; ++ ++ /* Do we even have data for this frame */ ++ if (!frame->fr_data) ++ return NULL; ++ + /* Type check */ + if (frame->fr_desc->fd_idstr[0] != 'T') + return NULL; +@@ -374,3 +379,54 @@ + return id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), + ID3_TEXT_FRAME_PTR(frame) + offset); + } ++ ++/* ++ * Function id3_set_comment (frame, text) ++ * ++ * Set text for the indicated frame. Return 0 upon ++ * success, or -1 if an error occured. ++ * ++ */ ++int id3_set_comment(struct id3_frame *frame, char *text) ++{ ++ int *intp; ++ ++ /* Type check */ ++ if (frame->fr_desc->fd_id != ID3_COMM) ++ return -1; ++ ++ /* ++ * Release memory occupied by previous data. ++ */ ++ id3_frame_clear_data(frame); ++ ++ /* ++ * Allocate memory for new data. ++ */ ++ frame->fr_raw_size = 13 + strlen(text); ++ frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); /* XXXComments\0<\0> ++ ++ /* Save time... we just need to zero out the start, not the whole ++ * block, so don't waste time with a calloc() ++ */ ++ ++ ((guint8 *)frame->fr_raw_data)[0] = ID3_ENCODING_ISO_8859_1; ++ ((guint8 *)frame->fr_raw_data)[1] = 0x58; ++ ((guint8 *)frame->fr_raw_data)[2] = 0x58; ++ ((guint8 *)frame->fr_raw_data)[3] = 0x58; ++ ++ memcpy((char *) frame->fr_raw_data + 4, "Comments", 9); ++ ++ /* ++ * Copy contents. ++ */ ++ memcpy((char *) frame->fr_raw_data + 13, text, strlen(text) + 1); ++ ++ frame->fr_altered = 1; ++ frame->fr_owner->id3_altered = 1; ++ ++ frame->fr_data = frame->fr_raw_data; ++ frame->fr_size = frame->fr_raw_size; ++ ++ return 0; ++} +diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame_url.c xmms-1.2.11-new/Input/mpg123/id3_frame_url.c +--- xmms-1.2.11/Input/mpg123/id3_frame_url.c 2005-05-21 20:05:56.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/id3_frame_url.c 2007-11-24 23:58:41.000000000 +0100 +@@ -34,6 +34,11 @@ + char *id3_get_url(struct id3_frame *frame) + { + int offset = 0; ++ ++ /* Do we even have data for this frame */ ++ if (!frame->fr_data) ++ return NULL; ++ + /* Type check */ + if (frame->fr_desc->fd_idstr[0] != 'W') + return NULL; +@@ -80,3 +85,32 @@ + return id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), + ID3_TEXT_FRAME_PTR(frame)); + } ++ ++/* ++ * Function id3_set_url (frame) ++ * ++ * Sets URL of frame. ++ * ++ */ ++void id3_set_url(struct id3_frame *frame, const char* url) ++{ ++ /* Type check */ ++ if ( frame->fr_desc->fd_idstr[0] != 'W' ) ++ return; ++ ++ /* Check if frame is compressed */ ++ if (id3_decompress_frame(frame) == -1) ++ return; ++ ++ /* ++ * Allocate memory for new data. ++ */ ++ frame->fr_raw_size = strlen(url) + 1; ++ frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); ++ ++ /* ++ * Copy contents. ++ */ ++ *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1; ++ memcpy((char *) frame->fr_raw_data + 1, url, frame->fr_raw_size); ++} +diff -dPNur xmms-1.2.11/Input/mpg123/id3.h xmms-1.2.11-new/Input/mpg123/id3.h +--- xmms-1.2.11/Input/mpg123/id3.h 2005-05-21 20:05:56.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/id3.h 2007-11-24 23:58:41.000000000 +0100 +@@ -22,6 +22,7 @@ + #define ID3_H + + #include ++#include + + /* + * Option flags to id3_open_*(). +@@ -49,8 +50,9 @@ + + int id3_version; /* Major ID3 version number */ + int id3_revision; /* ID3 revision number */ ++ int id3_size; /* Size of ID3 tag (as dictated by header) */ + +- int id3_tagsize; /* Total size of ID3 tag */ ++ int id3_totalsize; /* Total size of ID3 tag (including header, footer and padding) */ + int id3_pos; /* Current position within tag */ + + char *id3_error_msg; /* Last error message */ +@@ -140,8 +142,6 @@ + #define ID3_ENCODING_UTF16BE 0x02 + #define ID3_ENCODING_UTF8 0x03 + +- +- + /* + * ID3 frame id numbers. + */ +@@ -322,50 +322,51 @@ + */ + + /* From id3.c */ +-struct id3_tag *id3_open_mem(void *, int); +-struct id3_tag *id3_open_fd(int, int); +-struct id3_tag *id3_open_fp(FILE *, int); +-int id3_set_output(struct id3_tag *, char *); +-int id3_close(struct id3_tag *); +-int id3_tell(struct id3_tag *); +-int id3_alter_file(struct id3_tag *); +-int id3_write_tag(struct id3_tag *, int); ++struct id3_tag *id3_new(); ++struct id3_tag *id3_open_mem(void *ptr, int flags); ++struct id3_tag *id3_open_fd(int fd, int flags); ++struct id3_tag *id3_open_fp(FILE *fp, int flags); ++int id3_close(struct id3_tag *id3); ++int id3_tell(struct id3_tag *id3); ++int id3_alter_file(struct id3_tag *id3); ++int id3_write_tag(struct id3_tag *id3, int fd); ++int id3_write_tag_filename(struct id3_tag *id3, const char* filename); ++int id3_remove_tag_filename(const char* filename); + + /* From id3_frame.c */ + int id3_read_frame(struct id3_tag *id3); +-struct id3_frame *id3_get_frame(struct id3_tag *, guint32, int); ++struct id3_frame *id3_get_frame(struct id3_tag *id3, guint32 type, int num); + int id3_delete_frame(struct id3_frame *frame); +-struct id3_frame *id3_add_frame(struct id3_tag *, guint32); +-int id3_decompress_frame(struct id3_frame *); +-void id3_destroy_frames(struct id3_tag *id); ++struct id3_frame *id3_add_frame(struct id3_tag *id3, guint32 type); ++struct id3_frame *id3_get_or_add_frame(struct id3_tag *id3, guint32 type); ++int id3_decompress_frame(struct id3_frame *frame); ++void id3_destroy_frames(struct id3_tag *id3); + void id3_frame_clear_data(struct id3_frame *frame); + + /* From id3_frame_text.c */ + guint id3_string_size(guint8 encoding, const char* text); + char* id3_string_decode(guint8 encoding, const char* text); +-gint8 id3_get_encoding(struct id3_frame *); +-int id3_set_encoding(struct id3_frame *, gint8); +-char *id3_get_text(struct id3_frame *); +-char *id3_get_comment(struct id3_frame *); +-char *id3_get_text_desc(struct id3_frame *); +-int id3_get_text_number(struct id3_frame *); +-int id3_set_text(struct id3_frame *, char *); +-int id3_set_text_number(struct id3_frame *, int); ++gint8 id3_get_encoding(struct id3_frame *frame); ++int id3_set_encoding(struct id3_frame *frame, gint8 encoding); ++char *id3_get_text(struct id3_frame *frame); ++char *id3_get_comment(struct id3_frame *frame); ++char *id3_get_text_desc(struct id3_frame *frame); ++int id3_get_text_number(struct id3_frame *frame); ++int id3_set_text(struct id3_frame *frame, char *text); ++int id3_set_comment(struct id3_frame *frame, char *comment); ++int id3_set_text_number(struct id3_frame *frame, int number); + gboolean id3_frame_is_text(struct id3_frame *frame); + + /* From id3_frame_content.c */ +-char *id3_get_content(struct id3_frame *); ++char *id3_get_content(struct id3_frame *frame); + + /* From id3_frame_url.c */ +-char *id3_get_url(struct id3_frame *); +-char *id3_get_url_desc(struct id3_frame *); ++char *id3_get_url(struct id3_frame *frame); ++char *id3_get_url_desc(struct id3_frame *frame); ++void id3_set_url(struct id3_frame *frame, const char* url); + + /* From id3_tag.c */ + void id3_init_tag(struct id3_tag *id3); + int id3_read_tag(struct id3_tag *id3); + +-char *convert_from_utf16(const unsigned char *utf16); +-char *convert_from_utf16be(const unsigned char *utf16); +- +- + #endif /* ID3_H */ +diff -dPNur xmms-1.2.11/Input/mpg123/id3_header.h xmms-1.2.11-new/Input/mpg123/id3_header.h +--- xmms-1.2.11/Input/mpg123/id3_header.h 2005-05-21 20:05:56.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/id3_header.h 2007-11-24 23:58:41.000000000 +0100 +@@ -39,22 +39,21 @@ + #define ID3_THFLAG_USYNC 0x80 + #define ID3_THFLAG_EXT 0x40 + #define ID3_THFLAG_EXP 0x20 ++#define ID3_THFLAG_FOOTER 0x10 + + #define ID3_SET_SIZE28(size, a, b, c, d) \ +-do { \ +- a = (size >> (24 + 3)) & 0x7f; \ +- b = (size >> (16 + 2)) & 0x7f; \ +- c = (size >> ( 8 + 1)) & 0x7f; \ ++{ \ ++ a = (size >> (24 - 3)) & 0x7f; \ ++ b = (size >> (16 - 2)) & 0x7f; \ ++ c = (size >> ( 8 - 1)) & 0x7f; \ + d = size & 0x7f; \ +-} while (0) ++} + + #define ID3_GET_SIZE28(a, b, c, d) \ +-(((a & 0x7f) << (24 - 3)) | \ +- ((b & 0x7f) << (16 - 2)) | \ +- ((c & 0x7f) << ( 8 - 1)) | \ +- ((d & 0x7f))) +- +- ++ (((a & 0x7f) << (24 - 3)) | \ ++ ((b & 0x7f) << (16 - 2)) | \ ++ ((c & 0x7f) << ( 8 - 1)) | \ ++ ((d & 0x7f))) \ + + /* + * Layout for the extended header. +diff -dPNur xmms-1.2.11/Input/mpg123/id3_tag.c xmms-1.2.11-new/Input/mpg123/id3_tag.c +--- xmms-1.2.11/Input/mpg123/id3_tag.c 2005-05-21 20:05:56.000000000 +0200 ++++ xmms-1.2.11-new/Input/mpg123/id3_tag.c 2007-11-24 23:58:41.000000000 +0100 +@@ -39,7 +39,8 @@ + id3->id3_version = 3; + id3->id3_revision = 0; + id3->id3_flags = ID3_THFLAG_USYNC | ID3_THFLAG_EXP; +- id3->id3_tagsize = 0; ++ id3->id3_size = 0; ++ id3->id3_totalsize = 0; + + id3->id3_altered = 1; + id3->id3_newtag = 1; +@@ -63,13 +64,14 @@ + int id3_read_tag(struct id3_tag *id3) + { + char *buf; ++ guint8 padding; + + /* + * We know that the tag will be at least this big. + * + * tag header + "ID3" + */ +- id3->id3_tagsize = ID3_TAGHDR_SIZE + 3; ++ id3->id3_totalsize = ID3_TAGHDR_SIZE + 3; + + if (!(id3->id3_oflags & ID3_OPENF_NOCHK)) + { +@@ -100,9 +102,11 @@ + id3->id3_version = buf[0]; + id3->id3_revision = buf[1]; + id3->id3_flags = buf[2]; +- id3->id3_tagsize = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]); ++ id3->id3_size = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]); ++ id3->id3_totalsize += id3->id3_size; ++ if (id3->id3_flags & ID3_THFLAG_FOOTER) ++ id3->id3_totalsize += 10; + id3->id3_newtag = 0; +- id3->id3_pos = 0; + + if (id3->id3_version < 2 || id3->id3_version > 4) + return -1; +@@ -120,14 +124,34 @@ + /* + * Parse frames. + */ +- while (id3->id3_pos < id3->id3_tagsize) ++ while (id3->id3_pos < id3->id3_size) + { + if (id3_read_frame(id3) == -1) + return -1; + } + +- if (id3->id3_frame == NULL) +- return -1; ++ /* ++ * Like id3lib, we try to find unstandard padding (not within ++ * the tag size). This is important to know when we strip ++ * the tag or replace it. ++ * Another option might be looking for an MPEG sync, but we don't do it. ++ */ ++ ++ id3->id3_seek(id3, id3->id3_totalsize - id3->id3_pos); ++ ++ /* Temporarily increase totalsize, to try reading beyong the boundary */ ++ ++id3->id3_totalsize; ++ ++ while (id3->id3_read(id3, &padding, sizeof(padding)) != NULL) ++ { ++ if (padding == 0) ++ ++id3->id3_totalsize; ++ else ++ break; ++ } ++ ++ /* Decrease totalsize after we temporarily increased it */ ++ --id3->id3_totalsize; + + return 0; + } +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c +--- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:58:20.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:58:41.000000000 +0100 +@@ -129,9 +129,9 @@ + + #ifdef USE_SIMD + fr->dct36 = funcs_dct36[0]; +- ++ + if (CPU_HAS_3DNOW() && !p8 && +- (mpg123_cfg.default_synth == SYNTH_3DNOW || ++ (mpg123_cfg.default_synth == SYNTH_3DNOW || + mpg123_cfg.default_synth == SYNTH_AUTO)) + { + fr->synth = funcs[3][ds]; /* 3DNow! optimized synth_1to1() */ +@@ -320,11 +320,11 @@ + if (!strncasecmp(filename, "http://", 7)) + { /* We assume all http:// (except those ending in .ogg) are mpeg -- why do we do that? */ + ext = strrchr(filename, '.'); +- if (ext) ++ if (ext) + { +- if (!strncasecmp(ext, ".ogg", 4)) ++ if (!strncasecmp(ext, ".ogg", 4)) + return FALSE; +- if (!strncasecmp(ext, ".rm", 3) || ++ if (!strncasecmp(ext, ".rm", 3) || + !strncasecmp(ext, ".ra", 3) || + !strncasecmp(ext, ".rpm", 4) || + !strncasecmp(ext, ".fla", 4) || +@@ -534,7 +534,7 @@ + * Function mpg123_get_id3v2 (id3d, tag) + * + * Get desired contents from the indicated id3tag and store it in +- * `tag'. ++ * `tag'. + * + */ + struct id3v2tag_t* mpg123_id3v2_get(struct id3_tag *id3d) +@@ -550,6 +550,10 @@ + tag->track_number = id3v2_get_num(id3d, ID3_TRCK); + tag->comment = id3v2_get_text(id3d, ID3_COMM); + tag->genre = id3v2_get_text(id3d, ID3_TCON); ++ tag->composer = id3v2_get_text(id3d, ID3_TCOM); ++ tag->orig_artist = id3v2_get_text(id3d, ID3_TOPE); ++ tag->url = id3v2_get_text(id3d, ID3_WCOM); ++ tag->encoded_by = id3v2_get_text(id3d, ID3_TENC); + + return tag; + } +@@ -829,7 +833,7 @@ + static int mpg123_seek(struct frame *fr, xing_header_t *xh, gboolean vbr, int time) + { + int jumped = -1; +- ++ + if (xh) + { + int percent = ((double) time * 100.0) / +@@ -995,7 +999,7 @@ + mpg123_info->output_audio = FALSE; + continue; + } +- ++ + } + } + if(mpg123_freqs[fr.sampling_frequency] != mpg123_frequency || mpg123_stereo != fr.stereo) +@@ -1033,12 +1037,12 @@ + mpg123_info->output_audio = FALSE; + continue; + } +- } ++ } + } +- ++ + if (tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index] != mpg123_bitrate) + mpg123_bitrate = tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index]; +- ++ + if (!disp_count) + { + disp_count = 20; +@@ -1154,7 +1158,7 @@ + + if (aboutbox != NULL) + return; +- ++ + aboutbox = xmms_show_message( + _("About MPEG Layer 1/2/3 plugin"), + _("mpg123 decoding engine by Michael Hipp \n" +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.h xmms-1.2.11-new/Input/mpg123/mpg123.h +--- xmms-1.2.11/Input/mpg123/mpg123.h 2007-11-24 23:58:20.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.h 2007-11-24 23:58:41.000000000 +0100 +@@ -1,5 +1,5 @@ + /* +- * mpg123 defines ++ * mpg123 defines + * used source: musicout.h from mpegaudio package + */ + +@@ -79,6 +79,10 @@ + char *album; + char *comment; + char *genre; ++ char *composer; ++ char *orig_artist; ++ char *url; ++ char *encoded_by; + int year; + int track_number; + }; +@@ -300,7 +304,6 @@ + int mpg123_decode_header(struct frame *fr, unsigned long newhead); + double mpg123_compute_bpf(struct frame *fr); + double mpg123_compute_tpf(struct frame *fr); +-guint mpg123_strip_spaces(char *src, size_t n); + struct id3v2tag_t* mpg123_id3v2_get(struct id3_tag *id3d); + void mpg123_id3v2_destroy(struct id3v2tag_t* tag); + char *mpg123_format_song_title(struct id3v2tag_t *tag, char *filename); diff --git a/patches/xmms/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch b/patches/xmms/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch new file mode 100644 index 0000000..453c91b --- /dev/null +++ b/patches/xmms/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch @@ -0,0 +1,766 @@ +diff -dPNur xmms-1.2.11/configure.in xmms-1.2.11-new/configure.in +--- xmms-1.2.11/configure.in 2007-11-16 22:52:30.000000000 +0100 ++++ xmms-1.2.11-new/configure.in 2007-11-25 00:00:09.000000000 +0100 +@@ -144,6 +144,22 @@ + fi + AC_SUBST([PTHREAD_LIBS]) + ++dnl *** OpenSSL support ++AC_ARG_ENABLE( ssl, ++[ --disable-ssl Disable HTTP SSL in plugin(s) [default=enabled]],, ++ enable_ssl="yes") ++ ++if test "x$enable_ssl" = xyes; then ++ SSL_LIBS="" ++ AC_CHECK_LIB(ssl, SSL_read, [SSL_LIBS="-lssl" ++ AC_DEFINE(HTTP_SSL,,[Define if OpenSSL is available]) ++ AC_DEFINE(OPENSSL_NO_KRB5,,[Define if OpenSSL is available])], ++ echo "*** SSL support requires openssl and openssl-devel packages ***") ++ LIBS="$LIBS $SSL_LIBS" ++else ++ AC_MSG_RESULT([*** Disabling SSL in plugin(s) per user request ***]) ++ have_ssl=no ++fi + + dnl *** + dnl *** OpenGL +diff -dPNur xmms-1.2.11/Input/mpg123/common.c xmms-1.2.11-new/Input/mpg123/common.c +--- xmms-1.2.11/Input/mpg123/common.c 2007-11-24 23:59:35.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/common.c 2007-11-25 00:00:09.000000000 +0100 +@@ -464,7 +464,11 @@ + void mpg123_open_stream(char *bs_filenam, int fd, unsigned long range) + { + filept_opened = 1; ++#ifdef HTTP_SSL ++ if (!strncasecmp(bs_filenam, "http://", 7) || !strncasecmp(bs_filenam, "https://", 8)) ++#else + if (!strncasecmp(bs_filenam, "http://", 7)) ++#endif + { + filept = NULL; + mpg123_info->filesize = 0; +diff -dPNur xmms-1.2.11/Input/mpg123/http.c xmms-1.2.11-new/Input/mpg123/http.c +--- xmms-1.2.11/Input/mpg123/http.c 2007-11-24 23:53:33.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/http.c 2007-11-25 00:00:09.000000000 +0100 +@@ -33,6 +33,14 @@ + #include "mpg123.h" + #include "libxmms/util.h" + ++#ifdef HTTP_SSL ++#include ++#include ++#include ++#include ++#include ++#endif ++ + #define min(x,y) ((x)<(y)?(x):(y)) + #define min3(x,y,z) (min(x,y)<(z)?min(x,y):(z)) + #define min4(x,y,z,w) (min3(x,y,z)<(w)?min3(x,y,z):(w)) +@@ -117,7 +125,11 @@ + return res; + } + ++#ifdef HTTP_SSL ++static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename, int *ssl) ++#else + static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename) ++#endif + { + gchar *h, *p, *pt, *f, *temp, *ptr; + +@@ -126,6 +138,14 @@ + + if (!strncasecmp("http://", ptr, 7)) + ptr += 7; ++#ifdef HTTP_SSL ++ if (!strncasecmp("https://", ptr, 8)) { ++ ptr += 8; ++ *ssl = 1; ++ } else ++ *ssl = 0; ++#endif ++ + h = strchr(ptr, '@'); + f = strchr(ptr, '/'); + if (h != NULL && (!f || h < f)) +@@ -160,7 +180,12 @@ + { + if (f) + *f = '\0'; +- *port = 80; ++#ifdef HTTP_SSL ++ if (*ssl) ++ *port = 443; ++ else ++#endif ++ *port = 80; + } + *host = g_strdup(h); + +@@ -302,16 +327,27 @@ + return FALSE; + } + ++#ifdef HTTP_SSL ++gint mpg123_http_read_line(gchar * buf, gint size, SSL *ssl_c) ++#else + gint mpg123_http_read_line(gchar * buf, gint size) ++#endif + { +- gint i = 0; ++ gint i = 0, rc; + + while (going && i < size - 1) + { + if (http_check_for_data()) + { +- if (read(sock, buf + i, 1) <= 0) +- return -1; ++#ifdef HTTP_SSL ++ if (ssl_c) { ++ while ((rc = SSL_read(ssl_c, buf + i, 1)) == -1); ++ if (rc <= 0) ++ return -1; ++ } else ++#endif ++ if (read(sock, buf + i, 1) <= 0) ++ return -1; + if (buf[i] == '\n') + break; + if (buf[i] != '\r') +@@ -342,7 +378,13 @@ + struct sockaddr_in address; + #endif + struct timeval tv; +- ++#ifdef HTTP_SSL ++ SSL *ssl_c = NULL; ++ SSL_CTX *ssl_ctx = NULL; ++ BIO *b = NULL; ++ gint ssl=0; ++#endif ++ + url = (gchar *) arg; + do + { +@@ -350,7 +392,11 @@ + + g_strstrip(url); + ++#ifdef HTTP_SSL ++ parse_url(url, &user, &pass, &host, &port, &filename, &ssl); ++#else + parse_url(url, &user, &pass, &host, &port, &filename); ++#endif + + if ((!filename || !*filename) && url[strlen(url) - 1] != '/') + temp = g_strconcat(url, "/", NULL); +@@ -362,6 +408,26 @@ + chost = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_host : host; + cport = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_port : port; + ++#ifdef HTTP_SSL ++ if (ssl) { ++ SSL_library_init(); ++ OpenSSL_add_ssl_algorithms(); ++ SSL_load_error_strings(); ++ ++ ssl_ctx = SSL_CTX_new(SSLv23_client_method()); ++ if (ssl_ctx == NULL) { ++ fprintf(stderr, "SSL_CTX_new() failed."); ++ eof = TRUE; ++ } ++ ++ ssl_c = SSL_new(ssl_ctx); ++ if (ssl_c == NULL) { ++ fprintf(stderr, "SSL_new() failed.\n"); ++ eof = TRUE; ++ } ++ } ++#endif ++ + #ifdef USE_IPV6 + g_snprintf(service, 6, "%d", cport); + memset(&hints, 0, sizeof(hints)); +@@ -441,7 +507,20 @@ + eof = TRUE; + } + } ++#ifdef HTTP_SSL ++ if (ssl) { ++ b = BIO_new_socket(sock, BIO_NOCLOSE); ++ if (b == NULL) { ++ printf("BIO_new_socket() failed.\n"); ++ eof = TRUE; ++ } ++ ++ // cannot fail ++ SSL_set_bio(ssl_c, b, b); ++ } ++#endif + #endif ++ + while (going) + { + tv.tv_sec = 0; +@@ -466,6 +545,24 @@ + break; + } + } ++#ifdef HTTP_SSL ++ if (ssl) { ++ int rc; ++ ++ SSL_set_connect_state(ssl_c); ++ ++ while ((rc = SSL_connect(ssl_c)) == -1); ++ if (rc <= 0) { ++ fprintf(stderr, "SSL_connect() error. SSL error code: %d.\n", ++ SSL_get_error(ssl_c, rc)); ++ } ++ while ((rc = SSL_do_handshake(ssl_c)) == -1); ++ if (rc <= 0) { ++ fprintf(stderr, "SSL_do_handshake() error. SSL error code: %d.\n", ++ SSL_get_error(ssl_c, rc)); ++ } ++ } ++#endif + if (!eof) + { + gchar *auth = NULL, *proxy_auth = NULL; +@@ -517,14 +614,30 @@ + g_free(proxy_auth); + if(auth) + g_free(auth); +- write(sock, temp, strlen(temp)); ++#ifdef HTTP_SSL ++ if (ssl) { ++ int rc; ++ while ((rc = SSL_write(ssl_c, temp, strlen(temp))) == -1); ++ if (rc <= 0) { ++ fprintf(stderr, "SSL_write() error. SSL error code: %d.\n", ++ SSL_get_error(ssl_c, rc)); ++ eof = TRUE; ++ } ++ } else ++#endif ++ write(sock, temp, strlen(temp)); ++ + g_free(temp); + mpg123_ip.set_info_text(_("CONNECTED: WAITING FOR REPLY")); + while (going && !eof) + { + if (http_check_for_data()) + { ++#ifdef HTTP_SSL ++ if (mpg123_http_read_line(line, 1024, ssl_c)) ++#else + if (mpg123_http_read_line(line, 1024)) ++#endif + { + status = strchr(line, ' '); + if (status) +@@ -537,7 +650,11 @@ + { + if(http_check_for_data()) + { ++#ifdef HTTP_SSL ++ if((cnt = mpg123_http_read_line(line, 1024, ssl_c)) != -1) ++#else + if((cnt = mpg123_http_read_line(line, 1024)) != -1) ++#endif + { + if(!cnt) + break; +@@ -579,7 +696,11 @@ + { + if (http_check_for_data()) + { ++#ifdef HTTP_SSL ++ if ((cnt = mpg123_http_read_line(line, 1024, ssl_c)) != -1) ++#else + if ((cnt = mpg123_http_read_line(line, 1024)) != -1) ++#endif + { + if (!cnt) + break; +@@ -617,6 +738,10 @@ + fclose(output_file); + output_file = NULL; + } ++#ifdef HTTP_SSL ++ if (ssl) ++ SSL_shutdown(ssl_c); ++#endif + close(sock); + g_free(user); + g_free(pass); +@@ -634,6 +759,10 @@ + fname = file; + if (!strncasecmp(fname, "http://", 7)) + fname += 7; ++#ifdef HTTP_SSL ++ if (!strncasecmp(fname, "https://", 8)) ++ fname += 8; ++#endif + temp = strrchr(fname, '.'); + if (temp && !strcasecmp(temp, ".mp3")) + *temp = '\0'; +@@ -668,7 +797,12 @@ + cnt = min(http_free(), buffer_length - wr_index); + if (cnt > 1024) + cnt = 1024; +- written = read(sock, buffer + wr_index, cnt); ++#ifdef HTTP_SSL ++ if (ssl) ++ while ((written = SSL_read(ssl_c, buffer + wr_index, cnt)) == -1); ++ else ++#endif ++ written = read(sock, buffer + wr_index, cnt); + if (written <= 0) + { + eof = TRUE; +@@ -715,6 +849,10 @@ + fclose(output_file); + output_file = NULL; + } ++#ifdef HTTP_SSL ++ if (ssl) ++ SSL_shutdown(ssl_c); ++#endif + close(sock); + if (udp_sock != 0) + close(udp_sock); +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c +--- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:59:35.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-25 00:00:09.000000000 +0100 +@@ -317,7 +317,11 @@ + char *ext; + guint16 wavid; + ++#ifdef HTTP_SSL ++ if (!strncasecmp(filename, "http://", 7) || !strncasecmp(filename, "https://", 8)) ++#else + if (!strncasecmp(filename, "http://", 7)) ++#endif + { /* We assume all http:// (except those ending in .ogg) are mpeg -- why do we do that? */ + ext = strrchr(filename, '.'); + if (ext) +@@ -801,7 +805,11 @@ + /* + * TODO: Getting song info from http streams. + */ ++#ifdef HTTP_SSL ++ if (strncasecmp(filename, "http://", 7) && strncasecmp(filename, "https://", 8)) ++#else + if (strncasecmp(filename, "http://", 7)) ++#endif + { + if ((file = fopen(filename, "rb")) != NULL) + { +@@ -890,7 +898,12 @@ + mpg123_init_layer3(fr.down_sample_sblimit); + + mpg123_info->tpf = mpg123_compute_tpf(&fr); ++ ++#ifdef HTTP_SSL ++ if (strncasecmp(filename, "http://", 7) && strncasecmp(filename, "https://", 8)) ++#else + if (strncasecmp(filename, "http://", 7)) ++#endif + { + if (mpg123_stream_check_for_xing_header(&fr, &xing_header)) + { +@@ -937,7 +950,11 @@ + mpg123_mode = fr.mode; + mpg123_length = mpg123_info->num_frames * mpg123_info->tpf * 1000; + ++#ifdef HTTP_SSL ++ if (strncasecmp(filename, "http://", 7) && strncasecmp(filename, "https://", 8)) ++#else + if (strncasecmp(filename, "http://", 7)) ++#endif + { + if (!mpg123_title) + mpg123_title = get_song_title(NULL,filename); +@@ -1050,7 +1067,11 @@ + { + /* FIXME networks streams */ + disp_bitrate = mpg123_bitrate; ++#ifdef HTTP_SSL ++ if(!have_xing_header && strncasecmp(filename,"http://",7) && strncasecmp(filename, "https://", 8)) ++#else + if(!have_xing_header && strncasecmp(filename,"http://",7)) ++#endif + { + double rel = mpg123_relative_pos(); + if (rel) +diff -dPNur xmms-1.2.11/Input/vorbis/fileinfo.c xmms-1.2.11-new/Input/vorbis/fileinfo.c +--- xmms-1.2.11/Input/vorbis/fileinfo.c 2005-05-15 02:01:20.000000000 +0200 ++++ xmms-1.2.11-new/Input/vorbis/fileinfo.c 2007-11-25 00:00:09.000000000 +0100 +@@ -227,7 +227,12 @@ + vcedit_state *state; + vorbis_comment *comment; + ++#ifdef HTTP_SSL ++ if (!g_strncasecmp(vte.filename, "http://", 7) || ++ !g_strncasecmp(vte.filename, "https://", 8)) ++#else + if (!g_strncasecmp(vte.filename, "http://", 7)) ++#endif + return; + + state = vcedit_new_state(); +@@ -303,7 +308,12 @@ + vcedit_state *state; + vorbis_comment *comment; + ++#ifdef HTTP_SSL ++ if (!g_strncasecmp(vte.filename, "http://", 7) || ++ !g_strncasecmp(vte.filename, "https://", 8)) ++#else + if (!g_strncasecmp(vte.filename, "http://", 7)) ++#endif + return; + + state = vcedit_new_state(); +@@ -800,7 +810,12 @@ + } else + gdk_window_raise(window->window); + ++#ifdef HTTP_SSL ++ if (!g_strncasecmp(vte.filename, "http://", 7) || ++ !g_strncasecmp(vte.filename, "https://", 8)) ++#else + if (!g_strncasecmp(vte.filename, "http://", 7)) ++#endif + gtk_widget_set_sensitive(tag_frame, FALSE); + else + gtk_widget_set_sensitive(tag_frame, TRUE); +diff -dPNur xmms-1.2.11/Input/vorbis/http.c xmms-1.2.11-new/Input/vorbis/http.c +--- xmms-1.2.11/Input/vorbis/http.c 2007-11-16 22:51:24.000000000 +0100 ++++ xmms-1.2.11-new/Input/vorbis/http.c 2007-11-25 00:03:11.000000000 +0100 +@@ -39,6 +39,10 @@ + #include "xmms/plugin.h" + #include "xmms/i18n.h" + ++#ifdef HTTP_SSL ++#include ++#endif ++ + #define min(x,y) ((x)<(y)?(x):(y)) + #define min3(x,y,z) (min(x,y)<(z)?min(x,y):(z)) + #define min4(x,y,z,w) (min3(x,y,z)<(w)?min3(x,y,z):(w)) +@@ -116,7 +120,11 @@ + return res; + } + ++#ifdef HTTP_SSL ++static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename, int *ssl) ++#else + static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename) ++#endif + { + gchar *h, *p, *pt, *f, *temp, *ptr; + +@@ -125,6 +133,14 @@ + + if (!strncasecmp("http://", ptr, 7)) + ptr += 7; ++#ifdef HTTP_SSL ++ if (!strncasecmp("https://", ptr, 8)) { ++ ptr += 8; ++ *ssl = 1; ++ } else ++ *ssl = 0; ++#endif ++ + h = strchr(ptr, '@'); + f = strchr(ptr, '/'); + if (h != NULL && (!f || h < f)) +@@ -159,7 +175,12 @@ + { + if (f) + *f = '\0'; +- *port = 80; ++#ifdef HTTP_SSL ++ if (*ssl) ++ *port = 443; ++ else ++#endif ++ *port = 80; + } + *host = g_strdup(h); + +@@ -257,16 +278,27 @@ + return FALSE; + } + ++#ifdef HTTP_SSL ++gint vorbis_http_read_line(gchar * buf, gint size, SSL *ssl_c) ++#else + gint vorbis_http_read_line(gchar * buf, gint size) ++#endif + { +- gint i = 0; ++ gint i = 0, rc; + + while (going && i < size - 1) + { + if (http_check_for_data()) + { +- if (read(sock, buf + i, 1) <= 0) +- return -1; ++#ifdef HTTP_SSL ++ if (ssl_c) { ++ while ((rc = SSL_read(ssl_c, buf + i, 1)) == -1); ++ if (rc <= 0) ++ return -1; ++ } else ++#endif ++ if (read(sock, buf + i, 1) <= 0) ++ return -1; + if (buf[i] == '\n') + break; + if (buf[i] != '\r') +@@ -296,6 +328,12 @@ + struct sockaddr_in address; + #endif + struct timeval tv; ++#ifdef HTTP_SSL ++ SSL *ssl_c = NULL; ++ SSL_CTX *ssl_ctx = NULL; ++ BIO *b = NULL; ++ gint ssl=0; ++#endif + + url = (gchar *) arg; + do +@@ -304,7 +342,11 @@ + + g_strstrip(url); + ++#ifdef HTTP_SSL ++ parse_url(url, &user, &pass, &host, &port, &filename, &ssl); ++#else + parse_url(url, &user, &pass, &host, &port, &filename); ++#endif + + if ((!filename || !*filename) && url[strlen(url) - 1] != '/') + temp = g_strconcat(url, "/", NULL); +@@ -316,6 +358,26 @@ + chost = vorbis_cfg.use_proxy ? vorbis_cfg.proxy_host : host; + cport = vorbis_cfg.use_proxy ? vorbis_cfg.proxy_port : port; + ++#ifdef HTTP_SSL ++ if (ssl) { ++ SSL_library_init(); ++ OpenSSL_add_ssl_algorithms(); ++ SSL_load_error_strings(); ++ ++ ssl_ctx = SSL_CTX_new(SSLv23_client_method()); ++ if (ssl_ctx == NULL) { ++ fprintf(stderr, "SSL_CTX_new() failed."); ++ eof = TRUE; ++ } ++ ++ ssl_c = SSL_new(ssl_ctx); ++ if (ssl_c == NULL) { ++ fprintf(stderr, "SSL_new() failed.\n"); ++ eof = TRUE; ++ } ++ } ++#endif ++ + #ifdef USE_IPV6 + g_snprintf(service, 6, "%d", cport); + memset(&hints, 0, sizeof(hints)); +@@ -394,6 +456,18 @@ + eof = TRUE; + } + } ++#ifdef HTTP_SSL ++ if (ssl) { ++ b = BIO_new_socket(sock, BIO_NOCLOSE); ++ if (b == NULL) { ++ printf("BIO_new_socket() failed.\n"); ++ eof = TRUE; ++ } ++ ++ // cannot fail ++ SSL_set_bio(ssl_c, b, b); ++ } ++#endif + #endif + while (going) + { +@@ -419,6 +493,24 @@ + break; + } + } ++#ifdef HTTP_SSL ++ if (ssl) { ++ int rc; ++ ++ SSL_set_connect_state(ssl_c); ++ ++ while ((rc = SSL_connect(ssl_c)) == -1); ++ if (rc <= 0) { ++ fprintf(stderr, "SSL_connect() error. SSL error code: %d.\n", ++ SSL_get_error(ssl_c, rc)); ++ } ++ while ((rc = SSL_do_handshake(ssl_c)) == -1); ++ if (rc <= 0) { ++ fprintf(stderr, "SSL_do_handshake() error. SSL error code: %d.\n", ++ SSL_get_error(ssl_c, rc)); ++ } ++ } ++#endif + if (!eof) + { + gchar *auth = NULL, *proxy_auth = NULL; +@@ -449,14 +541,30 @@ + g_free(proxy_auth); + if(auth) + g_free(auth); +- write(sock, temp, strlen(temp)); ++#ifdef HTTP_SSL ++ if (ssl) { ++ int rc; ++ while ((rc = SSL_write(ssl_c, temp, strlen(temp))) == -1); ++ if (rc <= 0) { ++ fprintf(stderr, "SSL_write() error. SSL error code: %d.\n", ++ SSL_get_error(ssl_c, rc)); ++ eof = TRUE; ++ } ++ } else ++#endif ++ write(sock, temp, strlen(temp)); ++ + g_free(temp); + vorbis_ip.set_info_text(_("CONNECTED: WAITING FOR REPLY")); + while (going && !eof) + { + if (http_check_for_data()) + { ++#ifdef HTTP_SSL ++ if (vorbis_http_read_line(line, 1024, ssl_c)) ++#else + if (vorbis_http_read_line(line, 1024)) ++#endif + { + status = strchr(line, ' '); + if (status) +@@ -469,7 +577,11 @@ + { + if(http_check_for_data()) + { ++#ifdef HTTP_SSL ++ if((cnt = vorbis_http_read_line(line, 1024, ssl_c)) != -1) ++#else + if((cnt = vorbis_http_read_line(line, 1024)) != -1) ++#endif + { + if(!cnt) + break; +@@ -511,7 +623,11 @@ + { + if (http_check_for_data()) + { ++#ifdef HTTP_SSL ++ if ((cnt = vorbis_http_read_line(line, 1024, ssl_c)) != -1) ++#else + if ((cnt = vorbis_http_read_line(line, 1024)) != -1) ++#endif + { + if (!cnt) + break; +@@ -537,6 +653,10 @@ + fclose(output_file); + output_file = NULL; + } ++#ifdef HTTP_SSL ++ if (ssl) ++ SSL_shutdown(ssl_c); ++#endif + close(sock); + g_free(user); + g_free(pass); +@@ -554,6 +674,9 @@ + fname = file; + if (!strncasecmp(fname, "http://", 7)) + fname += 7; ++ if (!strncasecmp(fname, "https://", 8)) ++ fname += 8; ++ + temp = strrchr(fname, '.'); + if (temp && !strcasecmp(temp, ".ogg")) + *temp = '\0'; +@@ -588,7 +711,12 @@ + cnt = min(http_free(), buffer_length - wr_index); + if (cnt > 1024) + cnt = 1024; +- written = read(sock, buffer + wr_index, cnt); ++#ifdef HTTP_SSL ++ if (ssl) ++ while ((written = SSL_read(ssl_c, buffer + wr_index, cnt)) == -1); ++ else ++#endif ++ written = read(sock, buffer + wr_index, cnt); + if (written <= 0) + { + eof = TRUE; +@@ -629,6 +757,10 @@ + fclose(output_file); + output_file = NULL; + } ++#ifdef HTTP_SSL ++ if (ssl) ++ SSL_shutdown(ssl_c); ++#endif + close(sock); + + +diff -dPNur xmms-1.2.11/Input/vorbis/vorbis.c xmms-1.2.11-new/Input/vorbis/vorbis.c +--- xmms-1.2.11/Input/vorbis/vorbis.c 2006-07-16 15:40:04.000000000 +0200 ++++ xmms-1.2.11-new/Input/vorbis/vorbis.c 2007-11-25 00:00:09.000000000 +0100 +@@ -138,7 +138,12 @@ + char *ext; + + /* is this our http resource? */ ++#ifdef HTTP_SSL ++ if (strncasecmp(filename, "http://", 7) == 0 || ++ strncasecmp(filename, "https://", 8) == 0) { ++#else + if (strncasecmp(filename, "http://", 7) == 0) { ++#endif + ext = strrchr(filename, '.'); + if (ext) { + if (!strncasecmp(ext, ".ogg", 4)) { +@@ -332,7 +337,12 @@ + + memset(&vf, 0, sizeof(vf)); + ++#ifdef HTTP_SSL ++ if (strncasecmp("http://", filename, 7) && ++ strncasecmp("https://", filename, 8)) { ++#else + if (strncasecmp("http://", filename, 7) != 0) { ++#endif + /* file is a real file */ + if ((stream = fopen(filename, "r")) == NULL) { + vorbis_eos = TRUE; +@@ -536,7 +546,12 @@ + FILE *stream; + OggVorbis_File vf; /* avoid thread interaction */ + ++#ifdef HTTP_SSL ++ if (strncasecmp(filename, "http://", 7) && ++ strncasecmp(filename, "https://", 8)) { ++#else + if (strncasecmp(filename, "http://", 7)) { ++#endif + if ((stream = fopen(filename, "r")) == NULL) + return; + diff --git a/patches/xmms/ReadMe b/patches/xmms/ReadMe new file mode 100644 index 0000000..ef5082f --- /dev/null +++ b/patches/xmms/ReadMe @@ -0,0 +1,86 @@ +Prerequisites +------------- + The patched XMMS can be compiled without any additional dependency, + but to get recoding on you will need LibRCC (http://rusxmms.sf.net). + The LibRCC (Russian Charset Conversion Library) supports several + ways of encoding autodetection. To get this feature on the LibRCD, + Enca, db4 libraries should be installed prior to LibRCC compilation. + + Starting from version 0.2.0 LibRCC supports language autodetection using + aspell and language translation using libtranslate (the internet connection + is required). + + So, to get fully functional system, with multi-language playlist recoding, + you will need following libraries: + 1. LibRCD (http://rusxmms.sf.net) + 2. Enca + 3. DB4 (Brekley DB) + 4. LibXML2 + 5. LibRCC + To get language auto-detection: + 6. Aspell with dictionaries + To get language translation: + 7. Libtranslate + Internet Connection + +Compilation +----------- +1. Copy this folder as RusXMMS2 into the root of xmms source distribution + Run 'apply.sh' to get RusXMMS with ID3v2 enabled mpg123 + * Patches from Gentoo XMMS Distribution is used to provide ID3v2 + Custom: Just apply patches you need + * all files from source/*.[ch] should be copied into the + libxmms directory +2. Run 'aclocal && automake && autoconf' in the root of XMMS source tree in + order to regenerate Makefiles. +3. configure, compile and install as usual + +Patches +------- + xmms-ds-rusxmms: Base RusXMMS patch (required!) + xmms-ds-rusxmms-charset: UTF16/RCC for libxmms/charset.c. + * Required by Id3v2 tag editor. + xmms-ds-playlist: PlayList Recoding (Save/Load/Display) + * Recodes file names from playlist files + * Recodes titles from playlist files + * Recodes titles from plugins if AutoEngine enabled + xmms-ds-shade: Enables font selection for Shade Windows + * After applying the non-English titles will be + displayed correctly in the shade window + xmms-ds-textbox: Corrects UTF-8 displaying in xmms 'TextBox' + + xmms-ds-mpg123: Recodes mpg123 titles + editor: Enables editing of ID3 tags (v.1 and v.2) + keys: Enables fast keys + Esc, Enter: Cancel, Save and Exit + Ctrl+Left, Ctrl+Right: Navigate tabs + Ctrl+PgDn, Ctrl+PgUp: Navigate records + xmms-ds-vorbis-*: The same functionalities for vorbis plugin + ( No recoding patch is required ) + +Extra Patches +------------- + Some extra functionality, which is not included in default "apply.sh" + scripts and could be considered a bad or/and dangerous idea. + + xmms-ds-mpg123-wrongencoding.patch: + The ID3 v.2 defines 4 types of encodings: Latin1, UTF16, UTF16BE, UTF8. + Original version of XMMS assumes the tag broken if other encoding is + specified. This patch, assumes Latin1 for such encodings. + +Minimal Configurations: + xmms-ds-rusxmms + xmms-ds-playlist: + In the case then the autoengine is available, this solution will + give completely recoded playlist window. The recoding of plugins + will work as well. + xmms-ds-rusxmms + xmms-ds-mpg123(no editor and keys): + This solution will give completely recoded playlist even if no + autoengine is available, but playlists are unsupported. + +Notes +----- + * Edited ID3 tags and playlists will be saved in the corresponded + encodings selected using 'RusXMMS' preference page. + + +Project Page: http://rusxmms.sf.net +Author: Suren A. Chilingaryan diff --git a/patches/xmms/apply.sh b/patches/xmms/apply.sh new file mode 100755 index 0000000..69c4ea4 --- /dev/null +++ b/patches/xmms/apply.sh @@ -0,0 +1,50 @@ +#! /bin/bash + +TOP_DIR=`pwd | sed -e s/\\\/RusXMMS2$//` +if [ ! -d $TOP_DIR/RusXMMS2 ]; then + PATCH_DIR=$TOP_DIR/../ + if [ ! -d $PATCH_DIR/RusXMMS2 ]; then + exit 1 + fi +else + PATCH_DIR=$TOP_DIR +fi + +if [ ! -d $TOP_DIR/libxmms ]; then + exit 1 +fi + +echo "Patching: $TOP_DIR" + +cp $PATCH_DIR/RusXMMS2/source/* $TOP_DIR/libxmms/ + +# ID3 fixes +cat $PATCH_DIR/RusXMMS2/3rdparty/mpg123/*.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** gentoo mpg123 patches ***"; exit 1; fi + +# RusXMMS core +cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-rusxmms.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-rusxmms ***"; exit 1; fi +cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-rusxmms-charset.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-rusxmms-charset ***"; exit 1; fi + +# RusXMMS plugins +cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-mpg123.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-mpg123 ***"; exit 1; fi +cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-mpg123-editor.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-mpg123-editor ***"; exit 1; fi +cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-mpg123-editor-keys.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-mpg123-editor-keys ***"; exit 1; fi +cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-vorbis-editor.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-vorbis-editor ***"; exit 1; fi +cat $PATCH_DIR/RusXMMS2/patches/plugins/xmms-ds-vorbis-editor-keys.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-vorbis-editor-keys ***"; exit 1; fi + +# RusXMMS extra +cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-playlist.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-playlist ***"; exit 1; fi +cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-shade.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-shade ***"; exit 1; fi +cat $PATCH_DIR/RusXMMS2/patches/xmms-ds-textbox.patch | patch -d $TOP_DIR -p1 +if [ $? -ne 0 ]; then echo -e "\nFailed: *** xmms-ds-textbox ***"; exit 1; fi + diff --git a/patches/xmms/extra/xmms-ds-mpg123-wrongencoding.patch b/patches/xmms/extra/xmms-ds-mpg123-wrongencoding.patch deleted file mode 100644 index 66a2100..0000000 --- a/patches/xmms/extra/xmms-ds-mpg123-wrongencoding.patch +++ /dev/null @@ -1,157 +0,0 @@ -diff -dPNur xmms-1.2.11-orig/Input/mpg123/id3_frame_text.c xmms-1.2.11/Input/mpg123/id3_frame_text.c ---- xmms-1.2.11-orig/Input/mpg123/id3_frame_text.c 2008-04-11 15:44:34.000000000 +0200 -+++ xmms-1.2.11/Input/mpg123/id3_frame_text.c 2008-04-11 15:52:25.000000000 +0200 -@@ -46,6 +46,7 @@ - break; - case ID3_ENCODING_UTF16: - case ID3_ENCODING_UTF16BE: -+ case ID3_ENCODING_UTF16LE: - while (*text != 0 || *(text + 1) != 0) - { - text += 2; -@@ -73,6 +74,8 @@ - return xmms_charset_from_utf16(text); - case ID3_ENCODING_UTF16BE: - return xmms_charset_from_utf16be(text); -+ case ID3_ENCODING_UTF16LE: -+ return xmms_charset_from_utf16le(text); - default: - return NULL; - } -@@ -88,6 +91,8 @@ - */ - gint8 id3_get_encoding(struct id3_frame *frame) - { -+ gint8 encoding; -+ - /* Type check */ - if (!id3_frame_is_text(frame) && - frame->fr_desc->fd_id != ID3_WXXX && -@@ -106,7 +111,21 @@ - if (id3_decompress_frame(frame) == -1) - return -1; - -- return *(gint8 *) frame->fr_data; -+ encoding = *(gint8 *) frame->fr_data; -+ -+ switch (encoding) { -+ case ID3_ENCODING_ISO_8859_1: -+ case ID3_ENCODING_UTF8: -+ case ID3_ENCODING_UTF16: -+ case ID3_ENCODING_UTF16BE: -+ return encoding; -+ case ID3_ENCODING_UTF16LE: -+ printf("ID3V2 frame (%.4s) has invalid encoding (%u). Assuming UTF-16LE.\n", frame->fr_desc->fd_idstr?frame->fr_desc->fd_idstr:"UNKN", encoding); -+ return encoding; -+ default: -+ printf("ID3V2 frame (%.4s) has invalid encoding (%u). Assuming Latin1.\n", frame->fr_desc->fd_idstr?frame->fr_desc->fd_idstr:"UNKN", encoding); -+ return ID3_ENCODING_ISO_8859_1; -+ } - } - - -@@ -269,6 +288,7 @@ - else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); - else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); - else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); -+ else if (encoding == ID3_ENCODING_UTF16LE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16LE"); - else ctext = NULL; - - if (ctext) text = ctext; -@@ -433,6 +453,7 @@ - else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); - else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); - else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); -+ else if (encoding == ID3_ENCODING_UTF16LE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16LE"); - else ctext = NULL; - - if (ctext) text = ctext; -@@ -453,11 +474,12 @@ - *(gint8 *) frame->fr_raw_data = encoding; - memcpy((char*)frame->fr_raw_data + 1, xmms_rcc_get_language(), 3); - -- if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) { -+ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)||(encoding == ID3_ENCODING_UTF16LE)) { - int i; - lang = "Comments"; - if (encoding == ID3_ENCODING_UTF16) cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16"); -- else cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16BE"); -+ else if (encoding == ID3_ENCODING_UTF16BE) cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16BE"); -+ else cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16LE"); - memcpy((char *) frame->fr_raw_data + 4, cdata, 20); - g_free(cdata); - } else -diff -dPNur xmms-1.2.11-orig/Input/mpg123/id3.h xmms-1.2.11/Input/mpg123/id3.h ---- xmms-1.2.11-orig/Input/mpg123/id3.h 2008-04-11 15:44:34.000000000 +0200 -+++ xmms-1.2.11/Input/mpg123/id3.h 2008-04-11 15:50:58.000000000 +0200 -@@ -141,6 +141,7 @@ - #define ID3_ENCODING_UTF16 0x01 - #define ID3_ENCODING_UTF16BE 0x02 - #define ID3_ENCODING_UTF8 0x03 -+#define ID3_ENCODING_UTF16LE 0x04 - - /* - * ID3 frame id numbers. -@@ -312,7 +313,7 @@ - - - #define ID3_TEXT_FRAME_ENCODING(frame) \ -- (*(guint8*)(frame)->fr_data) -+ id3_get_encoding(frame) - - #define ID3_TEXT_FRAME_PTR(frame) \ - ((char *)(frame)->fr_data + 1) -diff -dPNur xmms-1.2.11-orig/libxmms/charset.c xmms-1.2.11/libxmms/charset.c ---- xmms-1.2.11-orig/libxmms/charset.c 2008-04-10 22:49:57.000000000 +0200 -+++ xmms-1.2.11/libxmms/charset.c 2008-04-11 15:50:21.000000000 +0200 -@@ -141,6 +141,14 @@ - return xmms_charset_convert(string, utf16_strlen(string), "UTF-16BE", NULL); - } - -+char *xmms_charset_from_utf16le(const unsigned char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return xmms_charset_convert(string, utf16_strlen(string), "UTF-16LE", NULL); -+} -+ - char* xmms_charset_from_latin1(const char *string) - { - char *cstring; -@@ -174,6 +182,9 @@ - if (!strcmp(from, "UTF-16BE") && !to) - return xmms_charset_from_utf16be(string); - -+ if (!strcmp(from, "UTF-16LE") && !to) -+ return xmms_charset_from_utf16le(string); -+ - return g_strdup(string); - } - -@@ -275,6 +286,14 @@ - return utf16_to_ascii(string, FALSE); - } - -+char *xmms_charset_from_utf16le(const unsigned char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return utf16_to_ascii(string, TRUE); -+} -+ - char* xmms_charset_from_latin1(const char *string) - { - char *cstring; -diff -dPNur xmms-1.2.11-orig/libxmms/charset.h xmms-1.2.11/libxmms/charset.h ---- xmms-1.2.11-orig/libxmms/charset.h 2008-04-10 22:49:57.000000000 +0200 -+++ xmms-1.2.11/libxmms/charset.h 2008-04-11 15:49:47.000000000 +0200 -@@ -14,6 +14,7 @@ - char* xmms_charset_from_utf8(const char *string); - char* xmms_charset_from_utf16(const unsigned char *string); - char* xmms_charset_from_utf16be(const unsigned char *string); -+char *xmms_charset_from_utf16le(const unsigned char *string); - char* xmms_charset_from_latin1(const char *string); - - size_t utf16_strlen(const char *string); diff --git a/patches/xmms/patches/extra/xmms-ds-mpg123-wrongencoding.patch b/patches/xmms/patches/extra/xmms-ds-mpg123-wrongencoding.patch new file mode 100644 index 0000000..66a2100 --- /dev/null +++ b/patches/xmms/patches/extra/xmms-ds-mpg123-wrongencoding.patch @@ -0,0 +1,157 @@ +diff -dPNur xmms-1.2.11-orig/Input/mpg123/id3_frame_text.c xmms-1.2.11/Input/mpg123/id3_frame_text.c +--- xmms-1.2.11-orig/Input/mpg123/id3_frame_text.c 2008-04-11 15:44:34.000000000 +0200 ++++ xmms-1.2.11/Input/mpg123/id3_frame_text.c 2008-04-11 15:52:25.000000000 +0200 +@@ -46,6 +46,7 @@ + break; + case ID3_ENCODING_UTF16: + case ID3_ENCODING_UTF16BE: ++ case ID3_ENCODING_UTF16LE: + while (*text != 0 || *(text + 1) != 0) + { + text += 2; +@@ -73,6 +74,8 @@ + return xmms_charset_from_utf16(text); + case ID3_ENCODING_UTF16BE: + return xmms_charset_from_utf16be(text); ++ case ID3_ENCODING_UTF16LE: ++ return xmms_charset_from_utf16le(text); + default: + return NULL; + } +@@ -88,6 +91,8 @@ + */ + gint8 id3_get_encoding(struct id3_frame *frame) + { ++ gint8 encoding; ++ + /* Type check */ + if (!id3_frame_is_text(frame) && + frame->fr_desc->fd_id != ID3_WXXX && +@@ -106,7 +111,21 @@ + if (id3_decompress_frame(frame) == -1) + return -1; + +- return *(gint8 *) frame->fr_data; ++ encoding = *(gint8 *) frame->fr_data; ++ ++ switch (encoding) { ++ case ID3_ENCODING_ISO_8859_1: ++ case ID3_ENCODING_UTF8: ++ case ID3_ENCODING_UTF16: ++ case ID3_ENCODING_UTF16BE: ++ return encoding; ++ case ID3_ENCODING_UTF16LE: ++ printf("ID3V2 frame (%.4s) has invalid encoding (%u). Assuming UTF-16LE.\n", frame->fr_desc->fd_idstr?frame->fr_desc->fd_idstr:"UNKN", encoding); ++ return encoding; ++ default: ++ printf("ID3V2 frame (%.4s) has invalid encoding (%u). Assuming Latin1.\n", frame->fr_desc->fd_idstr?frame->fr_desc->fd_idstr:"UNKN", encoding); ++ return ID3_ENCODING_ISO_8859_1; ++ } + } + + +@@ -269,6 +288,7 @@ + else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); + else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); + else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); ++ else if (encoding == ID3_ENCODING_UTF16LE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16LE"); + else ctext = NULL; + + if (ctext) text = ctext; +@@ -433,6 +453,7 @@ + else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); + else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); + else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); ++ else if (encoding == ID3_ENCODING_UTF16LE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16LE"); + else ctext = NULL; + + if (ctext) text = ctext; +@@ -453,11 +474,12 @@ + *(gint8 *) frame->fr_raw_data = encoding; + memcpy((char*)frame->fr_raw_data + 1, xmms_rcc_get_language(), 3); + +- if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) { ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)||(encoding == ID3_ENCODING_UTF16LE)) { + int i; + lang = "Comments"; + if (encoding == ID3_ENCODING_UTF16) cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16"); +- else cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16BE"); ++ else if (encoding == ID3_ENCODING_UTF16BE) cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16BE"); ++ else cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16LE"); + memcpy((char *) frame->fr_raw_data + 4, cdata, 20); + g_free(cdata); + } else +diff -dPNur xmms-1.2.11-orig/Input/mpg123/id3.h xmms-1.2.11/Input/mpg123/id3.h +--- xmms-1.2.11-orig/Input/mpg123/id3.h 2008-04-11 15:44:34.000000000 +0200 ++++ xmms-1.2.11/Input/mpg123/id3.h 2008-04-11 15:50:58.000000000 +0200 +@@ -141,6 +141,7 @@ + #define ID3_ENCODING_UTF16 0x01 + #define ID3_ENCODING_UTF16BE 0x02 + #define ID3_ENCODING_UTF8 0x03 ++#define ID3_ENCODING_UTF16LE 0x04 + + /* + * ID3 frame id numbers. +@@ -312,7 +313,7 @@ + + + #define ID3_TEXT_FRAME_ENCODING(frame) \ +- (*(guint8*)(frame)->fr_data) ++ id3_get_encoding(frame) + + #define ID3_TEXT_FRAME_PTR(frame) \ + ((char *)(frame)->fr_data + 1) +diff -dPNur xmms-1.2.11-orig/libxmms/charset.c xmms-1.2.11/libxmms/charset.c +--- xmms-1.2.11-orig/libxmms/charset.c 2008-04-10 22:49:57.000000000 +0200 ++++ xmms-1.2.11/libxmms/charset.c 2008-04-11 15:50:21.000000000 +0200 +@@ -141,6 +141,14 @@ + return xmms_charset_convert(string, utf16_strlen(string), "UTF-16BE", NULL); + } + ++char *xmms_charset_from_utf16le(const unsigned char *string) ++{ ++ if (!string) ++ return NULL; ++ ++ return xmms_charset_convert(string, utf16_strlen(string), "UTF-16LE", NULL); ++} ++ + char* xmms_charset_from_latin1(const char *string) + { + char *cstring; +@@ -174,6 +182,9 @@ + if (!strcmp(from, "UTF-16BE") && !to) + return xmms_charset_from_utf16be(string); + ++ if (!strcmp(from, "UTF-16LE") && !to) ++ return xmms_charset_from_utf16le(string); ++ + return g_strdup(string); + } + +@@ -275,6 +286,14 @@ + return utf16_to_ascii(string, FALSE); + } + ++char *xmms_charset_from_utf16le(const unsigned char *string) ++{ ++ if (!string) ++ return NULL; ++ ++ return utf16_to_ascii(string, TRUE); ++} ++ + char* xmms_charset_from_latin1(const char *string) + { + char *cstring; +diff -dPNur xmms-1.2.11-orig/libxmms/charset.h xmms-1.2.11/libxmms/charset.h +--- xmms-1.2.11-orig/libxmms/charset.h 2008-04-10 22:49:57.000000000 +0200 ++++ xmms-1.2.11/libxmms/charset.h 2008-04-11 15:49:47.000000000 +0200 +@@ -14,6 +14,7 @@ + char* xmms_charset_from_utf8(const char *string); + char* xmms_charset_from_utf16(const unsigned char *string); + char* xmms_charset_from_utf16be(const unsigned char *string); ++char *xmms_charset_from_utf16le(const unsigned char *string); + char* xmms_charset_from_latin1(const char *string); + + size_t utf16_strlen(const char *string); diff --git a/patches/xmms/patches/plugins/xmms-ds-mpg123-editor-keys.patch b/patches/xmms/patches/plugins/xmms-ds-mpg123-editor-keys.patch new file mode 100644 index 0000000..38a74e2 --- /dev/null +++ b/patches/xmms/patches/plugins/xmms-ds-mpg123-editor-keys.patch @@ -0,0 +1,164 @@ +diff -dPNur rusxmms-new/Input/mpg123/fileinfo.c rusxmms-new-keys/Input/mpg123/fileinfo.c +--- rusxmms-new/Input/mpg123/fileinfo.c 2005-07-17 11:46:05.000000000 +0200 ++++ rusxmms-new-keys/Input/mpg123/fileinfo.c 2005-07-18 01:12:36.000000000 +0200 +@@ -31,6 +31,10 @@ + #define MAX_STR_LEN 100 + #define MAX_ENTRY_LEN2 1023 + ++#include ++#include ++#include "../../xmms/xmms.h" ++ + static GtkWidget *window = NULL; + static GtkWidget *notebook = NULL; + static GtkWidget *filename_entry, *id3v1_frame, *id3v2_frame; +@@ -507,6 +511,106 @@ + gtk_widget_destroy(w); + } + ++static int restore_focus; ++static GtkWidget *save; ++ ++ ++static GtkWidget **widgets1[] = { &v1_title_entry, &v1_artist_entry, &v1_album_entry, &v1_comment_entry, &v1_year_entry, NULL }; ++static GtkWidget **widgets2[] = { &v2_title_entry, &v2_artist_entry, &v2_album_entry, &v2_comment_entry, &v2_year_entry, &v2_composer_entry, &v2_orig_artist_entry, &v2_url_entry, &v2_encoded_by_entry, NULL }; ++/* Info: gdktypes.h, gdkkeysyms.h */ ++gboolean mpg123_keypress_cb(GtkWidget * w, GdkEventKey * event, gpointer close) { ++ gint pos; ++ GtkWidget ***widgets, *widget, *focused; ++ ++ switch(event->keyval) { ++ case GDK_Return: ++ restore_focus=1; ++ gtk_signal_emit_by_name(GTK_OBJECT(save), "clicked", NULL); ++ gtk_signal_emit_by_name(GTK_OBJECT(close), "clicked", NULL); ++ return TRUE; ++ break; ++ case GDK_Escape: ++ restore_focus=1; ++ return TRUE; ++ break; ++ } ++ ++ if (event->state&GDK_CONTROL_MASK) { ++ switch(event->keyval) { ++ case GDK_Left: ++ gtk_notebook_prev_page(GTK_NOTEBOOK(notebook)); ++ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); ++ if (pos == 0) gtk_window_set_focus(GTK_WINDOW(window), *widgets2[0]); ++ else if (pos == 1) gtk_window_set_focus(GTK_WINDOW(window), *widgets1[0]); ++ gtk_window_activate_focus(GTK_WINDOW(window)); ++ return TRUE; ++ break; ++ case GDK_Right: ++ gtk_notebook_next_page(GTK_NOTEBOOK(notebook)); ++ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); ++ if (pos == 0) gtk_window_set_focus(GTK_WINDOW(window), *widgets2[0]); ++ else if (pos == 1) gtk_window_set_focus(GTK_WINDOW(window), *widgets1[0]); ++ gtk_window_activate_focus(GTK_WINDOW(window)); ++ return TRUE; ++ break; ++ } ++ } ++ { ++ switch(event->keyval) { ++ case GDK_Page_Up: ++ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); ++ ++ focused = GTK_WINDOW(window)->focus_widget; ++ if (pos == 1) widgets = widgets1; ++ else if (pos == 0) widgets = widgets2; ++ else return FALSE; ++ ++ for (pos = 0; widgets[pos]; pos++) { ++ if (focused == *widgets[pos]) { ++ if (pos == 0) { ++ while (widgets[pos+1]) pos++; ++ widget = *widgets[pos]; ++ } else widget = *widgets[pos - 1]; ++ ++ gtk_window_set_focus(GTK_WINDOW(window), widget); ++ return TRUE; ++ } ++ } ++ break; ++ case GDK_Page_Down: ++ case GDK_Tab: ++ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); ++ ++ focused = GTK_WINDOW(window)->focus_widget; ++ if (pos == 1) widgets = widgets1; ++ else if (pos == 0) widgets = widgets2; ++ else return FALSE; ++ ++ for (pos = 0; widgets[pos]; pos++) { ++ if (focused == *widgets[pos]) { ++ if (widgets[pos + 1]) widget = *widgets[pos + 1]; ++ else widget = *widgets[0]; ++ ++ gtk_window_set_focus(GTK_WINDOW(window), widget); ++ return TRUE; ++ } ++ } ++ ++ break; ++ } ++ } ++ ++ return FALSE; ++} ++ ++void gtk_widget_destroyed_focus(GtkWidget *widget, GtkWidget **widget_pointer) { ++ gtk_widget_destroyed(widget,widget_pointer); ++ if (restore_focus) { ++ gtk_widget_hide(playlistwin); ++ gtk_widget_show(playlistwin); ++ } ++} ++ + void mpg123_file_info_box(char *filename) + { + int i; +@@ -517,6 +621,8 @@ + const char *emphasis[4]; + const char *bool_label[2]; + ++ restore_focus = 0; ++ + emphasis[0] = _("None"); + emphasis[1] = _("50/15 ms"); + emphasis[2] = ""; +@@ -529,15 +635,16 @@ + GtkWidget *window_vbox, + *id3v1_vbox, *id3v2_vbox, *id3v1_frame_vbox, *id3v2_frame_vbox, + *mpeg_lvbox, *mpeg_rvbox, *mpeg_hbox, *mpeg_box, *mpeg_frame, +- *bbox, *save, *close, *copy_to, *copy_from, ++ *bbox, *close, *copy_to, *copy_from, + *table, *label, *filename_hbox; ++ GtkAccelGroup *ag; + + v1_labels_list = g_ptr_array_new(); + v2_labels_list = g_ptr_array_new(); + + window = gtk_window_new(GTK_WINDOW_DIALOG); +- gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window); +- gtk_signal_connect(GTK_OBJECT(window), "key_press_event", file_info_box_keypress_cb, NULL); ++ gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed_focus), &window); ++// gtk_signal_connect(GTK_OBJECT(window),"key_press_event",file_info_box_keypress_cb, NULL); + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + window_vbox = gtk_vbox_new(FALSE,10); +@@ -916,6 +1023,13 @@ + GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window)); + gtk_box_pack_start(GTK_BOX(bbox), close, TRUE, TRUE, 5); + ++ ag = gtk_accel_group_new(); ++ gtk_accel_group_add(ag, GDK_Escape, 0, 0, GTK_OBJECT(close), "clicked"); ++ gtk_accel_group_add(ag, GDK_Return, 0, 0, GTK_OBJECT(save), "clicked"); ++ gtk_window_add_accel_group(GTK_WINDOW(window), ag); ++ ++ gtk_signal_connect(GTK_OBJECT(window), "key_press_event", GTK_SIGNAL_FUNC(mpg123_keypress_cb), close); ++ + gtk_container_add(GTK_CONTAINER(window), window_vbox); + gtk_widget_show_all(window); + } diff --git a/patches/xmms/patches/plugins/xmms-ds-mpg123-editor.patch b/patches/xmms/patches/plugins/xmms-ds-mpg123-editor.patch new file mode 100644 index 0000000..a4afb70 --- /dev/null +++ b/patches/xmms/patches/plugins/xmms-ds-mpg123-editor.patch @@ -0,0 +1,202 @@ +diff -dPNur xmms-1.2.10/Input/mpg123/fileinfo.c xmms-1.2.10-new/Input/mpg123/fileinfo.c +--- rusxmms/Input/mpg123/fileinfo.c 2005-07-17 01:54:55.000000000 +0200 ++++ rusxmms-new/Input/mpg123/fileinfo.c 2005-07-17 11:46:05.000000000 +0200 +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include "mpg123.h" + +@@ -60,19 +61,33 @@ + + static void set_entry_tag_v1(GtkEntry * entry, const char * tag, int length) + { +- char *text = g_strchomp(g_strndup(tag, length)); ++ char *text; ++ ++ text = xmms_rcc_sized_recode(XMMS_RCC_ID3, XMMS_RCC_CTYPE, tag, length); ++ if (!text) text = g_strchomp(g_strndup(tag, length)); ++ + gtk_entry_set_text(entry, text); + g_free(text); + } + + static void get_entry_tag_v1(GtkEntry * entry, char * tag, int length) + { ++ gchar *ctext; ++ ++ ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_ID3, gtk_entry_get_text(entry)); ++ ++ if (ctext) { ++ strncpy(tag, ctext, length); ++ free(ctext); ++ } else + strncpy(tag, gtk_entry_get_text(entry), length); + } + + void copy_entry_tag_v1(GtkEntry * src, GtkEntry * dest, int length) + { +- set_entry_tag_v1(dest, gtk_entry_get_text(src), length); ++ char *text = g_strchomp(g_strndup(gtk_entry_get_text(src), length)); ++ gtk_entry_set_text(dest, text); ++ g_free(text); + return; + } + +@@ -497,6 +512,7 @@ + int i; + struct id3v1tag_t id3v1tag; + FILE *fh; ++ gchar *cfilename; + char *tmp, *title; + const char *emphasis[4]; + const char *bool_label[2]; +@@ -908,6 +924,9 @@ + g_free(current_filename); + current_filename = g_strdup(filename); + ++ cfilename = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_OUT, filename); ++ if (cfilename) filename=cfilename; ++ + title = g_strdup_printf(_("File Info - %s"), g_basename(filename)); + gtk_window_set_title(GTK_WINDOW(window), title); + g_free(title); +@@ -922,6 +941,8 @@ + gtk_entry_set_text(GTK_ENTRY(v2_title_entry), title); + g_free(title); + ++ if (cfilename) g_free(cfilename); ++ + gtk_entry_set_text(GTK_ENTRY(v1_artist_entry), ""); + gtk_entry_set_text(GTK_ENTRY(v1_album_entry), ""); + gtk_entry_set_text(GTK_ENTRY(v1_year_entry), ""); +diff -dPNur xmms-1.2.10/Input/mpg123/id3_frame_text.c xmms-1.2.10-new/Input/mpg123/id3_frame_text.c +--- xmms-1.2.10/Input/mpg123/id3_frame_text.c 2005-08-10 03:20:03.000000000 +0200 ++++ xmms-1.2.10-new/Input/mpg123/id3_frame_text.c 2005-08-10 03:29:40.000000000 +0200 +@@ -28,6 +28,7 @@ + #include "id3_header.h" + + #include "libxmms/charset.h" ++#include "libxmms/rcc.h" + + /* For extern mpg123_cfg */ + #include "mpg123.h" +@@ -247,6 +248,9 @@ + */ + int id3_set_text(struct id3_frame *frame, char *text) + { ++ char *ctext; ++ gint8 encoding; ++ + /* Type check */ + if (frame->fr_desc->fd_idstr[0] != 'T') + return -1; +@@ -256,18 +260,36 @@ + */ + id3_frame_clear_data(frame); + ++ ++ /* ++ * Recoding. ++ */ ++ encoding = (gint8)xmms_rcc_get_id3v2_encoding(); ++ if (encoding == ID3_ENCODING_ISO_8859_1) ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_ID3V2, text); ++ else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); ++ else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); ++ else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); ++ else ctext = NULL; ++ ++ if (ctext) text = ctext; ++ + /* + * Allocate memory for new data. + */ ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) ++ frame->fr_raw_size = utf16_strlen(text) + 2; ++ else + frame->fr_raw_size = strlen(text) + 1; + frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); + + /* + * Copy contents. + */ +- *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1; ++ *(gint8 *) frame->fr_raw_data = encoding; + memcpy((char *) frame->fr_raw_data + 1, text, frame->fr_raw_size); + ++ if (ctext) free(ctext); ++ + frame->fr_altered = 1; + frame->fr_owner->id3_altered = 1; + +@@ -389,7 +411,10 @@ + */ + int id3_set_comment(struct id3_frame *frame, char *text) + { ++ char *ctext, *cdata; ++ const char *lang; + int *intp; ++ gint8 encoding; + + /* Type check */ + if (frame->fr_desc->fd_id != ID3_COMM) +@@ -401,8 +426,23 @@ + id3_frame_clear_data(frame); + + /* ++ * Recoding. ++ */ ++ encoding = (gint8)xmms_rcc_get_id3v2_encoding(); ++ if (encoding == ID3_ENCODING_ISO_8859_1) ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_ID3V2, text); ++ else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); ++ else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); ++ else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); ++ else ctext = NULL; ++ ++ if (ctext) text = ctext; ++ ++ /* + * Allocate memory for new data. + */ ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) ++ frame->fr_raw_size = 25 + utf16_strlen(text); ++ else + frame->fr_raw_size = 13 + strlen(text); + frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); /* XXXComments\0<\0> + +@@ -410,18 +450,29 @@ + * block, so don't waste time with a calloc() + */ + +- ((guint8 *)frame->fr_raw_data)[0] = ID3_ENCODING_ISO_8859_1; +- ((guint8 *)frame->fr_raw_data)[1] = 0x58; +- ((guint8 *)frame->fr_raw_data)[2] = 0x58; +- ((guint8 *)frame->fr_raw_data)[3] = 0x58; ++ *(gint8 *) frame->fr_raw_data = encoding; ++ memcpy((char*)frame->fr_raw_data + 1, xmms_rcc_get_language(), 3); + ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) { ++ int i; ++ lang = "Comments"; ++ if (encoding == ID3_ENCODING_UTF16) cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16"); ++ else cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16BE"); ++ memcpy((char *) frame->fr_raw_data + 4, cdata, 20); ++ g_free(cdata); ++ } else + memcpy((char *) frame->fr_raw_data + 4, "Comments", 9); + + /* + * Copy contents. + */ ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) ++ memcpy((char *) frame->fr_raw_data + 24, text, utf16_strlen(text) + 2); ++ else + memcpy((char *) frame->fr_raw_data + 13, text, strlen(text) + 1); + ++ if (ctext) free(ctext); ++ + frame->fr_altered = 1; + frame->fr_owner->id3_altered = 1; + diff --git a/patches/xmms/patches/plugins/xmms-ds-mpg123.patch b/patches/xmms/patches/plugins/xmms-ds-mpg123.patch new file mode 100644 index 0000000..fc9c42e --- /dev/null +++ b/patches/xmms/patches/plugins/xmms-ds-mpg123.patch @@ -0,0 +1,20 @@ +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c +--- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-25 00:04:27.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-25 01:18:57.000000000 +0100 +@@ -3,6 +3,7 @@ + #include "libxmms/configfile.h" + #include "libxmms/titlestring.h" + #include "libxmms/charset.h" ++#include "libxmms/rcc.h" + #include + #include + #include +@@ -496,6 +497,8 @@ + /* + * Format according to filename. + */ ++ ret = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, g_basename(filename)); ++ if (!ret) + ret = g_strdup(g_basename(filename)); + if (extname(ret) != NULL) + *(extname(ret) - 1) = '\0'; /* removes period */ diff --git a/patches/xmms/patches/plugins/xmms-ds-vorbis-editor-keys.patch b/patches/xmms/patches/plugins/xmms-ds-vorbis-editor-keys.patch new file mode 100644 index 0000000..bf59951 --- /dev/null +++ b/patches/xmms/patches/plugins/xmms-ds-vorbis-editor-keys.patch @@ -0,0 +1,78 @@ +diff -dPNur xmms-1.2.11/Input/vorbis/fileinfo.c xmms-1.2.11-new/Input/vorbis/fileinfo.c +--- xmms-1.2.11/Input/vorbis/fileinfo.c 2007-11-25 01:23:31.000000000 +0100 ++++ xmms-1.2.11-new/Input/vorbis/fileinfo.c 2007-11-25 01:24:01.000000000 +0100 +@@ -39,6 +39,9 @@ + #include "libxmms/charset.h" + #include + ++#include "../../xmms/xmms.h" ++#include ++ + #include "vorbis.h" + #include "vcedit.h" + +@@ -444,6 +447,28 @@ + } + + /***********************************************************************/ ++static int restore_focus; ++ ++gboolean vorbis_keypress_cb(GtkWidget * w, GdkEventKey * event, gpointer save) { ++ switch(event->keyval) { ++ case GDK_Return: ++ restore_focus=1; ++ gtk_signal_emit_by_name(GTK_OBJECT(save), "clicked", NULL); ++ break; ++ case GDK_Escape: ++ restore_focus=1; ++ break; ++ } ++ return TRUE; ++} ++ ++void gtk_widget_destroyed_focus(GtkWidget *widget, GtkWidget **widget_pointer) { ++ gtk_widget_destroyed(widget,widget_pointer); ++ if (restore_focus) { ++ gtk_widget_hide(playlistwin); ++ gtk_widget_show(playlistwin); ++ } ++} + + void vorbis_file_info_box(char *fn) + { +@@ -465,6 +490,8 @@ + + g_free(vte.filename); + vte.filename = g_strdup(fn); ++ ++ restore_focus = 0; + + if (!window) + { +@@ -472,11 +499,12 @@ + GtkWidget *hbox, *label, *filename_hbox, *vbox, *left_vbox; + GtkWidget *table, *bbox, *cancel_button; + GtkWidget *save_button, *remove_button; ++ GtkAccelGroup *ag; + + 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_SIGNAL_FUNC(gtk_widget_destroyed_focus), &window); + gtk_signal_connect(GTK_OBJECT(window), "key_press_event", + keypress_cb, NULL); + gtk_container_set_border_width(GTK_CONTAINER(window), 10); +@@ -809,6 +837,12 @@ + FALSE, 0); + + gtk_widget_show_all(window); ++ ++ ag = gtk_accel_group_new(); ++ gtk_accel_group_add(ag, GDK_Escape, 0, 0, GTK_OBJECT(cancel_button), "clicked"); ++ gtk_accel_group_add(ag, GDK_Return, 0, 0, GTK_OBJECT(save_button), "clicked"); ++ gtk_window_add_accel_group(GTK_WINDOW(window), ag); ++ gtk_signal_connect(GTK_OBJECT(window),"key_press_event",GTK_SIGNAL_FUNC(vorbis_keypress_cb),save_button); + } else + gdk_window_raise(window->window); + diff --git a/patches/xmms/patches/plugins/xmms-ds-vorbis-editor.patch b/patches/xmms/patches/plugins/xmms-ds-vorbis-editor.patch new file mode 100644 index 0000000..47a7ba9 --- /dev/null +++ b/patches/xmms/patches/plugins/xmms-ds-vorbis-editor.patch @@ -0,0 +1,51 @@ +diff -dPNur xmms-1.2.11/Input/vorbis/fileinfo.c xmms-1.2.11-new/Input/vorbis/fileinfo.c +--- xmms-1.2.11/Input/vorbis/fileinfo.c 2007-11-25 00:04:27.000000000 +0100 ++++ xmms-1.2.11-new/Input/vorbis/fileinfo.c 2007-11-25 01:20:57.000000000 +0100 +@@ -34,6 +34,7 @@ + #include + #include + ++#include "libxmms/rcc.h" + #include "libxmms/util.h" + #include "libxmms/charset.h" + #include +@@ -451,6 +452,7 @@ + char *description, *version, *isrc, *copyright, *organization; + char *location, *vendor = "N/A"; + char *rg_track_gain, *rg_album_gain, *rg_track_peak, *rg_album_peak; ++ gchar *cfilename; + + int time, minutes, seconds, bitrate, avgbitrate, rate, channels; + int filesize, i; +@@ -931,6 +933,11 @@ + gtk_entry_set_text(GTK_ENTRY(isrc_entry), isrc); + gtk_entry_set_text(GTK_ENTRY(location_entry), location); + #endif ++ cfilename = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, vte.filename); ++ if (cfilename) { ++ gtk_entry_set_text(GTK_ENTRY(filename_entry), cfilename); ++ g_free(cfilename); ++ } else + gtk_entry_set_text(GTK_ENTRY(filename_entry), vte.filename); + gtk_editable_set_position(GTK_EDITABLE(filename_entry), -1); + +diff -dPNur xmms-1.2.11/Input/vorbis/vorbis.c xmms-1.2.11-new/Input/vorbis/vorbis.c +--- xmms-1.2.11/Input/vorbis/vorbis.c 2007-11-25 00:04:27.000000000 +0100 ++++ xmms-1.2.11-new/Input/vorbis/vorbis.c 2007-11-25 01:20:57.000000000 +0100 +@@ -46,6 +46,7 @@ + #include "xmms/plugin.h" + #include "libxmms/util.h" + #include "libxmms/configfile.h" ++#include "libxmms/rcc.h" + #include "libxmms/titlestring.h" + #include "libxmms/charset.h" + #include +@@ -754,6 +755,8 @@ + if (!vorbis_is_streaming) + { + char *tmp; ++ displaytitle = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_OUT, g_basename(fn)); ++ if (!displaytitle) + displaytitle = g_strdup(g_basename(fn)); + if ((tmp = strrchr(displaytitle, '.')) != NULL) + *tmp = '\0'; diff --git a/patches/xmms/patches/xmms-ds-playlist.patch b/patches/xmms/patches/xmms-ds-playlist.patch new file mode 100644 index 0000000..b72c8d0 --- /dev/null +++ b/patches/xmms/patches/xmms-ds-playlist.patch @@ -0,0 +1,526 @@ +diff -dPNur xmms-1.2.11/xmms/input.c xmms-1.2.11-new/xmms/input.c +--- xmms-1.2.11/xmms/input.c 2005-05-15 02:01:21.000000000 +0200 ++++ xmms-1.2.11-new/xmms/input.c 2008-10-27 18:14:08.000000000 +0100 +@@ -22,6 +22,7 @@ + #include "libxmms/titlestring.h" + #include "libxmms/util.h" + #include "libxmms/xentry.h" ++#include "libxmms/rcc.h" + + static pthread_mutex_t vis_mutex = PTHREAD_MUTEX_INITIALIZER; + +@@ -372,8 +373,12 @@ + + (*title) = xmms_get_titlestring(xmms_get_gentitle_format(), + input); +- if ( (*title) == NULL ) ++ if ( (*title) == NULL ) { ++ (*title) = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, input->file_name); ++ if (!*title) + (*title) = g_strdup(input->file_name); ++ } ++ + (*length) = -1; + g_free(temp); + g_free(input); +diff -dPNur xmms-1.2.11/xmms/main.c xmms-1.2.11-new/xmms/main.c +--- xmms-1.2.11/xmms/main.c 2006-07-16 15:40:04.000000000 +0200 ++++ xmms-1.2.11-new/xmms/main.c 2008-10-27 18:14:08.000000000 +0100 +@@ -36,6 +36,7 @@ + #include "libxmms/xmmsctrl.h" + #include "libxmms/util.h" + #include "libxmms/dirbrowser.h" ++#include "libxmms/rcc.h" + #include "xmms_mini.xpm" + + #define RANDTABLE_SIZE 128 +@@ -899,6 +900,7 @@ + gtk_timeout_remove(mainwin_timeout_tag); + util_set_cursor(NULL); + save_config(); ++ xmms_rcc_free(); + cleanup_ctrlsocket(); + playlist_stop_get_info_thread(); + playlist_clear(); +@@ -1036,8 +1038,14 @@ + + void mainwin_lock_info_text(char *text) + { ++ gchar *ctext; ++ ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_OUT, text); ++ if (ctext) text=ctext; ++ + mainwin_info_text_locked = TRUE; + textbox_set_text(mainwin_info, text); ++ ++ if (ctext) g_free(ctext); + } + + void mainwin_release_info_text(void) +@@ -1695,9 +1703,10 @@ + int match = 0; + char *title, *filename; + +- title = ((PlaylistEntry *) playlist->data)->title; +- filename = ((PlaylistEntry *) playlist->data)->filename; +- ++ title = playlist_check_entrytitle((PlaylistEntry *) playlist->data); ++ filename = xmms_rcc_get(XMMS_RCC_OUT, ((PlaylistEntry *) playlist->data)->fnstring); ++ if (!filename) filename = g_strdup(((PlaylistEntry *) playlist->data)->filename); ++ + if (title) + desc_buf[1] = title; + else if (strchr(filename, '/')) +@@ -1749,7 +1758,7 @@ + */ + match = mainwin_jump_to_file_match(song, words, nw); + } +- ++ + if (match) + { + int row, queue_pos, *data_buf; +@@ -1772,6 +1781,10 @@ + row_to_select = row; + } + ++ g_free(filename); ++ g_free(title); ++ ++ + songnr++; + playlist = playlist->next; + } +@@ -2072,8 +2085,10 @@ + int row, *data_buf; + char *title, *filename, *tmp_buf, *desc_buf[2]; + +- title = ((PlaylistEntry *) queue->data)->title; +- filename = ((PlaylistEntry *) queue->data)->filename; ++ title = playlist_check_entrytitle((PlaylistEntry *) queue->data); ++ filename = xmms_rcc_get(XMMS_RCC_OUT, ((PlaylistEntry *) queue->data)->fnstring); ++ if (!filename) filename = g_strdup(((PlaylistEntry *) queue->data)->filename); ++ + if (title) + desc_buf[1] = title; + else if (strchr(filename, '/')) +@@ -2086,6 +2101,9 @@ + row = gtk_clist_append(GTK_CLIST(qlist), desc_buf); + g_free(tmp_buf); + ++ g_free(filename); ++ g_free(title); ++ + data_buf = g_malloc(sizeof (int)); + *data_buf = pos; + gtk_clist_set_row_data_full(qlist, row, data_buf, g_free); +@@ -4217,6 +4235,7 @@ + #endif + + read_config(); ++ xmms_rcc_init(); + + #if defined(HAVE_SCHED_SETSCHEDULER) && defined(HAVE_SCHED_GET_PRIORITY_MAX) + if (cfg.use_realtime) +diff -dPNur xmms-1.2.11/xmms/playlist.c xmms-1.2.11-new/xmms/playlist.c +--- xmms-1.2.11/xmms/playlist.c 2007-11-16 22:51:30.000000000 +0100 ++++ xmms-1.2.11-new/xmms/playlist.c 2008-10-27 18:14:31.000000000 +0100 +@@ -20,6 +20,8 @@ + #include "xmms.h" + #include + #include "libxmms/util.h" ++#include ++#include "libxmms/rcc.h" + #include + #include + +@@ -91,6 +93,8 @@ + entry = node->data; + if (entry->filename) + g_free(entry->filename); ++ if (entry->fnstring) ++ g_free(entry->fnstring); + if (entry->title) + g_free(entry->title); + g_free(entry); +@@ -166,6 +170,8 @@ + + if (entry->filename) + g_free(entry->filename); ++ if (entry->fnstring) ++ g_free(entry->fnstring); + if (entry->title) + g_free(entry->title); + shuffle_list = g_list_remove(shuffle_list, entry); +@@ -280,9 +286,17 @@ + PlaylistEntry *entry; + + entry = g_malloc0(sizeof (PlaylistEntry)); ++ + entry->filename = g_strdup(filename); ++ entry->fnstring = xmms_rcc_put(XMMS_RCC_FS, filename); ++ if (!entry->fnstring) entry->fnstring = g_strdup(filename); ++ + if (title) ++ { ++ entry->title = xmms_rcc_put(XMMS_RCC_CTYPE, title); ++ if (!entry->title) + entry->title = g_strdup(title); ++ } + entry->length = len; + + PL_LOCK(); +@@ -624,6 +638,8 @@ + if (playlist_position) + { + g_free(playlist_position->title); ++ playlist_position->title = xmms_rcc_put(XMMS_RCC_CTYPE, title); ++ if (!playlist_position->title) + playlist_position->title = g_strdup(title); + playlist_position->length = length; + } +@@ -1015,6 +1031,7 @@ + char *playlist_get_info_text(void) + { + char *text, *title, *tmp, *numbers, *length; ++ char *ctitle; + + PL_LOCK(); + if (!playlist_position) +@@ -1023,10 +1040,20 @@ + return NULL; + } + +- if (playlist_position->title) ++ if (playlist_position->title) { ++ ctitle = xmms_rcc_get(XMMS_RCC_OUT, playlist_position->title); ++ if (ctitle) title = ctitle; ++ else + title = playlist_position->title; +- else ++ } else { ++ ctitle = xmms_rcc_get(XMMS_RCC_OUT, playlist_position->fnstring); ++ if (ctitle) { ++ title = g_strdup(g_basename(ctitle)); ++ g_free(ctitle); ++ ctitle = title; ++ } else + title = g_basename(playlist_position->filename); ++ } + + /* + * If the user don't want numbers in the playlist, don't +@@ -1048,6 +1075,7 @@ + text = g_strdup_printf("%s%s%s", numbers, title, length); + g_free(numbers); + g_free(length); ++ if (ctitle) g_free(ctitle); + + PL_UNLOCK(); + +@@ -1083,6 +1111,7 @@ + { + GList *node; + FILE *file; ++ gchar *ctitle, *cfn; + + if ((file = fopen(filename, "w")) == NULL) + return FALSE; +@@ -1101,10 +1130,12 @@ + while (node) + { + PlaylistEntry *entry = node->data; ++ if (!strstr(entry->filename,"://")) cfn = xmms_rcc_fs2pl(entry->fnstring, entry->filename); ++ else cfn=NULL; + if (is_pls) + fprintf(file, "File%d=%s\n", + g_list_position(playlist, node) + 1, +- entry->filename); ++ cfn?cfn:entry->filename); + else + { + if (entry->title && cfg.use_pl_metadata) +@@ -1116,11 +1147,14 @@ + else + seconds = -1; + ++ ctitle = xmms_rcc_get(XMMS_RCC_PL, entry->title); + fprintf(file, "#EXTINF:%d,%s\n", +- seconds, entry->title); ++ seconds, ctitle?ctitle:entry->title); ++ if (ctitle) g_free(ctitle); + } +- fprintf(file, "%s\n", entry->filename); ++ fprintf(file, "%s\n", cfn?cfn:entry->filename); + } ++ if (cfn) g_free(cfn); + node = g_list_next(node); + } + PL_UNLOCK(); +@@ -1151,16 +1185,32 @@ + *temp = '\0'; + else + { ++ if ((!strstr(filename,"://"))&&(!strstr(playlist_name, "://"))) { ++ temp = xmms_rcc_fs(XMMS_RCC_PLFS, XMMS_RCC_FS, NULL, NULL, filename); ++ if (temp) filename = temp; ++ } else temp = NULL; + __playlist_ins_with_info(filename, pos, title, len); ++ if (temp) g_free(temp); + return; + } ++ if ((!strstr(filename,"://"))&&(!strstr(playlist_name, "://"))) { ++ temp = xmms_rcc_fs(XMMS_RCC_PLFS, XMMS_RCC_FS, path, path, filename); ++ if (temp) filename = temp; ++ } else temp = NULL; ++ if (!temp) + temp = g_strdup_printf("%s/%s", path, filename); + __playlist_ins_with_info(temp, pos, title, len); + g_free(temp); + g_free(path); + } +- else ++ else { ++ if ((filename[0] == '/')&&(!strstr(playlist_name, "://"))) { ++ temp = xmms_rcc_fs(XMMS_RCC_PLFS, XMMS_RCC_FS, NULL, NULL, filename); ++ if (temp) filename = temp; ++ } else temp = NULL; + __playlist_ins_with_info(filename, pos, title, len); ++ if (temp) g_free(temp); ++ } + } + + static void parse_extm3u_info(char *info, char **title, int *length) +@@ -1182,6 +1232,10 @@ + *length *= 1000; + if ((str = strchr(info, ',')) != NULL) + { ++ if (*str) ++ while ((*(str+1)==' ')||(*(str+1)=='\t')) str++; /* g_strstrip removes leading and ending whitespaces */ ++ *title = xmms_rcc_put(XMMS_RCC_PL, str + 1); ++ if (!*title) + *title = g_strdup(str + 1); + g_strstrip(*title); + if (strlen(*title) < 1) +@@ -1210,7 +1264,7 @@ + line = read_ini_string(filename, "playlist", "NumberOfEntries"); + if (line == NULL) + return 0; +- ++ + noe = atoi(line); + g_free(line); + +@@ -1372,9 +1426,27 @@ + return ret; + } + ++gchar* playlist_check_entrytitle(PlaylistEntry *entry) { ++ gchar *title, *fn; ++ ++ if (!entry) return NULL; ++ ++ title = xmms_rcc_get(XMMS_RCC_OUT, entry->title); ++ if (!title) { ++ fn = xmms_rcc_get(XMMS_RCC_OUT, entry->fnstring); ++ if (fn) { ++ title = g_strdup(g_basename(fn)); ++ g_free(fn); ++ } else title = g_strdup(g_basename(entry->filename)); ++ } ++ ++ return title; ++} ++ + char * playlist_get_songtitle(int pos) + { + char *title = NULL, *filename; ++ char *ctitle; + PlaylistEntry *entry; + GList *node; + +@@ -1396,19 +1468,30 @@ + + if (entry->title == NULL && entry->length == -1) + { +- if (playlist_get_info_entry(entry)) ++ if (playlist_get_info_entry(entry)&&(entry->title)) { ++ title = xmms_rcc_get(XMMS_RCC_OUT, entry->title); ++ if (!title) + title = g_strdup(entry->title); ++ } + + PL_UNLOCK(); + } + else + { ++ title = xmms_rcc_get(XMMS_RCC_OUT, entry->title); ++ if (!title) + title = g_strdup(entry->title); + PL_UNLOCK(); + } + +- if (title == NULL) ++ if (title == NULL) { ++ ctitle = xmms_rcc_get(XMMS_RCC_OUT, entry->filename); ++ if (ctitle) { ++ title = g_strdup(g_basename(ctitle)); ++ g_free(ctitle); ++ } else + title = g_strdup(g_basename(filename)); ++ } + + g_free(filename); + +@@ -1453,36 +1536,41 @@ + + static int playlist_sort_by_title_cmpfunc(PlaylistEntry * a, PlaylistEntry * b) + { +- char *a_title, *b_title; ++ const char *a_title, *b_title; + + if (a->title) +- a_title = a->title; ++ a_title = xmms_rcc_string(a->title); + else + { +- if (strrchr(a->filename, '/')) +- a_title = strrchr(a->filename, '/') + 1; ++ if (strrchr(xmms_rcc_string(a->fnstring), '/')) ++ a_title = strrchr(xmms_rcc_string(a->fnstring), '/') + 1; + else +- a_title = a->filename; ++ a_title = xmms_rcc_string(a->filename); + } + + if (b->title) +- b_title = b->title; ++ b_title = xmms_rcc_string(b->title); + else + { +- if (strrchr(a->filename, '/')) +- b_title = strrchr(b->filename, '/') + 1; ++ if (strrchr(xmms_rcc_string(a->fnstring), '/')) ++ b_title = strrchr(xmms_rcc_string(b->fnstring), '/') + 1; + else +- b_title = b->filename; +- ++ b_title = xmms_rcc_string(b->filename); + } +- return strcasecmp(a_title, b_title); ++ return strcoll(a_title, b_title); + } + + void playlist_sort_by_title(void) + { ++ char *locale; ++ locale = setlocale(LC_COLLATE,"en_US.UTF-8"); ++ playlist_select_all(1); ++ playlist_read_info_selection(); ++ playlist_select_all(0); + PL_LOCK(); + playlist = g_list_sort(playlist, (GCompareFunc) playlist_sort_by_title_cmpfunc); + PL_UNLOCK(); ++ setlocale(LC_COLLATE,locale); + } + + static int playlist_sort_by_filename_cmpfunc(PlaylistEntry * a, PlaylistEntry * b) +@@ -1640,9 +1728,13 @@ + + void playlist_sort_selected_by_title(void) + { ++ char *locale; ++ locale = setlocale(LC_COLLATE,"en_US.UTF-8"); ++ playlist_read_info_selection(); + PL_LOCK(); + playlist = playlist_sort_selected(playlist, (GCompareFunc) playlist_sort_by_title_cmpfunc); + PL_UNLOCK(); ++ setlocale(LC_COLLATE,locale); + } + + void playlist_sort_selected_by_filename(void) +@@ -1859,6 +1951,8 @@ + return FALSE; + + /* entry is still around */ ++ entry->title = xmms_rcc_put(XMMS_RCC_CTYPE, temp_title); ++ if (!entry->title) + entry->title = temp_title; + entry->length = temp_length; + +diff -dPNur xmms-1.2.11/xmms/playlist.h xmms-1.2.11-new/xmms/playlist.h +--- xmms-1.2.11/xmms/playlist.h 2007-11-16 22:51:30.000000000 +0100 ++++ xmms-1.2.11-new/xmms/playlist.h 2008-10-27 18:14:08.000000000 +0100 +@@ -23,6 +23,7 @@ + typedef struct + { + gchar *filename; ++ gchar *fnstring; + gchar *title; + gint length; + gboolean selected; +@@ -86,6 +87,7 @@ + void playlist_fileinfo(gint pos); + void playlist_delete_index(glong index); + void playlist_delete_filenames(GList *filenames); ++gchar* playlist_check_entrytitle(PlaylistEntry *entry); + gchar* playlist_get_filename(gint pos); + gchar* playlist_get_songtitle(gint pos); + gint playlist_get_songtime(gint pos); +diff -dPNur xmms-1.2.11/xmms/playlist_list.c xmms-1.2.11-new/xmms/playlist_list.c +--- xmms-1.2.11/xmms/playlist_list.c 2003-06-11 20:44:17.000000000 +0200 ++++ xmms-1.2.11-new/xmms/playlist_list.c 2008-10-27 18:14:08.000000000 +0100 +@@ -451,10 +451,8 @@ + else + gdk_gc_set_foreground(gc, get_skin_color(SKIN_PLEDIT_NORMAL)); + +- if (entry->title) +- title = entry->title; +- else +- title = g_basename(entry->filename); ++ ++ title = playlist_check_entrytitle(entry); + + pos = playlist_get_queue_position(entry); + +@@ -497,6 +495,8 @@ + playlist_list_draw_string(pl, playlist_list_font, + i - pl->pl_first, tw, text); + g_free(text); ++ ++ g_free(title); + } + PL_UNLOCK(); + } +diff -dPNur xmms-1.2.11/xmms/prefswin.c xmms-1.2.11-new/xmms/prefswin.c +--- xmms-1.2.11/xmms/prefswin.c 2007-11-16 22:51:30.000000000 +0100 ++++ xmms-1.2.11-new/xmms/prefswin.c 2008-10-27 18:14:08.000000000 +0100 +@@ -18,6 +18,7 @@ + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + #include "xmms.h" ++#include "libxmms/rcc.h" + #include "libxmms/util.h" + #include "libxmms/titlestring.h" + +@@ -397,6 +398,8 @@ + draw_playlist_window(TRUE); + draw_equalizer_window(TRUE); + ++ xmms_rcc_prefswin_apply(); ++ + save_config(); + } + +@@ -1105,6 +1108,11 @@ + gtk_notebook_append_page(GTK_NOTEBOOK(prefswin_notebook), prefswin_fonts_vbox, gtk_label_new(_("Fonts"))); + + /* ++ * Coding Conversion page ++ */ ++ xmms_rcc_prefswin_create(prefswin_notebook); ++ ++ /* + * Title page + */ + prefswin_title_vbox = gtk_vbox_new(FALSE, 0); diff --git a/patches/xmms/patches/xmms-ds-rusxmms-charset.patch b/patches/xmms/patches/xmms-ds-rusxmms-charset.patch new file mode 100644 index 0000000..670f9e3 --- /dev/null +++ b/patches/xmms/patches/xmms-ds-rusxmms-charset.patch @@ -0,0 +1,87 @@ +diff -dPNur xmms-1.2.10/libxmms/charset.c xmms-1.2.10-new/libxmms/charset.c +--- xmms-1.2.10/libxmms/charset.c 2005-08-10 03:20:03.000000000 +0200 ++++ xmms-1.2.10-new/libxmms/charset.c 2005-08-10 02:54:12.000000000 +0200 +@@ -20,6 +20,7 @@ + #include + #endif + ++#include "rcc.h" + #include "charset.h" + + char* xmms_charset_get_current(void) +@@ -37,7 +38,7 @@ + return charset; + } + +-static size_t utf16_strlen(const char *string) ++size_t utf16_strlen(const char *string) + { + size_t len = 0; + +@@ -78,7 +79,7 @@ + /* + 1 for nul in case len == 1 */ + outsize = ((insize + 3) & ~3) + 1; + out = g_malloc(outsize); +- outleft = outsize - 1; ++ outleft = outsize - 2; + outptr = out; + + retry: +@@ -92,7 +93,7 @@ + outsize = (outsize - 1) * 2 + 1; + out = g_realloc(out, outsize); + outptr = out + used; +- outleft = outsize - 1 - used; ++ outleft = outsize - 2 - used; + goto retry; + case EINVAL: + break; +@@ -110,6 +111,7 @@ + } + } + *outptr = '\0'; ++ *(outptr+1) = '\0'; + + iconv_close(cd); + return out; +@@ -141,10 +143,14 @@ + + char* xmms_charset_from_latin1(const char *string) + { ++ char *cstring; + char *to = xmms_charset_get_current(); + + if (!string) + return NULL; ++ ++ cstring = xmms_rcc_recode(XMMS_RCC_ID3, XMMS_RCC_CTYPE, string); ++ if (cstring) return cstring; + + if (!strcmp(to, "UTF-8")) + return xmms_charset_convert(string, strlen(string), "ISO-8859-1", to); +@@ -271,9 +277,14 @@ + + char* xmms_charset_from_latin1(const char *string) + { ++ char *cstring; ++ + if (!string) + return NULL; + ++ cstring = xmms_rcc_recode(XMMS_RCC_ID3, XMMS_RCC_CTYPE, string); ++ if (cstring) return cstring; ++ + return g_strdup(string); + } + +diff -dPNur xmms-1.2.10/libxmms/charset.h xmms-1.2.10-new/libxmms/charset.h +--- xmms-1.2.10/libxmms/charset.h 2005-08-10 03:20:03.000000000 +0200 ++++ xmms-1.2.10-new/libxmms/charset.h 2005-08-10 01:41:01.000000000 +0200 +@@ -16,5 +16,7 @@ + char* xmms_charset_from_utf16be(const unsigned char *string); + char* xmms_charset_from_latin1(const char *string); + ++size_t utf16_strlen(const char *string); ++ + #endif /* XMMS_CHARSET_H */ + diff --git a/patches/xmms/patches/xmms-ds-rusxmms.patch b/patches/xmms/patches/xmms-ds-rusxmms.patch new file mode 100644 index 0000000..6b9287f --- /dev/null +++ b/patches/xmms/patches/xmms-ds-rusxmms.patch @@ -0,0 +1,172 @@ +diff -dPNur xmms-1.2.11/libxmms/configure.in xmms-1.2.11-new/libxmms/configure.in +--- xmms-1.2.11/libxmms/configure.in 2007-11-16 22:51:24.000000000 +0100 ++++ xmms-1.2.11-new/libxmms/configure.in 2007-11-25 17:38:56.000000000 +0100 +@@ -57,6 +57,16 @@ + AC_DEFINE([HAVE_CODESET],,[Define if nl_langinfo(CODESET) is available.]) + fi + ++AC_CHECK_LIB(rccgtk, rccUiInit,[ ++ AC_CHECK_HEADERS(librcc.h librccui.h,[ ++ LIBRCC_LIBS="-lrccgtk" ++ LIBRCC_INCLUDES="" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) + + AC_OUTPUT([ + Makefile +diff -dPNur xmms-1.2.11/libxmms/Makefile.am xmms-1.2.11-new/libxmms/Makefile.am +--- xmms-1.2.11/libxmms/Makefile.am 2004-04-04 10:51:20.000000000 +0200 ++++ xmms-1.2.11-new/libxmms/Makefile.am 2007-11-25 17:38:56.000000000 +0100 +@@ -4,10 +4,11 @@ + lib_LTLIBRARIES = libxmms.la + + libxmms_la_LDFLAGS = -export-dynamic -version-info $(LIBXMMS_MAJOR_VERSION):$(LIBXMMS_MINOR_VERSION):$(LIBXMMS_MICRO_VERSION) +-libxmms_la_LIBADD = @GTK_LIBS@ @POSIX_LIBS@ +-INCLUDES = @GTK_CFLAGS@ -I../intl -I.. ++libxmms_la_LIBADD = @LIBRCC_LIBS@ @GTK_LIBS@ @POSIX_LIBS@ ++INCLUDES = @LIBRCC_INCLUDES@ @GTK_CFLAGS@ -I../intl -I.. + + libxmms_la_SOURCES = \ ++rcc.c rcc.h rcc_langs.h \ + configfile.c configfile.h \ + xmmsctrl.c xmmsctrl.h \ + dirbrowser.c dirbrowser.h \ +diff -dPNur xmms-1.2.11/libxmms/titlestring.c xmms-1.2.11-new/libxmms/titlestring.c +--- xmms-1.2.11/libxmms/titlestring.c 2006-07-24 00:11:51.000000000 +0200 ++++ xmms-1.2.11-new/libxmms/titlestring.c 2007-11-25 17:39:21.000000000 +0100 +@@ -29,6 +29,7 @@ + #include + #include + ++#include "rcc.h" + #include "titlestring.h" + #include "../xmms/i18n.h" + +@@ -42,8 +43,9 @@ + PAD_SIDE_RIGHT, + }; + ++#define xmms_vputstr(out, pstr, pad) xmms_charset_vputstr(out, pstr, pad, from, pflag, c) + +-static int xmms_vputstr(GString *output, char *pstr, struct padding *pad) ++static int xmms_orig_vputstr(GString *output, char *pstr, struct padding *pad) + { + int i; + /* Lenght of the string that is actually printed */ +@@ -83,6 +85,22 @@ + return TRUE; + } + ++static int xmms_charset_vputstr(GString *output, char *pstr, struct padding *pad, int from, gint pflag, char c) { ++ int res; ++ gchar *cstring = NULL; ++ ++ if ((pflag&1)&&((c=='f')||(c=='F'))) { ++ cstring = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, pstr); ++ } ++ if ((pflag&2)&&((c=='a')||(c=='c')||(c=='g')||(c=='p')||(c=='t'))) { ++ cstring = xmms_rcc_recode((xmms_rcc_class)from, XMMS_RCC_CTYPE, pstr); ++ } ++ ++ res = xmms_orig_vputstr(output, cstring?cstring:pstr, pad); ++ if (cstring) g_free(cstring); ++ ++ return res; ++} + + static int xmms_vputnum(GString *output, int ival, struct padding *pad) + { +@@ -124,7 +142,7 @@ + return TRUE; + } + +-static int parse_variable(char **fmt, GString *string, TitleInput *input) ++static int parse_variable(char **fmt, GString *string, TitleInput *input, int from, gint pflag) + { + struct padding padding; + char *ptr = *fmt; +@@ -237,9 +255,33 @@ + return exp; + } + ++static int xmms_charset_analyze_fmt(gchar *fmt) { ++ int flag = 0; ++ ++ if (!fmt) return 0; ++ for (;*fmt;fmt++) { ++ while ((*fmt != '%')&&(*fmt != 0)) fmt++; ++ if (!*fmt) break; ++ while ((*fmt == '-')||(*fmt == ' ')||(*fmt == '0')) fmt++; ++ while (*fmt >= '0' && *fmt <= '9') fmt++; ++ if (*fmt == '.') { fmt++; while (*fmt >= '0' && *fmt <= '9') fmt++; } ++ if ((*fmt=='a')||(*fmt=='c')||(*fmt=='g')||(*fmt=='p')||(*fmt=='t')) flag|=1; ++ if ((*fmt=='f')||(*fmt=='F')) flag|=2; ++ } ++ ++ return flag; ++} ++ ++gchar *xmms_charset_get_titlestring(gchar *fmt, TitleInput *input, int from); + + char *xmms_get_titlestring(char *fmt, TitleInput *input) + { ++ return xmms_charset_get_titlestring(fmt, input, (xmms_rcc_class)-1); ++} ++ ++gchar *xmms_charset_get_titlestring(gchar *fmt, TitleInput *input, int from) { ++ gint pflag; ++ gchar *cstring = NULL; + int f_output = 0; + GString *string; + char *strptr; +@@ -249,12 +291,14 @@ + + string = g_string_new(""); + ++ pflag = (from == (xmms_rcc_class)-1)?0:xmms_charset_analyze_fmt(fmt); ++ + while (*fmt) + { + if (*fmt == '%') + { + fmt++; +- f_output += parse_variable(&fmt, string, input); ++ f_output += parse_variable(&fmt, string, input, from, pflag); + } + else + /* Normal character */ +@@ -271,6 +315,19 @@ + /* Return the result */ + strptr = string->str; + g_string_free(string, FALSE); ++ ++ if (pflag<3) { ++ if (pflag&2) ++ cstring = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, strptr); ++ else ++ cstring = xmms_rcc_recode((xmms_rcc_class)from, XMMS_RCC_CTYPE, strptr); ++ ++ if (cstring) { ++ g_free(strptr); ++ return cstring; ++ } ++ } ++ + return strptr; + } + +diff -dPNur xmms-1.2.11/libxmms/titlestring.h xmms-1.2.11-new/libxmms/titlestring.h +--- xmms-1.2.11/libxmms/titlestring.h 2005-05-15 02:01:20.000000000 +0200 ++++ xmms-1.2.11-new/libxmms/titlestring.h 2007-11-25 17:38:56.000000000 +0100 +@@ -77,6 +77,7 @@ + #endif + + gchar *xmms_get_titlestring(gchar *fmt, TitleInput *input); ++gchar *xmms_charset_get_titlestring(gchar *fmt, TitleInput *input, int from); + GtkWidget* xmms_titlestring_descriptions(char* tags, int rows); + + #ifdef __cplusplus diff --git a/patches/xmms/patches/xmms-ds-shade.patch b/patches/xmms/patches/xmms-ds-shade.patch new file mode 100644 index 0000000..41362df --- /dev/null +++ b/patches/xmms/patches/xmms-ds-shade.patch @@ -0,0 +1,194 @@ +diff -dPNur xmms-1.2.11/xmms/main.c xmms-1.2.11-new/xmms/main.c +--- xmms-1.2.11/xmms/main.c 2007-11-25 01:10:52.000000000 +0100 ++++ xmms-1.2.11-new/xmms/main.c 2007-11-25 01:11:13.000000000 +0100 +@@ -382,6 +382,8 @@ + + cfg.gentitle_format = NULL; + ++ cfg.shade_font = NULL; ++ + filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); + cfgfile = xmms_cfg_open_file(filename); + if (cfgfile) +@@ -481,6 +483,8 @@ + } + xmms_cfg_read_string(cfgfile, "xmms", "generic_title_format", &cfg.gentitle_format); + ++ xmms_cfg_read_string(cfgfile, "xmms", "shade_font", &cfg.shade_font); ++ + xmms_cfg_free(cfgfile); + } + +@@ -519,6 +523,13 @@ + if (cfg.eqpreset_extension == NULL) + cfg.eqpreset_extension = g_strdup("preset"); + ++ if (cfg.shade_font && strlen(cfg.shade_font) == 0) { ++ g_free(cfg.shade_font); ++ cfg.shade_font = NULL; ++ } ++ if (!cfg.shade_font) ++ cfg.shade_font = g_strdup("-misc-fixed-medium-r-*-*-7-*"); ++ + g_free(filename); + } + +@@ -677,6 +688,8 @@ + } + xmms_cfg_write_string(cfgfile, "xmms", "generic_title_format", cfg.gentitle_format); + ++ xmms_cfg_write_string(cfgfile, "xmms", "shade_font", cfg.shade_font); ++ + xmms_cfg_write_file(cfgfile, filename); + xmms_cfg_free(cfgfile); + +diff -dPNur xmms-1.2.11/xmms/main.h xmms-1.2.11-new/xmms/main.h +--- xmms-1.2.11/xmms/main.h 2006-07-16 15:40:04.000000000 +0200 ++++ xmms-1.2.11-new/xmms/main.h 2007-11-25 01:12:55.000000000 +0100 +@@ -60,6 +60,7 @@ + gint mouse_change; + gboolean playlist_transparent; + gchar *gentitle_format; ++ gchar *shade_font; + } + Config; + +diff -dPNur xmms-1.2.11/xmms/playlistwin.c xmms-1.2.11-new/xmms/playlistwin.c +--- xmms-1.2.11/xmms/playlistwin.c 2007-11-16 22:51:30.000000000 +0100 ++++ xmms-1.2.11-new/xmms/playlistwin.c 2007-11-25 01:11:13.000000000 +0100 +@@ -39,7 +39,8 @@ + PButton *playlistwin_shade, *playlistwin_close; + static PlaylistSlider *playlistwin_slider = NULL; + static TextBox *playlistwin_time_min, *playlistwin_time_sec; +-static TextBox *playlistwin_info, *playlistwin_sinfo; ++static TextBox *playlistwin_info; ++TextBox *playlistwin_sinfo; + static SButton *playlistwin_srew, *playlistwin_splay; + static SButton *playlistwin_spause, *playlistwin_sstop; + static SButton *playlistwin_sfwd, *playlistwin_seject; +@@ -1882,6 +1883,7 @@ + static void playlistwin_create_widgets(void) + { + playlistwin_sinfo = create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, 4, 4, cfg.playlist_width - 35, FALSE, SKIN_TEXT); ++ textbox_set_xfont(playlistwin_sinfo, cfg.mainwin_use_xfont, cfg.shade_font); + if (!cfg.playlist_shaded) + hide_widget(playlistwin_sinfo); + if (cfg.playlist_shaded) +diff -dPNur xmms-1.2.11/xmms/prefswin.c xmms-1.2.11-new/xmms/prefswin.c +--- xmms-1.2.11/xmms/prefswin.c 2007-11-25 01:10:52.000000000 +0100 ++++ xmms-1.2.11-new/xmms/prefswin.c 2007-11-25 01:11:13.000000000 +0100 +@@ -35,6 +35,7 @@ + + static GtkWidget *prefswin_options_sd_entry, *prefswin_options_pbs_entry; + ++static GtkWidget *prefswin_shade_font_entry, *prefswin_shade_font_browse; + static GtkWidget *prefswin_options_font_entry, *prefswin_options_font_browse; + static GtkWidget *prefswin_options_fontset, *prefswin_mainwin_font_entry; + static GtkWidget *prefswin_mainwin_xfont, *prefswin_options_mouse_spin; +@@ -48,6 +49,7 @@ + extern PButton *playlistwin_shade, *playlistwin_close, *equalizerwin_close; + extern PButton *mainwin_menubtn, *mainwin_minimize, *mainwin_shade, *mainwin_close; + extern TextBox *mainwin_info; ++extern TextBox *playlistwin_sinfo; + extern gboolean mainwin_focus, equalizerwin_focus, playlistwin_focus; + + static gboolean is_opening = FALSE; +@@ -343,11 +345,13 @@ + gboolean show_wm_old = cfg.show_wm_decorations; + g_free(cfg.playlist_font); + g_free(cfg.mainwin_font); ++ g_free(cfg.shade_font); + g_free(cfg.gentitle_format); + prefswin_options_write_data(); + cfg.snap_distance = CLAMP(atoi(gtk_entry_get_text(GTK_ENTRY(prefswin_options_sd_entry))), 0, 1000); + cfg.playlist_font = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_options_font_entry))); + cfg.mainwin_font = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_mainwin_font_entry))); ++ cfg.shade_font = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_shade_font_entry))); + cfg.gentitle_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_title_entry))); + cfg.pause_between_songs_time = CLAMP(atoi(gtk_entry_get_text(GTK_ENTRY(prefswin_options_pbs_entry))), 0, 1000); + cfg.mouse_change = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(prefswin_options_mouse_spin)); +@@ -390,6 +394,7 @@ + prefswin_toggle_wm_decorations(); + + textbox_set_xfont(mainwin_info, cfg.mainwin_use_xfont, cfg.mainwin_font); ++ textbox_set_xfont(playlistwin_sinfo, cfg.mainwin_use_xfont, cfg.shade_font); + playlist_list_set_font(cfg.playlist_font); + playlistwin_update_list(); + mainwin_set_info_text(); +@@ -475,6 +480,34 @@ + } + } + ++void prefswin_shade_font_browse_ok(GtkWidget * w, gpointer data) ++{ ++ GtkFontSelectionDialog *fontsel = GTK_FONT_SELECTION_DIALOG(data); ++ gchar *fontname; ++ ++ fontname = gtk_font_selection_dialog_get_font_name(fontsel); ++ ++ if (fontname) ++ gtk_entry_set_text(GTK_ENTRY(prefswin_shade_font_entry), fontname); ++ ++ gtk_widget_destroy(GTK_WIDGET(fontsel)); ++} ++ ++void prefswin_shade_font_browse_cb(GtkWidget * w, gpointer data) ++{ ++ static GtkWidget *fontsel; ++ ++ if (fontsel != NULL) ++ return; ++ ++ fontsel = gtk_font_selection_dialog_new(_("Select playlist font:")); ++ gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(fontsel), gtk_entry_get_text(GTK_ENTRY(prefswin_shade_font_entry))); ++ gtk_signal_connect(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->ok_button), "clicked", GTK_SIGNAL_FUNC(prefswin_shade_font_browse_ok), fontsel); ++ gtk_signal_connect_object(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(fontsel)); ++ gtk_signal_connect(GTK_OBJECT(fontsel), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &fontsel); ++ gtk_widget_show(fontsel); ++} ++ + void prefswin_gplugins_use_cb(GtkToggleButton * w, gpointer data) + { + gint sel; +@@ -693,7 +726,10 @@ + GtkWidget *prefswin_vplugins_box, *prefswin_vplugins_vbox; + GtkWidget *prefswin_vplugins_frame, *prefswin_vplugins_hbox; + GtkWidget *prefswin_vplugins_hbbox; +- ++ ++ GtkWidget *prefswin_fonts_shade_frame; ++ GtkWidget *options_font_shade_hbox, *options_font_shade_vbox; ++ + GtkWidget *prefswin_options_frame, *prefswin_options_vbox; + GtkWidget *prefswin_mainwin_frame, *prefswin_mainwin_vbox; + GtkWidget *prefswin_fonts_vbox, *prefswin_fonts_playlist_frame; +@@ -1105,6 +1141,21 @@ + gtk_widget_set_usize(prefswin_mainwin_font_browse, 85, 17); + gtk_box_pack_start(GTK_BOX(prefswin_mainwin_font_hbox), prefswin_mainwin_font_browse, FALSE, TRUE, 0); + ++ prefswin_fonts_shade_frame = gtk_frame_new(_("Shade")); ++ gtk_container_set_border_width(GTK_CONTAINER(prefswin_fonts_shade_frame), 5); ++ gtk_box_pack_start(GTK_BOX(prefswin_fonts_vbox), prefswin_fonts_shade_frame, FALSE, FALSE, 0); ++ options_font_shade_vbox = gtk_vbox_new(FALSE, 5); ++ gtk_container_border_width(GTK_CONTAINER(options_font_shade_vbox), 5); ++ gtk_container_add(GTK_CONTAINER(prefswin_fonts_shade_frame), options_font_shade_vbox); ++ options_font_shade_hbox = gtk_hbox_new(FALSE, 5); ++ gtk_box_pack_start_defaults(GTK_BOX(options_font_shade_vbox), options_font_shade_hbox); ++ prefswin_shade_font_entry = gtk_entry_new(); ++ gtk_box_pack_start(GTK_BOX(options_font_shade_hbox), prefswin_shade_font_entry, TRUE, TRUE, 0); ++ prefswin_shade_font_browse = gtk_button_new_with_label(_("Browse")); ++ gtk_signal_connect(GTK_OBJECT(prefswin_shade_font_browse), "clicked", GTK_SIGNAL_FUNC(prefswin_shade_font_browse_cb), NULL); ++ gtk_widget_set_usize(prefswin_shade_font_browse, 85, 17); ++ gtk_box_pack_start(GTK_BOX(options_font_shade_hbox), prefswin_shade_font_browse, FALSE, TRUE, 0); ++ + gtk_notebook_append_page(GTK_NOTEBOOK(prefswin_notebook), prefswin_fonts_vbox, gtk_label_new(_("Fonts"))); + + /* +@@ -1390,6 +1441,7 @@ + + gtk_entry_set_text(GTK_ENTRY(prefswin_options_font_entry), cfg.playlist_font); + gtk_entry_set_text(GTK_ENTRY(prefswin_mainwin_font_entry), cfg.mainwin_font); ++ gtk_entry_set_text(GTK_ENTRY(prefswin_shade_font_entry), cfg.shade_font); + gtk_entry_set_text(GTK_ENTRY(prefswin_title_entry), cfg.gentitle_format); + sprintf(temp, "%u", cfg.snap_distance); + gtk_entry_set_text(GTK_ENTRY(prefswin_options_sd_entry), temp); diff --git a/patches/xmms/patches/xmms-ds-textbox.patch b/patches/xmms/patches/xmms-ds-textbox.patch new file mode 100644 index 0000000..8442606 --- /dev/null +++ b/patches/xmms/patches/xmms-ds-textbox.patch @@ -0,0 +1,31 @@ +diff -dPNur xmms-1.2.10/xmms/textbox.c xmms-1.2.10-patched/xmms/textbox.c +--- xmms-1.2.10/xmms/textbox.c 2001-12-01 18:00:51.000000000 +0100 ++++ xmms-1.2.10-patched/xmms/textbox.c 2005-06-02 22:43:42.000000000 +0200 +@@ -166,6 +166,8 @@ + GdkGC *gc, *maskgc; + GdkColor *c, pattern; + GdkBitmap *mask; ++ GdkWChar *wtext; ++ int len; + + length = strlen(pixmaptext); + +@@ -192,6 +194,18 @@ + tb->tb_pixmap_width, tb->tb_widget.height); + pattern.pixel = 1; + gdk_gc_set_foreground(maskgc, &pattern); ++ if (cfg.use_fontsets) { ++ wtext = g_malloc((length + 1) * sizeof(GdkWChar)); ++ len = gdk_mbstowcs(wtext, pixmaptext, length + 1); ++ if (len == -1) { ++ for (len = 0; pixmaptext[len] != '\0'; len++) ++ wtext[len] = pixmaptext[len]; ++ } ++ wtext[len] = L'\0'; ++ gdk_draw_text_wc(mask,tb->tb_font, maskgc, 0, tb->tb_font->ascent, wtext, len ); ++ g_free(wtext); ++ } ++ else + gdk_draw_text(mask, tb->tb_font, maskgc, 0, + tb->tb_font->ascent, pixmaptext, length); + gdk_gc_unref(maskgc); diff --git a/patches/xmms/plugins/xmms-ds-mpg123-editor-keys.patch b/patches/xmms/plugins/xmms-ds-mpg123-editor-keys.patch deleted file mode 100644 index 38a74e2..0000000 --- a/patches/xmms/plugins/xmms-ds-mpg123-editor-keys.patch +++ /dev/null @@ -1,164 +0,0 @@ -diff -dPNur rusxmms-new/Input/mpg123/fileinfo.c rusxmms-new-keys/Input/mpg123/fileinfo.c ---- rusxmms-new/Input/mpg123/fileinfo.c 2005-07-17 11:46:05.000000000 +0200 -+++ rusxmms-new-keys/Input/mpg123/fileinfo.c 2005-07-18 01:12:36.000000000 +0200 -@@ -31,6 +31,10 @@ - #define MAX_STR_LEN 100 - #define MAX_ENTRY_LEN2 1023 - -+#include -+#include -+#include "../../xmms/xmms.h" -+ - static GtkWidget *window = NULL; - static GtkWidget *notebook = NULL; - static GtkWidget *filename_entry, *id3v1_frame, *id3v2_frame; -@@ -507,6 +511,106 @@ - gtk_widget_destroy(w); - } - -+static int restore_focus; -+static GtkWidget *save; -+ -+ -+static GtkWidget **widgets1[] = { &v1_title_entry, &v1_artist_entry, &v1_album_entry, &v1_comment_entry, &v1_year_entry, NULL }; -+static GtkWidget **widgets2[] = { &v2_title_entry, &v2_artist_entry, &v2_album_entry, &v2_comment_entry, &v2_year_entry, &v2_composer_entry, &v2_orig_artist_entry, &v2_url_entry, &v2_encoded_by_entry, NULL }; -+/* Info: gdktypes.h, gdkkeysyms.h */ -+gboolean mpg123_keypress_cb(GtkWidget * w, GdkEventKey * event, gpointer close) { -+ gint pos; -+ GtkWidget ***widgets, *widget, *focused; -+ -+ switch(event->keyval) { -+ case GDK_Return: -+ restore_focus=1; -+ gtk_signal_emit_by_name(GTK_OBJECT(save), "clicked", NULL); -+ gtk_signal_emit_by_name(GTK_OBJECT(close), "clicked", NULL); -+ return TRUE; -+ break; -+ case GDK_Escape: -+ restore_focus=1; -+ return TRUE; -+ break; -+ } -+ -+ if (event->state&GDK_CONTROL_MASK) { -+ switch(event->keyval) { -+ case GDK_Left: -+ gtk_notebook_prev_page(GTK_NOTEBOOK(notebook)); -+ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); -+ if (pos == 0) gtk_window_set_focus(GTK_WINDOW(window), *widgets2[0]); -+ else if (pos == 1) gtk_window_set_focus(GTK_WINDOW(window), *widgets1[0]); -+ gtk_window_activate_focus(GTK_WINDOW(window)); -+ return TRUE; -+ break; -+ case GDK_Right: -+ gtk_notebook_next_page(GTK_NOTEBOOK(notebook)); -+ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); -+ if (pos == 0) gtk_window_set_focus(GTK_WINDOW(window), *widgets2[0]); -+ else if (pos == 1) gtk_window_set_focus(GTK_WINDOW(window), *widgets1[0]); -+ gtk_window_activate_focus(GTK_WINDOW(window)); -+ return TRUE; -+ break; -+ } -+ } -+ { -+ switch(event->keyval) { -+ case GDK_Page_Up: -+ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); -+ -+ focused = GTK_WINDOW(window)->focus_widget; -+ if (pos == 1) widgets = widgets1; -+ else if (pos == 0) widgets = widgets2; -+ else return FALSE; -+ -+ for (pos = 0; widgets[pos]; pos++) { -+ if (focused == *widgets[pos]) { -+ if (pos == 0) { -+ while (widgets[pos+1]) pos++; -+ widget = *widgets[pos]; -+ } else widget = *widgets[pos - 1]; -+ -+ gtk_window_set_focus(GTK_WINDOW(window), widget); -+ return TRUE; -+ } -+ } -+ break; -+ case GDK_Page_Down: -+ case GDK_Tab: -+ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); -+ -+ focused = GTK_WINDOW(window)->focus_widget; -+ if (pos == 1) widgets = widgets1; -+ else if (pos == 0) widgets = widgets2; -+ else return FALSE; -+ -+ for (pos = 0; widgets[pos]; pos++) { -+ if (focused == *widgets[pos]) { -+ if (widgets[pos + 1]) widget = *widgets[pos + 1]; -+ else widget = *widgets[0]; -+ -+ gtk_window_set_focus(GTK_WINDOW(window), widget); -+ return TRUE; -+ } -+ } -+ -+ break; -+ } -+ } -+ -+ return FALSE; -+} -+ -+void gtk_widget_destroyed_focus(GtkWidget *widget, GtkWidget **widget_pointer) { -+ gtk_widget_destroyed(widget,widget_pointer); -+ if (restore_focus) { -+ gtk_widget_hide(playlistwin); -+ gtk_widget_show(playlistwin); -+ } -+} -+ - void mpg123_file_info_box(char *filename) - { - int i; -@@ -517,6 +621,8 @@ - const char *emphasis[4]; - const char *bool_label[2]; - -+ restore_focus = 0; -+ - emphasis[0] = _("None"); - emphasis[1] = _("50/15 ms"); - emphasis[2] = ""; -@@ -529,15 +635,16 @@ - GtkWidget *window_vbox, - *id3v1_vbox, *id3v2_vbox, *id3v1_frame_vbox, *id3v2_frame_vbox, - *mpeg_lvbox, *mpeg_rvbox, *mpeg_hbox, *mpeg_box, *mpeg_frame, -- *bbox, *save, *close, *copy_to, *copy_from, -+ *bbox, *close, *copy_to, *copy_from, - *table, *label, *filename_hbox; -+ GtkAccelGroup *ag; - - v1_labels_list = g_ptr_array_new(); - v2_labels_list = g_ptr_array_new(); - - window = gtk_window_new(GTK_WINDOW_DIALOG); -- gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window); -- gtk_signal_connect(GTK_OBJECT(window), "key_press_event", file_info_box_keypress_cb, NULL); -+ gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed_focus), &window); -+// gtk_signal_connect(GTK_OBJECT(window),"key_press_event",file_info_box_keypress_cb, NULL); - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - - window_vbox = gtk_vbox_new(FALSE,10); -@@ -916,6 +1023,13 @@ - GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window)); - gtk_box_pack_start(GTK_BOX(bbox), close, TRUE, TRUE, 5); - -+ ag = gtk_accel_group_new(); -+ gtk_accel_group_add(ag, GDK_Escape, 0, 0, GTK_OBJECT(close), "clicked"); -+ gtk_accel_group_add(ag, GDK_Return, 0, 0, GTK_OBJECT(save), "clicked"); -+ gtk_window_add_accel_group(GTK_WINDOW(window), ag); -+ -+ gtk_signal_connect(GTK_OBJECT(window), "key_press_event", GTK_SIGNAL_FUNC(mpg123_keypress_cb), close); -+ - gtk_container_add(GTK_CONTAINER(window), window_vbox); - gtk_widget_show_all(window); - } diff --git a/patches/xmms/plugins/xmms-ds-mpg123-editor.patch b/patches/xmms/plugins/xmms-ds-mpg123-editor.patch deleted file mode 100644 index a4afb70..0000000 --- a/patches/xmms/plugins/xmms-ds-mpg123-editor.patch +++ /dev/null @@ -1,202 +0,0 @@ -diff -dPNur xmms-1.2.10/Input/mpg123/fileinfo.c xmms-1.2.10-new/Input/mpg123/fileinfo.c ---- rusxmms/Input/mpg123/fileinfo.c 2005-07-17 01:54:55.000000000 +0200 -+++ rusxmms-new/Input/mpg123/fileinfo.c 2005-07-17 11:46:05.000000000 +0200 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include "mpg123.h" - -@@ -60,19 +61,33 @@ - - static void set_entry_tag_v1(GtkEntry * entry, const char * tag, int length) - { -- char *text = g_strchomp(g_strndup(tag, length)); -+ char *text; -+ -+ text = xmms_rcc_sized_recode(XMMS_RCC_ID3, XMMS_RCC_CTYPE, tag, length); -+ if (!text) text = g_strchomp(g_strndup(tag, length)); -+ - gtk_entry_set_text(entry, text); - g_free(text); - } - - static void get_entry_tag_v1(GtkEntry * entry, char * tag, int length) - { -+ gchar *ctext; -+ -+ ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_ID3, gtk_entry_get_text(entry)); -+ -+ if (ctext) { -+ strncpy(tag, ctext, length); -+ free(ctext); -+ } else - strncpy(tag, gtk_entry_get_text(entry), length); - } - - void copy_entry_tag_v1(GtkEntry * src, GtkEntry * dest, int length) - { -- set_entry_tag_v1(dest, gtk_entry_get_text(src), length); -+ char *text = g_strchomp(g_strndup(gtk_entry_get_text(src), length)); -+ gtk_entry_set_text(dest, text); -+ g_free(text); - return; - } - -@@ -497,6 +512,7 @@ - int i; - struct id3v1tag_t id3v1tag; - FILE *fh; -+ gchar *cfilename; - char *tmp, *title; - const char *emphasis[4]; - const char *bool_label[2]; -@@ -908,6 +924,9 @@ - g_free(current_filename); - current_filename = g_strdup(filename); - -+ cfilename = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_OUT, filename); -+ if (cfilename) filename=cfilename; -+ - title = g_strdup_printf(_("File Info - %s"), g_basename(filename)); - gtk_window_set_title(GTK_WINDOW(window), title); - g_free(title); -@@ -922,6 +941,8 @@ - gtk_entry_set_text(GTK_ENTRY(v2_title_entry), title); - g_free(title); - -+ if (cfilename) g_free(cfilename); -+ - gtk_entry_set_text(GTK_ENTRY(v1_artist_entry), ""); - gtk_entry_set_text(GTK_ENTRY(v1_album_entry), ""); - gtk_entry_set_text(GTK_ENTRY(v1_year_entry), ""); -diff -dPNur xmms-1.2.10/Input/mpg123/id3_frame_text.c xmms-1.2.10-new/Input/mpg123/id3_frame_text.c ---- xmms-1.2.10/Input/mpg123/id3_frame_text.c 2005-08-10 03:20:03.000000000 +0200 -+++ xmms-1.2.10-new/Input/mpg123/id3_frame_text.c 2005-08-10 03:29:40.000000000 +0200 -@@ -28,6 +28,7 @@ - #include "id3_header.h" - - #include "libxmms/charset.h" -+#include "libxmms/rcc.h" - - /* For extern mpg123_cfg */ - #include "mpg123.h" -@@ -247,6 +248,9 @@ - */ - int id3_set_text(struct id3_frame *frame, char *text) - { -+ char *ctext; -+ gint8 encoding; -+ - /* Type check */ - if (frame->fr_desc->fd_idstr[0] != 'T') - return -1; -@@ -256,18 +260,36 @@ - */ - id3_frame_clear_data(frame); - -+ -+ /* -+ * Recoding. -+ */ -+ encoding = (gint8)xmms_rcc_get_id3v2_encoding(); -+ if (encoding == ID3_ENCODING_ISO_8859_1) ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_ID3V2, text); -+ else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); -+ else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); -+ else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); -+ else ctext = NULL; -+ -+ if (ctext) text = ctext; -+ - /* - * Allocate memory for new data. - */ -+ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) -+ frame->fr_raw_size = utf16_strlen(text) + 2; -+ else - frame->fr_raw_size = strlen(text) + 1; - frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); - - /* - * Copy contents. - */ -- *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1; -+ *(gint8 *) frame->fr_raw_data = encoding; - memcpy((char *) frame->fr_raw_data + 1, text, frame->fr_raw_size); - -+ if (ctext) free(ctext); -+ - frame->fr_altered = 1; - frame->fr_owner->id3_altered = 1; - -@@ -389,7 +411,10 @@ - */ - int id3_set_comment(struct id3_frame *frame, char *text) - { -+ char *ctext, *cdata; -+ const char *lang; - int *intp; -+ gint8 encoding; - - /* Type check */ - if (frame->fr_desc->fd_id != ID3_COMM) -@@ -401,8 +426,23 @@ - id3_frame_clear_data(frame); - - /* -+ * Recoding. -+ */ -+ encoding = (gint8)xmms_rcc_get_id3v2_encoding(); -+ if (encoding == ID3_ENCODING_ISO_8859_1) ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_ID3V2, text); -+ else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); -+ else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); -+ else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); -+ else ctext = NULL; -+ -+ if (ctext) text = ctext; -+ -+ /* - * Allocate memory for new data. - */ -+ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) -+ frame->fr_raw_size = 25 + utf16_strlen(text); -+ else - frame->fr_raw_size = 13 + strlen(text); - frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); /* XXXComments\0<\0> - -@@ -410,18 +450,29 @@ - * block, so don't waste time with a calloc() - */ - -- ((guint8 *)frame->fr_raw_data)[0] = ID3_ENCODING_ISO_8859_1; -- ((guint8 *)frame->fr_raw_data)[1] = 0x58; -- ((guint8 *)frame->fr_raw_data)[2] = 0x58; -- ((guint8 *)frame->fr_raw_data)[3] = 0x58; -+ *(gint8 *) frame->fr_raw_data = encoding; -+ memcpy((char*)frame->fr_raw_data + 1, xmms_rcc_get_language(), 3); - -+ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) { -+ int i; -+ lang = "Comments"; -+ if (encoding == ID3_ENCODING_UTF16) cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16"); -+ else cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16BE"); -+ memcpy((char *) frame->fr_raw_data + 4, cdata, 20); -+ g_free(cdata); -+ } else - memcpy((char *) frame->fr_raw_data + 4, "Comments", 9); - - /* - * Copy contents. - */ -+ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) -+ memcpy((char *) frame->fr_raw_data + 24, text, utf16_strlen(text) + 2); -+ else - memcpy((char *) frame->fr_raw_data + 13, text, strlen(text) + 1); - -+ if (ctext) free(ctext); -+ - frame->fr_altered = 1; - frame->fr_owner->id3_altered = 1; - diff --git a/patches/xmms/plugins/xmms-ds-mpg123.patch b/patches/xmms/plugins/xmms-ds-mpg123.patch deleted file mode 100644 index fc9c42e..0000000 --- a/patches/xmms/plugins/xmms-ds-mpg123.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-25 00:04:27.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-25 01:18:57.000000000 +0100 -@@ -3,6 +3,7 @@ - #include "libxmms/configfile.h" - #include "libxmms/titlestring.h" - #include "libxmms/charset.h" -+#include "libxmms/rcc.h" - #include - #include - #include -@@ -496,6 +497,8 @@ - /* - * Format according to filename. - */ -+ ret = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, g_basename(filename)); -+ if (!ret) - ret = g_strdup(g_basename(filename)); - if (extname(ret) != NULL) - *(extname(ret) - 1) = '\0'; /* removes period */ diff --git a/patches/xmms/plugins/xmms-ds-vorbis-editor-keys.patch b/patches/xmms/plugins/xmms-ds-vorbis-editor-keys.patch deleted file mode 100644 index bf59951..0000000 --- a/patches/xmms/plugins/xmms-ds-vorbis-editor-keys.patch +++ /dev/null @@ -1,78 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/vorbis/fileinfo.c xmms-1.2.11-new/Input/vorbis/fileinfo.c ---- xmms-1.2.11/Input/vorbis/fileinfo.c 2007-11-25 01:23:31.000000000 +0100 -+++ xmms-1.2.11-new/Input/vorbis/fileinfo.c 2007-11-25 01:24:01.000000000 +0100 -@@ -39,6 +39,9 @@ - #include "libxmms/charset.h" - #include - -+#include "../../xmms/xmms.h" -+#include -+ - #include "vorbis.h" - #include "vcedit.h" - -@@ -444,6 +447,28 @@ - } - - /***********************************************************************/ -+static int restore_focus; -+ -+gboolean vorbis_keypress_cb(GtkWidget * w, GdkEventKey * event, gpointer save) { -+ switch(event->keyval) { -+ case GDK_Return: -+ restore_focus=1; -+ gtk_signal_emit_by_name(GTK_OBJECT(save), "clicked", NULL); -+ break; -+ case GDK_Escape: -+ restore_focus=1; -+ break; -+ } -+ return TRUE; -+} -+ -+void gtk_widget_destroyed_focus(GtkWidget *widget, GtkWidget **widget_pointer) { -+ gtk_widget_destroyed(widget,widget_pointer); -+ if (restore_focus) { -+ gtk_widget_hide(playlistwin); -+ gtk_widget_show(playlistwin); -+ } -+} - - void vorbis_file_info_box(char *fn) - { -@@ -465,6 +490,8 @@ - - g_free(vte.filename); - vte.filename = g_strdup(fn); -+ -+ restore_focus = 0; - - if (!window) - { -@@ -472,11 +499,12 @@ - GtkWidget *hbox, *label, *filename_hbox, *vbox, *left_vbox; - GtkWidget *table, *bbox, *cancel_button; - GtkWidget *save_button, *remove_button; -+ GtkAccelGroup *ag; - - 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_SIGNAL_FUNC(gtk_widget_destroyed_focus), &window); - gtk_signal_connect(GTK_OBJECT(window), "key_press_event", - keypress_cb, NULL); - gtk_container_set_border_width(GTK_CONTAINER(window), 10); -@@ -809,6 +837,12 @@ - FALSE, 0); - - gtk_widget_show_all(window); -+ -+ ag = gtk_accel_group_new(); -+ gtk_accel_group_add(ag, GDK_Escape, 0, 0, GTK_OBJECT(cancel_button), "clicked"); -+ gtk_accel_group_add(ag, GDK_Return, 0, 0, GTK_OBJECT(save_button), "clicked"); -+ gtk_window_add_accel_group(GTK_WINDOW(window), ag); -+ gtk_signal_connect(GTK_OBJECT(window),"key_press_event",GTK_SIGNAL_FUNC(vorbis_keypress_cb),save_button); - } else - gdk_window_raise(window->window); - diff --git a/patches/xmms/plugins/xmms-ds-vorbis-editor.patch b/patches/xmms/plugins/xmms-ds-vorbis-editor.patch deleted file mode 100644 index 47a7ba9..0000000 --- a/patches/xmms/plugins/xmms-ds-vorbis-editor.patch +++ /dev/null @@ -1,51 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/vorbis/fileinfo.c xmms-1.2.11-new/Input/vorbis/fileinfo.c ---- xmms-1.2.11/Input/vorbis/fileinfo.c 2007-11-25 00:04:27.000000000 +0100 -+++ xmms-1.2.11-new/Input/vorbis/fileinfo.c 2007-11-25 01:20:57.000000000 +0100 -@@ -34,6 +34,7 @@ - #include - #include - -+#include "libxmms/rcc.h" - #include "libxmms/util.h" - #include "libxmms/charset.h" - #include -@@ -451,6 +452,7 @@ - char *description, *version, *isrc, *copyright, *organization; - char *location, *vendor = "N/A"; - char *rg_track_gain, *rg_album_gain, *rg_track_peak, *rg_album_peak; -+ gchar *cfilename; - - int time, minutes, seconds, bitrate, avgbitrate, rate, channels; - int filesize, i; -@@ -931,6 +933,11 @@ - gtk_entry_set_text(GTK_ENTRY(isrc_entry), isrc); - gtk_entry_set_text(GTK_ENTRY(location_entry), location); - #endif -+ cfilename = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, vte.filename); -+ if (cfilename) { -+ gtk_entry_set_text(GTK_ENTRY(filename_entry), cfilename); -+ g_free(cfilename); -+ } else - gtk_entry_set_text(GTK_ENTRY(filename_entry), vte.filename); - gtk_editable_set_position(GTK_EDITABLE(filename_entry), -1); - -diff -dPNur xmms-1.2.11/Input/vorbis/vorbis.c xmms-1.2.11-new/Input/vorbis/vorbis.c ---- xmms-1.2.11/Input/vorbis/vorbis.c 2007-11-25 00:04:27.000000000 +0100 -+++ xmms-1.2.11-new/Input/vorbis/vorbis.c 2007-11-25 01:20:57.000000000 +0100 -@@ -46,6 +46,7 @@ - #include "xmms/plugin.h" - #include "libxmms/util.h" - #include "libxmms/configfile.h" -+#include "libxmms/rcc.h" - #include "libxmms/titlestring.h" - #include "libxmms/charset.h" - #include -@@ -754,6 +755,8 @@ - if (!vorbis_is_streaming) - { - char *tmp; -+ displaytitle = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_OUT, g_basename(fn)); -+ if (!displaytitle) - displaytitle = g_strdup(g_basename(fn)); - if ((tmp = strrchr(displaytitle, '.')) != NULL) - *tmp = '\0'; diff --git a/patches/xmms/plugins/xmms-wma-csa1.tar.bz2 b/patches/xmms/plugins/xmms-wma-csa1.tar.bz2 new file mode 100644 index 0000000..de6968c Binary files /dev/null and b/patches/xmms/plugins/xmms-wma-csa1.tar.bz2 differ diff --git a/patches/xmms/source/rcc.c b/patches/xmms/source/rcc.c new file mode 100644 index 0000000..c02f050 --- /dev/null +++ b/patches/xmms/source/rcc.c @@ -0,0 +1,185 @@ +#include +#include + +#include +#include + +#include "config.h" +#ifdef HAVE_LIBRCC_H +# ifdef HAVE_LIBRCCUI_H +# define HAVE_LIBRCC +# include +# include +# endif /* HAVE_LIBRCCUI_H */ +#endif /* HAVE_LIBRCC_H */ + +#include "rcc.h" +#include "rcc_langs.h" + +#ifdef HAVE_LIBRCC +static rcc_context ctx = NULL; +static rcc_ui_context uictx = NULL; + +static rcc_class_default_charset default_id3[] = { + { "ru", "CP1251" }, + { NULL, NULL } +}; + +static rcc_class classes[] = { + { "id3", RCC_CLASS_STANDARD, NULL, default_id3, "ID3 Encoding", 0 }, + { "id3v2", RCC_CLASS_STANDARD, "id3", default_id3, "ID3 v.2 Encoding", 0 }, + { "pl", RCC_CLASS_STANDARD, "id3", default_id3, "PlayList Title Encoding", 0 }, + { "plfs", RCC_CLASS_STANDARD, "pl", NULL, "PlayList File Encoding", 0 }, + { "fs", RCC_CLASS_FS, "LC_CTYPE", NULL, "FileSystem Encoding", 0 }, + { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, NULL, 0 }, + { "ctype", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, NULL, RCC_CLASS_FLAG_CONST|RCC_CLASS_FLAG_SKIP_SAVELOAD }, + { "utf8", RCC_CLASS_STANDARD, "UTF-8", NULL, NULL, RCC_CLASS_FLAG_CONST|RCC_CLASS_FLAG_SKIP_SAVELOAD }, + { NULL } +}; +#endif /* HAVE_LIBRCC */ + + + +void xmms_rcc_init() { +#ifdef HAVE_LIBRCC + rccInit(); + rccUiInit(); + ctx = rccCreateContext(NULL, 0, 0, classes, 0); + rccInitDb4(ctx, NULL, 0); + rccLoad(ctx, "xmms"); + uictx = rccUiCreateContext(ctx); +#endif /* HAVE_LIBRCC */ +} + +void xmms_rcc_free() { +#ifdef HAVE_LIBRCC + rccUiFreeContext(uictx); + rccSave(ctx, "xmms"); + rccFreeContext(ctx); + rccUiFree(); + rccFree(); +#endif /* HAVE_LIBRCC */ +} + +void xmms_rcc_prefswin_create(void *prefswin_notebook) { +#ifdef HAVE_LIBRCC + GtkWidget *vbox; + vbox = (GtkWidget*)rccUiGetPage(uictx, NULL); + gtk_notebook_append_page(GTK_NOTEBOOK(prefswin_notebook), vbox, gtk_label_new(rccUiGetDefaultPageName()->title)); +#endif /* HAVE_LIBRCC */ +} + +void xmms_rcc_prefswin_apply() { +#ifdef HAVE_LIBRCC + rccUiUpdate(uictx); + rccSave(ctx, "xmms"); +#endif /* HAVE_LIBRCC */ +} + +char *xmms_rcc_fs2pl(const char *fnstring, const char *filename) { +#ifdef HAVE_LIBRCC + rcc_language_config config; + + if (!rccStringCheck(fnstring)) return NULL; + + config = rccGetConfig(ctx, rccStringGetLanguage(fnstring)); + if (!config) return NULL; + + if (rccConfigGetCurrentCharset(config, (rcc_class_id)XMMS_RCC_FS) == rccConfigGetCurrentCharset(config, (rcc_class_id)XMMS_RCC_PLFS)) + return NULL; +#endif /* HAVE_LIBRCC */ + + return xmms_rcc_get(XMMS_RCC_PLFS, fnstring); +} + + +/* rcc_string to out */ +char *xmms_rcc_get(xmms_rcc_class charset, const char *buf) { +#ifdef HAVE_LIBRCC + return (char*)rccTo(ctx, (rcc_class_id)charset, (const rcc_string)buf); +#else /* HAVE_LIBRCC */ + return NULL; +#endif /* HAVE_LIBRCC */ +} + +char *xmms_rcc_put(xmms_rcc_class charset, const char *buf) { +#ifdef HAVE_LIBRCC + return (char*)rccFrom(ctx, (rcc_class_id)charset, buf); +#else /* HAVE_LIBRCC */ + return NULL; +#endif /* HAVE_LIBRCC */ +} + +char *xmms_rcc_sized_put(xmms_rcc_class charset, const char *buf, int size) { +#ifdef HAVE_LIBRCC + return (char*)rccSizedFrom(ctx, (rcc_class_id)charset, buf, size); +#else /* HAVE_LIBRCC */ + return NULL; +#endif /* HAVE_LIBRCC */ +} + +char *xmms_rcc_recode(xmms_rcc_class from, xmms_rcc_class to, const char *buf) { +#ifdef HAVE_LIBRCC + if (((from==XMMS_RCC_CTYPE)&&(to==XMMS_RCC_OUT))||((from==XMMS_RCC_OUT)&&(to==XMMS_RCC_CTYPE))) { + if (!rccGetSelectedCharset(ctx, XMMS_RCC_OUT)) return NULL; + } + + return (char*)rccRecode(ctx, (rcc_class_id)from, (rcc_class_id)to, buf); +#else /* HAVE_LIBRCC */ + return NULL; +#endif /* HAVE_LIBRCC */ +} + +char *xmms_rcc_sized_recode(xmms_rcc_class from, xmms_rcc_class to, const char *buf, int size) { +#ifdef HAVE_LIBRCC + return (char*)rccSizedRecode(ctx, (rcc_class_id)from, (rcc_class_id)to, buf, size, NULL); +#else /* HAVE_LIBRCC */ + return NULL; +#endif /* HAVE_LIBRCC */ +} + +char *xmms_rcc_fs(xmms_rcc_class from, xmms_rcc_class to, const char *fspath, const char *path, const char *filename) { +#ifdef HAVE_LIBRCC + return (char*)rccFS(ctx, (rcc_class_id)from, (rcc_class_id)to, fspath, path, filename); +#else /* HAVE_LIBRCC */ + return NULL; +#endif /* HAVE_LIBRCC */ +} + +const char *xmms_rcc_string(const char *buf) { +#ifdef HAVE_LIBRCC + return rccGetString((const rcc_string)buf); +#else /* HAVE_LIBRCC */ + return buf; +#endif /* HAVE_LIBRCC */ +} + +const char *xmms_rcc_get_language() { + const char *lang; +#ifdef HAVE_LIBRCC + lang = rccGetCurrentLanguageName(ctx); +#else /* HAVE_LIBRCC */ + lang = NULL; +#endif /* HAVE_LIBRCC */ + return xmms_rcc_get_639_2_name(lang); +} + +#define ID3_ENCODING_ISO_8859_1 0x00 +#define ID3_ENCODING_UTF16 0x01 +#define ID3_ENCODING_UTF16BE 0x02 +#define ID3_ENCODING_UTF8 0x03 + +int xmms_rcc_get_id3v2_encoding() { +#ifdef HAVE_LIBRCC + const char *name; + + name = rccGetCurrentCharsetName(ctx, (rcc_class_id)XMMS_RCC_ID3V2); + if (!name) return ID3_ENCODING_ISO_8859_1; + + if ((!strcasecmp(name,"UTF-8"))||(!strcasecmp(name,"UTF8"))) return ID3_ENCODING_UTF8; + if ((!strcasecmp(name,"UTF-16"))||(!strcasecmp(name,"UTF16"))||(!strcasecmp(name,"UTF16LE"))||(!strcasecmp(name,"UTF-16LE"))) return ID3_ENCODING_UTF16; + if ((!strcasecmp(name,"UTF-16BE"))||(!strcasecmp(name,"UTF16BE"))) return ID3_ENCODING_UTF16BE; +#endif /* HAVE_LIBRCC */ + + return ID3_ENCODING_ISO_8859_1; +} diff --git a/patches/xmms/source/rcc.h b/patches/xmms/source/rcc.h new file mode 100644 index 0000000..d5bc9b2 --- /dev/null +++ b/patches/xmms/source/rcc.h @@ -0,0 +1,32 @@ +#ifndef _XMMS_CHARSET_H +#define _XMMS_CHARSET_H + +typedef enum xmms_rcc_class_t { + XMMS_RCC_ID3 = 0, + XMMS_RCC_ID3V2, + XMMS_RCC_PL, + XMMS_RCC_PLFS, + XMMS_RCC_FS, + XMMS_RCC_OUT, + XMMS_RCC_CTYPE, + XMMS_RCC_UTF8 +} xmms_rcc_class; + +void xmms_rcc_init(); +void xmms_rcc_free(); +void xmms_rcc_prefswin_create(void *prefswin_notebook); +void xmms_rcc_prefswin_apply(); + +char *xmms_rcc_fs2pl(const char *fnstring, const char *filename); +char *xmms_rcc_get(xmms_rcc_class charset, const char *buf); +char *xmms_rcc_put(xmms_rcc_class charset, const char *buf); +char *xmms_rcc_sized_put(xmms_rcc_class charset, const char *buf, int size); +char *xmms_rcc_recode(xmms_rcc_class from, xmms_rcc_class to, const char *buf); +char *xmms_rcc_sized_recode(xmms_rcc_class from, xmms_rcc_class to, const char *buf, int size); +char *xmms_rcc_fs(xmms_rcc_class from, xmms_rcc_class to, const char *fspath, const char *path, const char *filename); + +const char *xmms_rcc_string(const char *buf); +const char *xmms_rcc_get_language(); +int xmms_rcc_get_id3v2_encoding(); + +#endif /* _XMMS_CHARSET_H */ diff --git a/patches/xmms/source/rcc_langs.h b/patches/xmms/source/rcc_langs.h new file mode 100644 index 0000000..70abebf --- /dev/null +++ b/patches/xmms/source/rcc_langs.h @@ -0,0 +1,120 @@ +typedef struct xmms_rcc_langs_t { + const char *sn; + const char *name; +} xmms_rcc_langs; + +static const char *default_lang = "XXX"; +static xmms_rcc_langs langs[] = { + { "aa", "aar" }, + { "ab", "abk" }, + { "af", "afr" }, + { "ak", "aka" }, + { "am", "amh" }, + { "ar", "ara" }, + { "an", "arg" }, + { "as", "asm" }, + { "av", "ava" }, + { "ae", "ave" }, + { "ay", "aym" }, + { "ba", "bak" }, + { "bm", "bam" }, + { "bn", "ben" }, + { "bh", "bih" }, + { "bi", "bis" }, + { "bs", "bos" }, + { "br", "bre" }, + { "bg", "bul" }, + { "ch", "cha" }, + { "cv", "chv" }, + { "kw", "cor" }, + { "co", "cos" }, + { "cr", "cre" }, + { "dv", "div" }, + { "dz", "dzo" }, + { "en", "eng" }, + { "et", "est" }, + { "fj", "fij" }, + { "fi", "fin" }, + { "fy", "fry" }, + { "ff", "ful" }, + { "ig", "ibo" }, + { "io", "ido" }, + { "iu", "iku" }, + { "ie", "ile" }, + { "ik", "ipk" }, + { "it", "ita" }, + { "jv", "jav" }, + { "ja", "jpn" }, + { "kn", "kan" }, + { "ks", "kas" }, + { "kr", "kau" }, + { "kk", "kaz" }, + { "km", "khm" }, + { "rw", "kin" }, + { "ky", "kir" }, + { "kv", "kom" }, + { "kg", "kon" }, + { "ku", "kur" }, + { "lo", "lao" }, + { "la", "lat" }, + { "lv", "lav" }, + { "ln", "lin" }, + { "lt", "lit" }, + { "lg", "lug" }, + { "mh", "mah" }, + { "ml", "mal" }, + { "mr", "mar" }, + { "mg", "mlg" }, + { "mt", "mlt" }, + { "mo", "mol" }, + { "mn", "mon" }, + { "na", "nau" }, + { "ng", "ndo" }, + { "oj", "oji" }, + { "or", "ori" }, + { "om", "orm" }, + { "pi", "pli" }, + { "ps", "pus" }, + { "qu", "que" }, + { "rn", "run" }, + { "ru", "rus" }, + { "sg", "sag" }, + { "sa", "san" }, + { "sn", "sna" }, + { "sd", "snd" }, + { "so", "som" }, + { "sc", "srd" }, + { "ss", "ssw" }, + { "sw", "swa" }, + { "ty", "tah" }, + { "ta", "tam" }, + { "tg", "tgk" }, + { "tl", "tgl" }, + { "ti", "tir" }, + { "tn", "tsn" }, + { "ts", "tso" }, + { "tr", "tur" }, + { "tw", "twi" }, + { "uk", "ukr" }, + { "ur", "urd" }, + { "uz", "uzb" }, + { "vi", "vie" }, + { "wa", "wln" }, + { "wo", "wol" }, + { "xh", "xho" }, + { "yi", "yid" }, + { "yo", "yor" }, + { "zu", "zul" }, + { NULL, NULL } +}; + +const char *xmms_rcc_get_639_2_name(const char *sn) { + unsigned int i; + + if ((!sn)||(!strcasecmp(sn, "off"))) return default_lang; + + for (i=0; langs[i].sn; i++) + if (!strcasecmp(sn, langs[i].sn)) return langs[i].name; + + return default_lang; +} diff --git a/patches/xmms/xmms-ds-playlist.patch b/patches/xmms/xmms-ds-playlist.patch deleted file mode 100644 index b72c8d0..0000000 --- a/patches/xmms/xmms-ds-playlist.patch +++ /dev/null @@ -1,526 +0,0 @@ -diff -dPNur xmms-1.2.11/xmms/input.c xmms-1.2.11-new/xmms/input.c ---- xmms-1.2.11/xmms/input.c 2005-05-15 02:01:21.000000000 +0200 -+++ xmms-1.2.11-new/xmms/input.c 2008-10-27 18:14:08.000000000 +0100 -@@ -22,6 +22,7 @@ - #include "libxmms/titlestring.h" - #include "libxmms/util.h" - #include "libxmms/xentry.h" -+#include "libxmms/rcc.h" - - static pthread_mutex_t vis_mutex = PTHREAD_MUTEX_INITIALIZER; - -@@ -372,8 +373,12 @@ - - (*title) = xmms_get_titlestring(xmms_get_gentitle_format(), - input); -- if ( (*title) == NULL ) -+ if ( (*title) == NULL ) { -+ (*title) = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, input->file_name); -+ if (!*title) - (*title) = g_strdup(input->file_name); -+ } -+ - (*length) = -1; - g_free(temp); - g_free(input); -diff -dPNur xmms-1.2.11/xmms/main.c xmms-1.2.11-new/xmms/main.c ---- xmms-1.2.11/xmms/main.c 2006-07-16 15:40:04.000000000 +0200 -+++ xmms-1.2.11-new/xmms/main.c 2008-10-27 18:14:08.000000000 +0100 -@@ -36,6 +36,7 @@ - #include "libxmms/xmmsctrl.h" - #include "libxmms/util.h" - #include "libxmms/dirbrowser.h" -+#include "libxmms/rcc.h" - #include "xmms_mini.xpm" - - #define RANDTABLE_SIZE 128 -@@ -899,6 +900,7 @@ - gtk_timeout_remove(mainwin_timeout_tag); - util_set_cursor(NULL); - save_config(); -+ xmms_rcc_free(); - cleanup_ctrlsocket(); - playlist_stop_get_info_thread(); - playlist_clear(); -@@ -1036,8 +1038,14 @@ - - void mainwin_lock_info_text(char *text) - { -+ gchar *ctext; -+ ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_OUT, text); -+ if (ctext) text=ctext; -+ - mainwin_info_text_locked = TRUE; - textbox_set_text(mainwin_info, text); -+ -+ if (ctext) g_free(ctext); - } - - void mainwin_release_info_text(void) -@@ -1695,9 +1703,10 @@ - int match = 0; - char *title, *filename; - -- title = ((PlaylistEntry *) playlist->data)->title; -- filename = ((PlaylistEntry *) playlist->data)->filename; -- -+ title = playlist_check_entrytitle((PlaylistEntry *) playlist->data); -+ filename = xmms_rcc_get(XMMS_RCC_OUT, ((PlaylistEntry *) playlist->data)->fnstring); -+ if (!filename) filename = g_strdup(((PlaylistEntry *) playlist->data)->filename); -+ - if (title) - desc_buf[1] = title; - else if (strchr(filename, '/')) -@@ -1749,7 +1758,7 @@ - */ - match = mainwin_jump_to_file_match(song, words, nw); - } -- -+ - if (match) - { - int row, queue_pos, *data_buf; -@@ -1772,6 +1781,10 @@ - row_to_select = row; - } - -+ g_free(filename); -+ g_free(title); -+ -+ - songnr++; - playlist = playlist->next; - } -@@ -2072,8 +2085,10 @@ - int row, *data_buf; - char *title, *filename, *tmp_buf, *desc_buf[2]; - -- title = ((PlaylistEntry *) queue->data)->title; -- filename = ((PlaylistEntry *) queue->data)->filename; -+ title = playlist_check_entrytitle((PlaylistEntry *) queue->data); -+ filename = xmms_rcc_get(XMMS_RCC_OUT, ((PlaylistEntry *) queue->data)->fnstring); -+ if (!filename) filename = g_strdup(((PlaylistEntry *) queue->data)->filename); -+ - if (title) - desc_buf[1] = title; - else if (strchr(filename, '/')) -@@ -2086,6 +2101,9 @@ - row = gtk_clist_append(GTK_CLIST(qlist), desc_buf); - g_free(tmp_buf); - -+ g_free(filename); -+ g_free(title); -+ - data_buf = g_malloc(sizeof (int)); - *data_buf = pos; - gtk_clist_set_row_data_full(qlist, row, data_buf, g_free); -@@ -4217,6 +4235,7 @@ - #endif - - read_config(); -+ xmms_rcc_init(); - - #if defined(HAVE_SCHED_SETSCHEDULER) && defined(HAVE_SCHED_GET_PRIORITY_MAX) - if (cfg.use_realtime) -diff -dPNur xmms-1.2.11/xmms/playlist.c xmms-1.2.11-new/xmms/playlist.c ---- xmms-1.2.11/xmms/playlist.c 2007-11-16 22:51:30.000000000 +0100 -+++ xmms-1.2.11-new/xmms/playlist.c 2008-10-27 18:14:31.000000000 +0100 -@@ -20,6 +20,8 @@ - #include "xmms.h" - #include - #include "libxmms/util.h" -+#include -+#include "libxmms/rcc.h" - #include - #include - -@@ -91,6 +93,8 @@ - entry = node->data; - if (entry->filename) - g_free(entry->filename); -+ if (entry->fnstring) -+ g_free(entry->fnstring); - if (entry->title) - g_free(entry->title); - g_free(entry); -@@ -166,6 +170,8 @@ - - if (entry->filename) - g_free(entry->filename); -+ if (entry->fnstring) -+ g_free(entry->fnstring); - if (entry->title) - g_free(entry->title); - shuffle_list = g_list_remove(shuffle_list, entry); -@@ -280,9 +286,17 @@ - PlaylistEntry *entry; - - entry = g_malloc0(sizeof (PlaylistEntry)); -+ - entry->filename = g_strdup(filename); -+ entry->fnstring = xmms_rcc_put(XMMS_RCC_FS, filename); -+ if (!entry->fnstring) entry->fnstring = g_strdup(filename); -+ - if (title) -+ { -+ entry->title = xmms_rcc_put(XMMS_RCC_CTYPE, title); -+ if (!entry->title) - entry->title = g_strdup(title); -+ } - entry->length = len; - - PL_LOCK(); -@@ -624,6 +638,8 @@ - if (playlist_position) - { - g_free(playlist_position->title); -+ playlist_position->title = xmms_rcc_put(XMMS_RCC_CTYPE, title); -+ if (!playlist_position->title) - playlist_position->title = g_strdup(title); - playlist_position->length = length; - } -@@ -1015,6 +1031,7 @@ - char *playlist_get_info_text(void) - { - char *text, *title, *tmp, *numbers, *length; -+ char *ctitle; - - PL_LOCK(); - if (!playlist_position) -@@ -1023,10 +1040,20 @@ - return NULL; - } - -- if (playlist_position->title) -+ if (playlist_position->title) { -+ ctitle = xmms_rcc_get(XMMS_RCC_OUT, playlist_position->title); -+ if (ctitle) title = ctitle; -+ else - title = playlist_position->title; -- else -+ } else { -+ ctitle = xmms_rcc_get(XMMS_RCC_OUT, playlist_position->fnstring); -+ if (ctitle) { -+ title = g_strdup(g_basename(ctitle)); -+ g_free(ctitle); -+ ctitle = title; -+ } else - title = g_basename(playlist_position->filename); -+ } - - /* - * If the user don't want numbers in the playlist, don't -@@ -1048,6 +1075,7 @@ - text = g_strdup_printf("%s%s%s", numbers, title, length); - g_free(numbers); - g_free(length); -+ if (ctitle) g_free(ctitle); - - PL_UNLOCK(); - -@@ -1083,6 +1111,7 @@ - { - GList *node; - FILE *file; -+ gchar *ctitle, *cfn; - - if ((file = fopen(filename, "w")) == NULL) - return FALSE; -@@ -1101,10 +1130,12 @@ - while (node) - { - PlaylistEntry *entry = node->data; -+ if (!strstr(entry->filename,"://")) cfn = xmms_rcc_fs2pl(entry->fnstring, entry->filename); -+ else cfn=NULL; - if (is_pls) - fprintf(file, "File%d=%s\n", - g_list_position(playlist, node) + 1, -- entry->filename); -+ cfn?cfn:entry->filename); - else - { - if (entry->title && cfg.use_pl_metadata) -@@ -1116,11 +1147,14 @@ - else - seconds = -1; - -+ ctitle = xmms_rcc_get(XMMS_RCC_PL, entry->title); - fprintf(file, "#EXTINF:%d,%s\n", -- seconds, entry->title); -+ seconds, ctitle?ctitle:entry->title); -+ if (ctitle) g_free(ctitle); - } -- fprintf(file, "%s\n", entry->filename); -+ fprintf(file, "%s\n", cfn?cfn:entry->filename); - } -+ if (cfn) g_free(cfn); - node = g_list_next(node); - } - PL_UNLOCK(); -@@ -1151,16 +1185,32 @@ - *temp = '\0'; - else - { -+ if ((!strstr(filename,"://"))&&(!strstr(playlist_name, "://"))) { -+ temp = xmms_rcc_fs(XMMS_RCC_PLFS, XMMS_RCC_FS, NULL, NULL, filename); -+ if (temp) filename = temp; -+ } else temp = NULL; - __playlist_ins_with_info(filename, pos, title, len); -+ if (temp) g_free(temp); - return; - } -+ if ((!strstr(filename,"://"))&&(!strstr(playlist_name, "://"))) { -+ temp = xmms_rcc_fs(XMMS_RCC_PLFS, XMMS_RCC_FS, path, path, filename); -+ if (temp) filename = temp; -+ } else temp = NULL; -+ if (!temp) - temp = g_strdup_printf("%s/%s", path, filename); - __playlist_ins_with_info(temp, pos, title, len); - g_free(temp); - g_free(path); - } -- else -+ else { -+ if ((filename[0] == '/')&&(!strstr(playlist_name, "://"))) { -+ temp = xmms_rcc_fs(XMMS_RCC_PLFS, XMMS_RCC_FS, NULL, NULL, filename); -+ if (temp) filename = temp; -+ } else temp = NULL; - __playlist_ins_with_info(filename, pos, title, len); -+ if (temp) g_free(temp); -+ } - } - - static void parse_extm3u_info(char *info, char **title, int *length) -@@ -1182,6 +1232,10 @@ - *length *= 1000; - if ((str = strchr(info, ',')) != NULL) - { -+ if (*str) -+ while ((*(str+1)==' ')||(*(str+1)=='\t')) str++; /* g_strstrip removes leading and ending whitespaces */ -+ *title = xmms_rcc_put(XMMS_RCC_PL, str + 1); -+ if (!*title) - *title = g_strdup(str + 1); - g_strstrip(*title); - if (strlen(*title) < 1) -@@ -1210,7 +1264,7 @@ - line = read_ini_string(filename, "playlist", "NumberOfEntries"); - if (line == NULL) - return 0; -- -+ - noe = atoi(line); - g_free(line); - -@@ -1372,9 +1426,27 @@ - return ret; - } - -+gchar* playlist_check_entrytitle(PlaylistEntry *entry) { -+ gchar *title, *fn; -+ -+ if (!entry) return NULL; -+ -+ title = xmms_rcc_get(XMMS_RCC_OUT, entry->title); -+ if (!title) { -+ fn = xmms_rcc_get(XMMS_RCC_OUT, entry->fnstring); -+ if (fn) { -+ title = g_strdup(g_basename(fn)); -+ g_free(fn); -+ } else title = g_strdup(g_basename(entry->filename)); -+ } -+ -+ return title; -+} -+ - char * playlist_get_songtitle(int pos) - { - char *title = NULL, *filename; -+ char *ctitle; - PlaylistEntry *entry; - GList *node; - -@@ -1396,19 +1468,30 @@ - - if (entry->title == NULL && entry->length == -1) - { -- if (playlist_get_info_entry(entry)) -+ if (playlist_get_info_entry(entry)&&(entry->title)) { -+ title = xmms_rcc_get(XMMS_RCC_OUT, entry->title); -+ if (!title) - title = g_strdup(entry->title); -+ } - - PL_UNLOCK(); - } - else - { -+ title = xmms_rcc_get(XMMS_RCC_OUT, entry->title); -+ if (!title) - title = g_strdup(entry->title); - PL_UNLOCK(); - } - -- if (title == NULL) -+ if (title == NULL) { -+ ctitle = xmms_rcc_get(XMMS_RCC_OUT, entry->filename); -+ if (ctitle) { -+ title = g_strdup(g_basename(ctitle)); -+ g_free(ctitle); -+ } else - title = g_strdup(g_basename(filename)); -+ } - - g_free(filename); - -@@ -1453,36 +1536,41 @@ - - static int playlist_sort_by_title_cmpfunc(PlaylistEntry * a, PlaylistEntry * b) - { -- char *a_title, *b_title; -+ const char *a_title, *b_title; - - if (a->title) -- a_title = a->title; -+ a_title = xmms_rcc_string(a->title); - else - { -- if (strrchr(a->filename, '/')) -- a_title = strrchr(a->filename, '/') + 1; -+ if (strrchr(xmms_rcc_string(a->fnstring), '/')) -+ a_title = strrchr(xmms_rcc_string(a->fnstring), '/') + 1; - else -- a_title = a->filename; -+ a_title = xmms_rcc_string(a->filename); - } - - if (b->title) -- b_title = b->title; -+ b_title = xmms_rcc_string(b->title); - else - { -- if (strrchr(a->filename, '/')) -- b_title = strrchr(b->filename, '/') + 1; -+ if (strrchr(xmms_rcc_string(a->fnstring), '/')) -+ b_title = strrchr(xmms_rcc_string(b->fnstring), '/') + 1; - else -- b_title = b->filename; -- -+ b_title = xmms_rcc_string(b->filename); - } -- return strcasecmp(a_title, b_title); -+ return strcoll(a_title, b_title); - } - - void playlist_sort_by_title(void) - { -+ char *locale; -+ locale = setlocale(LC_COLLATE,"en_US.UTF-8"); -+ playlist_select_all(1); -+ playlist_read_info_selection(); -+ playlist_select_all(0); - PL_LOCK(); - playlist = g_list_sort(playlist, (GCompareFunc) playlist_sort_by_title_cmpfunc); - PL_UNLOCK(); -+ setlocale(LC_COLLATE,locale); - } - - static int playlist_sort_by_filename_cmpfunc(PlaylistEntry * a, PlaylistEntry * b) -@@ -1640,9 +1728,13 @@ - - void playlist_sort_selected_by_title(void) - { -+ char *locale; -+ locale = setlocale(LC_COLLATE,"en_US.UTF-8"); -+ playlist_read_info_selection(); - PL_LOCK(); - playlist = playlist_sort_selected(playlist, (GCompareFunc) playlist_sort_by_title_cmpfunc); - PL_UNLOCK(); -+ setlocale(LC_COLLATE,locale); - } - - void playlist_sort_selected_by_filename(void) -@@ -1859,6 +1951,8 @@ - return FALSE; - - /* entry is still around */ -+ entry->title = xmms_rcc_put(XMMS_RCC_CTYPE, temp_title); -+ if (!entry->title) - entry->title = temp_title; - entry->length = temp_length; - -diff -dPNur xmms-1.2.11/xmms/playlist.h xmms-1.2.11-new/xmms/playlist.h ---- xmms-1.2.11/xmms/playlist.h 2007-11-16 22:51:30.000000000 +0100 -+++ xmms-1.2.11-new/xmms/playlist.h 2008-10-27 18:14:08.000000000 +0100 -@@ -23,6 +23,7 @@ - typedef struct - { - gchar *filename; -+ gchar *fnstring; - gchar *title; - gint length; - gboolean selected; -@@ -86,6 +87,7 @@ - void playlist_fileinfo(gint pos); - void playlist_delete_index(glong index); - void playlist_delete_filenames(GList *filenames); -+gchar* playlist_check_entrytitle(PlaylistEntry *entry); - gchar* playlist_get_filename(gint pos); - gchar* playlist_get_songtitle(gint pos); - gint playlist_get_songtime(gint pos); -diff -dPNur xmms-1.2.11/xmms/playlist_list.c xmms-1.2.11-new/xmms/playlist_list.c ---- xmms-1.2.11/xmms/playlist_list.c 2003-06-11 20:44:17.000000000 +0200 -+++ xmms-1.2.11-new/xmms/playlist_list.c 2008-10-27 18:14:08.000000000 +0100 -@@ -451,10 +451,8 @@ - else - gdk_gc_set_foreground(gc, get_skin_color(SKIN_PLEDIT_NORMAL)); - -- if (entry->title) -- title = entry->title; -- else -- title = g_basename(entry->filename); -+ -+ title = playlist_check_entrytitle(entry); - - pos = playlist_get_queue_position(entry); - -@@ -497,6 +495,8 @@ - playlist_list_draw_string(pl, playlist_list_font, - i - pl->pl_first, tw, text); - g_free(text); -+ -+ g_free(title); - } - PL_UNLOCK(); - } -diff -dPNur xmms-1.2.11/xmms/prefswin.c xmms-1.2.11-new/xmms/prefswin.c ---- xmms-1.2.11/xmms/prefswin.c 2007-11-16 22:51:30.000000000 +0100 -+++ xmms-1.2.11-new/xmms/prefswin.c 2008-10-27 18:14:08.000000000 +0100 -@@ -18,6 +18,7 @@ - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - #include "xmms.h" -+#include "libxmms/rcc.h" - #include "libxmms/util.h" - #include "libxmms/titlestring.h" - -@@ -397,6 +398,8 @@ - draw_playlist_window(TRUE); - draw_equalizer_window(TRUE); - -+ xmms_rcc_prefswin_apply(); -+ - save_config(); - } - -@@ -1105,6 +1108,11 @@ - gtk_notebook_append_page(GTK_NOTEBOOK(prefswin_notebook), prefswin_fonts_vbox, gtk_label_new(_("Fonts"))); - - /* -+ * Coding Conversion page -+ */ -+ xmms_rcc_prefswin_create(prefswin_notebook); -+ -+ /* - * Title page - */ - prefswin_title_vbox = gtk_vbox_new(FALSE, 0); diff --git a/patches/xmms/xmms-ds-rusxmms-charset.patch b/patches/xmms/xmms-ds-rusxmms-charset.patch deleted file mode 100644 index 670f9e3..0000000 --- a/patches/xmms/xmms-ds-rusxmms-charset.patch +++ /dev/null @@ -1,87 +0,0 @@ -diff -dPNur xmms-1.2.10/libxmms/charset.c xmms-1.2.10-new/libxmms/charset.c ---- xmms-1.2.10/libxmms/charset.c 2005-08-10 03:20:03.000000000 +0200 -+++ xmms-1.2.10-new/libxmms/charset.c 2005-08-10 02:54:12.000000000 +0200 -@@ -20,6 +20,7 @@ - #include - #endif - -+#include "rcc.h" - #include "charset.h" - - char* xmms_charset_get_current(void) -@@ -37,7 +38,7 @@ - return charset; - } - --static size_t utf16_strlen(const char *string) -+size_t utf16_strlen(const char *string) - { - size_t len = 0; - -@@ -78,7 +79,7 @@ - /* + 1 for nul in case len == 1 */ - outsize = ((insize + 3) & ~3) + 1; - out = g_malloc(outsize); -- outleft = outsize - 1; -+ outleft = outsize - 2; - outptr = out; - - retry: -@@ -92,7 +93,7 @@ - outsize = (outsize - 1) * 2 + 1; - out = g_realloc(out, outsize); - outptr = out + used; -- outleft = outsize - 1 - used; -+ outleft = outsize - 2 - used; - goto retry; - case EINVAL: - break; -@@ -110,6 +111,7 @@ - } - } - *outptr = '\0'; -+ *(outptr+1) = '\0'; - - iconv_close(cd); - return out; -@@ -141,10 +143,14 @@ - - char* xmms_charset_from_latin1(const char *string) - { -+ char *cstring; - char *to = xmms_charset_get_current(); - - if (!string) - return NULL; -+ -+ cstring = xmms_rcc_recode(XMMS_RCC_ID3, XMMS_RCC_CTYPE, string); -+ if (cstring) return cstring; - - if (!strcmp(to, "UTF-8")) - return xmms_charset_convert(string, strlen(string), "ISO-8859-1", to); -@@ -271,9 +277,14 @@ - - char* xmms_charset_from_latin1(const char *string) - { -+ char *cstring; -+ - if (!string) - return NULL; - -+ cstring = xmms_rcc_recode(XMMS_RCC_ID3, XMMS_RCC_CTYPE, string); -+ if (cstring) return cstring; -+ - return g_strdup(string); - } - -diff -dPNur xmms-1.2.10/libxmms/charset.h xmms-1.2.10-new/libxmms/charset.h ---- xmms-1.2.10/libxmms/charset.h 2005-08-10 03:20:03.000000000 +0200 -+++ xmms-1.2.10-new/libxmms/charset.h 2005-08-10 01:41:01.000000000 +0200 -@@ -16,5 +16,7 @@ - char* xmms_charset_from_utf16be(const unsigned char *string); - char* xmms_charset_from_latin1(const char *string); - -+size_t utf16_strlen(const char *string); -+ - #endif /* XMMS_CHARSET_H */ - diff --git a/patches/xmms/xmms-ds-rusxmms.patch b/patches/xmms/xmms-ds-rusxmms.patch deleted file mode 100644 index 6b9287f..0000000 --- a/patches/xmms/xmms-ds-rusxmms.patch +++ /dev/null @@ -1,172 +0,0 @@ -diff -dPNur xmms-1.2.11/libxmms/configure.in xmms-1.2.11-new/libxmms/configure.in ---- xmms-1.2.11/libxmms/configure.in 2007-11-16 22:51:24.000000000 +0100 -+++ xmms-1.2.11-new/libxmms/configure.in 2007-11-25 17:38:56.000000000 +0100 -@@ -57,6 +57,16 @@ - AC_DEFINE([HAVE_CODESET],,[Define if nl_langinfo(CODESET) is available.]) - fi - -+AC_CHECK_LIB(rccgtk, rccUiInit,[ -+ AC_CHECK_HEADERS(librcc.h librccui.h,[ -+ LIBRCC_LIBS="-lrccgtk" -+ LIBRCC_INCLUDES="" -+ ],[ -+ LIBRCC_LIBS="" -+ LIBRCC_INCLUDES="" -+])]) -+AC_SUBST(LIBRCC_LIBS) -+AC_SUBST(LIBRCC_INCLUDES) - - AC_OUTPUT([ - Makefile -diff -dPNur xmms-1.2.11/libxmms/Makefile.am xmms-1.2.11-new/libxmms/Makefile.am ---- xmms-1.2.11/libxmms/Makefile.am 2004-04-04 10:51:20.000000000 +0200 -+++ xmms-1.2.11-new/libxmms/Makefile.am 2007-11-25 17:38:56.000000000 +0100 -@@ -4,10 +4,11 @@ - lib_LTLIBRARIES = libxmms.la - - libxmms_la_LDFLAGS = -export-dynamic -version-info $(LIBXMMS_MAJOR_VERSION):$(LIBXMMS_MINOR_VERSION):$(LIBXMMS_MICRO_VERSION) --libxmms_la_LIBADD = @GTK_LIBS@ @POSIX_LIBS@ --INCLUDES = @GTK_CFLAGS@ -I../intl -I.. -+libxmms_la_LIBADD = @LIBRCC_LIBS@ @GTK_LIBS@ @POSIX_LIBS@ -+INCLUDES = @LIBRCC_INCLUDES@ @GTK_CFLAGS@ -I../intl -I.. - - libxmms_la_SOURCES = \ -+rcc.c rcc.h rcc_langs.h \ - configfile.c configfile.h \ - xmmsctrl.c xmmsctrl.h \ - dirbrowser.c dirbrowser.h \ -diff -dPNur xmms-1.2.11/libxmms/titlestring.c xmms-1.2.11-new/libxmms/titlestring.c ---- xmms-1.2.11/libxmms/titlestring.c 2006-07-24 00:11:51.000000000 +0200 -+++ xmms-1.2.11-new/libxmms/titlestring.c 2007-11-25 17:39:21.000000000 +0100 -@@ -29,6 +29,7 @@ - #include - #include - -+#include "rcc.h" - #include "titlestring.h" - #include "../xmms/i18n.h" - -@@ -42,8 +43,9 @@ - PAD_SIDE_RIGHT, - }; - -+#define xmms_vputstr(out, pstr, pad) xmms_charset_vputstr(out, pstr, pad, from, pflag, c) - --static int xmms_vputstr(GString *output, char *pstr, struct padding *pad) -+static int xmms_orig_vputstr(GString *output, char *pstr, struct padding *pad) - { - int i; - /* Lenght of the string that is actually printed */ -@@ -83,6 +85,22 @@ - return TRUE; - } - -+static int xmms_charset_vputstr(GString *output, char *pstr, struct padding *pad, int from, gint pflag, char c) { -+ int res; -+ gchar *cstring = NULL; -+ -+ if ((pflag&1)&&((c=='f')||(c=='F'))) { -+ cstring = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, pstr); -+ } -+ if ((pflag&2)&&((c=='a')||(c=='c')||(c=='g')||(c=='p')||(c=='t'))) { -+ cstring = xmms_rcc_recode((xmms_rcc_class)from, XMMS_RCC_CTYPE, pstr); -+ } -+ -+ res = xmms_orig_vputstr(output, cstring?cstring:pstr, pad); -+ if (cstring) g_free(cstring); -+ -+ return res; -+} - - static int xmms_vputnum(GString *output, int ival, struct padding *pad) - { -@@ -124,7 +142,7 @@ - return TRUE; - } - --static int parse_variable(char **fmt, GString *string, TitleInput *input) -+static int parse_variable(char **fmt, GString *string, TitleInput *input, int from, gint pflag) - { - struct padding padding; - char *ptr = *fmt; -@@ -237,9 +255,33 @@ - return exp; - } - -+static int xmms_charset_analyze_fmt(gchar *fmt) { -+ int flag = 0; -+ -+ if (!fmt) return 0; -+ for (;*fmt;fmt++) { -+ while ((*fmt != '%')&&(*fmt != 0)) fmt++; -+ if (!*fmt) break; -+ while ((*fmt == '-')||(*fmt == ' ')||(*fmt == '0')) fmt++; -+ while (*fmt >= '0' && *fmt <= '9') fmt++; -+ if (*fmt == '.') { fmt++; while (*fmt >= '0' && *fmt <= '9') fmt++; } -+ if ((*fmt=='a')||(*fmt=='c')||(*fmt=='g')||(*fmt=='p')||(*fmt=='t')) flag|=1; -+ if ((*fmt=='f')||(*fmt=='F')) flag|=2; -+ } -+ -+ return flag; -+} -+ -+gchar *xmms_charset_get_titlestring(gchar *fmt, TitleInput *input, int from); - - char *xmms_get_titlestring(char *fmt, TitleInput *input) - { -+ return xmms_charset_get_titlestring(fmt, input, (xmms_rcc_class)-1); -+} -+ -+gchar *xmms_charset_get_titlestring(gchar *fmt, TitleInput *input, int from) { -+ gint pflag; -+ gchar *cstring = NULL; - int f_output = 0; - GString *string; - char *strptr; -@@ -249,12 +291,14 @@ - - string = g_string_new(""); - -+ pflag = (from == (xmms_rcc_class)-1)?0:xmms_charset_analyze_fmt(fmt); -+ - while (*fmt) - { - if (*fmt == '%') - { - fmt++; -- f_output += parse_variable(&fmt, string, input); -+ f_output += parse_variable(&fmt, string, input, from, pflag); - } - else - /* Normal character */ -@@ -271,6 +315,19 @@ - /* Return the result */ - strptr = string->str; - g_string_free(string, FALSE); -+ -+ if (pflag<3) { -+ if (pflag&2) -+ cstring = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, strptr); -+ else -+ cstring = xmms_rcc_recode((xmms_rcc_class)from, XMMS_RCC_CTYPE, strptr); -+ -+ if (cstring) { -+ g_free(strptr); -+ return cstring; -+ } -+ } -+ - return strptr; - } - -diff -dPNur xmms-1.2.11/libxmms/titlestring.h xmms-1.2.11-new/libxmms/titlestring.h ---- xmms-1.2.11/libxmms/titlestring.h 2005-05-15 02:01:20.000000000 +0200 -+++ xmms-1.2.11-new/libxmms/titlestring.h 2007-11-25 17:38:56.000000000 +0100 -@@ -77,6 +77,7 @@ - #endif - - gchar *xmms_get_titlestring(gchar *fmt, TitleInput *input); -+gchar *xmms_charset_get_titlestring(gchar *fmt, TitleInput *input, int from); - GtkWidget* xmms_titlestring_descriptions(char* tags, int rows); - - #ifdef __cplusplus diff --git a/patches/xmms/xmms-ds-shade.patch b/patches/xmms/xmms-ds-shade.patch deleted file mode 100644 index 41362df..0000000 --- a/patches/xmms/xmms-ds-shade.patch +++ /dev/null @@ -1,194 +0,0 @@ -diff -dPNur xmms-1.2.11/xmms/main.c xmms-1.2.11-new/xmms/main.c ---- xmms-1.2.11/xmms/main.c 2007-11-25 01:10:52.000000000 +0100 -+++ xmms-1.2.11-new/xmms/main.c 2007-11-25 01:11:13.000000000 +0100 -@@ -382,6 +382,8 @@ - - cfg.gentitle_format = NULL; - -+ cfg.shade_font = NULL; -+ - filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); - cfgfile = xmms_cfg_open_file(filename); - if (cfgfile) -@@ -481,6 +483,8 @@ - } - xmms_cfg_read_string(cfgfile, "xmms", "generic_title_format", &cfg.gentitle_format); - -+ xmms_cfg_read_string(cfgfile, "xmms", "shade_font", &cfg.shade_font); -+ - xmms_cfg_free(cfgfile); - } - -@@ -519,6 +523,13 @@ - if (cfg.eqpreset_extension == NULL) - cfg.eqpreset_extension = g_strdup("preset"); - -+ if (cfg.shade_font && strlen(cfg.shade_font) == 0) { -+ g_free(cfg.shade_font); -+ cfg.shade_font = NULL; -+ } -+ if (!cfg.shade_font) -+ cfg.shade_font = g_strdup("-misc-fixed-medium-r-*-*-7-*"); -+ - g_free(filename); - } - -@@ -677,6 +688,8 @@ - } - xmms_cfg_write_string(cfgfile, "xmms", "generic_title_format", cfg.gentitle_format); - -+ xmms_cfg_write_string(cfgfile, "xmms", "shade_font", cfg.shade_font); -+ - xmms_cfg_write_file(cfgfile, filename); - xmms_cfg_free(cfgfile); - -diff -dPNur xmms-1.2.11/xmms/main.h xmms-1.2.11-new/xmms/main.h ---- xmms-1.2.11/xmms/main.h 2006-07-16 15:40:04.000000000 +0200 -+++ xmms-1.2.11-new/xmms/main.h 2007-11-25 01:12:55.000000000 +0100 -@@ -60,6 +60,7 @@ - gint mouse_change; - gboolean playlist_transparent; - gchar *gentitle_format; -+ gchar *shade_font; - } - Config; - -diff -dPNur xmms-1.2.11/xmms/playlistwin.c xmms-1.2.11-new/xmms/playlistwin.c ---- xmms-1.2.11/xmms/playlistwin.c 2007-11-16 22:51:30.000000000 +0100 -+++ xmms-1.2.11-new/xmms/playlistwin.c 2007-11-25 01:11:13.000000000 +0100 -@@ -39,7 +39,8 @@ - PButton *playlistwin_shade, *playlistwin_close; - static PlaylistSlider *playlistwin_slider = NULL; - static TextBox *playlistwin_time_min, *playlistwin_time_sec; --static TextBox *playlistwin_info, *playlistwin_sinfo; -+static TextBox *playlistwin_info; -+TextBox *playlistwin_sinfo; - static SButton *playlistwin_srew, *playlistwin_splay; - static SButton *playlistwin_spause, *playlistwin_sstop; - static SButton *playlistwin_sfwd, *playlistwin_seject; -@@ -1882,6 +1883,7 @@ - static void playlistwin_create_widgets(void) - { - playlistwin_sinfo = create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, 4, 4, cfg.playlist_width - 35, FALSE, SKIN_TEXT); -+ textbox_set_xfont(playlistwin_sinfo, cfg.mainwin_use_xfont, cfg.shade_font); - if (!cfg.playlist_shaded) - hide_widget(playlistwin_sinfo); - if (cfg.playlist_shaded) -diff -dPNur xmms-1.2.11/xmms/prefswin.c xmms-1.2.11-new/xmms/prefswin.c ---- xmms-1.2.11/xmms/prefswin.c 2007-11-25 01:10:52.000000000 +0100 -+++ xmms-1.2.11-new/xmms/prefswin.c 2007-11-25 01:11:13.000000000 +0100 -@@ -35,6 +35,7 @@ - - static GtkWidget *prefswin_options_sd_entry, *prefswin_options_pbs_entry; - -+static GtkWidget *prefswin_shade_font_entry, *prefswin_shade_font_browse; - static GtkWidget *prefswin_options_font_entry, *prefswin_options_font_browse; - static GtkWidget *prefswin_options_fontset, *prefswin_mainwin_font_entry; - static GtkWidget *prefswin_mainwin_xfont, *prefswin_options_mouse_spin; -@@ -48,6 +49,7 @@ - extern PButton *playlistwin_shade, *playlistwin_close, *equalizerwin_close; - extern PButton *mainwin_menubtn, *mainwin_minimize, *mainwin_shade, *mainwin_close; - extern TextBox *mainwin_info; -+extern TextBox *playlistwin_sinfo; - extern gboolean mainwin_focus, equalizerwin_focus, playlistwin_focus; - - static gboolean is_opening = FALSE; -@@ -343,11 +345,13 @@ - gboolean show_wm_old = cfg.show_wm_decorations; - g_free(cfg.playlist_font); - g_free(cfg.mainwin_font); -+ g_free(cfg.shade_font); - g_free(cfg.gentitle_format); - prefswin_options_write_data(); - cfg.snap_distance = CLAMP(atoi(gtk_entry_get_text(GTK_ENTRY(prefswin_options_sd_entry))), 0, 1000); - cfg.playlist_font = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_options_font_entry))); - cfg.mainwin_font = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_mainwin_font_entry))); -+ cfg.shade_font = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_shade_font_entry))); - cfg.gentitle_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_title_entry))); - cfg.pause_between_songs_time = CLAMP(atoi(gtk_entry_get_text(GTK_ENTRY(prefswin_options_pbs_entry))), 0, 1000); - cfg.mouse_change = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(prefswin_options_mouse_spin)); -@@ -390,6 +394,7 @@ - prefswin_toggle_wm_decorations(); - - textbox_set_xfont(mainwin_info, cfg.mainwin_use_xfont, cfg.mainwin_font); -+ textbox_set_xfont(playlistwin_sinfo, cfg.mainwin_use_xfont, cfg.shade_font); - playlist_list_set_font(cfg.playlist_font); - playlistwin_update_list(); - mainwin_set_info_text(); -@@ -475,6 +480,34 @@ - } - } - -+void prefswin_shade_font_browse_ok(GtkWidget * w, gpointer data) -+{ -+ GtkFontSelectionDialog *fontsel = GTK_FONT_SELECTION_DIALOG(data); -+ gchar *fontname; -+ -+ fontname = gtk_font_selection_dialog_get_font_name(fontsel); -+ -+ if (fontname) -+ gtk_entry_set_text(GTK_ENTRY(prefswin_shade_font_entry), fontname); -+ -+ gtk_widget_destroy(GTK_WIDGET(fontsel)); -+} -+ -+void prefswin_shade_font_browse_cb(GtkWidget * w, gpointer data) -+{ -+ static GtkWidget *fontsel; -+ -+ if (fontsel != NULL) -+ return; -+ -+ fontsel = gtk_font_selection_dialog_new(_("Select playlist font:")); -+ gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(fontsel), gtk_entry_get_text(GTK_ENTRY(prefswin_shade_font_entry))); -+ gtk_signal_connect(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->ok_button), "clicked", GTK_SIGNAL_FUNC(prefswin_shade_font_browse_ok), fontsel); -+ gtk_signal_connect_object(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(fontsel)); -+ gtk_signal_connect(GTK_OBJECT(fontsel), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &fontsel); -+ gtk_widget_show(fontsel); -+} -+ - void prefswin_gplugins_use_cb(GtkToggleButton * w, gpointer data) - { - gint sel; -@@ -693,7 +726,10 @@ - GtkWidget *prefswin_vplugins_box, *prefswin_vplugins_vbox; - GtkWidget *prefswin_vplugins_frame, *prefswin_vplugins_hbox; - GtkWidget *prefswin_vplugins_hbbox; -- -+ -+ GtkWidget *prefswin_fonts_shade_frame; -+ GtkWidget *options_font_shade_hbox, *options_font_shade_vbox; -+ - GtkWidget *prefswin_options_frame, *prefswin_options_vbox; - GtkWidget *prefswin_mainwin_frame, *prefswin_mainwin_vbox; - GtkWidget *prefswin_fonts_vbox, *prefswin_fonts_playlist_frame; -@@ -1105,6 +1141,21 @@ - gtk_widget_set_usize(prefswin_mainwin_font_browse, 85, 17); - gtk_box_pack_start(GTK_BOX(prefswin_mainwin_font_hbox), prefswin_mainwin_font_browse, FALSE, TRUE, 0); - -+ prefswin_fonts_shade_frame = gtk_frame_new(_("Shade")); -+ gtk_container_set_border_width(GTK_CONTAINER(prefswin_fonts_shade_frame), 5); -+ gtk_box_pack_start(GTK_BOX(prefswin_fonts_vbox), prefswin_fonts_shade_frame, FALSE, FALSE, 0); -+ options_font_shade_vbox = gtk_vbox_new(FALSE, 5); -+ gtk_container_border_width(GTK_CONTAINER(options_font_shade_vbox), 5); -+ gtk_container_add(GTK_CONTAINER(prefswin_fonts_shade_frame), options_font_shade_vbox); -+ options_font_shade_hbox = gtk_hbox_new(FALSE, 5); -+ gtk_box_pack_start_defaults(GTK_BOX(options_font_shade_vbox), options_font_shade_hbox); -+ prefswin_shade_font_entry = gtk_entry_new(); -+ gtk_box_pack_start(GTK_BOX(options_font_shade_hbox), prefswin_shade_font_entry, TRUE, TRUE, 0); -+ prefswin_shade_font_browse = gtk_button_new_with_label(_("Browse")); -+ gtk_signal_connect(GTK_OBJECT(prefswin_shade_font_browse), "clicked", GTK_SIGNAL_FUNC(prefswin_shade_font_browse_cb), NULL); -+ gtk_widget_set_usize(prefswin_shade_font_browse, 85, 17); -+ gtk_box_pack_start(GTK_BOX(options_font_shade_hbox), prefswin_shade_font_browse, FALSE, TRUE, 0); -+ - gtk_notebook_append_page(GTK_NOTEBOOK(prefswin_notebook), prefswin_fonts_vbox, gtk_label_new(_("Fonts"))); - - /* -@@ -1390,6 +1441,7 @@ - - gtk_entry_set_text(GTK_ENTRY(prefswin_options_font_entry), cfg.playlist_font); - gtk_entry_set_text(GTK_ENTRY(prefswin_mainwin_font_entry), cfg.mainwin_font); -+ gtk_entry_set_text(GTK_ENTRY(prefswin_shade_font_entry), cfg.shade_font); - gtk_entry_set_text(GTK_ENTRY(prefswin_title_entry), cfg.gentitle_format); - sprintf(temp, "%u", cfg.snap_distance); - gtk_entry_set_text(GTK_ENTRY(prefswin_options_sd_entry), temp); diff --git a/patches/xmms/xmms-ds-textbox.patch b/patches/xmms/xmms-ds-textbox.patch deleted file mode 100644 index 8442606..0000000 --- a/patches/xmms/xmms-ds-textbox.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff -dPNur xmms-1.2.10/xmms/textbox.c xmms-1.2.10-patched/xmms/textbox.c ---- xmms-1.2.10/xmms/textbox.c 2001-12-01 18:00:51.000000000 +0100 -+++ xmms-1.2.10-patched/xmms/textbox.c 2005-06-02 22:43:42.000000000 +0200 -@@ -166,6 +166,8 @@ - GdkGC *gc, *maskgc; - GdkColor *c, pattern; - GdkBitmap *mask; -+ GdkWChar *wtext; -+ int len; - - length = strlen(pixmaptext); - -@@ -192,6 +194,18 @@ - tb->tb_pixmap_width, tb->tb_widget.height); - pattern.pixel = 1; - gdk_gc_set_foreground(maskgc, &pattern); -+ if (cfg.use_fontsets) { -+ wtext = g_malloc((length + 1) * sizeof(GdkWChar)); -+ len = gdk_mbstowcs(wtext, pixmaptext, length + 1); -+ if (len == -1) { -+ for (len = 0; pixmaptext[len] != '\0'; len++) -+ wtext[len] = pixmaptext[len]; -+ } -+ wtext[len] = L'\0'; -+ gdk_draw_text_wc(mask,tb->tb_font, maskgc, 0, tb->tb_font->ascent, wtext, len ); -+ g_free(wtext); -+ } -+ else - gdk_draw_text(mask, tb->tb_font, maskgc, 0, - tb->tb_font->ascent, pixmaptext, length); - gdk_gc_unref(maskgc); diff --git a/release b/release new file mode 100755 index 0000000..a0d6915 --- /dev/null +++ b/release @@ -0,0 +1,38 @@ +#! /bin/bash + +RDIR=~/releases +NAME=RusXMMS2 + +if [ ! -d $RDIR ]; then + if [ -a $RDIR ]; then + echo "Release directory isn't a directory!" + exit + fi + mkdir -p $RDIR +fi + +version=$(cat VERSION) +rname="$NAME-$version"; + +if [ -d $RDIR/$rname ]; then + rm -rf $RDIR/$rname +fi +mkdir -p $RDIR/$rname +if [ ! -d $RDIR/$rname ]; then + echo "Can't create directory!!!" + exit +fi +cp -a * $RDIR/$rname + +( + cd $RDIR + + if [ -a $rname.tar.bz2 ]; then + rm -f $rname.tar.bz2 + fi + tar cjf $rname.tar.bz2 $rname + rm -rf $rname + + scp $rname.tar.bz2 csa@darksoft.org:/home/csa/public_html/files/rusxmms/ + ssh csa@darksoft.org ln -sf $rname.tar.bz2 /home/csa/public_html/files/rusxmms/$NAME-latest.tar.bz2 +) diff --git a/source/rcc.c b/source/rcc.c deleted file mode 100644 index c02f050..0000000 --- a/source/rcc.c +++ /dev/null @@ -1,185 +0,0 @@ -#include -#include - -#include -#include - -#include "config.h" -#ifdef HAVE_LIBRCC_H -# ifdef HAVE_LIBRCCUI_H -# define HAVE_LIBRCC -# include -# include -# endif /* HAVE_LIBRCCUI_H */ -#endif /* HAVE_LIBRCC_H */ - -#include "rcc.h" -#include "rcc_langs.h" - -#ifdef HAVE_LIBRCC -static rcc_context ctx = NULL; -static rcc_ui_context uictx = NULL; - -static rcc_class_default_charset default_id3[] = { - { "ru", "CP1251" }, - { NULL, NULL } -}; - -static rcc_class classes[] = { - { "id3", RCC_CLASS_STANDARD, NULL, default_id3, "ID3 Encoding", 0 }, - { "id3v2", RCC_CLASS_STANDARD, "id3", default_id3, "ID3 v.2 Encoding", 0 }, - { "pl", RCC_CLASS_STANDARD, "id3", default_id3, "PlayList Title Encoding", 0 }, - { "plfs", RCC_CLASS_STANDARD, "pl", NULL, "PlayList File Encoding", 0 }, - { "fs", RCC_CLASS_FS, "LC_CTYPE", NULL, "FileSystem Encoding", 0 }, - { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, NULL, 0 }, - { "ctype", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, NULL, RCC_CLASS_FLAG_CONST|RCC_CLASS_FLAG_SKIP_SAVELOAD }, - { "utf8", RCC_CLASS_STANDARD, "UTF-8", NULL, NULL, RCC_CLASS_FLAG_CONST|RCC_CLASS_FLAG_SKIP_SAVELOAD }, - { NULL } -}; -#endif /* HAVE_LIBRCC */ - - - -void xmms_rcc_init() { -#ifdef HAVE_LIBRCC - rccInit(); - rccUiInit(); - ctx = rccCreateContext(NULL, 0, 0, classes, 0); - rccInitDb4(ctx, NULL, 0); - rccLoad(ctx, "xmms"); - uictx = rccUiCreateContext(ctx); -#endif /* HAVE_LIBRCC */ -} - -void xmms_rcc_free() { -#ifdef HAVE_LIBRCC - rccUiFreeContext(uictx); - rccSave(ctx, "xmms"); - rccFreeContext(ctx); - rccUiFree(); - rccFree(); -#endif /* HAVE_LIBRCC */ -} - -void xmms_rcc_prefswin_create(void *prefswin_notebook) { -#ifdef HAVE_LIBRCC - GtkWidget *vbox; - vbox = (GtkWidget*)rccUiGetPage(uictx, NULL); - gtk_notebook_append_page(GTK_NOTEBOOK(prefswin_notebook), vbox, gtk_label_new(rccUiGetDefaultPageName()->title)); -#endif /* HAVE_LIBRCC */ -} - -void xmms_rcc_prefswin_apply() { -#ifdef HAVE_LIBRCC - rccUiUpdate(uictx); - rccSave(ctx, "xmms"); -#endif /* HAVE_LIBRCC */ -} - -char *xmms_rcc_fs2pl(const char *fnstring, const char *filename) { -#ifdef HAVE_LIBRCC - rcc_language_config config; - - if (!rccStringCheck(fnstring)) return NULL; - - config = rccGetConfig(ctx, rccStringGetLanguage(fnstring)); - if (!config) return NULL; - - if (rccConfigGetCurrentCharset(config, (rcc_class_id)XMMS_RCC_FS) == rccConfigGetCurrentCharset(config, (rcc_class_id)XMMS_RCC_PLFS)) - return NULL; -#endif /* HAVE_LIBRCC */ - - return xmms_rcc_get(XMMS_RCC_PLFS, fnstring); -} - - -/* rcc_string to out */ -char *xmms_rcc_get(xmms_rcc_class charset, const char *buf) { -#ifdef HAVE_LIBRCC - return (char*)rccTo(ctx, (rcc_class_id)charset, (const rcc_string)buf); -#else /* HAVE_LIBRCC */ - return NULL; -#endif /* HAVE_LIBRCC */ -} - -char *xmms_rcc_put(xmms_rcc_class charset, const char *buf) { -#ifdef HAVE_LIBRCC - return (char*)rccFrom(ctx, (rcc_class_id)charset, buf); -#else /* HAVE_LIBRCC */ - return NULL; -#endif /* HAVE_LIBRCC */ -} - -char *xmms_rcc_sized_put(xmms_rcc_class charset, const char *buf, int size) { -#ifdef HAVE_LIBRCC - return (char*)rccSizedFrom(ctx, (rcc_class_id)charset, buf, size); -#else /* HAVE_LIBRCC */ - return NULL; -#endif /* HAVE_LIBRCC */ -} - -char *xmms_rcc_recode(xmms_rcc_class from, xmms_rcc_class to, const char *buf) { -#ifdef HAVE_LIBRCC - if (((from==XMMS_RCC_CTYPE)&&(to==XMMS_RCC_OUT))||((from==XMMS_RCC_OUT)&&(to==XMMS_RCC_CTYPE))) { - if (!rccGetSelectedCharset(ctx, XMMS_RCC_OUT)) return NULL; - } - - return (char*)rccRecode(ctx, (rcc_class_id)from, (rcc_class_id)to, buf); -#else /* HAVE_LIBRCC */ - return NULL; -#endif /* HAVE_LIBRCC */ -} - -char *xmms_rcc_sized_recode(xmms_rcc_class from, xmms_rcc_class to, const char *buf, int size) { -#ifdef HAVE_LIBRCC - return (char*)rccSizedRecode(ctx, (rcc_class_id)from, (rcc_class_id)to, buf, size, NULL); -#else /* HAVE_LIBRCC */ - return NULL; -#endif /* HAVE_LIBRCC */ -} - -char *xmms_rcc_fs(xmms_rcc_class from, xmms_rcc_class to, const char *fspath, const char *path, const char *filename) { -#ifdef HAVE_LIBRCC - return (char*)rccFS(ctx, (rcc_class_id)from, (rcc_class_id)to, fspath, path, filename); -#else /* HAVE_LIBRCC */ - return NULL; -#endif /* HAVE_LIBRCC */ -} - -const char *xmms_rcc_string(const char *buf) { -#ifdef HAVE_LIBRCC - return rccGetString((const rcc_string)buf); -#else /* HAVE_LIBRCC */ - return buf; -#endif /* HAVE_LIBRCC */ -} - -const char *xmms_rcc_get_language() { - const char *lang; -#ifdef HAVE_LIBRCC - lang = rccGetCurrentLanguageName(ctx); -#else /* HAVE_LIBRCC */ - lang = NULL; -#endif /* HAVE_LIBRCC */ - return xmms_rcc_get_639_2_name(lang); -} - -#define ID3_ENCODING_ISO_8859_1 0x00 -#define ID3_ENCODING_UTF16 0x01 -#define ID3_ENCODING_UTF16BE 0x02 -#define ID3_ENCODING_UTF8 0x03 - -int xmms_rcc_get_id3v2_encoding() { -#ifdef HAVE_LIBRCC - const char *name; - - name = rccGetCurrentCharsetName(ctx, (rcc_class_id)XMMS_RCC_ID3V2); - if (!name) return ID3_ENCODING_ISO_8859_1; - - if ((!strcasecmp(name,"UTF-8"))||(!strcasecmp(name,"UTF8"))) return ID3_ENCODING_UTF8; - if ((!strcasecmp(name,"UTF-16"))||(!strcasecmp(name,"UTF16"))||(!strcasecmp(name,"UTF16LE"))||(!strcasecmp(name,"UTF-16LE"))) return ID3_ENCODING_UTF16; - if ((!strcasecmp(name,"UTF-16BE"))||(!strcasecmp(name,"UTF16BE"))) return ID3_ENCODING_UTF16BE; -#endif /* HAVE_LIBRCC */ - - return ID3_ENCODING_ISO_8859_1; -} diff --git a/source/rcc.h b/source/rcc.h deleted file mode 100644 index d5bc9b2..0000000 --- a/source/rcc.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _XMMS_CHARSET_H -#define _XMMS_CHARSET_H - -typedef enum xmms_rcc_class_t { - XMMS_RCC_ID3 = 0, - XMMS_RCC_ID3V2, - XMMS_RCC_PL, - XMMS_RCC_PLFS, - XMMS_RCC_FS, - XMMS_RCC_OUT, - XMMS_RCC_CTYPE, - XMMS_RCC_UTF8 -} xmms_rcc_class; - -void xmms_rcc_init(); -void xmms_rcc_free(); -void xmms_rcc_prefswin_create(void *prefswin_notebook); -void xmms_rcc_prefswin_apply(); - -char *xmms_rcc_fs2pl(const char *fnstring, const char *filename); -char *xmms_rcc_get(xmms_rcc_class charset, const char *buf); -char *xmms_rcc_put(xmms_rcc_class charset, const char *buf); -char *xmms_rcc_sized_put(xmms_rcc_class charset, const char *buf, int size); -char *xmms_rcc_recode(xmms_rcc_class from, xmms_rcc_class to, const char *buf); -char *xmms_rcc_sized_recode(xmms_rcc_class from, xmms_rcc_class to, const char *buf, int size); -char *xmms_rcc_fs(xmms_rcc_class from, xmms_rcc_class to, const char *fspath, const char *path, const char *filename); - -const char *xmms_rcc_string(const char *buf); -const char *xmms_rcc_get_language(); -int xmms_rcc_get_id3v2_encoding(); - -#endif /* _XMMS_CHARSET_H */ diff --git a/source/rcc_langs.h b/source/rcc_langs.h deleted file mode 100644 index 70abebf..0000000 --- a/source/rcc_langs.h +++ /dev/null @@ -1,120 +0,0 @@ -typedef struct xmms_rcc_langs_t { - const char *sn; - const char *name; -} xmms_rcc_langs; - -static const char *default_lang = "XXX"; -static xmms_rcc_langs langs[] = { - { "aa", "aar" }, - { "ab", "abk" }, - { "af", "afr" }, - { "ak", "aka" }, - { "am", "amh" }, - { "ar", "ara" }, - { "an", "arg" }, - { "as", "asm" }, - { "av", "ava" }, - { "ae", "ave" }, - { "ay", "aym" }, - { "ba", "bak" }, - { "bm", "bam" }, - { "bn", "ben" }, - { "bh", "bih" }, - { "bi", "bis" }, - { "bs", "bos" }, - { "br", "bre" }, - { "bg", "bul" }, - { "ch", "cha" }, - { "cv", "chv" }, - { "kw", "cor" }, - { "co", "cos" }, - { "cr", "cre" }, - { "dv", "div" }, - { "dz", "dzo" }, - { "en", "eng" }, - { "et", "est" }, - { "fj", "fij" }, - { "fi", "fin" }, - { "fy", "fry" }, - { "ff", "ful" }, - { "ig", "ibo" }, - { "io", "ido" }, - { "iu", "iku" }, - { "ie", "ile" }, - { "ik", "ipk" }, - { "it", "ita" }, - { "jv", "jav" }, - { "ja", "jpn" }, - { "kn", "kan" }, - { "ks", "kas" }, - { "kr", "kau" }, - { "kk", "kaz" }, - { "km", "khm" }, - { "rw", "kin" }, - { "ky", "kir" }, - { "kv", "kom" }, - { "kg", "kon" }, - { "ku", "kur" }, - { "lo", "lao" }, - { "la", "lat" }, - { "lv", "lav" }, - { "ln", "lin" }, - { "lt", "lit" }, - { "lg", "lug" }, - { "mh", "mah" }, - { "ml", "mal" }, - { "mr", "mar" }, - { "mg", "mlg" }, - { "mt", "mlt" }, - { "mo", "mol" }, - { "mn", "mon" }, - { "na", "nau" }, - { "ng", "ndo" }, - { "oj", "oji" }, - { "or", "ori" }, - { "om", "orm" }, - { "pi", "pli" }, - { "ps", "pus" }, - { "qu", "que" }, - { "rn", "run" }, - { "ru", "rus" }, - { "sg", "sag" }, - { "sa", "san" }, - { "sn", "sna" }, - { "sd", "snd" }, - { "so", "som" }, - { "sc", "srd" }, - { "ss", "ssw" }, - { "sw", "swa" }, - { "ty", "tah" }, - { "ta", "tam" }, - { "tg", "tgk" }, - { "tl", "tgl" }, - { "ti", "tir" }, - { "tn", "tsn" }, - { "ts", "tso" }, - { "tr", "tur" }, - { "tw", "twi" }, - { "uk", "ukr" }, - { "ur", "urd" }, - { "uz", "uzb" }, - { "vi", "vie" }, - { "wa", "wln" }, - { "wo", "wol" }, - { "xh", "xho" }, - { "yi", "yid" }, - { "yo", "yor" }, - { "zu", "zul" }, - { NULL, NULL } -}; - -const char *xmms_rcc_get_639_2_name(const char *sn) { - unsigned int i; - - if ((!sn)||(!strcasecmp(sn, "off"))) return default_lang; - - for (i=0; langs[i].sn; i++) - if (!strcasecmp(sn, langs[i].sn)) return langs[i].name; - - return default_lang; -} -- cgit v1.2.1