From 448f6f91c7bd14d9e4ad26ac4793a9d59845c0cd Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Sat, 27 Mar 2021 03:05:19 +0100 Subject: Restructure to make XMMS just one of the patches --- 3rdparty/mpg123/0050_all_libxmms-charset.patch | 191 -- 3rdparty/mpg123/2011_all_mpg123-http-seek.patch | 201 -- 3rdparty/mpg123/2012_all_mpg123-id3convert.patch | 41 - 3rdparty/mpg123/2013_all_mpg123-latin-id3.patch | 128 -- .../mpg123/2014_all_mpg123-encode-override.patch | 130 -- 3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch | 2247 -------------------- 3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch | 766 ------- 7 files changed, 3704 deletions(-) delete mode 100644 3rdparty/mpg123/0050_all_libxmms-charset.patch delete mode 100644 3rdparty/mpg123/2011_all_mpg123-http-seek.patch delete mode 100644 3rdparty/mpg123/2012_all_mpg123-id3convert.patch delete mode 100644 3rdparty/mpg123/2013_all_mpg123-latin-id3.patch delete mode 100644 3rdparty/mpg123/2014_all_mpg123-encode-override.patch delete mode 100644 3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch delete mode 100644 3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch (limited to '3rdparty/mpg123') diff --git a/3rdparty/mpg123/0050_all_libxmms-charset.patch b/3rdparty/mpg123/0050_all_libxmms-charset.patch deleted file mode 100644 index 94416dd..0000000 --- a/3rdparty/mpg123/0050_all_libxmms-charset.patch +++ /dev/null @@ -1,191 +0,0 @@ -diff -Naur xmms-1.2.10-20041012/libxmms/charset.c xmms-1.2.10-20041012.convert/libxmms/charset.c ---- xmms-1.2.10-20041012/libxmms/charset.c 2004-10-13 01:03:03.258234924 -0700 -+++ xmms-1.2.10-20041012.convert/libxmms/charset.c 2004-10-24 23:49:42.083591275 -0700 -@@ -22,7 +22,6 @@ - - #include "charset.h" - -- - char* xmms_charset_get_current(void) - { - char *charset = getenv("CHARSET"); -@@ -38,6 +37,18 @@ - return charset; - } - -+static size_t utf16_strlen(const char *string) -+{ -+ size_t len = 0; -+ -+ if (!string) -+ return 0; -+ -+ while (*(string + len) != 0 || *(string + len + 1) != 0) -+ len += 2; -+ -+ return len; -+} - - #ifdef HAVE_ICONV - char* xmms_charset_convert(const char *string, size_t insize, char *from, char *to) -@@ -108,15 +119,55 @@ - { - if (!string) - return NULL; -+ - return xmms_charset_convert(string, strlen(string), "UTF-8", NULL); - } - -+char *xmms_charset_from_utf16(const unsigned char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return xmms_charset_convert(string, utf16_strlen(string), "UTF-16", NULL); -+} -+ -+char *xmms_charset_from_utf16be(const unsigned char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return xmms_charset_convert(string, utf16_strlen(string), "UTF-16BE", NULL); -+} -+ -+char* xmms_charset_from_latin1(const char *string) -+{ -+ char *to = xmms_charset_get_current(); -+ -+ if (!string) -+ return NULL; -+ -+ if (!strcmp(to, "UTF-8")) -+ return xmms_charset_convert(string, strlen(string), "ISO-8859-1", to); -+ else -+ return g_strdup(string); -+} -+ - #else - - char* xmms_charset_convert(const char *string, size_t insize, char *from, char *to) - { -+ if (!string) -+ return NULL; -+ - if (!strcmp(from, "UTF-8") && !to) - return xmms_charset_from_utf8(string); -+ -+ if (!strcmp(from, "UTF-16") && !to) -+ return xmms_charset_from_utf16(string); -+ -+ if (!strcmp(from, "UTF-16BE") && !to) -+ return xmms_charset_from_utf16be(string); -+ - return g_strdup(string); - } - -@@ -155,11 +206,83 @@ - return ascii; - } - -+static char* utf16_to_ascii(const unsigned char *utf16, int le) -+{ -+ char *ascii; -+ unsigned int i, len, c; -+ -+ if (!utf16) -+ return NULL; -+ -+ len = utf16_strlen(utf16) / 2 + 1; -+ -+ ascii = g_malloc(len + 1); -+ -+ for (i = 0, c = 0; i < len; i++) -+ { -+ guint16 uc; -+ int o = i << 1; -+ -+ if (le) -+ uc = *(utf16 + o) | *(utf16 + o + 1) << 8; -+ else -+ uc = *(utf16 + o) << 8 | *(utf16 + o + 1); -+ -+ /* Skip BOM and surrogate pairs */ -+ if (uc == 0xfeff || (uc >= 0xd800 && uc <= 0xdfff)) -+ continue; -+ -+ if (uc < 0x80) -+ ascii[c] = uc; -+ else -+ ascii[c] = '?'; -+ c++; -+ } -+ -+ ascii[c] = 0; -+ return ascii; -+} -+ -+char *xmms_charset_from_utf16(const unsigned char *string) -+{ -+ int le = FALSE; -+ guint16 bom; -+ -+ if (!string) -+ return NULL; -+ -+ bom = *string << 8 | *(string + 1); -+ -+ if (bom == 0xfffe) -+ le = TRUE; -+ else if (bom != 0xfeff) -+ return g_strdup(""); -+ -+ return utf16_to_ascii(string, le); -+} -+ -+char *xmms_charset_from_utf16be(const unsigned char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return utf16_to_ascii(string, FALSE); -+} -+ -+char* xmms_charset_from_latin1(const char *string) -+{ -+ if (!string) -+ return NULL; -+ -+ return g_strdup(string); -+} -+ - #endif - - char* xmms_charset_to_utf8(const char *string) - { - if (!string) - return NULL; -+ - return xmms_charset_convert(string, strlen(string), NULL, "UTF-8"); - } -diff -Naur xmms-1.2.10-20041012/libxmms/charset.h xmms-1.2.10-20041012.convert/libxmms/charset.h ---- xmms-1.2.10-20041012/libxmms/charset.h 2004-10-13 01:03:03.260234595 -0700 -+++ xmms-1.2.10-20041012.convert/libxmms/charset.h 2004-10-23 08:54:11.421220833 -0700 -@@ -5,11 +5,16 @@ - * - */ - -+#ifndef XMMS_CHARSET_H -+#define XMMS_CHARSET_H - - char* xmms_charset_get_current(void); - char* xmms_charset_convert(const char *string, size_t insize, char *from, char *to); - char* xmms_charset_to_utf8(const char *string); - char* xmms_charset_from_utf8(const char *string); -+char* xmms_charset_from_utf16(const unsigned char *string); -+char* xmms_charset_from_utf16be(const unsigned char *string); -+char* xmms_charset_from_latin1(const char *string); - -- -+#endif /* XMMS_CHARSET_H */ - diff --git a/3rdparty/mpg123/2011_all_mpg123-http-seek.patch b/3rdparty/mpg123/2011_all_mpg123-http-seek.patch deleted file mode 100644 index 67ab4f5..0000000 --- a/3rdparty/mpg123/2011_all_mpg123-http-seek.patch +++ /dev/null @@ -1,201 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/mpg123/common.c xmms-1.2.11-new/Input/mpg123/common.c ---- xmms-1.2.11/Input/mpg123/common.c 2005-05-15 02:01:19.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/common.c 2007-11-24 23:52:01.000000000 +0100 -@@ -148,19 +148,34 @@ - int mpg123_stream_jump_to_frame(struct frame *fr, int frame) - { - if (!filept) -- return -1; -- mpg123_read_frame_init(); -- fseek(filept, frame * (fr->framesize + 4), SEEK_SET); -- mpg123_read_frame(fr); -+ { -+ unsigned long r; -+ -+ r = frame * (fr->framesize + 4); -+ mpg123_stream_close(); -+ mpg123_open_stream(mpg123_filename, -1, r); -+ } -+ else -+ { -+ mpg123_read_frame_init(); -+ fseek(filept, frame * (fr->framesize + 4), SEEK_SET); -+ mpg123_read_frame(fr); -+ } - return 0; - } - - int mpg123_stream_jump_to_byte(struct frame *fr, int byte) - { - if (!filept) -- return -1; -- fseek(filept, byte, SEEK_SET); -- mpg123_read_frame(fr); -+ { -+ mpg123_stream_close(); -+ mpg123_open_stream(mpg123_filename, -1, (unsigned long)byte); -+ } -+ else -+ { -+ fseek(filept, byte, SEEK_SET); -+ mpg123_read_frame(fr); -+ } - return 0; - } - -@@ -446,14 +461,14 @@ - return 1; - } - --void mpg123_open_stream(char *bs_filenam, int fd) -+void mpg123_open_stream(char *bs_filenam, int fd, unsigned long range) - { - filept_opened = 1; - if (!strncasecmp(bs_filenam, "http://", 7)) - { - filept = NULL; -- mpg123_http_open(bs_filenam); - mpg123_info->filesize = 0; -+ mpg123_http_open(bs_filenam, range); - mpg123_info->network_stream = TRUE; - } - else -diff -dPNur xmms-1.2.11/Input/mpg123/http.c xmms-1.2.11-new/Input/mpg123/http.c ---- xmms-1.2.11/Input/mpg123/http.c 2007-11-16 22:51:24.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/http.c 2007-11-24 23:52:01.000000000 +0100 -@@ -50,6 +50,7 @@ - extern gboolean mpg123_stereo; - - static gboolean prebuffering, going, eof = FALSE; -+static unsigned long range; - static gint sock, rd_index, wr_index, buffer_length, prebuffer_length; - static guint64 buffer_read = 0; - static gchar *buffer; -@@ -326,7 +327,7 @@ - static void *http_buffer_loop(void *arg) - { - gchar line[1024], *user, *pass, *host, *filename, -- *status, *url, *temp, *file; -+ *status, *url, *temp, *temp2, *file; - gchar *chost; - gint cnt, written, error, port, cport; - socklen_t err_len; -@@ -495,15 +496,22 @@ - } - else - file = g_strconcat("/", filename, NULL); -- temp = g_strdup_printf("GET %s HTTP/1.0\r\n" -+ if (range) -+ { -+ temp2 = g_strdup_printf("Range: bytes=%lu-\r\n", range); -+ } else -+ temp2 = NULL; -+ temp = g_strdup_printf("GET %s HTTP/1.1\r\n" - "Host: %s\r\n" - "User-Agent: %s/%s\r\n" -- "%s%s%s%s\r\n", -+ "%s%s%s%s%s\r\n", - file, host, PACKAGE, VERSION, - proxy_auth ? proxy_auth : "", auth ? auth : "", - mpg123_cfg.cast_title_streaming ? "Icy-MetaData:1\r\n" : "", -- mpg123_cfg.use_udp_channel ? udpspace : ""); -- -+ mpg123_cfg.use_udp_channel ? udpspace : "", -+ range ? temp2 : ""); -+ -+ g_free(temp2); - g_free(file); - if(proxy_auth) - g_free(proxy_auth); -@@ -587,7 +595,9 @@ - #endif - /* udp_serverport = atoi (line + 20); */ - } -- -+ if (!strncasecmp(line, "content-length:", 15)) { -+ mpg123_info->filesize = atoi(line + 15); -+ } - } - else - { -@@ -719,7 +729,7 @@ - pthread_exit(NULL); - } - --int mpg123_http_open(gchar * _url) -+int mpg123_http_open(gchar * _url, unsigned long rng) - { - gchar *url; - -@@ -735,6 +745,7 @@ - going = TRUE; - eof = FALSE; - buffer = g_malloc(buffer_length); -+ range = rng; - - pthread_create(&thread, NULL, http_buffer_loop, url); - -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2006-07-25 05:18:51.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:52:01.000000000 +0100 -@@ -857,7 +857,7 @@ - - mpg123_read_frame_init(); - -- mpg123_open_stream(filename, -1); -+ mpg123_open_stream(filename, -1, 0); - if (mpg123_info->eof || !mpg123_read_frame(&fr)) - mpg123_info->eof = TRUE; - if (!mpg123_info->eof && mpg123_info->going) -@@ -906,7 +906,7 @@ - break; - } - -- if (!have_xing_header && strncasecmp(filename, "http://", 7)) -+ if(!have_xing_header && mpg123_info->filesize != 0) - mpg123_info->num_frames = mpg123_calc_numframes(&fr); - - memcpy(&fr, &temp_fr, sizeof(struct frame)); -@@ -918,11 +918,10 @@ - mpg123_lsf = fr.lsf; - mpg123_mpeg25 = fr.mpeg25; - mpg123_mode = fr.mode; -- -+ mpg123_length = mpg123_info->num_frames * mpg123_info->tpf * 1000; -+ - if (strncasecmp(filename, "http://", 7)) - { -- mpg123_length = -- mpg123_info->num_frames * mpg123_info->tpf * 1000; - if (!mpg123_title) - mpg123_title = get_song_title(NULL,filename); - } -@@ -930,7 +929,6 @@ - { - if (!mpg123_title) - mpg123_title = mpg123_http_get_title(filename); -- mpg123_length = -1; - } - mpg123_ip.set_info(mpg123_title, mpg123_length, - mpg123_bitrate * 1000, -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.h xmms-1.2.11-new/Input/mpg123/mpg123.h ---- xmms-1.2.11/Input/mpg123/mpg123.h 2006-07-24 00:32:44.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.h 2007-11-24 23:52:01.000000000 +0100 -@@ -176,7 +176,7 @@ - - /* ------ Declarations from "http.c" ------ */ - --extern int mpg123_http_open(char *url); -+extern int mpg123_http_open(char *url, unsigned long rng); - int mpg123_http_read(gpointer data, gint length); - void mpg123_http_close(void); - char *mpg123_http_get_title(char * url); -@@ -188,7 +188,7 @@ - extern unsigned int mpg123_getbits(int); - extern unsigned int mpg123_getbits_fast(int); - --extern void mpg123_open_stream(char *bs_filenam, int fd); -+extern void mpg123_open_stream(char *bs_filenam, int fd, unsigned long range); - extern int mpg123_head_check(unsigned long); - extern void mpg123_stream_close(void); - diff --git a/3rdparty/mpg123/2012_all_mpg123-id3convert.patch b/3rdparty/mpg123/2012_all_mpg123-id3convert.patch deleted file mode 100644 index 8c1b76b..0000000 --- a/3rdparty/mpg123/2012_all_mpg123-id3convert.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:53:33.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:55:43.000000000 +0100 -@@ -2,6 +2,7 @@ - #include "id3_header.h" - #include "libxmms/configfile.h" - #include "libxmms/titlestring.h" -+#include "libxmms/charset.h" - #include - #include - #include -@@ -400,6 +401,14 @@ - return ext; - } - -+static char *convert_id3v1_field(const char *v1field, unsigned len) -+{ -+ char *tmp = g_strndup(v1field, len); -+ char *v2field = xmms_charset_from_latin1(g_strstrip(tmp)); -+ g_free(tmp); -+ return v2field; -+} -+ - /* - * Function id3v1_to_id3v2 (v1, v2) - * -@@ -411,10 +420,10 @@ - char *year; - struct id3v2tag_t *v2 = g_malloc0(sizeof (struct id3v2tag_t)); - -- v2->title = g_strstrip(g_strndup(v1->title, 30)); -- v2->artist = g_strstrip(g_strndup(v1->artist, 30)); -- v2->album = g_strstrip(g_strndup(v1->album, 30)); -- v2->comment = g_strstrip(g_strndup(v1->u.v1_0.comment, 30)); -+ v2->title = convert_id3v1_field(v1->title, 30); -+ v2->artist = convert_id3v1_field(v1->artist, 30); -+ v2->album = convert_id3v1_field(v1->album, 30); -+ v2->comment = convert_id3v1_field(v1->u.v1_0.comment, 30); - v2->genre = g_strstrip(g_strdup(mpg123_get_id3_genre(v1->genre))); - - year = g_strndup(v1->year, 4); diff --git a/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch b/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch deleted file mode 100644 index b1d33cd..0000000 --- a/3rdparty/mpg123/2013_all_mpg123-latin-id3.patch +++ /dev/null @@ -1,128 +0,0 @@ -diff -Naur xmms-1.2.10-20041012/Input/mpg123/Makefile.am xmms-1.2.10-20041012.id3latin/Input/mpg123/Makefile.am ---- xmms-1.2.10-20041012/Input/mpg123/Makefile.am 2004-10-13 01:03:03.186246768 -0700 -+++ xmms-1.2.10-20041012.id3latin/Input/mpg123/Makefile.am 2004-10-23 08:52:23.370409147 -0700 -@@ -15,7 +15,7 @@ - dxhead.c dxhead.h \ - id3.c id3.h \ - id3_frame.c id3_frame_content.c id3_frame_text.c id3_frame_url.c \ --id3_header.h id3_tag.c unicode.c -+id3_header.h id3_tag.c - - if ARCH_X86 - -diff -Naur xmms-1.2.10-20041012/Input/mpg123/id3_frame_text.c xmms-1.2.10-20041012.id3latin/Input/mpg123/id3_frame_text.c ---- xmms-1.2.10-20041012/Input/mpg123/id3_frame_text.c 2004-10-13 01:03:03.201244300 -0700 -+++ xmms-1.2.10-20041012.id3latin/Input/mpg123/id3_frame_text.c 2004-10-23 09:15:29.117825260 -0700 -@@ -60,13 +60,13 @@ - switch (encoding) - { - case ID3_ENCODING_ISO_8859_1: -- return g_strdup(text); -+ return xmms_charset_from_latin1(text); - case ID3_ENCODING_UTF8: - return xmms_charset_from_utf8(text); - case ID3_ENCODING_UTF16: -- return convert_from_utf16(text); -+ return xmms_charset_from_utf16(text); - case ID3_ENCODING_UTF16BE: -- return convert_from_utf16be(text); -+ return xmms_charset_from_utf16be(text); - default: - return NULL; - } -diff -Naur xmms-1.2.10-20041012/Input/mpg123/unicode.c xmms-1.2.10-20041012.id3latin/Input/mpg123/unicode.c ---- xmms-1.2.10-20041012/Input/mpg123/unicode.c 2004-10-13 01:03:03.215241997 -0700 -+++ xmms-1.2.10-20041012.id3latin/Input/mpg123/unicode.c 1969-12-31 16:00:00.000000000 -0800 -@@ -1,92 +0,0 @@ --/* -- * Copyright (C) 2004 Haavard Kvaalen -- * -- * Licensed under GNU GPL version 2. -- * -- */ --#include "config.h" -- --#include --#include -- --#include "libxmms/charset.h" -- --size_t utf16_strlen(const char *string) --{ -- size_t len = 0; -- -- while (*(string + len) != 0 || *(string + len + 1) != 0) -- len += 2; -- -- return len; --} -- --#ifdef HAVE_ICONV -- --char *convert_from_utf16(const unsigned char *utf16) --{ -- return xmms_charset_convert(utf16, utf16_strlen(utf16), "UTF-16", NULL); --} -- --char *convert_from_utf16be(const unsigned char *utf16) --{ -- return xmms_charset_convert(utf16, utf16_strlen(utf16), "UTF-16BE", NULL); --} -- -- --#else -- -- --static char* to_ascii(const unsigned char *utf16, int le) --{ -- char *ascii; -- unsigned int i, len, c; -- -- len = utf16_strlen(utf16) / 2 + 1; -- -- ascii = g_malloc(len + 1); -- -- for (i = 0, c = 0; i < len; i++) -- { -- guint16 uc; -- int o = i << 1; -- -- if (le) -- uc = *(utf16 + o) | *(utf16 + o + 1) << 8; -- else -- uc = *(utf16 + o) << 8 | *(utf16 + o + 1); -- -- /* Skip BOM and surrogate pairs */ -- if (uc == 0xfeff || (uc >= 0xd800 && uc <= 0xdfff)) -- continue; -- -- if (uc < 0x80) -- ascii[c] = uc; -- else -- ascii[c] = '?'; -- c++; -- } -- -- ascii[c] = 0; -- return ascii; --} -- --char *convert_from_utf16(const unsigned char *utf16) --{ -- int le = FALSE; -- guint16 bom = *utf16 << 8 | *(utf16 + 1); -- -- if (bom == 0xfffe) -- le = TRUE; -- else if (bom != 0xfeff) -- return g_strdup(""); -- -- return to_ascii(utf16, le); --} -- --char *convert_from_utf16be(const unsigned char *utf16) --{ -- return to_ascii(utf16, FALSE); --} -- --#endif diff --git a/3rdparty/mpg123/2014_all_mpg123-encode-override.patch b/3rdparty/mpg123/2014_all_mpg123-encode-override.patch deleted file mode 100644 index 5c27f66..0000000 --- a/3rdparty/mpg123/2014_all_mpg123-encode-override.patch +++ /dev/null @@ -1,130 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/mpg123/configure.c xmms-1.2.11-new/Input/mpg123/configure.c ---- xmms-1.2.11/Input/mpg123/configure.c 2005-05-15 02:01:19.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/configure.c 2007-11-24 23:57:29.000000000 +0100 -@@ -27,6 +27,7 @@ - static GtkWidget *streaming_proxy_hbox, *streaming_proxy_auth_hbox, *streaming_save_dirbrowser; - static GtkWidget *streaming_save_hbox, *title_id3_box, *title_tag_desc; - static GtkWidget *title_override, *title_id3_entry, *title_id3v2_disable; -+static GtkWidget *id3v2_encoding_override, *id3v2_encoding_box, *encoding_entry; - - MPG123Config mpg123_cfg; - -@@ -105,6 +106,8 @@ - mpg123_cfg.disable_id3v2 = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(title_id3v2_disable)); - g_free(mpg123_cfg.id3_format); - mpg123_cfg.id3_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(title_id3_entry))); -+ mpg123_cfg.id3v2_encoding_override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(id3v2_encoding_override)); -+ mpg123_cfg.id3v2_default_encoding = g_strdup(gtk_entry_get_text(GTK_ENTRY(encoding_entry))); - - filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); - cfg = xmms_cfg_open_file(filename); -@@ -134,6 +137,8 @@ - xmms_cfg_write_boolean(cfg, "MPG123", "title_override", mpg123_cfg.title_override); - xmms_cfg_write_boolean(cfg, "MPG123", "disable_id3v2", mpg123_cfg.disable_id3v2); - xmms_cfg_write_string(cfg, "MPG123", "id3_format", mpg123_cfg.id3_format); -+ xmms_cfg_write_boolean(cfg, "MPG123", "id3v2_encoding_override", mpg123_cfg.id3v2_encoding_override); -+ xmms_cfg_write_string(cfg, "MPG123", "id3v2_default_encoding", mpg123_cfg.id3v2_default_encoding); - xmms_cfg_write_int(cfg, "MPG123", "detect_by", mpg123_cfg.detect_by); - #ifdef USE_SIMD - xmms_cfg_write_int(cfg, "MPG123", "default_synth", mpg123_cfg.default_synth); -@@ -212,6 +217,13 @@ - gtk_widget_set_sensitive(title_tag_desc, override); - } - -+static void id3v2_encoding_override_cb(GtkWidget * w, gpointer data) -+{ -+ gboolean override; -+ override = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(id3v2_encoding_override)); -+ gtk_widget_set_sensitive(id3v2_encoding_box, override); -+} -+ - static void configure_destroy(GtkWidget * w, gpointer data) - { - if (streaming_save_dirbrowser) -@@ -230,6 +242,7 @@ - GtkWidget *streaming_save_label, *streaming_save_browse; - GtkWidget *streaming_cast_frame, *streaming_cast_vbox; - GtkWidget *title_frame, *title_id3_vbox, *title_id3_label; -+ GtkWidget *title_id3_label2; - GtkWidget *bbox, *ok, *cancel; - - char *temp; -@@ -576,6 +589,23 @@ - title_tag_desc = xmms_titlestring_descriptions("pafFetnygc", 2); - gtk_widget_set_sensitive(title_tag_desc, mpg123_cfg.title_override); - gtk_box_pack_start(GTK_BOX(title_id3_vbox), title_tag_desc, FALSE, FALSE, 0); -+ -+ id3v2_encoding_override = gtk_check_button_new_with_label(_("Override default ID3V2 encoding")); -+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(id3v2_encoding_override), mpg123_cfg.id3v2_encoding_override); -+ gtk_signal_connect(GTK_OBJECT(id3v2_encoding_override), "clicked", id3v2_encoding_override_cb, NULL); -+ gtk_box_pack_start(GTK_BOX(title_id3_vbox), id3v2_encoding_override, FALSE, FALSE, 0); -+ -+ id3v2_encoding_box = gtk_hbox_new(FALSE, 5); -+ gtk_widget_set_sensitive(id3v2_encoding_box, mpg123_cfg.id3v2_encoding_override); -+ gtk_box_pack_start(GTK_BOX(title_id3_vbox), id3v2_encoding_box, FALSE, FALSE, 0); -+ -+ title_id3_label2 = gtk_label_new(_("Encoding name:")); -+ gtk_box_pack_start(GTK_BOX(id3v2_encoding_box), title_id3_label2, FALSE, FALSE, 0); -+ -+ encoding_entry = gtk_entry_new(); -+ gtk_entry_set_text(GTK_ENTRY(encoding_entry), mpg123_cfg.id3v2_default_encoding); -+ gtk_box_pack_start(GTK_BOX(id3v2_encoding_box), encoding_entry, TRUE, TRUE, 0); -+ - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), title_frame, gtk_label_new(_("Title"))); - - bbox = gtk_hbutton_box_new(); -diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame_text.c xmms-1.2.11-new/Input/mpg123/id3_frame_text.c ---- xmms-1.2.11/Input/mpg123/id3_frame_text.c 2007-11-24 23:57:15.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/id3_frame_text.c 2007-11-24 23:57:29.000000000 +0100 -@@ -29,6 +29,8 @@ - - #include "libxmms/charset.h" - -+/* For extern mpg123_cfg */ -+#include "mpg123.h" - - /* Get size of string in bytes including null. */ - guint id3_string_size(guint8 encoding, const char* text) -@@ -60,6 +62,9 @@ - switch (encoding) - { - case ID3_ENCODING_ISO_8859_1: -+ if (mpg123_cfg.id3v2_encoding_override) { -+ return xmms_charset_convert(text, strlen(text), mpg123_cfg.id3v2_default_encoding, NULL); -+ } - return xmms_charset_from_latin1(text); - case ID3_ENCODING_UTF8: - return xmms_charset_from_utf8(text); -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:56:41.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:57:29.000000000 +0100 -@@ -171,6 +171,7 @@ - mpg123_cfg.use_udp_channel = FALSE; - mpg123_cfg.title_override = FALSE; - mpg123_cfg.disable_id3v2 = FALSE; -+ mpg123_cfg.id3v2_encoding_override = FALSE; - mpg123_cfg.detect_by = DETECT_EXTENSION; - mpg123_cfg.default_synth = SYNTH_AUTO; - -@@ -199,6 +200,9 @@ - xmms_cfg_read_boolean(cfg, "MPG123", "disable_id3v2", &mpg123_cfg.disable_id3v2); - if (!xmms_cfg_read_string(cfg, "MPG123", "id3_format", &mpg123_cfg.id3_format)) - mpg123_cfg.id3_format = g_strdup("%p - %t"); -+ xmms_cfg_read_boolean(cfg, "MPG123", "id3v2_encoding_override", &mpg123_cfg.id3v2_encoding_override); -+ if (!xmms_cfg_read_string(cfg, "MPG123", "id3v2_default_encoding", &mpg123_cfg.id3v2_default_encoding)) -+ mpg123_cfg.id3_format = g_strdup("ISO-8859-1"); - xmms_cfg_read_int(cfg, "MPG123", "detect_by", &mpg123_cfg.detect_by); - xmms_cfg_read_int(cfg, "MPG123", "default_synth", &mpg123_cfg.default_synth); - -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.h xmms-1.2.11-new/Input/mpg123/mpg123.h ---- xmms-1.2.11/Input/mpg123/mpg123.h 2007-11-24 23:53:33.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.h 2007-11-24 23:57:29.000000000 +0100 -@@ -159,6 +159,8 @@ - gboolean use_udp_channel; - gchar *id3_format; - gboolean title_override, disable_id3v2; -+ gboolean id3v2_encoding_override; -+ gchar *id3v2_default_encoding; - int detect_by; - int default_synth; - } diff --git a/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch b/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch deleted file mode 100644 index b1d47a2..0000000 --- a/3rdparty/mpg123/2015_all_mpg123-id3v2edit.patch +++ /dev/null @@ -1,2247 +0,0 @@ -diff -dPNur xmms-1.2.11/Input/mpg123/common.c xmms-1.2.11-new/Input/mpg123/common.c ---- xmms-1.2.11/Input/mpg123/common.c 2007-11-24 23:53:33.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/common.c 2007-11-24 23:58:41.000000000 +0100 -@@ -303,8 +303,8 @@ - mpg123_id3v2_destroy(tag); - id3_close(id3d); - } -- g_free(id3buf); - -+ g_free(id3buf); - return TRUE; - } - -diff -dPNur xmms-1.2.11/Input/mpg123/fileinfo.c xmms-1.2.11-new/Input/mpg123/fileinfo.c ---- xmms-1.2.11/Input/mpg123/fileinfo.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/fileinfo.c 2007-11-24 23:58:41.000000000 +0100 -@@ -27,42 +27,96 @@ - #include - #include "mpg123.h" - -+#define MAX_STR_LEN 100 -+#define MAX_ENTRY_LEN2 1023 -+ - static GtkWidget *window = NULL; --static GtkWidget *filename_entry, *id3_frame; --static GtkWidget *title_entry, *artist_entry, *album_entry, *year_entry; --static GtkWidget *tracknum_entry, *comment_entry, *genre_combo; -+static GtkWidget *notebook = NULL; -+static GtkWidget *filename_entry, *id3v1_frame, *id3v2_frame; -+static GtkWidget *v1_checkbox, *v2_checkbox; -+static GtkWidget *v1_title_entry, *v1_artist_entry, *v1_album_entry, *v1_year_entry, *v1_tracknum_entry, *v1_comment_entry; -+static GtkWidget *v2_title_entry, *v2_artist_entry, *v2_album_entry, *v2_year_entry, *v2_tracknum_entry, *v2_comment_entry, -+ *v2_composer_entry, *v2_orig_artist_entry, *v2_url_entry, *v2_encoded_by_entry; -+static GtkWidget *v1_genre_combo, *v2_genre_combo; - static GtkWidget *mpeg_level, *mpeg_bitrate, *mpeg_samplerate, *mpeg_flags; - static GtkWidget *mpeg_fileinfo; - -+static GPtrArray *v1_labels_list = NULL, *v2_labels_list = NULL; // TODO: Where will these be freed? - static GList *genre_list; - struct genre_item { - const char *name; - int id; - }; --static int current_genre; -+static int v1_current_genre; -+static int v2_current_genre; - static char *current_filename; - - extern char *mpg123_filename; - extern int mpg123_bitrate, mpg123_frequency, mpg123_layer, mpg123_lsf, mpg123_mode; - extern gboolean mpg123_stereo, mpg123_mpeg25; - --#define MAX_STR_LEN 100 -- --static void label_set_text(GtkWidget * label, char *str, ...) -+static void label_set_text(GtkWidget * label, const char *str, ...) - G_GNUC_PRINTF(2, 3); - --static void set_entry_tag(GtkEntry * entry, char * tag, int length) -+static void set_entry_tag_v1(GtkEntry * entry, const char * tag, int length) - { - char *text = g_strchomp(g_strndup(tag, length)); - gtk_entry_set_text(entry, text); - g_free(text); - } - --static void get_entry_tag(GtkEntry * entry, char * tag, int length) -+static void get_entry_tag_v1(GtkEntry * entry, char * tag, int length) - { - strncpy(tag, gtk_entry_get_text(entry), length); - } - -+void copy_entry_tag_v1(GtkEntry * src, GtkEntry * dest, int length) -+{ -+ set_entry_tag_v1(dest, gtk_entry_get_text(src), length); -+ return; -+} -+ -+static void set_entry_tag_v2(GtkEntry * entry, struct id3_tag* id3, guint32 frame_type) -+{ -+ struct id3_frame* frame; -+ -+ frame = id3_get_frame(id3, frame_type, 1); -+ if (frame != NULL) -+ { -+ char *text, *url, *comment; -+ -+ text = id3_get_text(frame); -+ if (text != NULL) -+ { -+ gtk_entry_set_text(entry, text); -+ g_free(text); -+ return; -+ } -+ -+ url = id3_get_url(frame); -+ if (url != NULL) -+ { -+ gtk_entry_set_text(entry, url); -+ g_free(url); -+ return; -+ } -+ -+ comment = id3_get_comment(frame); -+ if (comment != NULL) -+ { -+ gtk_entry_set_text(entry, comment); -+ g_free(url); -+ return; -+ } -+ } -+} -+ -+void copy_entry_tag_v2(GtkEntry * src, GtkEntry * dest) -+{ -+ gtk_entry_set_text(dest, gtk_entry_get_text(src)); -+ return; -+} -+ - static int genre_find_index(GList *genre_list, int id) - { - int idx = 0; -@@ -74,6 +128,24 @@ - idx++; - genre_list = genre_list->next; - } -+ if (!genre_list) -+ return 0; -+ return idx; -+} -+ -+static int genre_find_index_str(GList *genre_list, const char* str) -+{ -+ int idx = 0; -+ while (genre_list) -+ { -+ struct genre_item *item = genre_list->data; -+ if (strcmp(item->name, str) == 0) -+ break; -+ idx++; -+ genre_list = genre_list->next; -+ } -+ if (!genre_list) -+ return 0; - return idx; - } - -@@ -83,9 +155,9 @@ - return strcasecmp(ga->name, gb->name); - } - --static void save_cb(GtkWidget * w, gpointer data) -+static void remove_id3v1(void) - { -- int fd; -+ int fd, len; - struct id3v1tag_t tag; - char *msg = NULL; - -@@ -94,71 +166,36 @@ - - if ((fd = open(current_filename, O_RDWR)) != -1) - { -- int tracknum; -- -- lseek(fd, -128, SEEK_END); -+ len = lseek(fd, -128, SEEK_END); - read(fd, &tag, sizeof (struct id3v1tag_t)); - - if (!strncmp(tag.tag, "TAG", 3)) -- lseek(fd, -128, SEEK_END); -- else -- lseek(fd, 0, SEEK_END); -- tag.tag[0] = 'T'; -- tag.tag[1] = 'A'; -- tag.tag[2] = 'G'; -- get_entry_tag(GTK_ENTRY(title_entry), tag.title, 30); -- get_entry_tag(GTK_ENTRY(artist_entry), tag.artist, 30); -- get_entry_tag(GTK_ENTRY(album_entry), tag.album, 30); -- get_entry_tag(GTK_ENTRY(year_entry), tag.year, 4); -- tracknum = atoi(gtk_entry_get_text(GTK_ENTRY(tracknum_entry))); -- if (tracknum > 0) - { -- get_entry_tag(GTK_ENTRY(comment_entry), -- tag.u.v1_1.comment, 28); -- tag.u.v1_1.__zero = 0; -- tag.u.v1_1.track_number = MIN(tracknum, 255); -+ if (ftruncate(fd, len)) -+ msg = g_strdup_printf(_("%s\n" -+ "Unable to truncate file: %s"), -+ _("Couldn't remove tag!"), -+ strerror(errno)); - } -- else -- get_entry_tag(GTK_ENTRY(comment_entry), -- tag.u.v1_0.comment, 30); -- tag.genre = current_genre; -- if (write(fd, &tag, sizeof (tag)) != sizeof (tag)) -- msg = g_strdup_printf(_("%s\nUnable to write to file: %s"), -- _("Couldn't write tag!"), -- strerror(errno)); - close(fd); - } - else - msg = g_strdup_printf(_("%s\nUnable to open file: %s"), -- _("Couldn't write tag!"), -+ _("Couldn't remove tag!"), - strerror(errno)); - if (msg) - { -- GtkWidget *mwin = xmms_show_message(_("File Info"), msg, -- _("OK"), FALSE, NULL, NULL); -+ GtkWidget *mwin = xmms_show_message(_("File Info"), msg, _("OK"), -+ FALSE, NULL, NULL); - gtk_window_set_transient_for(GTK_WINDOW(mwin), - GTK_WINDOW(window)); - g_free(msg); - } -- else -- gtk_widget_destroy(window); --} -- --static void label_set_text(GtkWidget * label, char *str, ...) --{ -- va_list args; -- char tempstr[MAX_STR_LEN]; -- -- va_start(args, str); -- g_vsnprintf(tempstr, MAX_STR_LEN, str, args); -- va_end(args); -- -- gtk_label_set_text(GTK_LABEL(label), tempstr); - } - --static void remove_id3_cb(GtkWidget * w, gpointer data) -+static void save_cb(GtkWidget * w, gpointer data) - { -- int fd, len; -+ int fd; - struct id3v1tag_t tag; - char *msg = NULL; - -@@ -167,36 +204,112 @@ - - if ((fd = open(current_filename, O_RDWR)) != -1) - { -- len = lseek(fd, -128, SEEK_END); -- read(fd, &tag, sizeof (struct id3v1tag_t)); -+ if (!GTK_TOGGLE_BUTTON(v1_checkbox)->active) { -+ /* Try to save id3v1 tag */ -+ int tracknum; - -- if (!strncmp(tag.tag, "TAG", 3)) -- { -- if (ftruncate(fd, len)) -- msg = g_strdup_printf( -- _("%s\n" -- "Unable to truncate file: %s"), -- _("Couldn't remove tag!"), -- strerror(errno)); -+ lseek(fd, -128, SEEK_END); -+ read(fd, &tag, sizeof (struct id3v1tag_t)); -+ -+ if (!strncmp(tag.tag, "TAG", 3)) -+ lseek(fd, -128, SEEK_END); -+ else -+ lseek(fd, 0, SEEK_END); -+ tag.tag[0] = 'T'; -+ tag.tag[1] = 'A'; -+ tag.tag[2] = 'G'; -+ get_entry_tag_v1(GTK_ENTRY(v1_title_entry), tag.title, 30); -+ get_entry_tag_v1(GTK_ENTRY(v1_artist_entry), tag.artist, 30); -+ get_entry_tag_v1(GTK_ENTRY(v1_album_entry), tag.album, 30); -+ get_entry_tag_v1(GTK_ENTRY(v1_year_entry), tag.year, 4); -+ tracknum = atoi(gtk_entry_get_text(GTK_ENTRY(v1_tracknum_entry))); -+ if (tracknum > 0) -+ { -+ get_entry_tag_v1(GTK_ENTRY(v1_comment_entry), tag.u.v1_1.comment, 28); -+ tag.u.v1_1.__zero = 0; -+ tag.u.v1_1.track_number = MIN(tracknum, 255); -+ } -+ else -+ get_entry_tag_v1(GTK_ENTRY(v1_comment_entry), -+ tag.u.v1_0.comment, 30); -+ tag.genre = v1_current_genre; -+ if (write(fd, &tag, sizeof (tag)) != sizeof (tag)) -+ msg = g_strdup_printf(_("%s\nUnable to write to file: %s"), -+ _("Couldn't write tag!"), -+ strerror(errno)); -+ } else { -+ /* Remove the id3v1 tag from the file */ -+ remove_id3v1(); - } -- else -- msg = strdup(_("No tag to remove!")); -- close(fd); -+ -+ if (!GTK_TOGGLE_BUTTON(v2_checkbox)->active) { -+ struct id3_tag* id3; -+ -+ lseek(fd, SEEK_SET, 0); -+ id3 = id3_open_fd(fd, 0); -+ if (id3 == NULL) -+ id3 = id3_new(); -+ -+ if (id3 != NULL) -+ { -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TIT2), gtk_entry_get_text(GTK_ENTRY(v2_title_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TPE1), gtk_entry_get_text(GTK_ENTRY(v2_artist_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TALB), gtk_entry_get_text(GTK_ENTRY(v2_album_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TYER), gtk_entry_get_text(GTK_ENTRY(v2_year_entry))); -+ id3_set_comment(id3_get_or_add_frame(id3, ID3_COMM), gtk_entry_get_text(GTK_ENTRY(v2_comment_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TRCK), gtk_entry_get_text(GTK_ENTRY(v2_tracknum_entry))); -+ if (v2_current_genre != 0xff) -+ { -+ /* Essentially the same behavior as Winamp2's ID3v2 tagger */ -+ char genre[255]; -+ snprintf(genre, sizeof(genre), "(%d)%s", -+ v2_current_genre, -+ gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TCON), genre); -+ } -+ else -+ { -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TCON), gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry))); -+ } -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TCOM), gtk_entry_get_text(GTK_ENTRY(v2_composer_entry))); -+ id3_set_url(id3_get_or_add_frame(id3, ID3_WCOM), gtk_entry_get_text(GTK_ENTRY(v2_url_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TOPE), gtk_entry_get_text(GTK_ENTRY(v2_orig_artist_entry))); -+ id3_set_text(id3_get_or_add_frame(id3, ID3_TENC), gtk_entry_get_text(GTK_ENTRY(v2_encoded_by_entry))); -+ -+ id3_write_tag_filename(id3, current_filename); -+ } -+ -+ } else { -+ id3_remove_tag_filename(current_filename); -+ } -+ -+ if (fd) -+ close(fd); - } - else - msg = g_strdup_printf(_("%s\nUnable to open file: %s"), -- _("Couldn't remove tag!"), -+ _("Couldn't write tag!"), - strerror(errno)); - if (msg) - { -- GtkWidget *mwin = xmms_show_message(_("File Info"), msg, -- _("OK"), FALSE, NULL, NULL); -+ GtkWidget *mwin = xmms_show_message(_("File Info"), msg, _("OK"), -+ FALSE, NULL, NULL); - gtk_window_set_transient_for(GTK_WINDOW(mwin), - GTK_WINDOW(window)); - g_free(msg); - } -- else -- gtk_widget_destroy(window); -+} -+ -+static void label_set_text(GtkWidget * label, const char *str, ...) -+{ -+ va_list args; -+ char tempstr[MAX_STR_LEN]; -+ -+ va_start(args, str); -+ g_vsnprintf(tempstr, MAX_STR_LEN, str, args); -+ va_end(args); -+ -+ gtk_label_set_text(GTK_LABEL(label), tempstr); - } - - static void set_mpeg_level_label(gboolean mpeg25, int lsf, int layer) -@@ -219,28 +332,141 @@ - - static void file_info_http(char *filename) - { -- gtk_widget_set_sensitive(id3_frame, FALSE); -+ gtk_widget_set_sensitive(id3v1_frame, FALSE); -+ gtk_widget_set_sensitive(id3v2_frame, FALSE); - if (mpg123_filename && !strcmp(filename, mpg123_filename) && - mpg123_bitrate != 0) - { -- set_mpeg_level_label(mpg123_mpeg25, mpg123_lsf, mpg123_layer); -+ set_mpeg_level_label(mpg123_mpeg25, mpg123_lsf, -+ mpg123_layer); - label_set_text(mpeg_bitrate, _("Bitrate: %d kb/s"), -- mpg123_bitrate); -+ mpg123_bitrate); - label_set_text(mpeg_samplerate, _("Samplerate: %d Hz"), -- mpg123_frequency); -+ mpg123_frequency); - label_set_text(mpeg_flags, "%s", -- channel_mode_name(mpg123_mode)); -+ channel_mode_name(mpg123_mode)); - } - } - --static void genre_selected(GtkList *list, GtkWidget *w, gpointer data) -+void copy_v2_to_v1_cb(GtkButton *button, gpointer user_data) -+{ -+ copy_entry_tag_v1(GTK_ENTRY(v2_title_entry), GTK_ENTRY(v1_title_entry), 30); -+ copy_entry_tag_v1(GTK_ENTRY(v2_artist_entry), GTK_ENTRY(v1_artist_entry), 30); -+ copy_entry_tag_v1(GTK_ENTRY(v2_album_entry), GTK_ENTRY(v1_album_entry), 30); -+ copy_entry_tag_v1(GTK_ENTRY(v2_year_entry), GTK_ENTRY(v1_year_entry), 4); -+ copy_entry_tag_v1(GTK_ENTRY(v2_comment_entry), GTK_ENTRY(v1_comment_entry), 30); -+ copy_entry_tag_v1(GTK_ENTRY(v2_tracknum_entry), GTK_ENTRY(v1_tracknum_entry), 3); -+ -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v1_genre_combo)->list), genre_find_index(genre_list, v2_current_genre)); -+ return; -+} -+ -+void copy_v1_to_v2_cb(GtkButton *button, gpointer user_data) -+{ -+ copy_entry_tag_v2(GTK_ENTRY(v1_title_entry), GTK_ENTRY(v2_title_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_artist_entry), GTK_ENTRY(v2_artist_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_album_entry), GTK_ENTRY(v2_album_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_year_entry), GTK_ENTRY(v2_year_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_comment_entry), GTK_ENTRY(v2_comment_entry)); -+ copy_entry_tag_v2(GTK_ENTRY(v1_tracknum_entry), GTK_ENTRY(v2_tracknum_entry)); -+ -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v2_genre_combo)->list), genre_find_index(genre_list, v1_current_genre)); -+ return; -+} -+ -+void v1_toggle_cb (GtkWidget *widget, gpointer data) -+{ -+ int i = 0; -+ if (GTK_TOGGLE_BUTTON (widget)->active) -+ { -+ // If control reaches here, the toggle button is down -+ // Gray out labels -+ for (i = 0; i < v1_labels_list->len; i++) { -+ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v1_labels_list, i) ), FALSE); -+ } -+ gtk_widget_set_sensitive(v1_title_entry, FALSE); -+ gtk_widget_set_sensitive(v1_artist_entry, FALSE); -+ gtk_widget_set_sensitive(v1_album_entry, FALSE); -+ gtk_widget_set_sensitive(v1_year_entry, FALSE); -+ gtk_widget_set_sensitive(v1_tracknum_entry, FALSE); -+ gtk_widget_set_sensitive(v1_comment_entry, FALSE); -+ gtk_widget_set_sensitive(v1_genre_combo, FALSE); -+ } else { -+ -+ // If control reaches here, the toggle button is up -+ // Enable labels -+ for (i = 0; i < v1_labels_list->len; i++) { -+ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v1_labels_list, i) ), TRUE); -+ } -+ gtk_widget_set_sensitive(v1_title_entry, TRUE); -+ gtk_widget_set_sensitive(v1_artist_entry, TRUE); -+ gtk_widget_set_sensitive(v1_album_entry, TRUE); -+ gtk_widget_set_sensitive(v1_year_entry, TRUE); -+ gtk_widget_set_sensitive(v1_tracknum_entry, TRUE); -+ gtk_widget_set_sensitive(v1_comment_entry, TRUE); -+ gtk_widget_set_sensitive(v1_genre_combo, TRUE); -+ } -+} -+ -+void v2_toggle_cb (GtkWidget *widget, gpointer data) -+{ -+ int i = 0; -+ if (GTK_TOGGLE_BUTTON (widget)->active) -+ { -+ // If control reaches here, the toggle button is down -+ // Gray out labels -+ for (i = 0; i < v2_labels_list->len; i++) { -+ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v2_labels_list, i) ), FALSE); -+ } -+ gtk_widget_set_sensitive(v2_title_entry, FALSE); -+ gtk_widget_set_sensitive(v2_artist_entry, FALSE); -+ gtk_widget_set_sensitive(v2_album_entry, FALSE); -+ gtk_widget_set_sensitive(v2_year_entry, FALSE); -+ gtk_widget_set_sensitive(v2_tracknum_entry, FALSE); -+ gtk_widget_set_sensitive(v2_comment_entry, FALSE); -+ gtk_widget_set_sensitive(v2_composer_entry, FALSE); -+ gtk_widget_set_sensitive(v2_orig_artist_entry, FALSE); -+ gtk_widget_set_sensitive(v2_url_entry, FALSE); -+ gtk_widget_set_sensitive(v2_encoded_by_entry, FALSE); -+ gtk_widget_set_sensitive(v2_genre_combo, FALSE); -+ } else { -+ -+ // If control reaches here, the toggle button is up -+ // Enable labels -+ for (i = 0; i < v2_labels_list->len; i++) { -+ gtk_widget_set_sensitive(GTK_WIDGET( g_ptr_array_index(v2_labels_list, i) ), TRUE); -+ } -+ gtk_widget_set_sensitive(v2_title_entry, TRUE); -+ gtk_widget_set_sensitive(v2_artist_entry, TRUE); -+ gtk_widget_set_sensitive(v2_album_entry, TRUE); -+ gtk_widget_set_sensitive(v2_year_entry, TRUE); -+ gtk_widget_set_sensitive(v2_tracknum_entry, TRUE); -+ gtk_widget_set_sensitive(v2_comment_entry, TRUE); -+ gtk_widget_set_sensitive(v2_composer_entry, TRUE); -+ gtk_widget_set_sensitive(v2_orig_artist_entry, TRUE); -+ gtk_widget_set_sensitive(v2_url_entry, TRUE); -+ gtk_widget_set_sensitive(v2_encoded_by_entry, TRUE); -+ gtk_widget_set_sensitive(v2_genre_combo, TRUE); -+ } -+} -+static void v1_genre_selected(GtkList *list, GtkWidget *w, gpointer data) - { - void * p; - p = gtk_object_get_data(GTK_OBJECT(w), "genre_id"); - if (p != NULL) -- current_genre = GPOINTER_TO_INT(p); -+ v1_current_genre = GPOINTER_TO_INT(p); - else -- current_genre = 0; -+ v1_current_genre = 0; -+} -+ -+static void v2_genre_selected(GtkList *list, GtkWidget *w, gpointer data) -+{ -+ void * p; -+ p = gtk_object_get_data(GTK_OBJECT(w), "genre_id"); -+ if (p != NULL) -+ v2_current_genre = GPOINTER_TO_INT(p); -+ else -+ v2_current_genre = 0; - } - - static void genre_set_popdown(GtkWidget *combo, GList *genres) -@@ -269,7 +495,7 @@ - void mpg123_file_info_box(char *filename) - { - int i; -- struct id3v1tag_t tag; -+ struct id3v1tag_t id3v1tag; - FILE *fh; - char *tmp, *title; - const char *emphasis[4]; -@@ -284,205 +510,397 @@ - - if (!window) - { -- GtkWidget *vbox, *hbox, *left_vbox, *table; -- GtkWidget *mpeg_frame, *mpeg_box; -- GtkWidget *label, *filename_hbox; -- GtkWidget *bbox, *save, *remove_id3, *cancel; -- -+ GtkWidget *window_vbox, -+ *id3v1_vbox, *id3v2_vbox, *id3v1_frame_vbox, *id3v2_frame_vbox, -+ *mpeg_lvbox, *mpeg_rvbox, *mpeg_hbox, *mpeg_box, *mpeg_frame, -+ *bbox, *save, *close, *copy_to, *copy_from, -+ *table, *label, *filename_hbox; -+ -+ v1_labels_list = g_ptr_array_new(); -+ v2_labels_list = g_ptr_array_new(); -+ - window = gtk_window_new(GTK_WINDOW_DIALOG); -- gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE); -- gtk_signal_connect(GTK_OBJECT(window), "destroy", -- gtk_widget_destroyed, &window); -- gtk_signal_connect(GTK_OBJECT(window), "key_press_event", -- file_info_box_keypress_cb, NULL); -+ gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window); -+ gtk_signal_connect(GTK_OBJECT(window), "key_press_event", file_info_box_keypress_cb, NULL); - gtk_container_set_border_width(GTK_CONTAINER(window), 10); - -- vbox = gtk_vbox_new(FALSE, 10); -- gtk_container_add(GTK_CONTAINER(window), vbox); -- -+ window_vbox = gtk_vbox_new(FALSE,10); - filename_hbox = gtk_hbox_new(FALSE, 5); -- gtk_box_pack_start(GTK_BOX(vbox), filename_hbox, -- FALSE, TRUE, 0); -+ gtk_box_pack_start(GTK_BOX(window_vbox), filename_hbox, FALSE, TRUE, 0); - - label = gtk_label_new(_("Filename:")); -- gtk_box_pack_start(GTK_BOX(filename_hbox), label, -- FALSE, TRUE, 0); -+ gtk_box_pack_start(GTK_BOX(filename_hbox), label, FALSE, TRUE, 0); - filename_entry = xmms_entry_new(); - gtk_editable_set_editable(GTK_EDITABLE(filename_entry), FALSE); -- gtk_box_pack_start(GTK_BOX(filename_hbox), -- filename_entry, TRUE, TRUE, 0); -- -- hbox = gtk_hbox_new(FALSE, 10); -- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); -- -- left_vbox = gtk_vbox_new(FALSE, 10); -- gtk_box_pack_start(GTK_BOX(hbox), left_vbox, FALSE, FALSE, 0); -+ gtk_box_pack_start(GTK_BOX(filename_hbox), filename_entry, TRUE, TRUE, 0); - -- id3_frame = gtk_frame_new(_("ID3 Tag:")); -- gtk_box_pack_start(GTK_BOX(left_vbox), id3_frame, -- FALSE, FALSE, 0); -+ /* Set up the genres list */ - -- table = gtk_table_new(5, 5, FALSE); -+ if (!genre_list) -+ { -+ struct genre_item *item; -+ -+ for (i = 0; i < GENRE_MAX; i++) -+ { -+ item = g_malloc(sizeof (*item)); -+ item->name = gettext(mpg123_id3_genres[i]); -+ item->id = i; -+ genre_list = g_list_prepend(genre_list, item); -+ } -+ item = g_malloc(sizeof (*item)); -+ item->name = ""; -+ item->id = 0xff; -+ genre_list = g_list_prepend(genre_list, item); -+ genre_list = g_list_sort(genre_list, genre_comp_func); -+ } -+ -+ notebook = gtk_notebook_new (); -+ gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP); -+ -+ /* ID3v2 page */ -+ -+ id3v2_vbox = gtk_vbox_new(FALSE, 0); -+ -+ id3v2_frame = gtk_frame_new("ID3v2 Information"); -+ gtk_box_pack_start(GTK_BOX(id3v2_vbox), id3v2_frame, FALSE, FALSE, 0); -+ -+ id3v2_frame_vbox = gtk_vbox_new(FALSE, 0); -+ gtk_container_add(GTK_CONTAINER(id3v2_frame), id3v2_frame_vbox); -+ -+ table = gtk_table_new(6, 6, FALSE); - gtk_container_set_border_width(GTK_CONTAINER(table), 5); -- gtk_container_add(GTK_CONTAINER(id3_frame), table); -+ gtk_widget_set_usize(GTK_WIDGET(table), 400, -1); -+ gtk_box_pack_start(GTK_BOX(id3v2_frame_vbox), table, FALSE, FALSE, 0); - -- label = gtk_label_new(_("Title:")); -+ v2_checkbox = gtk_check_button_new_with_label ("Disable ID3v2 Tag"); -+ gtk_signal_connect(GTK_OBJECT(v2_checkbox), "toggled", GTK_SIGNAL_FUNC(v2_toggle_cb), NULL); -+ gtk_table_attach(GTK_TABLE(table), v2_checkbox, 1, 3, 0, 1, GTK_FILL, GTK_FILL, 0, 2); -+ -+ label = gtk_label_new("Track number:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -- gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, -- GTK_FILL, GTK_FILL, 5, 5); -+ gtk_table_attach(GTK_TABLE(table), label, 3, 4, 0, 1, -+ GTK_FILL, GTK_FILL, 5,5); - -- title_entry = gtk_entry_new_with_max_length(30); -- gtk_table_attach(GTK_TABLE(table), title_entry, 1, 4, 0, 1, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); -+ v2_tracknum_entry = gtk_entry_new_with_max_length(3); -+ gtk_widget_set_usize(v2_tracknum_entry, 20, -1); -+ gtk_table_attach(GTK_TABLE(table), v2_tracknum_entry, 4, 5, 0, 1, -+ GTK_FILL, GTK_FILL, 0, 2); - -- label = gtk_label_new(_("Artist:")); -+ label = gtk_label_new("Title:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -- gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, -- GTK_FILL, GTK_FILL, 5, 5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, GTK_FILL, GTK_FILL, 5, 5); - -- artist_entry = gtk_entry_new_with_max_length(30); -- gtk_table_attach(GTK_TABLE(table), artist_entry, 1, 4, 1, 2, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); -+ v2_title_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_title_entry, 1, 5, 1, 2, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); - -- label = gtk_label_new(_("Album:")); -+ label = gtk_label_new("Artist:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, -- GTK_FILL, GTK_FILL, 5, 5); -+ GTK_FILL, GTK_FILL, 5, 5); - -- album_entry = gtk_entry_new_with_max_length(30); -- gtk_table_attach(GTK_TABLE(table), album_entry, 1, 4, 2, 3, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); -+ v2_artist_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_artist_entry, 1, 5, 2, 3, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); - -- label = gtk_label_new(_("Comment:")); -+ label = gtk_label_new("Album:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, -- GTK_FILL, GTK_FILL, 5, 5); -+ GTK_FILL, GTK_FILL, 5, 5); - -- comment_entry = gtk_entry_new_with_max_length(30); -- gtk_table_attach(GTK_TABLE(table), comment_entry, 1, 4, 3, 4, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); -+ v2_album_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_album_entry, 1, 5, 3, 4, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); - -- label = gtk_label_new(_("Year:")); -+ label = gtk_label_new("Comment:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5, -- GTK_FILL, GTK_FILL, 5, 5); -+ GTK_FILL, GTK_FILL, 5, 5); - -- year_entry = gtk_entry_new_with_max_length(4); -- gtk_widget_set_usize(year_entry, 40, -1); -- gtk_table_attach(GTK_TABLE(table), year_entry, 1, 2, 4, 5, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); -+ v2_comment_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_comment_entry, 1, 5, 4, 5, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); - -- label = gtk_label_new(_("Track number:")); -+ label = gtk_label_new("Year:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -- gtk_table_attach(GTK_TABLE(table), label, 2, 3, 4, 5, -- GTK_FILL, GTK_FILL, 5, 5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6, -+ GTK_FILL, GTK_FILL, 5, 5); - -- tracknum_entry = gtk_entry_new_with_max_length(3); -- gtk_widget_set_usize(tracknum_entry, 40, -1); -- gtk_table_attach(GTK_TABLE(table), tracknum_entry, 3, 4, 4, 5, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); -+ v2_year_entry = gtk_entry_new_with_max_length(4); -+ gtk_widget_set_usize(v2_year_entry, 45, -1); -+ gtk_table_attach(GTK_TABLE(table), v2_year_entry, 1, 2, 5, 6, -+ GTK_FILL, GTK_FILL, 0, 2); - -- label = gtk_label_new(_("Genre:")); -+ label = gtk_label_new("Genre:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 2, 3, 5, 6, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_genre_combo = gtk_combo_new(); -+ gtk_combo_set_value_in_list(GTK_COMBO(v2_genre_combo), FALSE, TRUE); -+ -+ genre_set_popdown(v2_genre_combo, genre_list); -+ gtk_signal_connect(GTK_OBJECT(GTK_COMBO(v2_genre_combo)->list), -+ "select-child", v2_genre_selected, NULL); -+ -+ gtk_table_attach(GTK_TABLE(table), v2_genre_combo, 3, 5, 5, 6, -+ GTK_FILL | GTK_SHRINK, GTK_FILL | -+ GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Composer:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 6, 7, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_composer_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_composer_entry, 1, 5, 6, 7, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Orig. Artist:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 7, 8, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_orig_artist_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_orig_artist_entry, 1, 5, 7, 8, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("URL:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 8, 9, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_url_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_url_entry, 1, 5, 8, 9, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ label = gtk_label_new("Encoded By:"); -+ g_ptr_array_add(v2_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 9, 10, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v2_encoded_by_entry = gtk_entry_new_with_max_length(MAX_ENTRY_LEN2); -+ gtk_table_attach(GTK_TABLE(table), v2_encoded_by_entry, 1, 5, 9, 10, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ bbox = gtk_hbutton_box_new(); -+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START); -+ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 0); -+ gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); -+ gtk_box_pack_start(GTK_BOX(id3v2_frame_vbox), bbox, FALSE, FALSE, 0); -+ -+ copy_to = gtk_button_new_with_label("ID3v2 to ID3v1"); -+ gtk_signal_connect(GTK_OBJECT(copy_to), "clicked", GTK_SIGNAL_FUNC(copy_v2_to_v1_cb), NULL); -+ /* remove the next line to thicken the button width */ -+ GTK_WIDGET_SET_FLAGS(copy_to, GTK_CAN_DEFAULT); -+ gtk_box_pack_start(GTK_BOX(bbox), copy_to, FALSE, TRUE, 0); -+ -+ label = gtk_label_new ("ID3v2"); -+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), id3v2_vbox, label); -+ -+ /* ID3v1 page */ -+ -+ id3v1_vbox = gtk_vbox_new(FALSE, 10); -+ id3v1_frame = gtk_frame_new("ID3v1 Information"); -+ gtk_box_pack_start(GTK_BOX(id3v1_vbox), id3v1_frame, TRUE, TRUE, 0); -+ -+ id3v1_frame_vbox = gtk_vbox_new(FALSE,10); -+ gtk_container_add(GTK_CONTAINER(id3v1_frame), id3v1_frame_vbox); -+ -+ table = gtk_table_new(6, 6, FALSE); -+ gtk_container_set_border_width(GTK_CONTAINER(table), 5); -+ //gtk_widget_set_usize(GTK_WIDGET(table), 325, -1); -+ //gtk_container_add(GTK_CONTAINER(id3v1_frame), table); -+ gtk_box_pack_start(GTK_BOX(id3v1_frame_vbox), table, FALSE, FALSE, 0); -+ -+ v1_checkbox = gtk_check_button_new_with_label ("Disable ID3v1 Tag"); -+ gtk_signal_connect(GTK_OBJECT(v1_checkbox), "toggled", GTK_SIGNAL_FUNC(v1_toggle_cb), NULL); -+ gtk_table_attach(GTK_TABLE(table), v1_checkbox, 1, 3, 0, 1, -+ GTK_FILL, GTK_FILL, 0, 2); -+ -+ label = gtk_label_new("Track number:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 3, 4, 0, 1, -+ GTK_FILL, GTK_FILL, 5,5); -+ -+ v1_tracknum_entry = gtk_entry_new_with_max_length(3); -+ gtk_widget_set_usize(v1_tracknum_entry, 20, -1); -+ gtk_table_attach(GTK_TABLE(table), v1_tracknum_entry, 4, 5, 0, 1, -+ GTK_FILL, GTK_FILL, 0, 2); -+ -+ label = gtk_label_new("Title:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v1_title_entry = gtk_entry_new_with_max_length(30); -+ gtk_table_attach(GTK_TABLE(table), v1_title_entry, 1, 5, 1, 2, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Artist:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 2, 3, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v1_artist_entry = gtk_entry_new_with_max_length(30); -+ gtk_table_attach(GTK_TABLE(table), v1_artist_entry, 1, 5, 2, 3, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Album:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 3, 4, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v1_album_entry = gtk_entry_new_with_max_length(30); -+ gtk_table_attach(GTK_TABLE(table), v1_album_entry, 1, 5, 3, 4, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Comment:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5, -+ GTK_FILL, GTK_FILL, 5, 5); -+ -+ v1_comment_entry = gtk_entry_new_with_max_length(30); -+ gtk_table_attach(GTK_TABLE(table), v1_comment_entry, 1, 5, 4, 5, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, -+ GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 2); -+ -+ label = gtk_label_new("Year:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); - gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); - gtk_table_attach(GTK_TABLE(table), label, 0, 1, 5, 6, -- GTK_FILL, GTK_FILL, 5, 5); -+ GTK_FILL, GTK_FILL, 5, 5); - -- genre_combo = gtk_combo_new(); -- gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(genre_combo)->entry), -- FALSE); -- if (!genre_list) -- { -- struct genre_item *item; -+ v1_year_entry = gtk_entry_new_with_max_length(4); -+ gtk_widget_set_usize(v1_year_entry, 45, -1); -+ gtk_table_attach(GTK_TABLE(table), v1_year_entry, 1, 2, 5, 6, -+ GTK_FILL, GTK_FILL, 0, 2); - -- for (i = 0; i < GENRE_MAX; i++) -- { -- item = g_malloc(sizeof (*item)); -- item->name = gettext(mpg123_id3_genres[i]); -- item->id = i; -- genre_list = g_list_prepend(genre_list, item); -- } -- item = g_malloc(sizeof (*item)); -- item->name = ""; -- item->id = 0xff; -- genre_list = g_list_prepend(genre_list, item); -- genre_list = g_list_sort(genre_list, genre_comp_func); -- } -- genre_set_popdown(genre_combo, genre_list); -- gtk_signal_connect(GTK_OBJECT(GTK_COMBO(genre_combo)->list), -- "select-child", genre_selected, NULL); -+ label = gtk_label_new("Genre:"); -+ g_ptr_array_add(v1_labels_list, (gpointer)label); -+ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); -+ gtk_table_attach(GTK_TABLE(table), label, 2, 3, 5, 6, -+ GTK_FILL, GTK_FILL, 5, 5); - -- gtk_table_attach(GTK_TABLE(table), genre_combo, 1, 4, 5, 6, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, -- GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); -+ v1_genre_combo = gtk_combo_new(); -+ gtk_entry_set_editable(GTK_ENTRY(GTK_COMBO(v1_genre_combo)->entry), FALSE); -+ genre_set_popdown(v1_genre_combo, genre_list); -+ gtk_signal_connect(GTK_OBJECT(GTK_COMBO(v1_genre_combo)->list), -+ "select-child", v1_genre_selected, NULL); -+ -+ gtk_table_attach(GTK_TABLE(table), v1_genre_combo, 3, 5, 5, 6, -+ GTK_FILL | GTK_SHRINK, GTK_FILL | -+ GTK_SHRINK, 0, 2); - - bbox = gtk_hbutton_box_new(); -- gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), -- GTK_BUTTONBOX_END); -- gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5); -- gtk_box_pack_start(GTK_BOX(left_vbox), bbox, FALSE, FALSE, 0); -+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_START); -+ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 0); -+ gtk_container_set_border_width(GTK_CONTAINER(bbox), 5); -+ gtk_box_pack_start(GTK_BOX(id3v1_frame_vbox), bbox, FALSE, FALSE, 0); - -- save = gtk_button_new_with_label(_("Save")); -- gtk_signal_connect(GTK_OBJECT(save), "clicked", save_cb, NULL); -- GTK_WIDGET_SET_FLAGS(save, GTK_CAN_DEFAULT); -- gtk_box_pack_start(GTK_BOX(bbox), save, TRUE, TRUE, 0); -- gtk_widget_grab_default(save); -+ copy_from = gtk_button_new_with_label("ID3v1 to ID3v2"); -+ gtk_signal_connect(GTK_OBJECT(copy_from), "clicked", GTK_SIGNAL_FUNC(copy_v1_to_v2_cb), NULL); -+ // remove the next line to thicken the button width -+ GTK_WIDGET_SET_FLAGS(copy_from, GTK_CAN_DEFAULT); -+ gtk_box_pack_start(GTK_BOX(bbox), copy_from, FALSE, TRUE, 0); - -- remove_id3 = gtk_button_new_with_label(_("Remove ID3")); -- gtk_signal_connect(GTK_OBJECT(remove_id3), "clicked", -- remove_id3_cb, NULL); -- GTK_WIDGET_SET_FLAGS(remove_id3, GTK_CAN_DEFAULT); -- gtk_box_pack_start(GTK_BOX(bbox), remove_id3, TRUE, TRUE, 0); -+ label = gtk_label_new ("ID3v1"); -+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), id3v1_vbox, label); - -- cancel = gtk_button_new_with_label(_("Cancel")); -- gtk_signal_connect_object(GTK_OBJECT(cancel), "clicked", -- gtk_widget_destroy, GTK_OBJECT(window)); -- GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT); -- gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0); -+ /* MPEG info page */ - -- mpeg_frame = gtk_frame_new(_("MPEG Info:")); -- gtk_box_pack_start(GTK_BOX(hbox), mpeg_frame, FALSE, FALSE, 0); -+ mpeg_frame = gtk_frame_new("MPEG Information"); -+ mpeg_hbox = gtk_hbox_new(FALSE,50); -+ gtk_container_add(GTK_CONTAINER(mpeg_frame), mpeg_hbox); -+ -+ mpeg_lvbox = gtk_vbox_new(FALSE, 5); -+ gtk_container_set_border_width(GTK_CONTAINER(mpeg_lvbox), 10); -+ gtk_box_pack_start(GTK_BOX(mpeg_hbox), mpeg_lvbox, FALSE, FALSE, 0); - - mpeg_box = gtk_vbox_new(FALSE, 5); -- gtk_container_add(GTK_CONTAINER(mpeg_frame), mpeg_box); -+ gtk_box_pack_start(GTK_BOX(mpeg_hbox), mpeg_box, FALSE, FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(mpeg_box), 10); - gtk_box_set_spacing(GTK_BOX(mpeg_box), 0); - - mpeg_level = gtk_label_new(""); -- gtk_widget_set_usize(mpeg_level, 120, -2); -- gtk_misc_set_alignment(GTK_MISC(mpeg_level), 0, 0); -- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_level, FALSE, FALSE, 0); -- -- mpeg_bitrate = gtk_label_new(""); -- gtk_misc_set_alignment(GTK_MISC(mpeg_bitrate), 0, 0); -- gtk_label_set_justify(GTK_LABEL(mpeg_bitrate), -- GTK_JUSTIFY_LEFT); -- gtk_box_pack_start(GTK_BOX(mpeg_box), -- mpeg_bitrate, FALSE, FALSE, 0); -+ //gtk_widget_set_usize(mpeg_level, 120, -2); -+ gtk_label_set_justify (GTK_LABEL(mpeg_level), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_level), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_lvbox), mpeg_level, FALSE, FALSE, 0); - - mpeg_samplerate = gtk_label_new(""); -- gtk_misc_set_alignment(GTK_MISC(mpeg_samplerate), 0, 0); -- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_samplerate, -- FALSE, FALSE, 0); -+ gtk_label_set_justify (GTK_LABEL(mpeg_samplerate), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_samplerate), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_lvbox), mpeg_samplerate, FALSE, FALSE, 0); -+ -+ mpeg_fileinfo = gtk_label_new(""); -+ gtk_label_set_justify (GTK_LABEL(mpeg_fileinfo), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_fileinfo), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_lvbox), mpeg_fileinfo, FALSE, FALSE, 0); -+ -+ mpeg_rvbox = gtk_vbox_new(FALSE, 5); -+ gtk_box_pack_start(GTK_BOX(mpeg_hbox), mpeg_rvbox, FALSE, FALSE, 0); -+ gtk_container_set_border_width(GTK_CONTAINER(mpeg_rvbox), 10); -+ -+ mpeg_bitrate = gtk_label_new(""); -+ gtk_label_set_justify (GTK_LABEL(mpeg_bitrate), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_bitrate), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_rvbox), mpeg_bitrate, FALSE, FALSE, 0); - - mpeg_flags = gtk_label_new(""); -- gtk_misc_set_alignment(GTK_MISC(mpeg_flags), 0, 0); -- gtk_label_set_justify(GTK_LABEL(mpeg_flags), GTK_JUSTIFY_LEFT); -- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_flags, -- FALSE, FALSE, 0); -+ gtk_label_set_justify (GTK_LABEL(mpeg_flags), GTK_JUSTIFY_LEFT); -+ gtk_misc_set_alignment(GTK_MISC(mpeg_flags), 0, 0.5); -+ gtk_box_pack_start(GTK_BOX(mpeg_rvbox), mpeg_flags, FALSE, FALSE, 0); - -- mpeg_fileinfo = gtk_label_new(""); -- gtk_misc_set_alignment(GTK_MISC(mpeg_fileinfo), 0, 0); -- gtk_label_set_justify(GTK_LABEL(mpeg_fileinfo), -- GTK_JUSTIFY_LEFT); -- gtk_box_pack_start(GTK_BOX(mpeg_box), mpeg_fileinfo, -- FALSE, FALSE, 0); -+ label = gtk_label_new ("MPEG"); -+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), mpeg_frame, label); -+ -+ /* add notebook to window vbox */ -+ gtk_box_pack_start(GTK_BOX(window_vbox), notebook, FALSE, FALSE, 0); -+ -+ /* add button box to window vbox */ -+ bbox = gtk_hbutton_box_new(); -+ gtk_box_pack_start(GTK_BOX(window_vbox), bbox, FALSE, FALSE, 0); - -+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END); -+ gtk_button_box_set_spacing (GTK_BUTTON_BOX (bbox), 5); -+ -+ save = gtk_button_new_with_label("Save"); -+ gtk_signal_connect(GTK_OBJECT(save), "clicked", GTK_SIGNAL_FUNC(save_cb), NULL); -+ gtk_box_pack_start(GTK_BOX(bbox), save, TRUE, TRUE, 5); -+ -+ close = gtk_button_new_with_label("Close"); -+ gtk_signal_connect_object(GTK_OBJECT(close), "clicked", -+ GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window)); -+ gtk_box_pack_start(GTK_BOX(bbox), close, TRUE, TRUE, 5); -+ -+ gtk_container_add(GTK_CONTAINER(window), window_vbox); - gtk_widget_show_all(window); - } - -@@ -500,73 +918,128 @@ - title = g_strdup(g_basename(filename)); - if ((tmp = strrchr(title, '.')) != NULL) - *tmp = '\0'; -- gtk_entry_set_text(GTK_ENTRY(title_entry), title); -+ gtk_entry_set_text(GTK_ENTRY(v1_title_entry), title); -+ gtk_entry_set_text(GTK_ENTRY(v2_title_entry), title); - g_free(title); - -- gtk_entry_set_text(GTK_ENTRY(artist_entry), ""); -- gtk_entry_set_text(GTK_ENTRY(album_entry), ""); -- gtk_entry_set_text(GTK_ENTRY(year_entry), ""); -- gtk_entry_set_text(GTK_ENTRY(tracknum_entry), ""); -- gtk_entry_set_text(GTK_ENTRY(comment_entry), ""); -- gtk_list_select_item(GTK_LIST(GTK_COMBO(genre_combo)->list), -+ gtk_entry_set_text(GTK_ENTRY(v1_artist_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v1_album_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v1_year_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v1_tracknum_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v1_comment_entry), ""); -+ -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v1_genre_combo)->list), - genre_find_index(genre_list, 0xff)); -+ -+ gtk_entry_set_text(GTK_ENTRY(v2_artist_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_album_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_year_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_tracknum_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_comment_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_composer_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_orig_artist_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_url_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(v2_encoded_by_entry), ""); -+ gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry), ""); -+ - gtk_label_set_text(GTK_LABEL(mpeg_level), "MPEG ?, layer ?"); - gtk_label_set_text(GTK_LABEL(mpeg_bitrate), ""); - gtk_label_set_text(GTK_LABEL(mpeg_samplerate), ""); - gtk_label_set_text(GTK_LABEL(mpeg_flags), ""); - gtk_label_set_text(GTK_LABEL(mpeg_fileinfo), ""); -- - if (!strncasecmp(filename, "http://", 7)) - { - file_info_http(filename); - return; - } - -- gtk_widget_set_sensitive(id3_frame, TRUE); -+ gtk_widget_set_sensitive(id3v1_frame, TRUE); -+ gtk_widget_set_sensitive(id3v2_frame, TRUE); - - if ((fh = fopen(current_filename, "rb")) != NULL) - { - struct frame frm; - gboolean id3_found = FALSE; -+ struct id3_tag *id3 = NULL; - guint8 *buf; - double tpf; - int pos; - xing_header_t xing_header; - guint32 num_frames; -- -- fseek(fh, -sizeof (tag), SEEK_END); -- if (fread(&tag, 1, sizeof (tag), fh) == sizeof (tag)) -+ /* -+ * Try reading ID3v2 tag. -+ */ -+ fseek(fh, 0, SEEK_SET); -+ id3 = id3_open_fp(fh, 0); -+ if (id3 != NULL) - { -- if (!strncmp(tag.tag, "TAG", 3)) -+ struct id3_frame* frame; -+ -+ set_entry_tag_v2(GTK_ENTRY(v2_title_entry), id3, ID3_TIT2); -+ set_entry_tag_v2(GTK_ENTRY(v2_artist_entry), id3, ID3_TPE1); -+ set_entry_tag_v2(GTK_ENTRY(v2_album_entry), id3, ID3_TALB); -+ set_entry_tag_v2(GTK_ENTRY(v2_comment_entry), id3, ID3_COMM); -+ set_entry_tag_v2(GTK_ENTRY(v2_composer_entry), id3, ID3_TCOM); -+ set_entry_tag_v2(GTK_ENTRY(v2_orig_artist_entry), id3, ID3_TOPE); -+ set_entry_tag_v2(GTK_ENTRY(v2_url_entry), id3, ID3_WCOM); -+ set_entry_tag_v2(GTK_ENTRY(v2_encoded_by_entry), id3, ID3_TENC); -+ set_entry_tag_v2(GTK_ENTRY(v2_tracknum_entry), id3, ID3_TRCK); -+ set_entry_tag_v2(GTK_ENTRY(v2_year_entry), id3, ID3_TYER); -+ -+ frame = id3_get_frame(id3, ID3_TCON, 1); -+ if (frame != NULL) - { -- id3_found = TRUE; -- set_entry_tag(GTK_ENTRY(title_entry), -- tag.title, 30); -- set_entry_tag(GTK_ENTRY(artist_entry), -- tag.artist, 30); -- set_entry_tag(GTK_ENTRY(album_entry), -- tag.album, 30); -- set_entry_tag(GTK_ENTRY(year_entry), -- tag.year, 4); -- /* Check for v1.1 tags */ -- if (tag.u.v1_1.__zero == 0 && tag.u.v1_1.track_number > 0) -- { -- char *temp = g_strdup_printf("%d", tag.u.v1_1.track_number); -- set_entry_tag(GTK_ENTRY(comment_entry), -- tag.u.v1_1.comment, 28); -- gtk_entry_set_text(GTK_ENTRY(tracknum_entry), temp); -- g_free(temp); -- } -- else -+ char* genre = id3_get_content(frame); -+ if (genre != NULL) - { -- set_entry_tag(GTK_ENTRY(comment_entry), -- tag.u.v1_0.comment, 30); -- gtk_entry_set_text(GTK_ENTRY(tracknum_entry), ""); -+ int genre_idx = genre_find_index_str(genre_list, genre); -+ if (genre_idx > 0) -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v2_genre_combo)->list), genre_idx); -+ else -+ gtk_entry_set_text(GTK_ENTRY(GTK_COMBO(v2_genre_combo)->entry), genre); - } -- -- gtk_list_select_item(GTK_LIST(GTK_COMBO(genre_combo)->list), genre_find_index(genre_list, tag.genre)); - } -+ -+ id3_close(id3); -+ } -+ else -+ { -+ /* Grey out the id3v2 tab */ -+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(v2_checkbox), TRUE); -+ } -+ -+ /* -+ * Try reading ID3v1 tag. -+ */ -+ fseek(fh, -sizeof (id3v1tag), SEEK_END); -+ if ( (fread(&id3v1tag, 1, sizeof (id3v1tag), fh) == sizeof (id3v1tag)) && !strncmp(id3v1tag.tag, "TAG", 3)) -+ { -+ id3_found = TRUE; -+ set_entry_tag_v1(GTK_ENTRY(v1_title_entry), id3v1tag.title, 30); -+ set_entry_tag_v1(GTK_ENTRY(v1_artist_entry), id3v1tag.artist, 30); -+ set_entry_tag_v1(GTK_ENTRY(v1_album_entry), id3v1tag.album, 30); -+ set_entry_tag_v1(GTK_ENTRY(v1_year_entry), id3v1tag.year, 4); -+ /* Check for v1.1 tags */ -+ if (id3v1tag.u.v1_1.__zero == 0 && id3v1tag.u.v1_1.track_number > 0) -+ { -+ char *temp = g_strdup_printf("%d", id3v1tag.u.v1_1.track_number); -+ set_entry_tag_v1(GTK_ENTRY(v1_comment_entry), id3v1tag.u.v1_1.comment, 28); -+ gtk_entry_set_text(GTK_ENTRY(v1_tracknum_entry), temp); -+ g_free(temp); -+ } -+ else -+ { -+ set_entry_tag_v1(GTK_ENTRY(v1_comment_entry), id3v1tag.u.v1_0.comment, 30); -+ gtk_entry_set_text(GTK_ENTRY(v1_tracknum_entry), ""); - } -+ gtk_list_select_item(GTK_LIST(GTK_COMBO(v1_genre_combo)->list), genre_find_index(genre_list, id3v1tag.genre)); -+ } -+ else -+ { -+ // Grey out id3v1 tab -+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(v1_checkbox), TRUE); -+ } -+ - rewind(fh); - - if (!mpg123_get_first_frame(fh, &frm, &buf)) -diff -dPNur xmms-1.2.11/Input/mpg123/id3.c xmms-1.2.11-new/Input/mpg123/id3.c ---- xmms-1.2.11/Input/mpg123/id3.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3.c 2007-11-24 23:58:41.000000000 +0100 -@@ -22,6 +22,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -49,7 +50,7 @@ - */ - static int id3_seek_mem(struct id3_tag *id3, int offset) - { -- if (id3->id3_pos + offset > id3->id3_tagsize || -+ if (id3->id3_pos + offset > id3->id3_totalsize || - id3->id3_pos + offset < 0) - { - id3_error(id3, "seeking beyond tag boundary"); -@@ -77,7 +78,7 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + size > id3->id3_tagsize) -+ if (id3->id3_pos + size > id3->id3_totalsize) - return NULL; - - /* -@@ -118,7 +119,7 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + offset > id3->id3_tagsize || -+ if (id3->id3_pos + offset > id3->id3_totalsize || - id3->id3_pos + offset < 0) - return -1; - -@@ -148,8 +149,8 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + size > id3->id3_tagsize) -- return NULL; -+ if (id3->id3_pos + size > id3->id3_totalsize) -+ size = id3->id3_totalsize - id3->id3_pos; - - /* - * If buffer is NULL, we use the default buffer. -@@ -205,7 +206,7 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + offset > id3->id3_tagsize || -+ if (id3->id3_pos + offset > id3->id3_totalsize || - id3->id3_pos + offset < 0) - return -1; - -@@ -263,8 +264,8 @@ - /* - * Check boundary. - */ -- if (id3->id3_pos + size > id3->id3_tagsize) -- size = id3->id3_tagsize - id3->id3_pos; -+ if (id3->id3_pos + size > id3->id3_totalsize) -+ size = id3->id3_totalsize - id3->id3_pos; - - /* - * If buffer is NULL, we use the default buffer. -@@ -338,6 +339,32 @@ - return NULL; - } - -+/* -+ * Function id3_new() -+ * -+ * Creates a new ID3 tag structure. Useful for creating -+ * a new tag. -+ * -+ */ -+struct id3_tag *id3_new() -+{ -+ struct id3_tag *id3; -+ -+ /* -+ * Allocate ID3 structure. -+ */ -+ id3 = g_malloc0( sizeof(struct id3_tag) ); -+ -+ if (id3 != NULL) -+ { -+ id3_init_tag ( id3 ); -+ id3->id3_type = ID3_TYPE_NONE; -+ id3->id3_seek = NULL; -+ id3->id3_read = NULL; -+ } -+ -+ return id3; -+} - - /* - * Function id3_open_fd (fd, flags) -@@ -493,7 +520,7 @@ - if (id3->id3_newtag) - return 0; - else -- return id3->id3_tagsize + 3 + sizeof(id3_taghdr_t); -+ return id3->id3_totalsize + 3 + sizeof(id3_taghdr_t); - } - #endif - -@@ -560,6 +587,81 @@ - return 0; - } - -+/* -+ * Function id3_remove_tag_filename(filename) -+ * -+ * Remove the ID3v2 tag from the file indicated by filename. Takes care of resizing -+ * the file, if needed. Returns 0 upon success, or -1 if an error occured. -+ * -+ */ -+int id3_remove_tag_filename(const char* filename) -+{ -+ struct id3_tag *current_id3; -+ int fd; -+ int current_totalsize; -+ struct stat stat_buf; -+ -+ fd = open(filename, O_RDWR); -+ if (fd == -1) -+ return -1; -+ -+ /* -+ * Figure out how large the current tag is. -+ */ -+ current_id3 = id3_open_fd(fd, 0); -+ if (current_id3 != NULL) -+ { -+ /* We use MAX to make sure an erroneous tag doesn't confuse us */ -+ current_totalsize = MAX(current_id3->id3_totalsize, 0); -+ id3_close(current_id3); -+ } -+ else -+ { -+ current_totalsize = 0; -+ } -+ -+ if (current_totalsize <= 0) -+ return 0; -+ -+ /* -+ * Rewrite the file. -+ */ -+ -+ stat(filename, &stat_buf); -+ -+ /* Re-position all the data current_totalsize bytes backwards */ -+ { -+ int read_pos, write_pos; -+ size_t read_size; -+ char buf[4096]; -+ -+ /* TODO: Add error handling to IO operations */ -+ -+ /* We reposition the data by going forwards, each time reading -+ a block and copying it backward. That way, we never write -+ over a block which we intend to read later. */ -+ write_pos = 0; -+ read_pos = write_pos + current_totalsize; -+ -+ do -+ { -+ lseek(fd, read_pos, SEEK_SET); -+ read_size = read(fd, buf, sizeof(buf)); -+ read_pos += read_size; -+ -+ /* Write whatever block we've got */ -+ lseek(fd, write_pos, SEEK_SET); -+ write(fd, buf, read_size); -+ write_pos += read_size; -+ } -+ while (read_size > 0); -+ -+ ftruncate(fd, stat_buf.st_size - current_totalsize); -+ } -+ -+ close(fd); -+ return 0; -+} - - /* - * Function id3_write_tag (id3, fd) -@@ -567,30 +669,25 @@ - * Wrtite the ID3 tag to the indicated file descriptor. Return 0 - * upon success, or -1 if an error occured. - * -+ * Warning: This function is called by id3_write_tag_filename and should -+ * not be called standalone, as it doesn't perform seeking -+ * and doesn't enlarge the file as necessary, and thus might -+ * OVERWRITE THE AUDIO DATA. -+ * - */ - int id3_write_tag(struct id3_tag *id3, int fd) - { - struct id3_frame *fr; - GList *node; -- int size = 0; - char buf[ID3_TAGHDR_SIZE]; - - /* -- * Calculate size of ID3 tag. -- */ -- for (node = id3->id3_frame; node != NULL; node = node->next) -- { -- fr = node->data; -- size += fr->fr_size + ID3_FRAMEHDR_SIZE; -- } -- -- /* - * Write tag header. - */ - buf[0] = id3->id3_version; - buf[1] = id3->id3_revision; - buf[2] = id3->id3_flags; -- ID3_SET_SIZE28(size, buf[3], buf[4], buf[5], buf[6]); -+ ID3_SET_SIZE28(id3->id3_size, buf[3], buf[4], buf[5], buf[6]); - - if (safe_write(fd, "ID3", 3) == -1) - return -1; -@@ -617,19 +714,203 @@ - * TODO: Support compressed headers, encoded - * headers, and grouping info. - */ -- /* fhdr.fh_id = fr->fr_desc ? g_htonl(fr->fr_desc->fd_id) : 0; */ -- fhdr[3] = (fr->fr_size >> 24) & 0xff; -- fhdr[4] = (fr->fr_size >> 16) & 0xff; -- fhdr[5] = (fr->fr_size >> 8) & 0xff; -- fhdr[6] = fr->fr_size & 0xff; -- fhdr[7] = (fr->fr_flags >> 8) & 0xff; -- fhdr[8] = fr->fr_flags & 0xff; -+ fhdr[0] = fr->fr_desc->fd_idstr[0]; -+ fhdr[1] = fr->fr_desc->fd_idstr[1]; -+ fhdr[2] = fr->fr_desc->fd_idstr[2]; -+ fhdr[3] = fr->fr_desc->fd_idstr[3]; -+ fhdr[4] = (fr->fr_raw_size >> 24) & 0xff; -+ fhdr[5] = (fr->fr_raw_size >> 16) & 0xff; -+ fhdr[6] = (fr->fr_raw_size >> 8) & 0xff; -+ fhdr[7] = fr->fr_raw_size & 0xff; -+ fhdr[8] = (fr->fr_flags >> 8) & 0xff; -+ fhdr[9] = fr->fr_flags & 0xff; - - if (safe_write(fd, fhdr, sizeof(fhdr)) == -1) - return -1; - -- if (safe_write(fd, fr->fr_data, fr->fr_size) == -1) -+ if (safe_write(fd, fr->fr_raw_data, fr->fr_raw_size) == -1) - return -1; - } - return 0; - } -+ -+ -+/* -+ * Function id3_write_tag_file(id3, filename) -+ * -+ * Write the ID3 tag to the file indicated by filename. Takes care of enlarging -+ * the file, if needed. Returns 0 upon success, or -1 if an error occured. -+ * -+ */ -+int id3_write_tag_filename(struct id3_tag *id3, const char* filename) -+{ -+ struct id3_tag *current_id3; -+ int fd; -+ int current_totalsize, new_totalsize; -+ GList* node; -+ -+ fd = open(filename, O_RDWR); -+ if (fd == -1) -+ return -1; -+ -+ /* -+ * Figure out how large the current tag is. -+ */ -+ current_id3 = id3_open_fd(fd, 0); -+ if (current_id3 != NULL) -+ { -+ /* We use MAX to make sure an erroneous tag doesn't confuse us */ -+ current_totalsize = MAX(current_id3->id3_totalsize, 0); -+ id3_close(current_id3); -+ } -+ else -+ { -+ current_totalsize = 0; -+ } -+ -+ /* -+ * Figure out how large the new tag will be. -+ */ -+ new_totalsize = 10; -+ node = id3->id3_frame; -+ while (node != NULL) -+ { -+ struct id3_frame* fr = node->data; -+ -+ { -+ char* text = id3_get_text(fr); -+ if (text != NULL) -+ { -+ int len = strlen(text); -+ g_free(text); -+ -+ if (len == 0) -+ { -+ /* We skip over frames with empty text */ -+ node = node->next; -+ id3_delete_frame(fr); -+ continue; -+ } -+ } -+ } -+ -+ { -+ char* url = id3_get_url(fr); -+ if (url != NULL) -+ { -+ int len = strlen(url); -+ g_free(url); -+ -+ if (len == 0) -+ { -+ /* We skip over frames with empty URLs */ -+ node = node->next; -+ id3_delete_frame(fr); -+ continue; -+ } -+ } -+ } -+ -+ new_totalsize += fr->fr_raw_size + ID3_FRAMEHDR_SIZE; -+ node = node->next; -+ } -+ new_totalsize += 0; /* no extended header, no footer, no padding */ -+ id3->id3_flags = 0; -+ -+ /* -+ * Determine whether we need to rewrite the file to make place for the new tag. -+ */ -+ if (new_totalsize > current_totalsize) -+ { -+ struct stat stat_buf; -+ int grow_size; -+ -+ stat(filename, &stat_buf); -+ grow_size = new_totalsize - current_totalsize; -+ ftruncate(fd, stat_buf.st_size + grow_size); -+ -+ /* truncate adds "sparse" zeros; we'll turn them into real ones, -+ which occupy space on disk, to make sure we actually have -+ the disk space before we start enlarging the file */ -+ { -+ int remaining = grow_size; -+ char buf[1024] = { 0 }; -+ lseek(fd, stat_buf.st_size, SEEK_SET); -+ while (remaining > 0) -+ { -+ int ret = write(fd, buf, MIN(sizeof(buf), remaining)); -+ if (ret >= 0) -+ remaining -= ret; -+ else -+ { -+ id3_error(id3, "Unable to enlarge file for the new tag"); -+ ftruncate(fd, stat_buf.st_size); -+ close(fd); -+ return -1; -+ } -+ } -+ } -+ -+ /* and now, re-position all the data grow_size bytes forward */ -+ { -+ int area_to_move_size = stat_buf.st_size - current_totalsize; -+ int read_pos, write_pos; -+ size_t read_size, read_size_desired; -+ char buf[4096]; -+ -+ /* TODO: Add error handling to IO operations */ -+ -+ /* We reposition the data by going backwards, each time reading -+ a block and copying it forward. That way, we never write -+ over a block which we intend to read later. */ -+ write_pos = lseek(fd, 0, SEEK_END); -+ read_pos = write_pos - grow_size; -+ -+ /* While we still have bytes to move... */ -+ while(area_to_move_size > 0) -+ { -+ /* Get 1 block or the remaining bytes -- the smallest of the two */ -+ read_size_desired = MIN(area_to_move_size, sizeof(buf)); -+ read_pos -= read_size_desired; -+ lseek(fd, read_pos, SEEK_SET); -+ read_size = read(fd, buf, read_size_desired); -+ -+ /* Write whatever block we've got */ -+ write_pos -= read_size; -+ lseek(fd, write_pos, SEEK_SET); -+ write(fd, buf, read_size); -+ -+ area_to_move_size -= read_size; -+ } -+ } -+ } -+ else -+ { -+ new_totalsize = current_totalsize; -+ } -+ -+ id3->id3_size = new_totalsize - 10; -+ -+ /* Zero-out the ID3v2 tag area */ -+ { -+ char buf[1024] = {0}; -+ size_t remaining; -+ -+ lseek(fd, 0, SEEK_SET); -+ for(remaining = new_totalsize; remaining > 0; remaining -= MIN(remaining,sizeof(buf))) -+ { -+ write(fd, buf, MIN(remaining,sizeof(buf))); -+ } -+ } -+ -+ /* Write the new tag */ -+ lseek(fd, 0, SEEK_SET); -+ if (id3_write_tag(id3, fd) == -1) -+ { -+ close(fd); -+ return -1; -+ } -+ -+ close(fd); -+ return 0; -+} -diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame.c xmms-1.2.11-new/Input/mpg123/id3_frame.c ---- xmms-1.2.11/Input/mpg123/id3_frame.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3_frame.c 2007-11-24 23:58:41.000000000 +0100 -@@ -283,7 +283,7 @@ - */ - if (!((buf[0] >= '0' && buf[0] <= '9') || (buf[0] >= 'A' && buf[0] <= 'Z'))) - { -- id3->id3_seek(id3, id3->id3_tagsize - id3->id3_pos); -+ id3->id3_seek(id3, id3->id3_totalsize - id3->id3_pos); - return 0; - } - id = ID3_FRAME_ID(buf[0], buf[1], buf[2], buf[3]); -@@ -308,7 +308,7 @@ - */ - - frame->fr_desc = find_frame_description(id); -- -+ - /* - * Check if frame had a valid id. - */ -@@ -385,6 +385,29 @@ - } - - /* -+ * Function id3_get_or_add_frame (id3, type) -+ * -+ * Search in the list of frames for the ID3-tag, and return the first frame -+ * of the indicated type. If no frame of the indicated type exists yet, -+ * it will add one and return it. -+ * -+ */ -+struct id3_frame *id3_get_or_add_frame(struct id3_tag *id3, guint32 type) -+{ -+ struct id3_frame* fr; -+ -+ fr = id3_get_frame(id3, type, 1); -+ if (fr != NULL) -+ { -+ return fr; -+ } -+ else -+ { -+ return id3_add_frame(id3, type); -+ } -+} -+ -+/* - * Function decompress_frame(frame) - * - * Uncompress the indicated frame. Return 0 upon success, or -1 if -@@ -517,27 +540,26 @@ - */ - int id3_delete_frame(struct id3_frame *frame) - { -- GList *list = frame->fr_owner->id3_frame; -+ struct id3_tag* id3 = frame->fr_owner; -+ GList *list = id3->id3_frame; - int ret; - - /* - * Search for frame in list. - */ -- if (g_list_find(list, frame) != NULL) -- { -- /* -- * Frame does not exist in frame list. -- */ -- ret = -1; -- } -- else -- { -+ if (g_list_find(list, frame) != NULL) { - /* - * Remove frame from frame list. - */ - list = g_list_remove(list, frame); -- frame->fr_owner->id3_altered = 1; -- ret = 0; -+ id3->id3_frame = list; -+ id3->id3_altered = 1; -+ ret = 0; -+ } else { -+ /* -+ * Frame does not exist in frame list. -+ */ -+ ret = -1; - } - - /* -@@ -704,7 +726,7 @@ - */ - if (!((buf[0] >= '0' && buf[0] <= '9') || (buf[0] >= 'A' && buf[0] <= 'Z'))) - { -- id3->id3_seek(id3, id3->id3_tagsize - id3->id3_pos); -+ id3->id3_seek(id3, id3->id3_size - id3->id3_pos); - return 0; - } - -diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame_text.c xmms-1.2.11-new/Input/mpg123/id3_frame_text.c ---- xmms-1.2.11/Input/mpg123/id3_frame_text.c 2007-11-24 23:58:20.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/id3_frame_text.c 2007-11-24 23:58:41.000000000 +0100 -@@ -155,6 +155,11 @@ - char *id3_get_text(struct id3_frame *frame) - { - int offset = 0; -+ -+ /* Do we even have data for this frame */ -+ if (!frame->fr_data) -+ return NULL; -+ - /* Type check */ - if (frame->fr_desc->fd_idstr[0] != 'T') - return NULL; -@@ -374,3 +379,54 @@ - return id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), - ID3_TEXT_FRAME_PTR(frame) + offset); - } -+ -+/* -+ * Function id3_set_comment (frame, text) -+ * -+ * Set text for the indicated frame. Return 0 upon -+ * success, or -1 if an error occured. -+ * -+ */ -+int id3_set_comment(struct id3_frame *frame, char *text) -+{ -+ int *intp; -+ -+ /* Type check */ -+ if (frame->fr_desc->fd_id != ID3_COMM) -+ return -1; -+ -+ /* -+ * Release memory occupied by previous data. -+ */ -+ id3_frame_clear_data(frame); -+ -+ /* -+ * Allocate memory for new data. -+ */ -+ frame->fr_raw_size = 13 + strlen(text); -+ frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); /* XXXComments\0<\0> -+ -+ /* Save time... we just need to zero out the start, not the whole -+ * block, so don't waste time with a calloc() -+ */ -+ -+ ((guint8 *)frame->fr_raw_data)[0] = ID3_ENCODING_ISO_8859_1; -+ ((guint8 *)frame->fr_raw_data)[1] = 0x58; -+ ((guint8 *)frame->fr_raw_data)[2] = 0x58; -+ ((guint8 *)frame->fr_raw_data)[3] = 0x58; -+ -+ memcpy((char *) frame->fr_raw_data + 4, "Comments", 9); -+ -+ /* -+ * Copy contents. -+ */ -+ memcpy((char *) frame->fr_raw_data + 13, text, strlen(text) + 1); -+ -+ frame->fr_altered = 1; -+ frame->fr_owner->id3_altered = 1; -+ -+ frame->fr_data = frame->fr_raw_data; -+ frame->fr_size = frame->fr_raw_size; -+ -+ return 0; -+} -diff -dPNur xmms-1.2.11/Input/mpg123/id3_frame_url.c xmms-1.2.11-new/Input/mpg123/id3_frame_url.c ---- xmms-1.2.11/Input/mpg123/id3_frame_url.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3_frame_url.c 2007-11-24 23:58:41.000000000 +0100 -@@ -34,6 +34,11 @@ - char *id3_get_url(struct id3_frame *frame) - { - int offset = 0; -+ -+ /* Do we even have data for this frame */ -+ if (!frame->fr_data) -+ return NULL; -+ - /* Type check */ - if (frame->fr_desc->fd_idstr[0] != 'W') - return NULL; -@@ -80,3 +85,32 @@ - return id3_string_decode(ID3_TEXT_FRAME_ENCODING(frame), - ID3_TEXT_FRAME_PTR(frame)); - } -+ -+/* -+ * Function id3_set_url (frame) -+ * -+ * Sets URL of frame. -+ * -+ */ -+void id3_set_url(struct id3_frame *frame, const char* url) -+{ -+ /* Type check */ -+ if ( frame->fr_desc->fd_idstr[0] != 'W' ) -+ return; -+ -+ /* Check if frame is compressed */ -+ if (id3_decompress_frame(frame) == -1) -+ return; -+ -+ /* -+ * Allocate memory for new data. -+ */ -+ frame->fr_raw_size = strlen(url) + 1; -+ frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); -+ -+ /* -+ * Copy contents. -+ */ -+ *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1; -+ memcpy((char *) frame->fr_raw_data + 1, url, frame->fr_raw_size); -+} -diff -dPNur xmms-1.2.11/Input/mpg123/id3.h xmms-1.2.11-new/Input/mpg123/id3.h ---- xmms-1.2.11/Input/mpg123/id3.h 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3.h 2007-11-24 23:58:41.000000000 +0100 -@@ -22,6 +22,7 @@ - #define ID3_H - - #include -+#include - - /* - * Option flags to id3_open_*(). -@@ -49,8 +50,9 @@ - - int id3_version; /* Major ID3 version number */ - int id3_revision; /* ID3 revision number */ -+ int id3_size; /* Size of ID3 tag (as dictated by header) */ - -- int id3_tagsize; /* Total size of ID3 tag */ -+ int id3_totalsize; /* Total size of ID3 tag (including header, footer and padding) */ - int id3_pos; /* Current position within tag */ - - char *id3_error_msg; /* Last error message */ -@@ -140,8 +142,6 @@ - #define ID3_ENCODING_UTF16BE 0x02 - #define ID3_ENCODING_UTF8 0x03 - -- -- - /* - * ID3 frame id numbers. - */ -@@ -322,50 +322,51 @@ - */ - - /* From id3.c */ --struct id3_tag *id3_open_mem(void *, int); --struct id3_tag *id3_open_fd(int, int); --struct id3_tag *id3_open_fp(FILE *, int); --int id3_set_output(struct id3_tag *, char *); --int id3_close(struct id3_tag *); --int id3_tell(struct id3_tag *); --int id3_alter_file(struct id3_tag *); --int id3_write_tag(struct id3_tag *, int); -+struct id3_tag *id3_new(); -+struct id3_tag *id3_open_mem(void *ptr, int flags); -+struct id3_tag *id3_open_fd(int fd, int flags); -+struct id3_tag *id3_open_fp(FILE *fp, int flags); -+int id3_close(struct id3_tag *id3); -+int id3_tell(struct id3_tag *id3); -+int id3_alter_file(struct id3_tag *id3); -+int id3_write_tag(struct id3_tag *id3, int fd); -+int id3_write_tag_filename(struct id3_tag *id3, const char* filename); -+int id3_remove_tag_filename(const char* filename); - - /* From id3_frame.c */ - int id3_read_frame(struct id3_tag *id3); --struct id3_frame *id3_get_frame(struct id3_tag *, guint32, int); -+struct id3_frame *id3_get_frame(struct id3_tag *id3, guint32 type, int num); - int id3_delete_frame(struct id3_frame *frame); --struct id3_frame *id3_add_frame(struct id3_tag *, guint32); --int id3_decompress_frame(struct id3_frame *); --void id3_destroy_frames(struct id3_tag *id); -+struct id3_frame *id3_add_frame(struct id3_tag *id3, guint32 type); -+struct id3_frame *id3_get_or_add_frame(struct id3_tag *id3, guint32 type); -+int id3_decompress_frame(struct id3_frame *frame); -+void id3_destroy_frames(struct id3_tag *id3); - void id3_frame_clear_data(struct id3_frame *frame); - - /* From id3_frame_text.c */ - guint id3_string_size(guint8 encoding, const char* text); - char* id3_string_decode(guint8 encoding, const char* text); --gint8 id3_get_encoding(struct id3_frame *); --int id3_set_encoding(struct id3_frame *, gint8); --char *id3_get_text(struct id3_frame *); --char *id3_get_comment(struct id3_frame *); --char *id3_get_text_desc(struct id3_frame *); --int id3_get_text_number(struct id3_frame *); --int id3_set_text(struct id3_frame *, char *); --int id3_set_text_number(struct id3_frame *, int); -+gint8 id3_get_encoding(struct id3_frame *frame); -+int id3_set_encoding(struct id3_frame *frame, gint8 encoding); -+char *id3_get_text(struct id3_frame *frame); -+char *id3_get_comment(struct id3_frame *frame); -+char *id3_get_text_desc(struct id3_frame *frame); -+int id3_get_text_number(struct id3_frame *frame); -+int id3_set_text(struct id3_frame *frame, char *text); -+int id3_set_comment(struct id3_frame *frame, char *comment); -+int id3_set_text_number(struct id3_frame *frame, int number); - gboolean id3_frame_is_text(struct id3_frame *frame); - - /* From id3_frame_content.c */ --char *id3_get_content(struct id3_frame *); -+char *id3_get_content(struct id3_frame *frame); - - /* From id3_frame_url.c */ --char *id3_get_url(struct id3_frame *); --char *id3_get_url_desc(struct id3_frame *); -+char *id3_get_url(struct id3_frame *frame); -+char *id3_get_url_desc(struct id3_frame *frame); -+void id3_set_url(struct id3_frame *frame, const char* url); - - /* From id3_tag.c */ - void id3_init_tag(struct id3_tag *id3); - int id3_read_tag(struct id3_tag *id3); - --char *convert_from_utf16(const unsigned char *utf16); --char *convert_from_utf16be(const unsigned char *utf16); -- -- - #endif /* ID3_H */ -diff -dPNur xmms-1.2.11/Input/mpg123/id3_header.h xmms-1.2.11-new/Input/mpg123/id3_header.h ---- xmms-1.2.11/Input/mpg123/id3_header.h 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3_header.h 2007-11-24 23:58:41.000000000 +0100 -@@ -39,22 +39,21 @@ - #define ID3_THFLAG_USYNC 0x80 - #define ID3_THFLAG_EXT 0x40 - #define ID3_THFLAG_EXP 0x20 -+#define ID3_THFLAG_FOOTER 0x10 - - #define ID3_SET_SIZE28(size, a, b, c, d) \ --do { \ -- a = (size >> (24 + 3)) & 0x7f; \ -- b = (size >> (16 + 2)) & 0x7f; \ -- c = (size >> ( 8 + 1)) & 0x7f; \ -+{ \ -+ a = (size >> (24 - 3)) & 0x7f; \ -+ b = (size >> (16 - 2)) & 0x7f; \ -+ c = (size >> ( 8 - 1)) & 0x7f; \ - d = size & 0x7f; \ --} while (0) -+} - - #define ID3_GET_SIZE28(a, b, c, d) \ --(((a & 0x7f) << (24 - 3)) | \ -- ((b & 0x7f) << (16 - 2)) | \ -- ((c & 0x7f) << ( 8 - 1)) | \ -- ((d & 0x7f))) -- -- -+ (((a & 0x7f) << (24 - 3)) | \ -+ ((b & 0x7f) << (16 - 2)) | \ -+ ((c & 0x7f) << ( 8 - 1)) | \ -+ ((d & 0x7f))) \ - - /* - * Layout for the extended header. -diff -dPNur xmms-1.2.11/Input/mpg123/id3_tag.c xmms-1.2.11-new/Input/mpg123/id3_tag.c ---- xmms-1.2.11/Input/mpg123/id3_tag.c 2005-05-21 20:05:56.000000000 +0200 -+++ xmms-1.2.11-new/Input/mpg123/id3_tag.c 2007-11-24 23:58:41.000000000 +0100 -@@ -39,7 +39,8 @@ - id3->id3_version = 3; - id3->id3_revision = 0; - id3->id3_flags = ID3_THFLAG_USYNC | ID3_THFLAG_EXP; -- id3->id3_tagsize = 0; -+ id3->id3_size = 0; -+ id3->id3_totalsize = 0; - - id3->id3_altered = 1; - id3->id3_newtag = 1; -@@ -63,13 +64,14 @@ - int id3_read_tag(struct id3_tag *id3) - { - char *buf; -+ guint8 padding; - - /* - * We know that the tag will be at least this big. - * - * tag header + "ID3" - */ -- id3->id3_tagsize = ID3_TAGHDR_SIZE + 3; -+ id3->id3_totalsize = ID3_TAGHDR_SIZE + 3; - - if (!(id3->id3_oflags & ID3_OPENF_NOCHK)) - { -@@ -100,9 +102,11 @@ - id3->id3_version = buf[0]; - id3->id3_revision = buf[1]; - id3->id3_flags = buf[2]; -- id3->id3_tagsize = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]); -+ id3->id3_size = ID3_GET_SIZE28(buf[3], buf[4], buf[5], buf[6]); -+ id3->id3_totalsize += id3->id3_size; -+ if (id3->id3_flags & ID3_THFLAG_FOOTER) -+ id3->id3_totalsize += 10; - id3->id3_newtag = 0; -- id3->id3_pos = 0; - - if (id3->id3_version < 2 || id3->id3_version > 4) - return -1; -@@ -120,14 +124,34 @@ - /* - * Parse frames. - */ -- while (id3->id3_pos < id3->id3_tagsize) -+ while (id3->id3_pos < id3->id3_size) - { - if (id3_read_frame(id3) == -1) - return -1; - } - -- if (id3->id3_frame == NULL) -- return -1; -+ /* -+ * Like id3lib, we try to find unstandard padding (not within -+ * the tag size). This is important to know when we strip -+ * the tag or replace it. -+ * Another option might be looking for an MPEG sync, but we don't do it. -+ */ -+ -+ id3->id3_seek(id3, id3->id3_totalsize - id3->id3_pos); -+ -+ /* Temporarily increase totalsize, to try reading beyong the boundary */ -+ ++id3->id3_totalsize; -+ -+ while (id3->id3_read(id3, &padding, sizeof(padding)) != NULL) -+ { -+ if (padding == 0) -+ ++id3->id3_totalsize; -+ else -+ break; -+ } -+ -+ /* Decrease totalsize after we temporarily increased it */ -+ --id3->id3_totalsize; - - return 0; - } -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:58:20.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-24 23:58:41.000000000 +0100 -@@ -129,9 +129,9 @@ - - #ifdef USE_SIMD - fr->dct36 = funcs_dct36[0]; -- -+ - if (CPU_HAS_3DNOW() && !p8 && -- (mpg123_cfg.default_synth == SYNTH_3DNOW || -+ (mpg123_cfg.default_synth == SYNTH_3DNOW || - mpg123_cfg.default_synth == SYNTH_AUTO)) - { - fr->synth = funcs[3][ds]; /* 3DNow! optimized synth_1to1() */ -@@ -320,11 +320,11 @@ - if (!strncasecmp(filename, "http://", 7)) - { /* We assume all http:// (except those ending in .ogg) are mpeg -- why do we do that? */ - ext = strrchr(filename, '.'); -- if (ext) -+ if (ext) - { -- if (!strncasecmp(ext, ".ogg", 4)) -+ if (!strncasecmp(ext, ".ogg", 4)) - return FALSE; -- if (!strncasecmp(ext, ".rm", 3) || -+ if (!strncasecmp(ext, ".rm", 3) || - !strncasecmp(ext, ".ra", 3) || - !strncasecmp(ext, ".rpm", 4) || - !strncasecmp(ext, ".fla", 4) || -@@ -534,7 +534,7 @@ - * Function mpg123_get_id3v2 (id3d, tag) - * - * Get desired contents from the indicated id3tag and store it in -- * `tag'. -+ * `tag'. - * - */ - struct id3v2tag_t* mpg123_id3v2_get(struct id3_tag *id3d) -@@ -550,6 +550,10 @@ - tag->track_number = id3v2_get_num(id3d, ID3_TRCK); - tag->comment = id3v2_get_text(id3d, ID3_COMM); - tag->genre = id3v2_get_text(id3d, ID3_TCON); -+ tag->composer = id3v2_get_text(id3d, ID3_TCOM); -+ tag->orig_artist = id3v2_get_text(id3d, ID3_TOPE); -+ tag->url = id3v2_get_text(id3d, ID3_WCOM); -+ tag->encoded_by = id3v2_get_text(id3d, ID3_TENC); - - return tag; - } -@@ -829,7 +833,7 @@ - static int mpg123_seek(struct frame *fr, xing_header_t *xh, gboolean vbr, int time) - { - int jumped = -1; -- -+ - if (xh) - { - int percent = ((double) time * 100.0) / -@@ -995,7 +999,7 @@ - mpg123_info->output_audio = FALSE; - continue; - } -- -+ - } - } - if(mpg123_freqs[fr.sampling_frequency] != mpg123_frequency || mpg123_stereo != fr.stereo) -@@ -1033,12 +1037,12 @@ - mpg123_info->output_audio = FALSE; - continue; - } -- } -+ } - } -- -+ - if (tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index] != mpg123_bitrate) - mpg123_bitrate = tabsel_123[fr.lsf][fr.lay - 1][fr.bitrate_index]; -- -+ - if (!disp_count) - { - disp_count = 20; -@@ -1154,7 +1158,7 @@ - - if (aboutbox != NULL) - return; -- -+ - aboutbox = xmms_show_message( - _("About MPEG Layer 1/2/3 plugin"), - _("mpg123 decoding engine by Michael Hipp \n" -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.h xmms-1.2.11-new/Input/mpg123/mpg123.h ---- xmms-1.2.11/Input/mpg123/mpg123.h 2007-11-24 23:58:20.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.h 2007-11-24 23:58:41.000000000 +0100 -@@ -1,5 +1,5 @@ - /* -- * mpg123 defines -+ * mpg123 defines - * used source: musicout.h from mpegaudio package - */ - -@@ -79,6 +79,10 @@ - char *album; - char *comment; - char *genre; -+ char *composer; -+ char *orig_artist; -+ char *url; -+ char *encoded_by; - int year; - int track_number; - }; -@@ -300,7 +304,6 @@ - int mpg123_decode_header(struct frame *fr, unsigned long newhead); - double mpg123_compute_bpf(struct frame *fr); - double mpg123_compute_tpf(struct frame *fr); --guint mpg123_strip_spaces(char *src, size_t n); - struct id3v2tag_t* mpg123_id3v2_get(struct id3_tag *id3d); - void mpg123_id3v2_destroy(struct id3v2tag_t* tag); - char *mpg123_format_song_title(struct id3v2tag_t *tag, char *filename); diff --git a/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch b/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch deleted file mode 100644 index 453c91b..0000000 --- a/3rdparty/mpg123/2020_all_mpg123-vorbis-ssl.patch +++ /dev/null @@ -1,766 +0,0 @@ -diff -dPNur xmms-1.2.11/configure.in xmms-1.2.11-new/configure.in ---- xmms-1.2.11/configure.in 2007-11-16 22:52:30.000000000 +0100 -+++ xmms-1.2.11-new/configure.in 2007-11-25 00:00:09.000000000 +0100 -@@ -144,6 +144,22 @@ - fi - AC_SUBST([PTHREAD_LIBS]) - -+dnl *** OpenSSL support -+AC_ARG_ENABLE( ssl, -+[ --disable-ssl Disable HTTP SSL in plugin(s) [default=enabled]],, -+ enable_ssl="yes") -+ -+if test "x$enable_ssl" = xyes; then -+ SSL_LIBS="" -+ AC_CHECK_LIB(ssl, SSL_read, [SSL_LIBS="-lssl" -+ AC_DEFINE(HTTP_SSL,,[Define if OpenSSL is available]) -+ AC_DEFINE(OPENSSL_NO_KRB5,,[Define if OpenSSL is available])], -+ echo "*** SSL support requires openssl and openssl-devel packages ***") -+ LIBS="$LIBS $SSL_LIBS" -+else -+ AC_MSG_RESULT([*** Disabling SSL in plugin(s) per user request ***]) -+ have_ssl=no -+fi - - dnl *** - dnl *** OpenGL -diff -dPNur xmms-1.2.11/Input/mpg123/common.c xmms-1.2.11-new/Input/mpg123/common.c ---- xmms-1.2.11/Input/mpg123/common.c 2007-11-24 23:59:35.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/common.c 2007-11-25 00:00:09.000000000 +0100 -@@ -464,7 +464,11 @@ - void mpg123_open_stream(char *bs_filenam, int fd, unsigned long range) - { - filept_opened = 1; -+#ifdef HTTP_SSL -+ if (!strncasecmp(bs_filenam, "http://", 7) || !strncasecmp(bs_filenam, "https://", 8)) -+#else - if (!strncasecmp(bs_filenam, "http://", 7)) -+#endif - { - filept = NULL; - mpg123_info->filesize = 0; -diff -dPNur xmms-1.2.11/Input/mpg123/http.c xmms-1.2.11-new/Input/mpg123/http.c ---- xmms-1.2.11/Input/mpg123/http.c 2007-11-24 23:53:33.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/http.c 2007-11-25 00:00:09.000000000 +0100 -@@ -33,6 +33,14 @@ - #include "mpg123.h" - #include "libxmms/util.h" - -+#ifdef HTTP_SSL -+#include -+#include -+#include -+#include -+#include -+#endif -+ - #define min(x,y) ((x)<(y)?(x):(y)) - #define min3(x,y,z) (min(x,y)<(z)?min(x,y):(z)) - #define min4(x,y,z,w) (min3(x,y,z)<(w)?min3(x,y,z):(w)) -@@ -117,7 +125,11 @@ - return res; - } - -+#ifdef HTTP_SSL -+static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename, int *ssl) -+#else - static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename) -+#endif - { - gchar *h, *p, *pt, *f, *temp, *ptr; - -@@ -126,6 +138,14 @@ - - if (!strncasecmp("http://", ptr, 7)) - ptr += 7; -+#ifdef HTTP_SSL -+ if (!strncasecmp("https://", ptr, 8)) { -+ ptr += 8; -+ *ssl = 1; -+ } else -+ *ssl = 0; -+#endif -+ - h = strchr(ptr, '@'); - f = strchr(ptr, '/'); - if (h != NULL && (!f || h < f)) -@@ -160,7 +180,12 @@ - { - if (f) - *f = '\0'; -- *port = 80; -+#ifdef HTTP_SSL -+ if (*ssl) -+ *port = 443; -+ else -+#endif -+ *port = 80; - } - *host = g_strdup(h); - -@@ -302,16 +327,27 @@ - return FALSE; - } - -+#ifdef HTTP_SSL -+gint mpg123_http_read_line(gchar * buf, gint size, SSL *ssl_c) -+#else - gint mpg123_http_read_line(gchar * buf, gint size) -+#endif - { -- gint i = 0; -+ gint i = 0, rc; - - while (going && i < size - 1) - { - if (http_check_for_data()) - { -- if (read(sock, buf + i, 1) <= 0) -- return -1; -+#ifdef HTTP_SSL -+ if (ssl_c) { -+ while ((rc = SSL_read(ssl_c, buf + i, 1)) == -1); -+ if (rc <= 0) -+ return -1; -+ } else -+#endif -+ if (read(sock, buf + i, 1) <= 0) -+ return -1; - if (buf[i] == '\n') - break; - if (buf[i] != '\r') -@@ -342,7 +378,13 @@ - struct sockaddr_in address; - #endif - struct timeval tv; -- -+#ifdef HTTP_SSL -+ SSL *ssl_c = NULL; -+ SSL_CTX *ssl_ctx = NULL; -+ BIO *b = NULL; -+ gint ssl=0; -+#endif -+ - url = (gchar *) arg; - do - { -@@ -350,7 +392,11 @@ - - g_strstrip(url); - -+#ifdef HTTP_SSL -+ parse_url(url, &user, &pass, &host, &port, &filename, &ssl); -+#else - parse_url(url, &user, &pass, &host, &port, &filename); -+#endif - - if ((!filename || !*filename) && url[strlen(url) - 1] != '/') - temp = g_strconcat(url, "/", NULL); -@@ -362,6 +408,26 @@ - chost = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_host : host; - cport = mpg123_cfg.use_proxy ? mpg123_cfg.proxy_port : port; - -+#ifdef HTTP_SSL -+ if (ssl) { -+ SSL_library_init(); -+ OpenSSL_add_ssl_algorithms(); -+ SSL_load_error_strings(); -+ -+ ssl_ctx = SSL_CTX_new(SSLv23_client_method()); -+ if (ssl_ctx == NULL) { -+ fprintf(stderr, "SSL_CTX_new() failed."); -+ eof = TRUE; -+ } -+ -+ ssl_c = SSL_new(ssl_ctx); -+ if (ssl_c == NULL) { -+ fprintf(stderr, "SSL_new() failed.\n"); -+ eof = TRUE; -+ } -+ } -+#endif -+ - #ifdef USE_IPV6 - g_snprintf(service, 6, "%d", cport); - memset(&hints, 0, sizeof(hints)); -@@ -441,7 +507,20 @@ - eof = TRUE; - } - } -+#ifdef HTTP_SSL -+ if (ssl) { -+ b = BIO_new_socket(sock, BIO_NOCLOSE); -+ if (b == NULL) { -+ printf("BIO_new_socket() failed.\n"); -+ eof = TRUE; -+ } -+ -+ // cannot fail -+ SSL_set_bio(ssl_c, b, b); -+ } -+#endif - #endif -+ - while (going) - { - tv.tv_sec = 0; -@@ -466,6 +545,24 @@ - break; - } - } -+#ifdef HTTP_SSL -+ if (ssl) { -+ int rc; -+ -+ SSL_set_connect_state(ssl_c); -+ -+ while ((rc = SSL_connect(ssl_c)) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_connect() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ } -+ while ((rc = SSL_do_handshake(ssl_c)) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_do_handshake() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ } -+ } -+#endif - if (!eof) - { - gchar *auth = NULL, *proxy_auth = NULL; -@@ -517,14 +614,30 @@ - g_free(proxy_auth); - if(auth) - g_free(auth); -- write(sock, temp, strlen(temp)); -+#ifdef HTTP_SSL -+ if (ssl) { -+ int rc; -+ while ((rc = SSL_write(ssl_c, temp, strlen(temp))) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_write() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ eof = TRUE; -+ } -+ } else -+#endif -+ write(sock, temp, strlen(temp)); -+ - g_free(temp); - mpg123_ip.set_info_text(_("CONNECTED: WAITING FOR REPLY")); - while (going && !eof) - { - if (http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if (mpg123_http_read_line(line, 1024, ssl_c)) -+#else - if (mpg123_http_read_line(line, 1024)) -+#endif - { - status = strchr(line, ' '); - if (status) -@@ -537,7 +650,11 @@ - { - if(http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if((cnt = mpg123_http_read_line(line, 1024, ssl_c)) != -1) -+#else - if((cnt = mpg123_http_read_line(line, 1024)) != -1) -+#endif - { - if(!cnt) - break; -@@ -579,7 +696,11 @@ - { - if (http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if ((cnt = mpg123_http_read_line(line, 1024, ssl_c)) != -1) -+#else - if ((cnt = mpg123_http_read_line(line, 1024)) != -1) -+#endif - { - if (!cnt) - break; -@@ -617,6 +738,10 @@ - fclose(output_file); - output_file = NULL; - } -+#ifdef HTTP_SSL -+ if (ssl) -+ SSL_shutdown(ssl_c); -+#endif - close(sock); - g_free(user); - g_free(pass); -@@ -634,6 +759,10 @@ - fname = file; - if (!strncasecmp(fname, "http://", 7)) - fname += 7; -+#ifdef HTTP_SSL -+ if (!strncasecmp(fname, "https://", 8)) -+ fname += 8; -+#endif - temp = strrchr(fname, '.'); - if (temp && !strcasecmp(temp, ".mp3")) - *temp = '\0'; -@@ -668,7 +797,12 @@ - cnt = min(http_free(), buffer_length - wr_index); - if (cnt > 1024) - cnt = 1024; -- written = read(sock, buffer + wr_index, cnt); -+#ifdef HTTP_SSL -+ if (ssl) -+ while ((written = SSL_read(ssl_c, buffer + wr_index, cnt)) == -1); -+ else -+#endif -+ written = read(sock, buffer + wr_index, cnt); - if (written <= 0) - { - eof = TRUE; -@@ -715,6 +849,10 @@ - fclose(output_file); - output_file = NULL; - } -+#ifdef HTTP_SSL -+ if (ssl) -+ SSL_shutdown(ssl_c); -+#endif - close(sock); - if (udp_sock != 0) - close(udp_sock); -diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c ---- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-24 23:59:35.000000000 +0100 -+++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-25 00:00:09.000000000 +0100 -@@ -317,7 +317,11 @@ - char *ext; - guint16 wavid; - -+#ifdef HTTP_SSL -+ if (!strncasecmp(filename, "http://", 7) || !strncasecmp(filename, "https://", 8)) -+#else - if (!strncasecmp(filename, "http://", 7)) -+#endif - { /* We assume all http:// (except those ending in .ogg) are mpeg -- why do we do that? */ - ext = strrchr(filename, '.'); - if (ext) -@@ -801,7 +805,11 @@ - /* - * TODO: Getting song info from http streams. - */ -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) && strncasecmp(filename, "https://", 8)) -+#else - if (strncasecmp(filename, "http://", 7)) -+#endif - { - if ((file = fopen(filename, "rb")) != NULL) - { -@@ -890,7 +898,12 @@ - mpg123_init_layer3(fr.down_sample_sblimit); - - mpg123_info->tpf = mpg123_compute_tpf(&fr); -+ -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) && strncasecmp(filename, "https://", 8)) -+#else - if (strncasecmp(filename, "http://", 7)) -+#endif - { - if (mpg123_stream_check_for_xing_header(&fr, &xing_header)) - { -@@ -937,7 +950,11 @@ - mpg123_mode = fr.mode; - mpg123_length = mpg123_info->num_frames * mpg123_info->tpf * 1000; - -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) && strncasecmp(filename, "https://", 8)) -+#else - if (strncasecmp(filename, "http://", 7)) -+#endif - { - if (!mpg123_title) - mpg123_title = get_song_title(NULL,filename); -@@ -1050,7 +1067,11 @@ - { - /* FIXME networks streams */ - disp_bitrate = mpg123_bitrate; -+#ifdef HTTP_SSL -+ if(!have_xing_header && strncasecmp(filename,"http://",7) && strncasecmp(filename, "https://", 8)) -+#else - if(!have_xing_header && strncasecmp(filename,"http://",7)) -+#endif - { - double rel = mpg123_relative_pos(); - if (rel) -diff -dPNur xmms-1.2.11/Input/vorbis/fileinfo.c xmms-1.2.11-new/Input/vorbis/fileinfo.c ---- xmms-1.2.11/Input/vorbis/fileinfo.c 2005-05-15 02:01:20.000000000 +0200 -+++ xmms-1.2.11-new/Input/vorbis/fileinfo.c 2007-11-25 00:00:09.000000000 +0100 -@@ -227,7 +227,12 @@ - vcedit_state *state; - vorbis_comment *comment; - -+#ifdef HTTP_SSL -+ if (!g_strncasecmp(vte.filename, "http://", 7) || -+ !g_strncasecmp(vte.filename, "https://", 8)) -+#else - if (!g_strncasecmp(vte.filename, "http://", 7)) -+#endif - return; - - state = vcedit_new_state(); -@@ -303,7 +308,12 @@ - vcedit_state *state; - vorbis_comment *comment; - -+#ifdef HTTP_SSL -+ if (!g_strncasecmp(vte.filename, "http://", 7) || -+ !g_strncasecmp(vte.filename, "https://", 8)) -+#else - if (!g_strncasecmp(vte.filename, "http://", 7)) -+#endif - return; - - state = vcedit_new_state(); -@@ -800,7 +810,12 @@ - } else - gdk_window_raise(window->window); - -+#ifdef HTTP_SSL -+ if (!g_strncasecmp(vte.filename, "http://", 7) || -+ !g_strncasecmp(vte.filename, "https://", 8)) -+#else - if (!g_strncasecmp(vte.filename, "http://", 7)) -+#endif - gtk_widget_set_sensitive(tag_frame, FALSE); - else - gtk_widget_set_sensitive(tag_frame, TRUE); -diff -dPNur xmms-1.2.11/Input/vorbis/http.c xmms-1.2.11-new/Input/vorbis/http.c ---- xmms-1.2.11/Input/vorbis/http.c 2007-11-16 22:51:24.000000000 +0100 -+++ xmms-1.2.11-new/Input/vorbis/http.c 2007-11-25 00:03:11.000000000 +0100 -@@ -39,6 +39,10 @@ - #include "xmms/plugin.h" - #include "xmms/i18n.h" - -+#ifdef HTTP_SSL -+#include -+#endif -+ - #define min(x,y) ((x)<(y)?(x):(y)) - #define min3(x,y,z) (min(x,y)<(z)?min(x,y):(z)) - #define min4(x,y,z,w) (min3(x,y,z)<(w)?min3(x,y,z):(w)) -@@ -116,7 +120,11 @@ - return res; - } - -+#ifdef HTTP_SSL -+static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename, int *ssl) -+#else - static void parse_url(const gchar * url, gchar ** user, gchar ** pass, gchar ** host, int *port, gchar ** filename) -+#endif - { - gchar *h, *p, *pt, *f, *temp, *ptr; - -@@ -125,6 +133,14 @@ - - if (!strncasecmp("http://", ptr, 7)) - ptr += 7; -+#ifdef HTTP_SSL -+ if (!strncasecmp("https://", ptr, 8)) { -+ ptr += 8; -+ *ssl = 1; -+ } else -+ *ssl = 0; -+#endif -+ - h = strchr(ptr, '@'); - f = strchr(ptr, '/'); - if (h != NULL && (!f || h < f)) -@@ -159,7 +175,12 @@ - { - if (f) - *f = '\0'; -- *port = 80; -+#ifdef HTTP_SSL -+ if (*ssl) -+ *port = 443; -+ else -+#endif -+ *port = 80; - } - *host = g_strdup(h); - -@@ -257,16 +278,27 @@ - return FALSE; - } - -+#ifdef HTTP_SSL -+gint vorbis_http_read_line(gchar * buf, gint size, SSL *ssl_c) -+#else - gint vorbis_http_read_line(gchar * buf, gint size) -+#endif - { -- gint i = 0; -+ gint i = 0, rc; - - while (going && i < size - 1) - { - if (http_check_for_data()) - { -- if (read(sock, buf + i, 1) <= 0) -- return -1; -+#ifdef HTTP_SSL -+ if (ssl_c) { -+ while ((rc = SSL_read(ssl_c, buf + i, 1)) == -1); -+ if (rc <= 0) -+ return -1; -+ } else -+#endif -+ if (read(sock, buf + i, 1) <= 0) -+ return -1; - if (buf[i] == '\n') - break; - if (buf[i] != '\r') -@@ -296,6 +328,12 @@ - struct sockaddr_in address; - #endif - struct timeval tv; -+#ifdef HTTP_SSL -+ SSL *ssl_c = NULL; -+ SSL_CTX *ssl_ctx = NULL; -+ BIO *b = NULL; -+ gint ssl=0; -+#endif - - url = (gchar *) arg; - do -@@ -304,7 +342,11 @@ - - g_strstrip(url); - -+#ifdef HTTP_SSL -+ parse_url(url, &user, &pass, &host, &port, &filename, &ssl); -+#else - parse_url(url, &user, &pass, &host, &port, &filename); -+#endif - - if ((!filename || !*filename) && url[strlen(url) - 1] != '/') - temp = g_strconcat(url, "/", NULL); -@@ -316,6 +358,26 @@ - chost = vorbis_cfg.use_proxy ? vorbis_cfg.proxy_host : host; - cport = vorbis_cfg.use_proxy ? vorbis_cfg.proxy_port : port; - -+#ifdef HTTP_SSL -+ if (ssl) { -+ SSL_library_init(); -+ OpenSSL_add_ssl_algorithms(); -+ SSL_load_error_strings(); -+ -+ ssl_ctx = SSL_CTX_new(SSLv23_client_method()); -+ if (ssl_ctx == NULL) { -+ fprintf(stderr, "SSL_CTX_new() failed."); -+ eof = TRUE; -+ } -+ -+ ssl_c = SSL_new(ssl_ctx); -+ if (ssl_c == NULL) { -+ fprintf(stderr, "SSL_new() failed.\n"); -+ eof = TRUE; -+ } -+ } -+#endif -+ - #ifdef USE_IPV6 - g_snprintf(service, 6, "%d", cport); - memset(&hints, 0, sizeof(hints)); -@@ -394,6 +456,18 @@ - eof = TRUE; - } - } -+#ifdef HTTP_SSL -+ if (ssl) { -+ b = BIO_new_socket(sock, BIO_NOCLOSE); -+ if (b == NULL) { -+ printf("BIO_new_socket() failed.\n"); -+ eof = TRUE; -+ } -+ -+ // cannot fail -+ SSL_set_bio(ssl_c, b, b); -+ } -+#endif - #endif - while (going) - { -@@ -419,6 +493,24 @@ - break; - } - } -+#ifdef HTTP_SSL -+ if (ssl) { -+ int rc; -+ -+ SSL_set_connect_state(ssl_c); -+ -+ while ((rc = SSL_connect(ssl_c)) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_connect() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ } -+ while ((rc = SSL_do_handshake(ssl_c)) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_do_handshake() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ } -+ } -+#endif - if (!eof) - { - gchar *auth = NULL, *proxy_auth = NULL; -@@ -449,14 +541,30 @@ - g_free(proxy_auth); - if(auth) - g_free(auth); -- write(sock, temp, strlen(temp)); -+#ifdef HTTP_SSL -+ if (ssl) { -+ int rc; -+ while ((rc = SSL_write(ssl_c, temp, strlen(temp))) == -1); -+ if (rc <= 0) { -+ fprintf(stderr, "SSL_write() error. SSL error code: %d.\n", -+ SSL_get_error(ssl_c, rc)); -+ eof = TRUE; -+ } -+ } else -+#endif -+ write(sock, temp, strlen(temp)); -+ - g_free(temp); - vorbis_ip.set_info_text(_("CONNECTED: WAITING FOR REPLY")); - while (going && !eof) - { - if (http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if (vorbis_http_read_line(line, 1024, ssl_c)) -+#else - if (vorbis_http_read_line(line, 1024)) -+#endif - { - status = strchr(line, ' '); - if (status) -@@ -469,7 +577,11 @@ - { - if(http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if((cnt = vorbis_http_read_line(line, 1024, ssl_c)) != -1) -+#else - if((cnt = vorbis_http_read_line(line, 1024)) != -1) -+#endif - { - if(!cnt) - break; -@@ -511,7 +623,11 @@ - { - if (http_check_for_data()) - { -+#ifdef HTTP_SSL -+ if ((cnt = vorbis_http_read_line(line, 1024, ssl_c)) != -1) -+#else - if ((cnt = vorbis_http_read_line(line, 1024)) != -1) -+#endif - { - if (!cnt) - break; -@@ -537,6 +653,10 @@ - fclose(output_file); - output_file = NULL; - } -+#ifdef HTTP_SSL -+ if (ssl) -+ SSL_shutdown(ssl_c); -+#endif - close(sock); - g_free(user); - g_free(pass); -@@ -554,6 +674,9 @@ - fname = file; - if (!strncasecmp(fname, "http://", 7)) - fname += 7; -+ if (!strncasecmp(fname, "https://", 8)) -+ fname += 8; -+ - temp = strrchr(fname, '.'); - if (temp && !strcasecmp(temp, ".ogg")) - *temp = '\0'; -@@ -588,7 +711,12 @@ - cnt = min(http_free(), buffer_length - wr_index); - if (cnt > 1024) - cnt = 1024; -- written = read(sock, buffer + wr_index, cnt); -+#ifdef HTTP_SSL -+ if (ssl) -+ while ((written = SSL_read(ssl_c, buffer + wr_index, cnt)) == -1); -+ else -+#endif -+ written = read(sock, buffer + wr_index, cnt); - if (written <= 0) - { - eof = TRUE; -@@ -629,6 +757,10 @@ - fclose(output_file); - output_file = NULL; - } -+#ifdef HTTP_SSL -+ if (ssl) -+ SSL_shutdown(ssl_c); -+#endif - close(sock); - - -diff -dPNur xmms-1.2.11/Input/vorbis/vorbis.c xmms-1.2.11-new/Input/vorbis/vorbis.c ---- xmms-1.2.11/Input/vorbis/vorbis.c 2006-07-16 15:40:04.000000000 +0200 -+++ xmms-1.2.11-new/Input/vorbis/vorbis.c 2007-11-25 00:00:09.000000000 +0100 -@@ -138,7 +138,12 @@ - char *ext; - - /* is this our http resource? */ -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) == 0 || -+ strncasecmp(filename, "https://", 8) == 0) { -+#else - if (strncasecmp(filename, "http://", 7) == 0) { -+#endif - ext = strrchr(filename, '.'); - if (ext) { - if (!strncasecmp(ext, ".ogg", 4)) { -@@ -332,7 +337,12 @@ - - memset(&vf, 0, sizeof(vf)); - -+#ifdef HTTP_SSL -+ if (strncasecmp("http://", filename, 7) && -+ strncasecmp("https://", filename, 8)) { -+#else - if (strncasecmp("http://", filename, 7) != 0) { -+#endif - /* file is a real file */ - if ((stream = fopen(filename, "r")) == NULL) { - vorbis_eos = TRUE; -@@ -536,7 +546,12 @@ - FILE *stream; - OggVorbis_File vf; /* avoid thread interaction */ - -+#ifdef HTTP_SSL -+ if (strncasecmp(filename, "http://", 7) && -+ strncasecmp(filename, "https://", 8)) { -+#else - if (strncasecmp(filename, "http://", 7)) { -+#endif - if ((stream = fopen(filename, "r")) == NULL) - return; - -- cgit v1.2.3