summaryrefslogtreecommitdiffstats
path: root/3rdparty/mpg123
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2021-03-27 03:05:19 +0100
committerSuren A. Chilingaryan <csa@suren.me>2021-03-27 03:05:19 +0100
commit448f6f91c7bd14d9e4ad26ac4793a9d59845c0cd (patch)
tree825f7f2839435991f7148f1cebdb29813b9d34e2 /3rdparty/mpg123
parent86973510c4730cc7d25fcf7442ebb49ddefcaec0 (diff)
downloadrusxmms2-448f6f91c7bd14d9e4ad26ac4793a9d59845c0cd.tar.gz
rusxmms2-448f6f91c7bd14d9e4ad26ac4793a9d59845c0cd.tar.bz2
rusxmms2-448f6f91c7bd14d9e4ad26ac4793a9d59845c0cd.tar.xz
rusxmms2-448f6f91c7bd14d9e4ad26ac4793a9d59845c0cd.zip
Restructure to make XMMS just one of the patches
Diffstat (limited to '3rdparty/mpg123')
-rw-r--r--3rdparty/mpg123/0050_all_libxmms-charset.patch191
-rw-r--r--3rdparty/mpg123/2011_all_mpg123-http-seek.patch201
-rw-r--r--3rdparty/mpg123/2012_all_mpg123-id3convert.patch41
-rw-r--r--3rdparty/mpg123/2013_all_mpg123-latin-id3.patch128
-rw-r--r--3rdparty/mpg123/2014_all_mpg123-encode-override.patch130
-rw-r--r--3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch2247
-rw-r--r--3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch766
7 files changed, 0 insertions, 3704 deletions
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 <string.h>
- #include <stdlib.h>
- #include <pthread.h>
-@@ -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 <havardk@xmms.org>
-- *
-- * Licensed under GNU GPL version 2.
-- *
-- */
--#include "config.h"
--
--#include <stdlib.h>
--#include <glib.h>
--
--#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 <gdk/gdkkeysyms.h>
- #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 <sys/types.h>
- #include <sys/uio.h>
-+#include <sys/stat.h>
- #include <glib.h>
- #include <fcntl.h>
- #include <unistd.h>
-@@ -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); /* <encode>XXXComments\0<comment><\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 <glib.h>
-+#include <string.h>
-
- /*
- * 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 <mh@mpg123.de>\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 <openssl/ssl.h>
-+#include <openssl/err.h>
-+#include <openssl/x509.h>
-+#include <openssl/pem.h>
-+#include <openssl/crypto.h>
-+#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 <openssl/ssl.h>
-+#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;
-