diff options
Diffstat (limited to 'patches')
62 files changed, 15850 insertions, 0 deletions
diff --git a/patches/gftp/gftp-ds-rcc.patch b/patches/gftp/gftp-ds-rcc.patch new file mode 100644 index 0000000..a704deb --- /dev/null +++ b/patches/gftp/gftp-ds-rcc.patch @@ -0,0 +1,822 @@ +diff -dPNur gftp-2.0.18-orig/configure.in gftp-2.0.18-new/configure.in +--- gftp-2.0.18-orig/configure.in 2005-02-04 16:42:32.000000000 +0100 ++++ gftp-2.0.18-new/configure.in 2005-07-23 18:54:53.000000000 +0200 +@@ -288,6 +288,20 @@ + fi + AC_SUBST(SSL_LIBS) + ++AC_CHECK_LIB(rccui, rccUiInit,[ ++ AC_CHECK_HEADERS(librcc.h librccui.h,[ ++ LIBRCC_LIBS="-lrccui" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ + AM_GNU_GETTEXT + + AC_CHECK_PROG(DB2HTML, db2html, true, false) +diff -dPNur gftp-2.0.18-orig/lib/gftp.h gftp-2.0.18-new/lib/gftp.h +--- gftp-2.0.18-orig/lib/gftp.h 2005-01-19 00:09:58.000000000 +0100 ++++ gftp-2.0.18-new/lib/gftp.h 2005-07-23 20:57:03.000000000 +0200 +@@ -362,6 +362,7 @@ + { + int protonum; /* Current number of the protocol this is + set to */ ++ int language, charset; /* Remote language and encoding */ + char *hostname, /* Hostname we will connect to */ + *username, /* Username for host*/ + *password, /* Password for host */ +@@ -928,6 +929,12 @@ + const char *filename, + mode_t * mode ); + ++void gftp_set_language ( gftp_request * request, ++ int language ); ++ ++void gftp_set_charset ( gftp_request * request, ++ int charset ); ++ + void gftp_set_hostname ( gftp_request * request, + const char *hostname ); + +diff -dPNur gftp-2.0.18-orig/lib/Makefile.am gftp-2.0.18-new/lib/Makefile.am +--- gftp-2.0.18-orig/lib/Makefile.am 2005-01-16 17:10:12.000000000 +0100 ++++ gftp-2.0.18-new/lib/Makefile.am 2005-07-23 18:58:12.000000000 +0200 +@@ -4,6 +4,6 @@ + noinst_LIBRARIES = libgftp.a + libgftp_a_SOURCES=bookmark.c cache.c config_file.c fsp.c ftps.c https.c \ + local.c misc.c mkstemps.c protocols.c pty.c rfc959.c \ +- rfc2068.c sshv2.c sslcommon.c +-INCLUDES=@GLIB_CFLAGS@ @PTHREAD_CFLAGS@ -I../intl -DSHARE_DIR=\"$(datadir)/gftp\" -DLOCALE_DIR=\"$(datadir)/locale\" +-noinst_HEADERS=gftp.h ftpcommon.h httpcommon.h options.h ++ rfc2068.c sshv2.c sslcommon.c rcc.c ++INCLUDES=@LIBRCC_INCLUDES@ @GLIB_CFLAGS@ @PTHREAD_CFLAGS@ -I../intl -DSHARE_DIR=\"$(datadir)/gftp\" -DLOCALE_DIR=\"$(datadir)/locale\" ++noinst_HEADERS=gftp.h ftpcommon.h httpcommon.h options.h rcc.h +diff -dPNur gftp-2.0.18-orig/lib/rcc.c gftp-2.0.18-new/lib/rcc.c +--- gftp-2.0.18-orig/lib/rcc.c 1970-01-01 01:00:00.000000000 +0100 ++++ gftp-2.0.18-new/lib/rcc.c 2005-07-24 01:53:25.000000000 +0200 +@@ -0,0 +1,289 @@ ++#include <stdlib.h> ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++# include <librccui.h> ++#endif /* HAVE_LIBRCC */ ++ ++#include "rcc.h" ++ ++#ifdef HAVE_LIBRCC ++static rcc_class classes[] = { ++ { "ftp", RCC_CLASS_STANDARD, NULL, NULL, "FTP Encoding", 0 }, ++ { "http", RCC_CLASS_STANDARD, NULL, NULL, "HTTP Encoding", 0 }, ++ { "ssh", RCC_CLASS_STANDARD, NULL, NULL, "SSH Encoding", 0 }, ++ { "fs", RCC_CLASS_STANDARD, NULL, NULL, "FS Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, NULL, NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++rcc_context ctx; ++rcc_ui_context uictx; ++static int rcc_initialized = 0; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccUiFreeContext(uictx); ++ rccFreeContext(ctx); ++ rccUiFree(); ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ ctx = rccCreateContext(NULL, 0, 0, classes, 0); ++ if (ctx) { ++ rccLoad(ctx, "ftp"); ++ rccInitDb4(ctx, NULL, 0); ++ rccUiInit(); ++ uictx = rccUiCreateContext(ctx); ++ if (uictx) rcc_initialized = 1; ++ else { ++ rccUiFree(); ++ rccFreeContext(ctx); ++ rccFree(); ++ } ++ } else rccFree(); ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++#ifdef HAVE_LIBRCC ++static char *rcc_languages[RCC_MAX_LANGUAGES+1]; ++static char *rcc_charsets[RCC_MAX_CHARSETS+1]; ++#endif /* HAVE_LIBRCC */ ++ ++char **rccPatchGetLanguageList() { ++#ifdef HAVE_LIBRCC ++ unsigned int i, num; ++ ++ if (rcc_initialized) { ++ num = rccGetLanguageNumber(ctx); ++ for (i=0;i<(num?num:1);i++) ++ rcc_languages[i] = (char*)rccUiGetLanguageName(uictx, (rcc_language_id)i); ++ ++ rcc_languages[i] = NULL; ++ return rcc_languages; ++ } ++#endif /* HAVE_LIBRCC */ ++ ++ return NULL; ++ ++} ++ ++char **rccPatchGetCharsetList(int lid) { ++#ifdef HAVE_LIBRCC ++ unsigned int i, num; ++ rcc_language_config config; ++ ++ if (rcc_initialized) { ++ config = rccGetConfig(ctx, (rcc_language_id)lid); ++ num = rccConfigGetCharsetNumber(config); ++ for (i=0;i<(num?num:1);i++) ++ rcc_charsets[i] = (char*)rccUiGetCharsetName(uictx, (rcc_language_id)lid, (rcc_class_id)0 /* first class, they are equal*/, (rcc_charset_id)i); ++ ++ rcc_charsets[i] = NULL; ++ return rcc_charsets; ++ } ++#endif /* HAVE_LIBRCC */ ++ ++ return NULL; ++} ++ ++char *rccPatchFrom(gftp_request * request, const char *str) { ++#ifdef HAVE_LIBRCC ++ rcc_class_id cl; ++ if (rcc_initialized) { ++ switch (request->protonum) { ++ case GFTP_FTP_NUM: ++ case GFTP_FTPS_NUM: ++ cl = (rcc_class_id)RCC_CLASS_FTP; ++ break; ++ case GFTP_HTTP_NUM: ++ case GFTP_HTTPS_NUM: ++ cl = (rcc_class_id)RCC_CLASS_HTTP; ++ break; ++ case GFTP_SSHV2_NUM: ++ cl = (rcc_class_id)RCC_CLASS_SSH; ++ break; ++ case GFTP_LOCAL_NUM: ++ cl = (rcc_class_id)RCC_CLASS_FS; ++ break; ++ default: ++ return NULL; ++ } ++ ++ if ((cl == RCC_CLASS_FTP)||(cl == RCC_CLASS_HTTP)||(cl == RCC_CLASS_SSH)) { ++ if (request->language) rccSetLanguage(ctx, (rcc_language_id)request->language); ++ if (request->charset) rccSetCharset(ctx, cl, (rcc_charset_id)request->charset); ++ } ++ ++ return rccRecodeFromCharset(ctx, cl, "UTF-8", str); ++ } ++#endif /* HAVE_LIBRCC */ ++ return NULL; ++} ++ ++char *rccPatchTo(gftp_request * request, const char *str) { ++#ifdef HAVE_LIBRCC ++ rcc_class_id cl; ++ if (rcc_initialized) { ++ switch (request->protonum) { ++ case GFTP_FTP_NUM: ++ case GFTP_FTPS_NUM: ++ cl = (rcc_class_id)RCC_CLASS_FTP; ++ break; ++ case GFTP_HTTP_NUM: ++ case GFTP_HTTPS_NUM: ++ cl = (rcc_class_id)RCC_CLASS_HTTP; ++ break; ++ case GFTP_SSHV2_NUM: ++ cl = (rcc_class_id)RCC_CLASS_SSH; ++ break; ++ case GFTP_LOCAL_NUM: ++ cl = (rcc_class_id)RCC_CLASS_FS; ++ break; ++ default: ++ return NULL; ++ } ++ ++ if ((cl == RCC_CLASS_FTP)||(cl == RCC_CLASS_HTTP)||(cl == RCC_CLASS_SSH)) { ++ if (request->language) rccSetLanguage(ctx, (rcc_language_id)request->language); ++ if (request->charset) rccSetCharset(ctx, cl, (rcc_charset_id)request->charset); ++ } ++ ++ return rccRecodeToCharset(ctx, cl, "UTF-8", str); ++ } ++#endif /* HAVE_LIBRCC */ ++ return NULL; ++} ++ ++char *rccPatch(gftp_request *from, gftp_request *to, const char *str) { ++ char *res, *ret; ++ const char *tmp; ++ ++ if (from->protonum == to->protonum) return NULL; ++ printf("%u %u\n", from->protonum, to->protonum); ++ ++ tmp = strstr(str, to->directory); ++ if (!tmp) tmp = str; ++ ++ res = rccPatchTo(from, tmp); ++ if (!res) res = (char*)tmp; ++ ++ ret = rccPatchFrom(to, res); ++ if (ret) { ++ if (res!=tmp) free(res); ++ } else { ++ if (res!=tmp) ret = res; ++ else return NULL; ++ } ++ ++ if (tmp != str) { ++ res = (char*)malloc((strlen(ret) + (tmp-str) + 1)*sizeof(char)); ++ if (res) { ++ memcpy(res, str, (tmp-str)); ++ strcpy(res+(tmp-str), ret); ++ } ++ free(ret); ++ if (res) puts(res); ++ return res; ++ } ++ ++ return ret; ++} ++ ++char *rccPatchFromClass(gftp_request * request, int from, const char *str) { ++#ifdef HAVE_LIBRCC ++ rcc_class_id cl; ++ if (rcc_initialized) { ++ switch (request->protonum) { ++ case GFTP_FTP_NUM: ++ case GFTP_FTPS_NUM: ++ cl = (rcc_class_id)RCC_CLASS_FTP; ++ break; ++ case GFTP_HTTP_NUM: ++ case GFTP_HTTPS_NUM: ++ cl = (rcc_class_id)RCC_CLASS_HTTP; ++ break; ++ case GFTP_SSHV2_NUM: ++ cl = (rcc_class_id)RCC_CLASS_SSH; ++ break; ++ case GFTP_LOCAL_NUM: ++ cl = (rcc_class_id)RCC_CLASS_FS; ++ break; ++ default: ++ return NULL; ++ } ++ ++ if ((cl == RCC_CLASS_FTP)||(cl == RCC_CLASS_HTTP)||(cl == RCC_CLASS_SSH)) { ++ if (request->language) rccSetLanguage(ctx, (rcc_language_id)request->language); ++ if (request->charset) rccSetCharset(ctx, cl, (rcc_charset_id)request->charset); ++ } ++ ++ return rccRecode(ctx, (rcc_class_id)from, cl, str); ++ } ++#endif /* HAVE_LIBRCC */ ++ return NULL; ++} ++ ++char *rccPatchToClass(gftp_request * request, int to, const char *str) { ++#ifdef HAVE_LIBRCC ++ rcc_class_id cl; ++ if (rcc_initialized) { ++ switch (request->protonum) { ++ case GFTP_FTP_NUM: ++ case GFTP_FTPS_NUM: ++ cl = (rcc_class_id)RCC_CLASS_FTP; ++ break; ++ case GFTP_HTTP_NUM: ++ case GFTP_HTTPS_NUM: ++ cl = (rcc_class_id)RCC_CLASS_HTTP; ++ break; ++ case GFTP_SSHV2_NUM: ++ cl = (rcc_class_id)RCC_CLASS_SSH; ++ break; ++ case GFTP_LOCAL_NUM: ++ cl = (rcc_class_id)RCC_CLASS_FS; ++ break; ++ default: ++ return NULL; ++ } ++ ++ if ((cl == RCC_CLASS_FTP)||(cl == RCC_CLASS_HTTP)||(cl == RCC_CLASS_SSH)) { ++ if (request->language) rccSetLanguage(ctx, (rcc_language_id)request->language); ++ if (request->charset) rccSetCharset(ctx, cl, (rcc_charset_id)request->charset); ++ } ++ ++ return rccRecode(ctx, cl, (rcc_class_id)to, str); ++ } ++#endif /* HAVE_LIBRCC */ ++ return NULL; ++} ++ ++ ++char *rccPatchUTF2OUT(const char *str) { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ return rccRecodeFromCharset(ctx, RCC_CLASS_OUT, "UTF-8", str); ++ } ++#endif /* HAVE_LIBRCC */ ++ return NULL; ++} ++ ++char *rccPatchOUT2UTF(const char *str) { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ return rccRecodeToCharset(ctx, RCC_CLASS_OUT, "UTF-8", str); ++ } ++#endif /* HAVE_LIBRCC */ ++ return NULL; ++} +diff -dPNur gftp-2.0.18-orig/lib/rcc.h gftp-2.0.18-new/lib/rcc.h +--- gftp-2.0.18-orig/lib/rcc.h 1970-01-01 01:00:00.000000000 +0100 ++++ gftp-2.0.18-new/lib/rcc.h 2005-07-24 01:49:20.000000000 +0200 +@@ -0,0 +1,28 @@ ++#ifndef _RCC_H ++#define _RCC_H ++ ++#include "gftp.h" ++ ++#define RCC_CLASS_FTP 0 ++#define RCC_CLASS_HTTP 1 ++#define RCC_CLASS_SSH 2 ++#define RCC_CLASS_FS 3 ++#define RCC_CLASS_OUT 4 ++ ++void rccPatchFree(); ++void rccPatchInit(); ++ ++char **rccPatchGetLanguageList(); ++char **rccPatchGetCharsetList(int lid); ++ ++char *rccPatchFrom(gftp_request * request, const char *str); ++char *rccPatchTo(gftp_request * request, const char *str); ++char *rccPatch(gftp_request *from, gftp_request *to, const char *str); ++ ++char *rccPatchFromClass(gftp_request * request, int from, const char *str); ++char *rccPatchToClass(gftp_request * request, int to, const char *str); ++ ++char *rccPatchUTF2OUT(const char *str); ++char *rccPatchOUT2UTF(const char *str); ++ ++#endif /* _RCC_H */ +diff -dPNur gftp-2.0.18-orig/src/gtk/gtkui.c gftp-2.0.18-new/src/gtk/gtkui.c +--- gftp-2.0.18-orig/src/gtk/gtkui.c 2005-01-26 04:22:05.000000000 +0100 ++++ gftp-2.0.18-new/src/gtk/gtkui.c 2005-07-24 00:40:47.000000000 +0200 +@@ -351,6 +351,8 @@ + filelist = wdata->files; + templist = get_next_selection (templist, &filelist, &num); + curfle = filelist->data; ++ cdata->source_string = gftp_string_to_utf8(wdata->request, curfle->file); ++ if (!cdata->source_string) + cdata->source_string = g_strdup (curfle->file); + + tempstr = g_strdup_printf (_("What would you like to rename %s to?"), +diff -dPNur gftp-2.0.18-orig/src/gtk/Makefile.am gftp-2.0.18-new/src/gtk/Makefile.am +--- gftp-2.0.18-orig/src/gtk/Makefile.am 2005-01-16 17:12:08.000000000 +0100 ++++ gftp-2.0.18-new/src/gtk/Makefile.am 2005-07-23 19:16:26.000000000 +0200 +@@ -5,6 +5,6 @@ + gftp_gtk_SOURCES = bookmarks.c chmod_dialog.c delete_dialog.c dnd.c \ + gftp-gtk.c gtkui.c gtkui_transfer.c menu-items.c \ + misc-gtk.c options_dialog.c transfer.c view_dialog.c +-INCLUDES = @GTK_CFLAGS@ @PTHREAD_CFLAGS@ -I../../intl +-LDADD = ../../lib/libgftp.a ../../lib/fsplib/libfsp.a ../uicommon/libgftpui.a @GTK_LIBS@ @PTHREAD_LIBS@ @EXTRA_LIBS@ @GTHREAD_LIBS@ @SSL_LIBS@ @LIBINTL@ ++INCLUDES = @LIBRCC_INCLUDES@ @GTK_CFLAGS@ @PTHREAD_CFLAGS@ -I../../intl ++LDADD = ../../lib/libgftp.a ../../lib/fsplib/libfsp.a ../uicommon/libgftpui.a @GTK_LIBS@ @PTHREAD_LIBS@ @EXTRA_LIBS@ @GTHREAD_LIBS@ @SSL_LIBS@ @LIBINTL@ @LIBRCC_LIBS@ + noinst_HEADERS = gftp-gtk.h +diff -dPNur gftp-2.0.18-orig/src/text/gftp-text.c gftp-2.0.18-new/src/text/gftp-text.c +--- gftp-2.0.18-orig/src/text/gftp-text.c 2005-01-25 02:11:00.000000000 +0100 ++++ gftp-2.0.18-new/src/text/gftp-text.c 2005-07-24 01:54:25.000000000 +0200 +@@ -18,6 +18,7 @@ + /*****************************************************************************/ + + #include "gftp-text.h" ++#include "../../lib/rcc.h" + static const char cvsid[] = "$Id: gftp-text.c,v 1.45 2005/01/25 01:11:00 masneyb Exp $"; + + unsigned int +@@ -93,6 +94,7 @@ + const char *string, ...) + { + char tempstr[512], *utf8_str = NULL, *outstr; ++ char *locale_str; + va_list argp; + + g_return_if_fail (string != NULL); +@@ -140,7 +142,14 @@ + } + + if (level == gftp_logging_misc_nolog) ++{ ++ locale_str = rccPatchUTF2OUT(outstr); ++ if (locale_str) { ++ printf ("%s", locale_str); ++ free(locale_str); ++ } else + printf ("%s", outstr); ++} + else + gftp_text_write_string (request, outstr); + +@@ -158,6 +167,7 @@ + gchar *locale_question; + sigset_t sig, sigsave; + char *pos, *termname; ++ char *tmp; + int singlechar; + FILE *infd; + +@@ -247,6 +257,9 @@ + #else + char tempstr[512]; + #endif ++ char *recoded = NULL; ++ ++ rccPatchInit(); + + gftpui_common_init (&argc, &argv, gftp_text_log); + +@@ -298,9 +311,11 @@ + g_snprintf (prompt, sizeof (prompt), "%sftp%s> ", GFTPUI_COMMON_COLOR_BLUE, GFTPUI_COMMON_COLOR_DEFAULT); + while ((tempstr = readline (prompt))) + { ++ if (recoded) free(recoded); ++ recoded = rccPatchFromClass(gftp_text_remreq, RCC_CLASS_OUT, tempstr); + if (gftpui_common_process_command (locuidata, gftp_text_locreq, + remuidata, gftp_text_remreq, +- tempstr) == 0) ++ recoded?recoded:tempstr) == 0) + break; + + add_history (tempstr); +@@ -310,16 +325,20 @@ + printf ("%sftp%s> ", GFTPUI_COMMON_COLOR_BLUE, GFTPUI_COMMON_COLOR_DEFAULT); + while (fgets (tempstr, sizeof (tempstr), stdin) != NULL) + { ++ if (recoded) free(recoded); ++ recoded = rccPatchFromClass(gftp_tetxt_remreq, RCC_CLASS_OUT, tempstr); + if (gftpui_common_process_command (locuidata, gftp_text_locreq, + remuidata, gftp_text_remreq, +- tempstr) == 0) ++ recoded?recoded:tempstr) == 0) + break; + + printf ("%sftp%s> ", GFTPUI_COMMON_COLOR_BLUE, GFTPUI_COMMON_COLOR_DEFAULT); + } + #endif +- ++ if (recoded) free(recoded); ++ + gftp_shutdown (); ++ rccPatchFree(); + return (0); + } + +diff -dPNur gftp-2.0.18-orig/src/text/Makefile.am gftp-2.0.18-new/src/text/Makefile.am +--- gftp-2.0.18-orig/src/text/Makefile.am 2005-01-16 17:12:00.000000000 +0100 ++++ gftp-2.0.18-new/src/text/Makefile.am 2005-07-23 19:16:39.000000000 +0200 +@@ -3,7 +3,7 @@ + bin_PROGRAMS = @GFTP_TEXT@ + EXTRA_PROGRAMS = gftp-text + gftp_text_SOURCES=gftp-text.c textui.c +-INCLUDES=@GLIB_CFLAGS@ -I../../intl +-LDADD = ../../lib/libgftp.a ../../lib/fsplib/libfsp.a ../uicommon/libgftpui.a @GLIB_LIBS@ @EXTRA_LIBS@ @READLINE_LIBS@ @SSL_LIBS@ @LIBINTL@ ++INCLUDES=@LIBRCC_INCLUDES@ @GLIB_CFLAGS@ -I../../intl ++LDADD = ../../lib/libgftp.a ../../lib/fsplib/libfsp.a ../uicommon/libgftpui.a @GLIB_LIBS@ @EXTRA_LIBS@ @READLINE_LIBS@ @SSL_LIBS@ @LIBINTL@ @LIBRCC_LIBS@ + noinst_HEADERS=gftp-text.h + localedir=$(datadir)/locale +diff -dPNur gftp-2.0.18-orig/lib/protocols.c gftp-2.0.18-new/lib/protocols.c +--- gftp-2.0.18-orig/lib/protocols.c 2005-07-23 15:30:59.000000000 +0200 ++++ gftp-2.0.18-new/lib/protocols.c 2005-07-24 00:56:12.000000000 +0200 +@@ -18,6 +18,8 @@ + /*****************************************************************************/ + + #include "gftp.h" ++#include "rcc.h" ++ + static const char cvsid[] = "$Id: protocols.c,v 1.125 2005/01/25 02:34:18 masneyb Exp $"; + + gftp_request * +@@ -26,6 +28,8 @@ + gftp_request *request; + + request = g_malloc0 (sizeof (*request)); ++ request->language = 0; ++ request->charset = 0; + request->datafd = -1; + request->cachefd = -1; + request->server_type = GFTP_DIRTYPE_OTHER; +@@ -460,6 +469,9 @@ + gftp_lookup_request_option (request, "remote_charsets", &tempstr); + if (*tempstr == '\0') + { ++ ret = rccPatchTo(request, str); ++ if (ret) return ret; ++ + error = NULL; + if ((ret = g_locale_to_utf8 (str, -1, &bread, &bwrite, &error)) != NULL) + return (ret); +@@ -531,6 +544,9 @@ + gftp_lookup_request_option (request, "remote_charsets", &tempstr); + if (*tempstr == '\0') + { ++ ret = rccPatchFrom(request, str); ++ if (ret) return ret; ++ + error = NULL; + if ((ret = g_locale_from_utf8 (str, -1, &bread, &bwrite, &error)) != NULL) + return (ret); +@@ -919,6 +935,18 @@ + } + + ++void ++gftp_set_language (gftp_request * request, int language) { ++ g_return_if_fail (request != NULL); ++ request->language = language; ++} ++ ++void ++gftp_set_charset (gftp_request * request, int charset) { ++ g_return_if_fail (request != NULL); ++ request->charset = charset; ++} ++ + void + gftp_set_hostname (gftp_request * request, const char *hostname) + { +@@ -1056,6 +1084,7 @@ + const char *newname) + { + char *utf8; ++ char *oldutf8; + int ret; + + g_return_val_if_fail (request != NULL, GFTP_EFATAL); +@@ -1064,13 +1093,13 @@ + return (GFTP_EFATAL); + + utf8 = gftp_string_from_utf8 (request, newname); ++ oldutf8 = gftp_string_from_utf8 (request, oldname); ++ ret = request->rename (request, oldutf8?oldutf8:oldname, utf8?utf8:newname); ++ + if (utf8 != NULL) +- { +- ret = request->rename (request, oldname, utf8); + g_free (utf8); +- } +- else +- ret = request->rename (request, oldname, newname); ++ if (oldutf8 != NULL) ++ g_free (oldutf8); + + return (ret); + } +@@ -1948,11 +1977,14 @@ + (newsize = g_hash_table_lookup (dirhash, fle->file)) != NULL) + fle->startsize = *newsize; + +- if (transfer->toreq && fle->destfile == NULL) ++ if (transfer->toreq && fle->destfile == NULL) { ++ newname = rccPatch(transfer->fromreq, transfer->toreq, fle->file); + fle->destfile = gftp_build_path (transfer->toreq, + transfer->toreq->directory, +- fle->file, NULL); +- ++ newname?newname:fle->file, NULL); ++ if (newname) free(newname); ++ } ++ + if (transfer->fromreq->directory != NULL && + *transfer->fromreq->directory != '\0' && + *fle->file != '/') +@@ -2026,11 +2058,15 @@ + return (curfle->size); + } + +- if (transfer->toreq && curfle->destfile == NULL) ++ if (transfer->toreq && curfle->destfile == NULL) { ++ newname = rccPatch(transfer->fromreq, transfer->toreq, curfle->file); + curfle->destfile = gftp_build_path (transfer->toreq, + transfer->toreq->directory, +- curfle->file, NULL); ++ newname?newname:curfle->file, NULL); ++ if (newname) free(newname); ++ } + ++ + if (transfer->fromreq->directory != NULL && + *transfer->fromreq->directory != '\0' && *curfle->file != '/') + { +diff -dPNur gftp-2.0.18-orig/src/gtk/gftp-gtk.c gftp-2.0.18-new/src/gtk/gftp-gtk.c +--- gftp-2.0.18-orig/src/gtk/gftp-gtk.c 2005-01-25 03:34:19.000000000 +0100 ++++ gftp-2.0.18-new/src/gtk/gftp-gtk.c 2005-07-23 22:22:42.000000000 +0200 +@@ -18,6 +18,7 @@ + /*****************************************************************************/ + + #include "gftp-gtk.h" ++#include "../../lib/rcc.h" + static const char cvsid[] = "$Id: gftp-gtk.c,v 1.66 2005/01/25 02:34:19 masneyb Exp $"; + + static GtkItemFactory *log_factory, *dl_factory; +@@ -28,6 +29,7 @@ + GtkWidget * stop_btn, * hostedit, * useredit, * passedit, * portedit, * logwdw, + * dlwdw, * protocol_menu, * optionmenu, * gftpui_command_widget, + * download_left_arrow, * upload_right_arrow, * openurl_btn; ++GtkWidget * language_menu, * charset_menu; + GtkTooltips * openurl_tooltip; + GtkAdjustment * logwdw_vadj; + #if GTK_MAJOR_VERSION > 1 +@@ -420,6 +422,42 @@ + return (factory->widget); + } + ++#ifdef HAVE_LIBRCC ++static int rcc_current_language = 0; ++static int rcc_current_charset = 0; ++ ++static void rccCharsetCB(GtkWidget * w, gpointer item) { ++ rcc_current_charset = g_list_index(GTK_MENU_SHELL(charset_menu)->children, gtk_menu_get_active(GTK_MENU(charset_menu))); ++} ++ ++static void rccLanguageCB(GtkWidget * w, gpointer item) { ++ GtkWidget *tempwid, *optionmenu; ++ unsigned int i; ++ char **langs; ++ gint cur; ++ ++ cur = g_list_index(GTK_MENU_SHELL(language_menu)->children, gtk_menu_get_active(GTK_MENU(language_menu))); ++ optionmenu = gtk_menu_get_attach_widget(GTK_MENU(charset_menu)); ++ ++ rcc_current_language = cur; ++ rcc_current_charset = 0; ++ ++ langs = rccPatchGetCharsetList(cur); ++ if (langs) { ++ charset_menu = gtk_menu_new (); ++ for (i=0;langs[i];i++) { ++ tempwid = gtk_menu_item_new_with_label (langs[i]); ++ gtk_object_set_user_data (GTK_OBJECT (tempwid), GINT_TO_POINTER(i)); ++ gtk_menu_append (GTK_MENU (charset_menu), tempwid); ++ gtk_widget_show (tempwid); ++ } ++ ++ gtk_option_menu_remove_menu (GTK_OPTION_MENU (optionmenu)); ++ gtk_option_menu_set_menu (GTK_OPTION_MENU (optionmenu), charset_menu); ++ gtk_option_menu_set_history (GTK_OPTION_MENU (optionmenu), 0); ++ } ++} ++#endif /* HAVE_LIBRCC */ + + static GtkWidget * + CreateConnectToolbar (GtkWidget * parent) +@@ -430,14 +468,19 @@ + {"application/x-rootwin-drop", 0, 1} + }; + GtkWidget *toolbar, *box, *tempwid; ++ GtkWidget *vbox; ++ GtkWidget *tmpoptionmenu; + gftp_config_list_vars * tmplistvar; + char *default_protocol, *tempstr; ++ char **langs; + int i, num; + + toolbar = gtk_handle_box_new (); + ++ vbox = gtk_vbox_new (FALSE, 0); + box = gtk_hbox_new (FALSE, 4); +- gtk_container_add (GTK_CONTAINER (toolbar), box); ++ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); ++ gtk_container_add (GTK_CONTAINER (toolbar), vbox); + gtk_container_border_width (GTK_CONTAINER (box), 5); + + openurl_tooltip = gtk_tooltips_new (); +@@ -548,6 +591,7 @@ + optionmenu = gtk_option_menu_new (); + gtk_box_pack_start (GTK_BOX (tempwid), optionmenu, TRUE, FALSE, 0); + ++ + num = 0; + gftp_lookup_global_option ("default_protocol", &default_protocol); + protocol_menu = gtk_menu_new (); +@@ -584,6 +628,61 @@ + gtk_container_border_width (GTK_CONTAINER (stop_btn), 1); + gtk_box_pack_start (GTK_BOX (box), stop_btn, FALSE, FALSE, 0); + ++#ifdef HAVE_LIBRCC ++ box = gtk_hbox_new (FALSE, 4); ++ gtk_box_pack_start(GTK_BOX(vbox), box, FALSE, FALSE, 0); ++ gtk_container_border_width (GTK_CONTAINER (box), 5); ++ ++ langs = rccPatchGetCharsetList(0); ++ if (langs) { ++ tempwid = gtk_vbox_new (FALSE, 0); ++ gtk_box_pack_end (GTK_BOX (box), tempwid, FALSE, FALSE, 0); ++ ++ tmpoptionmenu = gtk_option_menu_new (); ++ gtk_box_pack_start (GTK_BOX (tempwid), tmpoptionmenu, TRUE, FALSE, 0); ++ ++ charset_menu = gtk_menu_new (); ++ for (i=0;langs[i];i++) { ++ tempwid = gtk_menu_item_new_with_label (langs[i]); ++ gtk_signal_connect(GTK_OBJECT(tempwid), "activate", GTK_SIGNAL_FUNC(rccCharsetCB), NULL); ++ gtk_object_set_user_data (GTK_OBJECT (tempwid), GINT_TO_POINTER(i)); ++ gtk_menu_append (GTK_MENU (charset_menu), tempwid); ++ gtk_widget_show (tempwid); ++ } ++ ++ gtk_option_menu_set_menu (GTK_OPTION_MENU (tmpoptionmenu), charset_menu); ++ gtk_option_menu_set_history (GTK_OPTION_MENU (tmpoptionmenu), rcc_current_charset); ++ ++ tempwid = gtk_label_new (_("Charset: ")); ++ gtk_box_pack_end (GTK_BOX (box), tempwid, FALSE, FALSE, 0); ++ } ++ ++ langs = rccPatchGetLanguageList(); ++ if (langs) { ++ tempwid = gtk_vbox_new (FALSE, 0); ++ gtk_box_pack_end (GTK_BOX (box), tempwid, FALSE, FALSE, 0); ++ ++ tmpoptionmenu = gtk_option_menu_new (); ++ gtk_box_pack_start (GTK_BOX (tempwid), tmpoptionmenu, TRUE, FALSE, 0); ++ ++ language_menu = gtk_menu_new (); ++ for (i=0;langs[i];i++) { ++ tempwid = gtk_menu_item_new_with_label (langs[i]); ++ gtk_signal_connect(GTK_OBJECT(tempwid), "activate", GTK_SIGNAL_FUNC(rccLanguageCB), NULL); ++ gtk_object_set_user_data (GTK_OBJECT (tempwid), GINT_TO_POINTER(i)); ++ gtk_menu_append (GTK_MENU (language_menu), tempwid); ++ gtk_widget_show (tempwid); ++ } ++ ++ gtk_option_menu_set_menu (GTK_OPTION_MENU (tmpoptionmenu), language_menu); ++ gtk_option_menu_set_history (GTK_OPTION_MENU (tmpoptionmenu), rcc_current_language); ++ ++ tempwid = gtk_label_new (_("Language: ")); ++ gtk_box_pack_end (GTK_BOX (box), tempwid, FALSE, FALSE, 0); ++ } ++#endif /* HAVE_LIBRCC */ ++ ++ + gtk_widget_grab_focus (GTK_COMBO (hostedit)->entry); + + return (toolbar); +@@ -1132,6 +1231,16 @@ + add_history (current_wdata->combo, current_wdata->history, + current_wdata->histlen, current_wdata->request->directory); + ++#ifdef HAVE_LIBRCC ++ tempwid = gtk_menu_get_active (GTK_MENU (language_menu)); ++ num = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (tempwid))); ++ gftp_set_language(current_wdata->request, num); ++ ++ tempwid = gtk_menu_get_active (GTK_MENU (charset_menu)); ++ num = GPOINTER_TO_INT (gtk_object_get_user_data (GTK_OBJECT (tempwid))); ++ gftp_set_charset(current_wdata->request, num); ++#endif /* HAVE_LIBRCC */ ++ + ftp_connect (current_wdata, current_wdata->request, 1); + } + +@@ -1270,6 +1379,8 @@ + { + GtkWidget *window, *ui; + ++ rccPatchInit(); ++ + /* We override the read color functions because we are using a GdkColor + structures to store the color. If I put this in lib/config_file.c, then + the core library would be dependant on Gtk+ being present */ +@@ -1336,6 +1447,8 @@ + GDK_THREADS_ENTER (); + gtk_main (); + GDK_THREADS_LEAVE (); ++ ++ rccPatchFree(); + + return (0); + } diff --git a/patches/gstreamer/gst-plugins-good-0.10.16-rusxmms.diff b/patches/gstreamer/gst-plugins-good-0.10.16-rusxmms.diff new file mode 100644 index 0000000..95aea19 --- /dev/null +++ b/patches/gstreamer/gst-plugins-good-0.10.16-rusxmms.diff @@ -0,0 +1,224 @@ +diff -dPNur gst-plugins-good-0.10.16/configure.ac gst-plugins-good-0.10.16-ds/configure.ac +--- gst-plugins-good-0.10.16/configure.ac 2009-08-29 00:05:24.000000000 +0400 ++++ gst-plugins-good-0.10.16-ds/configure.ac 2009-10-29 06:20:29.000000000 +0300 +@@ -939,6 +939,13 @@ + AC_SUBST(BZ2_LIBS) + ]) + ++dnl *** id3demux to use LibRCC ++translit(dnm, m, l) AM_CONDITIONAL(USE_LIBRCC, true) ++AG_GST_CHECK_FEATURE(LIBRCC, [librcc support for id3demux],, [ ++ AG_GST_CHECK_LIBHEADER(LIBRCC, rcc, rccInit, ,librcc.h, LIBRCC_LIBS="-lrcc") ++ AC_SUBST(LIBRCC_LIBS) ++]) ++ + else + + dnl not building plugins with external dependencies, +@@ -974,6 +981,7 @@ + AM_CONDITIONAL(USE_XSHM, false) + AM_CONDITIONAL(USE_XVIDEO, false) + AM_CONDITIONAL(USE_ZLIB, false) ++AM_CONDITIONAL(USE_LIBRCC, false) + + fi dnl of EXT plugins + +diff -dPNur gst-plugins-good-0.10.16/gst/id3demux/gstid3demux.c gst-plugins-good-0.10.16-ds/gst/id3demux/gstid3demux.c +--- gst-plugins-good-0.10.16/gst/id3demux/gstid3demux.c 2009-08-11 02:15:55.000000000 +0400 ++++ gst-plugins-good-0.10.16-ds/gst/id3demux/gstid3demux.c 2009-10-29 06:44:25.000000000 +0300 +@@ -56,6 +56,7 @@ + + #include "gstid3demux.h" + #include "id3tags.h" ++#include "rccpatch.h" + + static const GstElementDetails gst_id3demux_details = + GST_ELEMENT_DETAILS ("ID3 tag demuxer", +@@ -107,11 +108,22 @@ + } + + static void ++gst_id3demux_finalize (GObject * object) ++{ ++ GstID3Demux *demux = GST_ID3DEMUX (object); ++ ++ rcc_patch_unref(); ++ ++ G_OBJECT_CLASS (parent_class)->finalize (object); ++} ++ ++static void + gst_id3demux_class_init (GstID3DemuxClass * klass) + { + GstTagDemuxClass *tagdemux_class = (GstTagDemuxClass *) klass; + GObjectClass *gobject_class = (GObjectClass *) klass; + ++ gobject_class->finalize = gst_id3demux_finalize; + gobject_class->set_property = gst_id3demux_set_property; + gobject_class->get_property = gst_id3demux_get_property; + +@@ -133,6 +145,7 @@ + gst_id3demux_init (GstID3Demux * id3demux, GstID3DemuxClass * klass) + { + id3demux->prefer_v1 = DEFAULT_PREFER_V1; ++ rcc_patch_ref(); + } + + static gboolean +diff -dPNur gst-plugins-good-0.10.16/gst/id3demux/id3v2frames.c gst-plugins-good-0.10.16-ds/gst/id3demux/id3v2frames.c +--- gst-plugins-good-0.10.16/gst/id3demux/id3v2frames.c 2009-08-11 02:15:55.000000000 +0400 ++++ gst-plugins-good-0.10.16-ds/gst/id3demux/id3v2frames.c 2009-10-29 06:40:17.000000000 +0300 +@@ -33,6 +33,7 @@ + #endif + + #include "id3tags.h" ++#include "rccpatch.h" + + GST_DEBUG_CATEGORY_EXTERN (id3demux_debug); + #define GST_CAT_DEFAULT (id3demux_debug) +@@ -986,7 +987,12 @@ + utf8 = NULL; + } + } +- } ++ } ++ ++ /* Try LibRCC library to detect encoding */ ++ utf8 = rcc_patch_to_utf8(start, size); ++ if (utf8) goto beach; ++ + /* Try current locale (if not UTF-8) */ + if (!g_get_charset (&env)) { + if ((utf8 = g_locale_to_utf8 (start, size, &bytes_read, NULL, NULL))) { +diff -dPNur gst-plugins-good-0.10.16/gst/id3demux/Makefile.am gst-plugins-good-0.10.16-ds/gst/id3demux/Makefile.am +--- gst-plugins-good-0.10.16/gst/id3demux/Makefile.am 2009-08-11 02:15:55.000000000 +0400 ++++ gst-plugins-good-0.10.16-ds/gst/id3demux/Makefile.am 2009-10-29 06:20:06.000000000 +0300 +@@ -1,10 +1,15 @@ + plugin_LTLIBRARIES = libgstid3demux.la + +-libgstid3demux_la_SOURCES = gstid3demux.c id3tags.c id3v2frames.c ++libgstid3demux_la_SOURCES = gstid3demux.c id3tags.c id3v2frames.c rccpatch.c + libgstid3demux_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_BASE_CFLAGS) $(GST_CFLAGS) + libgstid3demux_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgsttag-@GST_MAJORMINOR@ \ + -lgstpbutils-@GST_MAJORMINOR@ $(GST_BASE_LIBS) $(ZLIB_LIBS) + libgstid3demux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) + libgstid3demux_la_LIBTOOLFLAGS = --tag=disable-static + +-noinst_HEADERS = gstid3demux.h id3tags.h ++if USE_LIBRCC ++ libgstid3demux_la_LIBADD += @LIBRCC_LIBS@ ++endif ++ ++ ++noinst_HEADERS = gstid3demux.h id3tags.h rccpatch.h +diff -dPNur gst-plugins-good-0.10.16/gst/id3demux/rccpatch.c gst-plugins-good-0.10.16-ds/gst/id3demux/rccpatch.c +--- gst-plugins-good-0.10.16/gst/id3demux/rccpatch.c 1970-01-01 03:00:00.000000000 +0300 ++++ gst-plugins-good-0.10.16-ds/gst/id3demux/rccpatch.c 2009-10-29 07:05:20.000000000 +0300 +@@ -0,0 +1,91 @@ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include <stdlib.h> ++#include "rccpatch.h" ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++static void rcc_patch_free() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ puts("clean"); ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rcc_patch_init() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ puts("init"); ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++static int registered = 0; ++static int ref_count = 0; ++static GStaticMutex lock = G_STATIC_MUTEX_INIT; ++ ++void rcc_patch_ref() { ++ puts("ref"); ++ g_static_mutex_lock(&lock); ++ if (!registered) { ++ g_atexit(rcc_patch_free); ++ registered = 1; ++ } ++ if (++ref_count==1) rcc_patch_init(); ++ g_static_mutex_unlock(&lock); ++} ++ ++void rcc_patch_unref() { ++ puts("unref"); ++ g_static_mutex_lock(&lock); ++ if (--ref_count==0) rcc_patch_free(); ++ g_static_mutex_unlock(&lock); ++} ++ ++gchar *rcc_patch_to_utf8(const gchar *str, const guint size) { ++#ifdef HAVE_LIBRCC ++ gchar *res; ++ ++ if (rcc_initialized) { ++ g_static_mutex_lock(&lock); ++ res = rccSizedRecode(ctx, ID3_CLASS, UTF_CLASS, str, size, NULL); ++ g_static_mutex_unlock(&lock); ++ ++ return res; ++ } ++#endif /* HAVE_LIBRCC */ ++ ++ return NULL; ++} ++ +diff -dPNur gst-plugins-good-0.10.16/gst/id3demux/rccpatch.h gst-plugins-good-0.10.16-ds/gst/id3demux/rccpatch.h +--- gst-plugins-good-0.10.16/gst/id3demux/rccpatch.h 1970-01-01 03:00:00.000000000 +0300 ++++ gst-plugins-good-0.10.16-ds/gst/id3demux/rccpatch.h 2009-10-29 06:23:58.000000000 +0300 +@@ -0,0 +1,12 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <gst/gst.h> ++ ++void rcc_patch_ref(); ++void rcc_patch_unref(); ++ ++gchar *rcc_patch_to_utf8(const gchar *str, const guint size); ++ ++ ++#endif /* _RCC_PATCH_H */ diff --git a/patches/gstreamer/gstreamer b/patches/gstreamer/gstreamer new file mode 100644 index 0000000..86a0b5f --- /dev/null +++ b/patches/gstreamer/gstreamer @@ -0,0 +1,14 @@ +totem -> gstreamer -> + mp3 playback [mad,ffmpeg,flump3dec] + id3 id3demux (plugins-good) + it uses tag functions (from plugins-base/gst-libs/gst/tag) to + access id3 v.1 and maintains id3 v.2 itself. + +tag contains 'gst_tag_freeform_string_to_utf8' which should be rcc'ized and +used from id3demux (and probably other places) instead of current patch. + +The question is initialization... + + +GST_TAG_ENCODING=CP1251 totem 01_-_vpotmah_192_lame_cbr.mp3 + diff --git a/patches/gstreamer/libid3_problems b/patches/gstreamer/libid3_problems new file mode 100644 index 0000000..4d74a7f --- /dev/null +++ b/patches/gstreamer/libid3_problems @@ -0,0 +1,3 @@ +problems with building of libid3 complaining due to id3_frametype_* undefined are due to + - missing gperf and as a result empty frametype.c and compat.c generated + - gperf should be installed and empty frametype.c, compat.c deleted diff --git a/patches/id3lib/id3lib-ds-rcc.patch b/patches/id3lib/id3lib-ds-rcc.patch new file mode 100644 index 0000000..22c7aa9 --- /dev/null +++ b/patches/id3lib/id3lib-ds-rcc.patch @@ -0,0 +1,169 @@ +diff -dPNur id3lib-3.8.3-orig/configure.in id3lib-3.8.3-new/configure.in +--- id3lib-3.8.3-orig/configure.in 2003-03-02 01:23:00.000000000 +0100 ++++ id3lib-3.8.3-new/configure.in 2005-07-19 22:03:12.000000000 +0200 +@@ -217,6 +217,20 @@ + LIBS="$LIBS $ICONV_LIB" + fi + ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ + dnl Check for c++ features + AC_LANG_SAVE + AC_LANG_CPLUSPLUS +@@ -315,5 +329,5 @@ + src/Makefile \ + examples/Makefile \ + prj/Makefile \ +- libprj/Makefile ++ libprj/Makefile + ) +diff -dPNur id3lib-3.8.3-orig/src/field_string_ascii.cpp id3lib-3.8.3-new/src/field_string_ascii.cpp +--- id3lib-3.8.3-orig/src/field_string_ascii.cpp 2003-03-02 01:23:00.000000000 +0100 ++++ id3lib-3.8.3-new/src/field_string_ascii.cpp 2005-07-19 21:34:12.000000000 +0200 +@@ -27,6 +27,7 @@ + #include "field_impl.h" + #include "id3/utils.h" // has <config.h> "id3/id3lib_streams.h" "id3/globals.h" "id3/id3lib_strings.h" + #include "io_helpers.h" ++#include "rccpatch.h" + + using namespace dami; + +@@ -92,8 +93,15 @@ + buffer != NULL && maxLength > 0) + { + String data = this->GetText(); ++ char *recoded = rccPatchRecode(data.data(), (size_t)data.size(), (size_t*)&size); ++ if (recoded) { ++ size = dami::min(maxLength, size); ++ ::memcpy(buffer, recoded, size); ++ free(recoded); ++ } else { + size = dami::min(maxLength, data.size()); + ::memcpy(buffer, data.data(), size); ++ } + if (size < maxLength) + { + buffer[size] = '\0'; +diff -dPNur id3lib-3.8.3-orig/src/Makefile.am id3lib-3.8.3-new/src/Makefile.am +--- id3lib-3.8.3-orig/src/Makefile.am 2003-03-02 01:23:00.000000000 +0100 ++++ id3lib-3.8.3-new/src/Makefile.am 2005-07-19 21:38:31.000000000 +0200 +@@ -17,7 +17,7 @@ + zlib_include = + endif + +-INCLUDES = \ ++INCLUDES = @LIBRCC_INCLUDES@ \ + @ID3LIB_DEBUG_FLAGS@ -I$(top_srcdir)/include/id3 -I$(top_srcdir)/include $(zlib_include) + + noinst_HEADERS = \ +@@ -31,7 +31,8 @@ + header_tag.h \ + mp3_header.h \ + tag_impl.h \ +- spec.h ++ spec.h \ ++ rccpatch.h + + id3lib_sources = \ + c_wrapper.cpp \ +@@ -66,7 +67,8 @@ + tag_parse_v1.cpp \ + tag_render.cpp \ + utils.cpp \ +- writers.cpp ++ writers.cpp \ ++ rccpatch.cpp + + lib_LTLIBRARIES = libid3.la + +@@ -77,6 +79,7 @@ + endif + + libid3_la_LDFLAGS = \ ++ @LIBRCC_LIBS@ \ + -version-info $(LT_VERSION) \ + -release $(LT_RELEASE) \ + -export-dynamic +diff -dPNur id3lib-3.8.3-orig/src/rccpatch.cpp id3lib-3.8.3-new/src/rccpatch.cpp +--- id3lib-3.8.3-orig/src/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ id3lib-3.8.3-new/src/rccpatch.cpp 2005-07-19 22:10:47.000000000 +0200 +@@ -0,0 +1,60 @@ ++#include <stdlib.h> ++ ++#include "../config.h" ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define OUT_CLASS 1 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, NULL, NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++char *rccPatchRecode(const char *str, size_t len, size_t *rlen) { ++#ifdef HAVE_LIBRCC ++ char *res; ++ rccPatchTryInit(); ++ return rccSizedRecode(NULL, ID3_CLASS, OUT_CLASS, str, len, rlen); ++#else ++ return NULL; ++#endif /* HAVE_LIBRCC */ ++} +diff -dPNur id3lib-3.8.3-orig/src/rccpatch.h id3lib-3.8.3-new/src/rccpatch.h +--- id3lib-3.8.3-orig/src/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ id3lib-3.8.3-new/src/rccpatch.h 2005-07-19 21:34:51.000000000 +0200 +@@ -0,0 +1,3 @@ ++void rccPatchFree(); ++void rccPatchInit(); ++char *rccPatchRecode(const char *str, size_t len, size_t *rlen); diff --git a/patches/libid3tag/README b/patches/libid3tag/README new file mode 100644 index 0000000..f927e0d --- /dev/null +++ b/patches/libid3tag/README @@ -0,0 +1,2 @@ +Read-only patch. The configuration in 'xmms' config. Both ID3 ID3 v.2 Latin1 +encoding is taken out of 'id3' class. diff --git a/patches/libid3tag/libid3tag-0.15.1b-ds-rcc.patch b/patches/libid3tag/libid3tag-0.15.1b-ds-rcc.patch new file mode 100644 index 0000000..4641f3d --- /dev/null +++ b/patches/libid3tag/libid3tag-0.15.1b-ds-rcc.patch @@ -0,0 +1,300 @@ +diff -dPNur libid3tag-0.15.1b/configure.ac libid3tag-0.15.1b-ds/configure.ac +--- libid3tag-0.15.1b/configure.ac 2004-01-24 00:22:46.000000000 +0100 ++++ libid3tag-0.15.1b-ds/configure.ac 2008-04-12 21:36:35.000000000 +0200 +@@ -145,6 +145,22 @@ + *** environment variable to specify its installed location, e.g. -L<dir>.]) + ]) + ++ ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ ++ + dnl handle --enable and --disable options + + AC_CACHE_SAVE +diff -dPNur libid3tag-0.15.1b/latin1.c libid3tag-0.15.1b-ds/latin1.c +--- libid3tag-0.15.1b/latin1.c 2004-01-23 10:41:32.000000000 +0100 ++++ libid3tag-0.15.1b-ds/latin1.c 2008-04-12 21:36:35.000000000 +0200 +@@ -31,6 +31,9 @@ + # include "latin1.h" + # include "ucs4.h" + ++# include "utf8.h" ++# include "rccpatch.h" ++ + /* + * NAME: latin1->length() + * DESCRIPTION: return the number of ucs4 chars represented by a latin1 string +@@ -172,6 +175,11 @@ + id3_length_t size = 0; + id3_latin1_t latin1[1], *out; + ++/* ++ Theoretically, we should add here a code for converting ucs4 to ++ recoded latin1 string. However, using non-standard latin1 tags ++ in ID3v.2 tags is completely idiotic. So, I'll not do that. ++*/ + while (*ucs4) { + switch (id3_latin1_encodechar(out = latin1, *ucs4++)) { + case 1: size += id3_latin1_put(ptr, *out++); +@@ -193,6 +201,7 @@ + { + id3_byte_t const *end; + id3_latin1_t *latin1ptr, *latin1; ++ id3_utf8_t *utf8; + id3_ucs4_t *ucs4; + + end = *ptr + length; +@@ -207,6 +216,19 @@ + + *latin1ptr = 0; + ++ ++ utf8 = rccPatchLatin2UTF(latin1); ++ if (utf8) { ++ ucs4 = malloc((id3_utf8_length(utf8) + 1) * sizeof(*ucs4)); ++ if (ucs4) ++ id3_utf8_decode(utf8, ucs4); ++ free(utf8); ++ free(latin1); ++ ++ ++ return ucs4; ++ } ++ + ucs4 = malloc((id3_latin1_length(latin1) + 1) * sizeof(*ucs4)); + if (ucs4) + id3_latin1_decode(latin1, ucs4); +diff -dPNur libid3tag-0.15.1b/Makefile.am libid3tag-0.15.1b-ds/Makefile.am +--- libid3tag-0.15.1b/Makefile.am 2004-02-17 03:11:28.000000000 +0100 ++++ libid3tag-0.15.1b-ds/Makefile.am 2008-04-12 21:36:35.000000000 +0200 +@@ -81,6 +81,7 @@ + libid3tag_la_SOURCES = version.c ucs4.c latin1.c utf16.c utf8.c \ + parse.c render.c field.c frametype.c compat.c \ + genre.c frame.c crc.c util.c tag.c file.c \ ++ rccpatch.c rccpatch.h \ + version.h ucs4.h latin1.h utf16.h utf8.h \ + parse.h render.h field.h frametype.h compat.h \ + genre.h frame.h crc.h util.h tag.h file.h \ +@@ -90,7 +91,8 @@ + frametype.gperf compat.gperf genre.dat.in \ + debug.c debug.h + +-libid3tag_la_LDFLAGS = -version-info $(version_info) ++INCLUDES = @LIBRCC_INCLUDES@ ++libid3tag_la_LDFLAGS = -version-info $(version_info) @LIBRCC_LIBS@ + + BUILT_SOURCES = frametype.c compat.c genre.dat + +diff -dPNur libid3tag-0.15.1b/rccpatch.c libid3tag-0.15.1b-ds/rccpatch.c +--- libid3tag-0.15.1b/rccpatch.c 1970-01-01 01:00:00.000000000 +0100 ++++ libid3tag-0.15.1b-ds/rccpatch.c 2008-04-12 21:36:35.000000000 +0200 +@@ -0,0 +1,96 @@ ++#include <stdlib.h> ++#include "rccpatch.h" ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++id3_utf8_t *rccPatchLatin2UTF(id3_latin1_t *str) { ++#ifdef HAVE_LIBRCC ++ rccPatchTryInit(); ++ ++ return rccRecode(ctx, ID3_CLASS, UTF_CLASS, str); ++#else ++ return NULL; ++#endif /* HAVE_LIBRCC */ ++} ++ ++id3_latin1_t *rccPatchUTF2Latin(id3_utf8_t *str) { ++#ifdef HAVE_LIBRCC ++ rccPatchTryInit(); ++ ++ return rccRecode(ctx, UTF_CLASS, ID3_CLASS, str); ++#else ++ return NULL; ++#endif /* HAVE_LIBRCC */ ++} ++ ++id3_latin1_t *rccPatchUTF2Out(id3_utf8_t *str) { ++#ifdef HAVE_LIBRCC ++ rccPatchTryInit(); ++ ++ return rccRecode(ctx, UTF_CLASS, OUT_CLASS, str); ++#else ++ return NULL; ++#endif /* HAVE_LIBRCC */ ++} ++ +diff -dPNur libid3tag-0.15.1b/rccpatch.h libid3tag-0.15.1b-ds/rccpatch.h +--- libid3tag-0.15.1b/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ libid3tag-0.15.1b-ds/rccpatch.h 2008-04-12 21:36:35.000000000 +0200 +@@ -0,0 +1,15 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include "id3tag.h" ++ ++void rccPatchFree(); ++void rccPatchInit(); ++void rccPatchSetContext(void *newctx); ++ ++id3_utf8_t *rccPatchLatin2UTF(id3_latin1_t *str); ++id3_latin1_t *rccPatchUTF2Latin(id3_utf8_t *str); ++id3_latin1_t *rccPatchUTF2Out(id3_utf8_t *str); ++ ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur libid3tag-0.15.1b/tag.c libid3tag-0.15.1b-ds/tag.c +--- libid3tag-0.15.1b/tag.c 2004-02-17 03:04:10.000000000 +0100 ++++ libid3tag-0.15.1b-ds/tag.c 2008-04-12 21:37:12.000000000 +0200 +@@ -45,6 +45,9 @@ + # include "field.h" + # include "util.h" + ++# include "utf8.h" ++# include "rccpatch.h" ++ + /* + * NAME: tag->new() + * DESCRIPTION: allocate and return a new, empty tag +@@ -335,6 +338,8 @@ + { + struct id3_frame *frame; + id3_ucs4_t ucs4[31]; ++ ++ id3_utf8_t *utf8; + + if (text) { + trim(text); +@@ -350,9 +355,15 @@ + ID3_FIELD_TEXTENCODING_ISO_8859_1) == -1) + goto fail; + +- if (text) ++ if (text) { ++ utf8 = rccPatchLatin2UTF(text); ++ if (utf8) { ++ if (strlen(utf8) > 30) utf8[30] = 0; ++ id3_utf8_decode(utf8, ucs4); ++ free(utf8); ++ } else + id3_latin1_decode(text, ucs4); +- else ++ } else + id3_ucs4_putnumber(ucs4, number); + + if (strcmp(id, ID3_FRAME_COMMENT) == 0) { +diff -dPNur libid3tag-0.15.1b/ucs4.c libid3tag-0.15.1b-ds/ucs4.c +--- libid3tag-0.15.1b/ucs4.c 2004-01-23 10:41:32.000000000 +0100 ++++ libid3tag-0.15.1b-ds/ucs4.c 2008-04-12 21:36:35.000000000 +0200 +@@ -33,6 +33,9 @@ + # include "utf16.h" + # include "utf8.h" + ++# include <string.h> ++# include "rccpatch.h" ++ + id3_ucs4_t const id3_ucs4_empty[] = { 0 }; + + /* +@@ -125,6 +128,27 @@ + { + id3_latin1_t *latin1; + ++ ++ id3_latin1_t *ltmp; ++ id3_utf8_t *utf8; ++ ++ utf8 = malloc(id3_ucs4_utf8size(ucs4) * sizeof(*utf8)); ++ if (utf8) { ++ id3_utf8_encode(utf8, ucs4); ++ ltmp = rccPatchUTF2Out(utf8); ++ free(utf8); ++ ++ if (ltmp) { ++ latin1 = malloc((1+strlen(ltmp))*sizeof(char)); ++ if (latin1) { ++ memcpy(latin1, ltmp, (1+strlen(ltmp))); ++ free(ltmp); ++ return release(latin1); ++ } ++ free(ltmp); ++ } ++ } ++ + latin1 = malloc(id3_ucs4_latin1size(ucs4) * sizeof(*latin1)); + if (latin1) + id3_latin1_encode(latin1, ucs4); diff --git a/patches/libtranslate/README.txt b/patches/libtranslate/README.txt new file mode 100644 index 0000000..e152812 --- /dev/null +++ b/patches/libtranslate/README.txt @@ -0,0 +1,5 @@ +Apply the patches in the order they listed. Use patches from 'soup22' directory +to build against libsoup versions before 2.4, otherwise use patches from +'soup24' (tested up to 2.8). + +Replace data/services.xml.in by provided services.xml with updated services. diff --git a/patches/libtranslate/libtranslate-ds2-memory.patch b/patches/libtranslate/libtranslate-ds2-memory.patch new file mode 100644 index 0000000..e05c7b4 --- /dev/null +++ b/patches/libtranslate/libtranslate-ds2-memory.patch @@ -0,0 +1,12 @@ +diff -dPNur libtranslate-0.99/src/translate-util.c libtranslate-0.99-new/src/translate-util.c +--- libtranslate-0.99/src/translate-util.c 2005-01-17 16:45:45.000000000 +0000 ++++ libtranslate-0.99-new/src/translate-util.c 2005-12-29 18:35:04.000000000 +0000 +@@ -136,7 +136,7 @@ + g_return_val_if_fail(big != NULL, NULL); + g_return_val_if_fail(little != NULL, NULL); + +- lower_big = g_ascii_strdown(big, big_len); ++ lower_big = g_ascii_strdown(big, (int)big_len); + lower_little = g_ascii_strdown(little, -1); + + s = strstr(lower_big, lower_little); diff --git a/patches/libtranslate/libtranslate-ds3-charsetparse.patch b/patches/libtranslate/libtranslate-ds3-charsetparse.patch new file mode 100644 index 0000000..2f578e9 --- /dev/null +++ b/patches/libtranslate/libtranslate-ds3-charsetparse.patch @@ -0,0 +1,47 @@ +--- libtranslate-0.99/src/modules/translate-generic-service.c.orig Mon Apr 11 23:08:47 2005 ++++ libtranslate-0.99/src/modules/translate-generic-service.c Mon Apr 11 23:15:54 2005 +@@ -484,7 +484,7 @@ + + if (SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) + { +- const char *charset = NULL; ++ char *charset = NULL; + + if (flags & TRANSFER_CONVERT) + { +@@ -493,14 +493,31 @@ + content_type = translate_generic_service_get_header(message, &info, "Content-Type"); + if (content_type) + { +- charset = translate_ascii_strcasestr(content_type, "charset="); +- if (charset) +- charset += 8; ++ const char *tmp; ++ ++ tmp = translate_ascii_strcasestr(content_type, "charset="); ++ if (tmp) ++ { ++ int len; ++ ++ tmp += 8; ++ if (*tmp == '\'' || *tmp == '"') ++ tmp++; ++ ++ len = strlen(tmp); ++ if (len > 0 && (tmp[len - 1] == '\'' || tmp[len - 1] == '"')) ++ len--; ++ ++ charset = g_strndup(tmp, len); ++ } + } + } + + if (charset) +- response = g_convert(message->response.body, message->response.length, "UTF-8", charset, NULL, NULL, err); ++ { ++ response = g_convert(message->response.body, message->response.length, "UTF-8", charset, NULL, NULL, err); ++ g_free(charset); ++ } + else + { + if ((flags & TRANSFER_CONVERT) && ! g_utf8_validate(message->response.body, message->response.length, NULL)) diff --git a/patches/libtranslate/libtranslate-ds4-condfix.patch b/patches/libtranslate/libtranslate-ds4-condfix.patch new file mode 100644 index 0000000..9915a80 --- /dev/null +++ b/patches/libtranslate/libtranslate-ds4-condfix.patch @@ -0,0 +1,38 @@ +--- libtranslate-0.99/src/translate-session.c.orig Mon Apr 11 22:44:53 2005 ++++ libtranslate-0.99/src/translate-session.c Mon Apr 11 22:51:48 2005 +@@ -703,7 +703,14 @@ + GError *tmp_err = NULL; + + g_mutex_lock(info->mutex); +- ret = info->err != NULL; ++ if (info->err) ++ { ++ ret = TRUE; ++ if (info->progress_cond) ++ g_cond_signal(info->progress_cond); ++ } ++ else ++ ret = FALSE; + g_mutex_unlock(info->mutex); + + if (ret) +@@ -728,6 +735,9 @@ + else + g_propagate_error(&info->err, tmp_err); + ++ if (info->progress_cond) ++ g_cond_signal(info->progress_cond); ++ + g_mutex_unlock(info->mutex); + + return; +@@ -759,6 +769,9 @@ + info->err = g_error_new(TRANSLATE_SESSION_ERROR, + TRANSLATE_SESSION_ERROR_NO_SERVICE, + _("no service could translate chunk")); ++ ++ if (info->progress_cond) ++ g_cond_signal(info->progress_cond); + } + + g_mutex_unlock(info->mutex); diff --git a/patches/libtranslate/libtranslate-ds5-empty.patch b/patches/libtranslate/libtranslate-ds5-empty.patch new file mode 100644 index 0000000..eb2e0ce --- /dev/null +++ b/patches/libtranslate/libtranslate-ds5-empty.patch @@ -0,0 +1,17 @@ +diff -dPNur libtranslate-0.99/src/modules/translate-generic-service.c libtranslate-0.99-new/src/modules/translate-generic-service.c +--- libtranslate-0.99/src/modules/translate-generic-service.c 2007-06-27 17:26:10.000000000 +0200 ++++ libtranslate-0.99-new/src/modules/translate-generic-service.c 2007-06-27 17:23:55.000000000 +0200 +@@ -1042,6 +1042,13 @@ + + g_free(response); + } ++ ++ if ((!answer)&&(!*err)) { ++ g_set_error(err, ++ TRANSLATE_GENERIC_SERVICE_ERROR, ++ TRANSLATE_GENERIC_SERVICE_ERROR_PARSE, ++ _("empty server response")); ++ } + + return answer ? g_string_free(answer, FALSE) : NULL; + } diff --git a/patches/libtranslate/libtranslate-ds6-promt.patch b/patches/libtranslate/libtranslate-ds6-promt.patch new file mode 100644 index 0000000..6b30145 --- /dev/null +++ b/patches/libtranslate/libtranslate-ds6-promt.patch @@ -0,0 +1,27 @@ +diff -dPNur libtranslate-0.99/src/modules/translate-generic-service.c libtranslate-0.99-new/src/modules/translate-generic-service.c +--- libtranslate-0.99/src/modules/translate-generic-service.c 2007-06-27 17:26:10.000000000 +0200 ++++ libtranslate-0.99-new/src/modules/translate-generic-service.c 2007-06-27 17:23:55.000000000 +0200 +@@ -1238,7 +1245,22 @@ + { + if (modifier_value) + g_warning(_("%s: value specified for \"escape\" modifier"), warning_prefix); +- modified = soup_uri_encode(value, NULL); ++ modified = soup_uri_encode(value, "&"); ++ } ++ else if (! strcmp(modifier_name, "entities")) ++ { ++ int i; ++ char *ptr; ++ ++ modified = g_malloc(strlen(value)*6 + 1); ++ for (i=0,ptr=modified;value[i];i++) { ++ if ((unsigned char)(value[i])<160) *(ptr++)=value[i]; ++ else { ++ sprintf(ptr, "&#%u;", (unsigned char)(value[i])); ++ ptr+=6; ++ } ++ } ++ *ptr = 0; + } + else if (! strcmp(modifier_name, "charset")) + { diff --git a/patches/libtranslate/libtranslate-ds7-fixcharset.patch b/patches/libtranslate/libtranslate-ds7-fixcharset.patch new file mode 100644 index 0000000..0665d2f --- /dev/null +++ b/patches/libtranslate/libtranslate-ds7-fixcharset.patch @@ -0,0 +1,93 @@ +diff -dPNur libtranslate-0.99-new/src/modules/translate-generic-parser.c libtranslate-0.99-new-uk/src/modules/translate-generic-parser.c +--- libtranslate-0.99-new/src/modules/translate-generic-parser.c 2005-01-17 17:46:24.000000000 +0100 ++++ libtranslate-0.99-new-uk/src/modules/translate-generic-parser.c 2007-06-27 22:40:04.000000000 +0200 +@@ -726,6 +726,7 @@ + { + const char *url; + const char *post; ++ const char *charset; + const char *content_type; + + g_return_if_fail(info != NULL); +@@ -740,6 +741,7 @@ + "url", REQUIRED, &url, + "post", OPTIONAL, &post, + "content-type", OPTIONAL, &content_type, ++ "response-charset", OPTIONAL, &charset, + NULL); + + if (! *err) +@@ -748,6 +750,7 @@ + (*location)->url = g_strdup(url); + (*location)->post = g_strdup(post); + (*location)->content_type = g_strdup(content_type ? content_type : "application/x-www-form-urlencoded"); ++ (*location)->response_charset = g_strdup(charset); + } + } + +@@ -759,6 +762,7 @@ + g_free(location->url); + g_free(location->post); + g_free(location->content_type); ++ g_free(location->response_charset); + g_slist_foreach(location->http_headers, (GFunc) translate_generic_http_header_free, NULL); + g_slist_free(location->http_headers); + g_free(location); +diff -dPNur libtranslate-0.99-new/src/modules/translate-generic-parser.h libtranslate-0.99-new-uk/src/modules/translate-generic-parser.h +--- libtranslate-0.99-new/src/modules/translate-generic-parser.h 2005-01-17 17:46:30.000000000 +0100 ++++ libtranslate-0.99-new-uk/src/modules/translate-generic-parser.h 2007-06-27 22:34:13.000000000 +0200 +@@ -51,6 +51,7 @@ + char *url; + char *post; + char *content_type; ++ char *response_charset; + GSList *http_headers; + } TranslateGenericLocation; + +diff -dPNur libtranslate-0.99-new/src/modules/translate-generic-service.c libtranslate-0.99-new-uk/src/modules/translate-generic-service.c +--- libtranslate-0.99-new/src/modules/translate-generic-service.c 2007-06-27 17:23:55.000000000 +0200 ++++ libtranslate-0.99-new-uk/src/modules/translate-generic-service.c 2007-06-27 22:40:29.000000000 +0200 +@@ -129,6 +129,7 @@ + static char *translate_generic_service_get (const char *uri, + const char *post, + const char *post_content_type, ++ const char *response_charset, + const GSList *headers, + TransferFlags flags, + GTimeVal *deadline, +@@ -407,6 +408,7 @@ + translate_generic_service_get (const char *uri, + const char *post, + const char *post_content_type, ++ const char *response_charset, + const GSList *headers, + TransferFlags flags, + GTimeVal *deadline, +@@ -550,9 +552,9 @@ + } + } + +- if (charset) ++ if ((charset)||(response_charset)) + { +- response = g_convert(message->response.body, message->response.length, "UTF-8", charset, NULL, NULL, err); ++ response = g_convert(message->response.body, message->response.length, "UTF-8", response_charset?response_charset:charset, NULL, NULL, err); + g_free(charset); + } + else +@@ -941,6 +943,7 @@ + response = translate_generic_service_get(url, + post, + group->text_location->content_type, ++ group->text_location->response_charset, + headers, + TRANSFER_FOLLOW_REFRESH | TRANSFER_CONVERT, + deadline, +@@ -1339,6 +1342,7 @@ + response = translate_generic_service_get(translation_url, + post, + group->web_page_location->content_type, ++ group->web_page_location->response_charset, + headers, + 0, + NULL, diff --git a/patches/libtranslate/services.xml b/patches/libtranslate/services.xml new file mode 100644 index 0000000..14d0548 --- /dev/null +++ b/patches/libtranslate/services.xml @@ -0,0 +1,258 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE services SYSTEM "services.dtd"> +<services> + <custom-language tag="zh-TW" name="Chinese (Taiwan)"/> + + <service nick="Google" name="google"> + <group> + <language to="*" tag="en"/> + <language to="en,de" tag="fr"/> + <language to="en,fr" tag="de"/> + <language to="en" tag="it"/> + <language to="en" tag="pt"/> + <language to="en" tag="es"/> + <language to="en" tag="pt"/> + <language to="en" tag="ru"/> + <language to="en" tag="zh"/> + <language to="en" tag="zh-TW"/> + <language to="en" tag="ja"/> + <language to="en" tag="ko"/> + <language to="en" tag="ar"/> + <text-translation url="http://www.google.com/translate_t?text=${text:escape}&langpair=${from}|${to}&ie=utf8&oe=utf8"> + <pre-marker text="id=result_box"/> + <pre-marker text="mouseover"/> + <pre-marker text=">"/> + <post-marker text="<br>"/> + </text-translation> + <web-page-translation url="http://www.google.com/translate_c?u=${url:escape}&langpair=${from}|${to}"/> + </group> + </service> + + <service nick="FreeTranslation" name="freetranslation" max-chunk-len="600"> + <group> + <language to="en" tag="nl" service-tag="dutch"/> + <language to="*" tag="en" service-tag="english"/> + <language to="en" tag="fr" service-tag="french"/> + <language to="en" tag="de" service-tag="german"/> + <language to="en" tag="it" service-tag="italian"/> + <language tag="no" service-tag="norwegian"/> + <language to="en" tag="pt" service-tag="portuguese"/> + <language to="en" tag="es" service-tag="spanish"/> + <text-translation url="http://ets.freetranslation.com/?sequence=core&srctext=${text:escape}&language=${from}/${to}&charset=utf-8"/> + <web-page-translation url="http://fets5.freetranslation.com/?sequence=core&url=${url:escape}&language=${from}/${to}"/> + </group> + <group> + <language tag="zh" service-tag="simplifiedchinese"/> + <language tag="zh-TW" service-tag="traditionalchinese"/> + <language to="*" tag="en" service-tag="english"/> + <language to="en" tag="ru" service-tag="russian"/> + <text-translation url="http://ets6.freetranslation.com/?sequence=core&srctext=${text:escape}&language=${from}/${to}&charset=utf-8"/> + </group> + <group> + <language to="*" tag="en" service-tag="english"/> + <language to="en" tag="ja" service-tag="japanese"/> + <text-translation url="http://tets9.freetranslation.com/?sequence=core&srctext=${text:escape}&language=${from}/${to}&charset=utf-8"/> + </group> + </service> + + <service nick="Pereklad" name="pereklad"> + <group> + <language to="*" tag="ru" service-tag="Rus"/> + <language to="*" tag="uk" service-tag="Ukr"/> + <text-translation + url="http://pereklad.online.ua/" + post="TranFrom=${from}&TranTo=${to}&SrcTxt=${text:escape}"> + <pre-marker text="id="DstTxt""/> + <pre-marker text=">"/> + <post-marker text="</textarea>"/> + </text-translation> + </group> + <group> + <language to="*" tag="en" service-tag="Eng"/> + <language to="*" tag="de" service-tag="Ger"/> + <language to="*" tag="fr" service-tag="Fra"/> + <text-translation + url="http://pereklad.online.ua/" + post="TranFrom=${from}&TranTo=${to}&SrcTxt=${text:escape}" + response-charset="ISO-8859-1"> + <pre-marker text="id="DstTxt""/> + <pre-marker text=">"/> + <post-marker text="</textarea>"/> + </text-translation> + </group> + <group> + <language to="en,de,fr" tag="ru" service-tag="Rus"/> + <language to="en,de,fr" tag="uk" service-tag="Ukr"/> + <language to="" tag="en" service-tag="Eng"/> + <language to="" tag="de" service-tag="Ger"/> + <language to="" tag="fr" service-tag="Fra"/> + <text-translation + url="http://pereklad.online.ua/" + post="TranFrom=${from}&TranTo=${to}&SrcTxt=${text:escape}" + response-charset="ISO-8859-1"> + <pre-marker text="id="DstTxt""/> + <pre-marker text=">"/> + <post-marker text="</textarea>"/> + </text-translation> + </group> + <group> + <language to="" tag="ru" service-tag="Rus"/> + <language to="" tag="uk" service-tag="Ukr"/> + <language to="ru,uk" tag="en" service-tag="Eng"/> + <language to="ru,uk" tag="de" service-tag="Ger"/> + <language to="ru,uk" tag="fr" service-tag="Fra"/> + <text-translation + url="http://pereklad.online.ua/" + post="TranFrom=${from}&TranTo=${to}&SrcTxt=${text:escape}"> + <pre-marker text="id="DstTxt""/> + <pre-marker text=">"/> + <post-marker text="</textarea>"/> + </text-translation> + </group> + <group> + <language to="" tag="ru" service-tag="Rus"/> + <language to="" tag="uk" service-tag="Ukr"/> + <language to="ru,uk" tag="lv" service-tag="Lat"/> + <text-translation + url="http://pereklad.online.ua/" + post="TranFrom=${from}&TranTo=${to}&SrcTxt=${text:escape}"> + <pre-marker text="id="DstTxt""/> + <pre-marker text=">"/> + <post-marker text="</textarea>"/> + </text-translation> + </group> + <group> + <language to="*" tag="lv" service-tag="Lat"/> + <language to="" tag="en" service-tag="Eng"/> + <language to="" tag="de" service-tag="Ger"/> + <language to="" tag="fr" service-tag="Fra"/> + <text-translation + url="http://pereklad.online.ua/" + post="TranFrom=${from}&TranTo=${to}&SrcTxt=${text:escape}" + response-charset="ISO-8859-1"> + <pre-marker text="id="DstTxt""/> + <pre-marker text=">"/> + <post-marker text="</textarea>"/> + </text-translation> + </group> + <group> + <language to="" tag="lv" service-tag="Lat"/> + <language to="lv" tag="ru" service-tag="Rus"/> + <language to="lv" tag="uk" service-tag="Ukr"/> + <text-translation + url="http://pereklad.online.ua/" + post="TranFrom=${from}&TranTo=${to}&SrcTxt=${text:escape}" + response-charset="ISO-8859-4"> + <pre-marker text="id="DstTxt""/> + <pre-marker text=">"/> + <post-marker text="</textarea>"/> + </text-translation> + </group> + <group> + <language to="" tag="lv" service-tag="Lat"/> + <language to="lv" tag="en" service-tag="Eng"/> + <language to="lv" tag="de" service-tag="Ger"/> + <language to="lv" tag="fr" service-tag="Fra"/> + <text-translation + url="http://pereklad.online.ua/" + post="TranFrom=${from}&TranTo=${to}&SrcTxt=${text:escape}" + response-charset="ISO-8859-4"> + <pre-marker text="id="DstTxt""/> + <pre-marker text=">"/> + <post-marker text="</textarea>"/> + </text-translation> + </group> + </service> + + <service nick="Promt" name="promt"> + <group> + <language to="*" tag="ru" service-tag="r"/> + <language to="ru,de,fr,es" tag="en" service-tag="e"/> + <language to="ru,en,fr,es" tag="de" service-tag="g"/> + <language to="ru,en,de,es" tag="fr" service-tag="f"/> + <language to="ru,en" tag="it" service-tag="i"/> + <language to="ru,en,de,fr" tag="es" service-tag="s"/> + <language to="en" tag="pt" service-tag="p"/> + <text-translation + url="http://www.translate.ru/Default.aspx/Text" + post="__EVENTTARGET=&__EVENTTARGUMENT=&ctl00$SiteContent$MA_trasnlform$bTranslate=Translate&ctl00$SiteContent$MA_trasnlform$DropDownList2=&ctl00$SiteContent$trasnlform$sLang=${from}&ctl00$SiteContent$MA_trasnlform$rLang=${to}&ctl00$SiteContent$MA_trasnlform$sourceText=${text:escape}&ctl00$SiteContent$MA_trasnlform$rblTemplates=General"> + <pre-marker text="ctl00$SiteContent$MA_trasnlform$tbPismo"/> + <pre-marker text=">"/> + <post-marker text="</textarea"/> + + </text-translation> + </group> + </service> + + <service nick="SYSTRAN" name="systran"> + <group> + <language to="en" tag="ar"/> + <language to="en" tag="zh"/> + <language to="en" tag="zh-TW" service-tag="zt"/> + <language to="en,fr" tag="nl"/> + <language to="*" tag="en"/> + <language to="nl,en,de,it,pt,es" tag="fr"/> + <language to="en,fr" tag="de"/> + <language to="en,fr" tag="it"/> + <language to="en" tag="ja"/> + <language to="en" tag="ko"/> + <language to="en,fr" tag="pt"/> + <language to="en" tag="ru"/> + <language to="en,fr" tag="es"/> + <language to="en" tag="sv"/> + <http-header value="http://www.systransoft.com/" name="Referer"/> + <text-translation + url="http://www.systranet.com/tt?lp=${from}_${to}&service=translate" + post=". ${text}."> + <pre-marker text=". "/> + <post-marker text="."/> + </text-translation> + </group> + </service> + + <service nick="Babel Fish" name="babelfish"> + <group> + <language to="en" tag="zh"/> + <language to="en" tag="zh-TW" service-tag="zt"/> + <language to="*" tag="en"/> + <language to="en,fr" tag="nl"/> + <language to="en,de,el,it,pt,nl,es" tag="fr"/> + <language to="en,fr" tag="de"/> + <language to="en,fr" tag="el"/> + <language to="en,fr" tag="it"/> + <language to="en" tag="ja"/> + <language to="en" tag="ko"/> + <language to="en,fr" tag="pt"/> + <language to="en" tag="ru"/> + <language to="en,fr" tag="es"/> + <text-translation + url="http://babelfish.yahoo.com/translate_txt" + post="trtext=${text:escape}&lp=${from}_${to}&ei=UTF-8"> + <pre-marker text="id="result""/> + <pre-marker text="<div"/> + <pre-marker text=">"/> + <post-marker text="</div"/> + </text-translation> +<!-- + <web-page-translation url="http://babelfish.altavista.com/babelfish/trurl_load?url=${url:escape}&lp=${from}_${to}&enc=utf8"/> +!--> + </group> + </service> + +<!-- + <service nick="Kataku" name="kataku"> + <group> + <language to="*" tag="en"/> + <language to="*" tag="id" service-tag="in"/> + <text-translation url="http://www.toggletext.com/kataku_trial.php" post="input_text=${text:charset=ISO8859-1,escape}&langset_text=${from}_${to}"> + <pre-marker text="Translation:"/> + <pre-marker text="<pre"/> + <pre-marker text=">"/> + <post-marker text=" </pre>"/> + </text-translation> + <web-page-translation url="http://www.toggletext.com/kataku_webpage_translate.php?input=${url:escape}&langset=${from}_${to}"/> + </group> + </service> +--> + +</services>
\ No newline at end of file diff --git a/patches/libtranslate/soup22/libtranslate-ds1-timed.patch b/patches/libtranslate/soup22/libtranslate-ds1-timed.patch new file mode 100644 index 0000000..c98868a --- /dev/null +++ b/patches/libtranslate/soup22/libtranslate-ds1-timed.patch @@ -0,0 +1,352 @@ +diff -dPNur libtranslate-0.99/src/modules/translate-generic-service.c libtranslate-0.99-new/src/modules/translate-generic-service.c +--- libtranslate-0.99/src/modules/translate-generic-service.c 2005-01-17 17:46:38.000000000 +0100 ++++ libtranslate-0.99-new/src/modules/translate-generic-service.c 2005-07-27 22:13:33.000000000 +0200 +@@ -131,6 +131,7 @@ + const char *post_content_type, + const GSList *headers, + TransferFlags flags, ++ GTimeVal *deadline, + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err); +@@ -181,6 +182,15 @@ + gpointer user_data, + GError **err); + ++static char *translate_generic_service_timed_translate_text (TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ GTimeVal *deadline, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err); ++ + char *translate_generic_service_expand (const char *warning_prefix, + const char *str, + ...); +@@ -248,6 +258,7 @@ + + service_class->get_pairs = translate_generic_service_get_pairs; + service_class->translate_text = translate_generic_service_translate_text; ++ service_class->timed_translate_text = translate_generic_service_timed_translate_text; + service_class->translate_web_page = translate_generic_service_translate_web_page; + + g_object_class_install_property(object_class, +@@ -387,12 +398,18 @@ + return TRUE; /* continue */ + } + ++static void send_message_cb(SoupMessage *req, gpointer user_data) { ++ g_object_ref(req); ++ *(gboolean*)user_data = TRUE; ++} ++ + static char * + translate_generic_service_get (const char *uri, + const char *post, + const char *post_content_type, + const GSList *headers, + TransferFlags flags, ++ GTimeVal *deadline, + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err) +@@ -400,6 +417,8 @@ + TransferInfo info; + SoupMessage *message; + const GSList *l; ++ GTimeVal tv; ++ gboolean completed = 0, canceled = 0; + char *response = NULL; + + g_return_val_if_fail(uri != NULL, FALSE); +@@ -479,9 +498,27 @@ + if (translate_generic_debug_flags & TRANSLATE_GENERIC_DEBUG_LOG_TRANSFERS) + translate_generic_service_log_connect(message); + ++ if (deadline) { ++ soup_session_queue_message(info.session, message, send_message_cb, &completed); ++ ++ do { ++ g_main_iteration (FALSE); ++ if (completed) break; ++ ++ g_get_current_time(&tv); ++ } while ((tv.tv_sec < deadline->tv_sec)||((tv.tv_sec == deadline->tv_sec)&&(tv.tv_usec < deadline->tv_usec))); ++ ++ if (!completed) { ++ soup_session_cancel_message(info.session, message); ++ canceled = 1; ++ } ++ } else + soup_session_send_message(info.session, message); + g_object_unref(info.session); + ++ if (canceled) ++ g_set_error(err, TRANSLATE_ERROR, TRANSLATE_ERROR_CANCELLED, _("Timeout")); ++ else + if (SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) + { + const char *charset = NULL; +@@ -833,10 +870,11 @@ + } + + static char * +-translate_generic_service_translate_text (TranslateService *service, ++translate_generic_service_timed_translate_text (TranslateService *service, + const char *text, + const char *from, + const char *to, ++ GTimeVal *deadline, + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err) +@@ -882,16 +920,16 @@ + + headers = g_slist_copy(group->http_headers); + headers = g_slist_concat(headers, g_slist_copy(group->text_location->http_headers)); +- ++ + response = translate_generic_service_get(url, + post, + group->text_location->content_type, + headers, + TRANSFER_FOLLOW_REFRESH | TRANSFER_CONVERT, ++ deadline, + progress_func, + user_data, + err); +- + g_free(url); + g_free(post); + g_slist_free(headers); +@@ -991,6 +1029,18 @@ + return answer ? g_string_free(answer, FALSE) : NULL; + } + ++static char * ++translate_generic_service_translate_text (TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err) ++{ ++ return translate_generic_service_timed_translate_text(service, text, from, to, NULL, progress_func, user_data, err); ++} ++ + char * + translate_generic_service_expand (const char *warning_prefix, + const char *str, +@@ -1252,6 +1302,7 @@ + group->web_page_location->content_type, + headers, + 0, ++ NULL, + progress_func, + user_data, + err); +@@ -1311,7 +1362,7 @@ + g_free(proxy_text_uri); + } + +- session = soup_session_sync_new_with_options(SOUP_SESSION_PROXY_URI, proxy_uri, NULL); ++ session = soup_session_async_new_with_options(SOUP_SESSION_PROXY_URI, proxy_uri, NULL); + + if (proxy_uri) + soup_uri_free(proxy_uri); +diff -dPNur libtranslate-0.99/src/translate-service.c libtranslate-0.99-new/src/translate-service.c +--- libtranslate-0.99/src/translate-service.c 2005-01-17 17:45:23.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-service.c 2005-07-27 17:18:07.000000000 +0200 +@@ -372,6 +372,28 @@ + } + + char * ++translate_service_timed_translate_text (TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ GTimeVal *deadline, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err) ++{ ++ g_return_val_if_fail(TRANSLATE_IS_SERVICE(service), NULL); ++ g_return_val_if_fail(TRANSLATE_SERVICE_GET_CLASS(service)->translate_text != NULL, NULL); ++ g_return_val_if_fail(text != NULL, NULL); ++ g_return_val_if_fail(from != NULL, NULL); ++ g_return_val_if_fail(to != NULL, NULL); ++ ++ if (TRANSLATE_SERVICE_GET_CLASS(service)->timed_translate_text) ++ return TRANSLATE_SERVICE_GET_CLASS(service)->timed_translate_text(service, text, from, to, deadline, progress_func, user_data, err); ++ ++ return TRANSLATE_SERVICE_GET_CLASS(service)->translate_text(service, text, from, to, progress_func, user_data, err); ++} ++ ++char * + translate_service_translate_web_page (TranslateService *service, + const char *url, + const char *from, +diff -dPNur libtranslate-0.99/src/translate-service.h libtranslate-0.99-new/src/translate-service.h +--- libtranslate-0.99/src/translate-service.h 2005-01-17 17:45:29.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-service.h 2005-07-27 16:54:46.000000000 +0200 +@@ -73,6 +73,14 @@ + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err); ++ char *(*timed_translate_text)(TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ GTimeVal *deadline, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err); + char *(*translate_web_page) (TranslateService *service, + const char *url, + const char *from, +diff -dPNur libtranslate-0.99/src/translate-service-private.h libtranslate-0.99-new/src/translate-service-private.h +--- libtranslate-0.99/src/translate-service-private.h 2005-01-17 17:45:17.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-service-private.h 2005-07-27 17:30:00.000000000 +0200 +@@ -41,6 +41,14 @@ + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err); ++char *translate_service_timed_translate_text (TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ GTimeVal *deadline, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err); + char *translate_service_translate_web_page (TranslateService *service, + const char *url, + const char *from, +diff -dPNur libtranslate-0.99/src/translate-session.c libtranslate-0.99-new/src/translate-session.c +--- libtranslate-0.99/src/translate-session.c 2005-01-17 17:45:35.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-session.c 2005-07-27 16:52:46.000000000 +0200 +@@ -62,6 +62,8 @@ + { + GMutex *mutex; + GCond *progress_cond; ++ ++ GTimeVal *deadline; + + TranslateSession *session; + GSList *services; +@@ -487,6 +489,7 @@ + * @text: a nul-terminated string. + * @from: a RFC 3066 language tag. + * @to: a RFC 3066 language tag. ++ * @timeout: timeout in microseconds. + * @progress_func: a function to call when progressing, or %NULL. + * @user_data: data to pass to @progress_func, or %NULL. + * @err: a location to report errors, or %NULL. Any of the errors in +@@ -505,10 +508,11 @@ + * when no longer needed. + **/ + char * +-translate_session_translate_text (TranslateSession *session, ++translate_session_timed_translate_text (TranslateSession *session, + const char *text, + const char *from, + const char *to, ++ gulong timeout, + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err) +@@ -519,6 +523,7 @@ + unsigned int max_threads; + GThreadPool *pool; + GSList *l; ++ GTimeVal deadline; + unsigned int max_chunk_len = 0; + char *translated = NULL; + +@@ -527,6 +532,11 @@ + g_return_val_if_fail(from != NULL, NULL); + g_return_val_if_fail(to != NULL, NULL); + ++ if (timeout) { ++ g_get_current_time(&deadline); ++ g_time_val_add(&deadline, timeout); ++ } ++ + LOCK(session); + info.services = translate_session_get_services_for_translation(session, + TRANSLATE_PAIR_TEXT, +@@ -560,7 +570,8 @@ + chunks = translate_session_split(text, max_chunk_len); + + info.mutex = g_mutex_new(); +- info.progress_cond = progress_func ? g_cond_new() : NULL; ++ info.progress_cond = (progress_func||timeout) ? g_cond_new() : NULL; ++ info.deadline = timeout ? &deadline : NULL; + info.session = session; + info.chunks = NULL; + info.from = from; +@@ -614,6 +625,11 @@ + GSList *l; + int n_chunks; + ++ if (timeout) { ++ if (!g_cond_timed_wait(info.progress_cond, info.mutex, info.deadline)) ++ info.err = g_error_new(TRANSLATE_ERROR,TRANSLATE_ERROR_CANCELLED,_("timeout")); ++ break; ++ } else + g_cond_wait(info.progress_cond, info.mutex); + + if (info.err) +@@ -680,6 +696,18 @@ + return translated; + } + ++char * ++translate_session_translate_text (TranslateSession *session, ++ const char *text, ++ const char *from, ++ const char *to, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err) ++{ ++ return translate_session_timed_translate_text(session, text, from, to, 0, progress_func, user_data, err); ++} ++ + static void + translate_session_translate_thread (gpointer data, gpointer user_data) + { +@@ -709,10 +737,11 @@ + if (ret) + return; + +- chunk_info->translated = translate_service_translate_text(service, ++ chunk_info->translated = translate_service_timed_translate_text(service, + chunk_info->chunk, + info->from, + info->to, ++ info->deadline, + info->progress_cond ? translate_session_translate_progress_cb : NULL, + info->progress_cond ? chunk_info : NULL, + &tmp_err); +diff -dPNur libtranslate-0.99/src/translate-session.h libtranslate-0.99-new/src/translate-session.h +--- libtranslate-0.99/src/translate-session.h 2005-01-17 17:45:40.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-session.h 2005-07-27 14:41:05.000000000 +0200 +@@ -93,6 +93,14 @@ + unsigned int translate_session_get_max_threads (TranslateSession *session); + int translate_session_get_max_retries (TranslateSession *session); + ++char *translate_session_timed_translate_text (TranslateSession *session, ++ const char *text, ++ const char *from, ++ const char *to, ++ gulong timeout, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err); + char *translate_session_translate_text (TranslateSession *session, + const char *text, + const char *from, diff --git a/patches/libtranslate/soup24/libtranslate-ds1-timed24.patch b/patches/libtranslate/soup24/libtranslate-ds1-timed24.patch new file mode 100644 index 0000000..daf3811 --- /dev/null +++ b/patches/libtranslate/soup24/libtranslate-ds1-timed24.patch @@ -0,0 +1,360 @@ +diff -dPNur libtranslate-0.99/src/modules/translate-generic-service.c libtranslate-0.99-new/src/modules/translate-generic-service.c +--- libtranslate-0.99/src/modules/translate-generic-service.c 2005-01-17 17:46:38.000000000 +0100 ++++ libtranslate-0.99-new/src/modules/translate-generic-service.c 2005-07-27 22:13:33.000000000 +0200 +@@ -131,6 +131,7 @@ + const char *post_content_type, + const GSList *headers, + TransferFlags flags, ++ GTimeVal *deadline, + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err); +@@ -181,6 +182,15 @@ + gpointer user_data, + GError **err); + ++static char *translate_generic_service_timed_translate_text (TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ GTimeVal *deadline, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err); ++ + char *translate_generic_service_expand (const char *warning_prefix, + const char *str, + ...); +@@ -248,6 +258,7 @@ + + service_class->get_pairs = translate_generic_service_get_pairs; + service_class->translate_text = translate_generic_service_translate_text; ++ service_class->timed_translate_text = translate_generic_service_timed_translate_text; + service_class->translate_web_page = translate_generic_service_translate_web_page; + + g_object_class_install_property(object_class, +@@ -387,12 +398,22 @@ + return TRUE; /* continue */ + } + ++#ifdef HAVE_LIBSOUP22 ++static void send_message_cb(SoupMessage *req, gpointer user_data) { ++#else ++static void send_message_cb(SoupSession *session, SoupMessage *req, gpointer user_data) { ++#endif ++ g_object_ref(req); ++ *(gboolean*)user_data = TRUE; ++} ++ + static char * + translate_generic_service_get (const char *uri, + const char *post, + const char *post_content_type, + const GSList *headers, + TransferFlags flags, ++ GTimeVal *deadline, + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err) +@@ -400,6 +417,8 @@ + TransferInfo info; + SoupMessage *message; + const GSList *l; ++ GTimeVal tv; ++ gboolean completed = 0, canceled = 0; + char *response = NULL; + + g_return_val_if_fail(uri != NULL, FALSE); +@@ -479,9 +498,31 @@ + if (translate_generic_debug_flags & TRANSLATE_GENERIC_DEBUG_LOG_TRANSFERS) + translate_generic_service_log_connect(message); + ++ if (deadline) { ++ soup_session_queue_message(info.session, message, send_message_cb, &completed); ++ ++ do { ++ g_main_iteration (FALSE); ++ if (completed) break; ++ ++ g_get_current_time(&tv); ++ } while ((tv.tv_sec < deadline->tv_sec)||((tv.tv_sec == deadline->tv_sec)&&(tv.tv_usec < deadline->tv_usec))); ++ ++ if (!completed) { ++#ifdef HAVE_LIBSOUP22 ++ soup_session_cancel_message(info.session, message); ++#else ++ soup_session_cancel_message(info.session, message, SOUP_STATUS_CANCELLED); ++#endif ++ canceled = 1; ++ } ++ } else + soup_session_send_message(info.session, message); + g_object_unref(info.session); + ++ if (canceled) ++ g_set_error(err, TRANSLATE_ERROR, TRANSLATE_ERROR_CANCELLED, _("Timeout")); ++ else + if (SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) + { + const char *charset = NULL; +@@ -833,10 +870,11 @@ + } + + static char * +-translate_generic_service_translate_text (TranslateService *service, ++translate_generic_service_timed_translate_text (TranslateService *service, + const char *text, + const char *from, + const char *to, ++ GTimeVal *deadline, + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err) +@@ -882,16 +920,16 @@ + + headers = g_slist_copy(group->http_headers); + headers = g_slist_concat(headers, g_slist_copy(group->text_location->http_headers)); +- ++ + response = translate_generic_service_get(url, + post, + group->text_location->content_type, + headers, + TRANSFER_FOLLOW_REFRESH | TRANSFER_CONVERT, ++ deadline, + progress_func, + user_data, + err); +- + g_free(url); + g_free(post); + g_slist_free(headers); +@@ -991,6 +1029,18 @@ + return answer ? g_string_free(answer, FALSE) : NULL; + } + ++static char * ++translate_generic_service_translate_text (TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err) ++{ ++ return translate_generic_service_timed_translate_text(service, text, from, to, NULL, progress_func, user_data, err); ++} ++ + char * + translate_generic_service_expand (const char *warning_prefix, + const char *str, +@@ -1252,6 +1302,7 @@ + group->web_page_location->content_type, + headers, + 0, ++ NULL, + progress_func, + user_data, + err); +@@ -1311,7 +1362,7 @@ + g_free(proxy_text_uri); + } + +- session = soup_session_sync_new_with_options(SOUP_SESSION_PROXY_URI, proxy_uri, NULL); ++ session = soup_session_async_new_with_options(SOUP_SESSION_PROXY_URI, proxy_uri, NULL); + + if (proxy_uri) + soup_uri_free(proxy_uri); +diff -dPNur libtranslate-0.99/src/translate-service.c libtranslate-0.99-new/src/translate-service.c +--- libtranslate-0.99/src/translate-service.c 2005-01-17 17:45:23.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-service.c 2005-07-27 17:18:07.000000000 +0200 +@@ -372,6 +372,28 @@ + } + + char * ++translate_service_timed_translate_text (TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ GTimeVal *deadline, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err) ++{ ++ g_return_val_if_fail(TRANSLATE_IS_SERVICE(service), NULL); ++ g_return_val_if_fail(TRANSLATE_SERVICE_GET_CLASS(service)->translate_text != NULL, NULL); ++ g_return_val_if_fail(text != NULL, NULL); ++ g_return_val_if_fail(from != NULL, NULL); ++ g_return_val_if_fail(to != NULL, NULL); ++ ++ if (TRANSLATE_SERVICE_GET_CLASS(service)->timed_translate_text) ++ return TRANSLATE_SERVICE_GET_CLASS(service)->timed_translate_text(service, text, from, to, deadline, progress_func, user_data, err); ++ ++ return TRANSLATE_SERVICE_GET_CLASS(service)->translate_text(service, text, from, to, progress_func, user_data, err); ++} ++ ++char * + translate_service_translate_web_page (TranslateService *service, + const char *url, + const char *from, +diff -dPNur libtranslate-0.99/src/translate-service.h libtranslate-0.99-new/src/translate-service.h +--- libtranslate-0.99/src/translate-service.h 2005-01-17 17:45:29.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-service.h 2005-07-27 16:54:46.000000000 +0200 +@@ -73,6 +73,14 @@ + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err); ++ char *(*timed_translate_text)(TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ GTimeVal *deadline, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err); + char *(*translate_web_page) (TranslateService *service, + const char *url, + const char *from, +diff -dPNur libtranslate-0.99/src/translate-service-private.h libtranslate-0.99-new/src/translate-service-private.h +--- libtranslate-0.99/src/translate-service-private.h 2005-01-17 17:45:17.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-service-private.h 2005-07-27 17:30:00.000000000 +0200 +@@ -41,6 +41,14 @@ + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err); ++char *translate_service_timed_translate_text (TranslateService *service, ++ const char *text, ++ const char *from, ++ const char *to, ++ GTimeVal *deadline, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err); + char *translate_service_translate_web_page (TranslateService *service, + const char *url, + const char *from, +diff -dPNur libtranslate-0.99/src/translate-session.c libtranslate-0.99-new/src/translate-session.c +--- libtranslate-0.99/src/translate-session.c 2005-01-17 17:45:35.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-session.c 2005-07-27 16:52:46.000000000 +0200 +@@ -62,6 +62,8 @@ + { + GMutex *mutex; + GCond *progress_cond; ++ ++ GTimeVal *deadline; + + TranslateSession *session; + GSList *services; +@@ -487,6 +489,7 @@ + * @text: a nul-terminated string. + * @from: a RFC 3066 language tag. + * @to: a RFC 3066 language tag. ++ * @timeout: timeout in microseconds. + * @progress_func: a function to call when progressing, or %NULL. + * @user_data: data to pass to @progress_func, or %NULL. + * @err: a location to report errors, or %NULL. Any of the errors in +@@ -505,10 +508,11 @@ + * when no longer needed. + **/ + char * +-translate_session_translate_text (TranslateSession *session, ++translate_session_timed_translate_text (TranslateSession *session, + const char *text, + const char *from, + const char *to, ++ gulong timeout, + TranslateProgressFunc progress_func, + gpointer user_data, + GError **err) +@@ -519,6 +523,7 @@ + unsigned int max_threads; + GThreadPool *pool; + GSList *l; ++ GTimeVal deadline; + unsigned int max_chunk_len = 0; + char *translated = NULL; + +@@ -527,6 +532,11 @@ + g_return_val_if_fail(from != NULL, NULL); + g_return_val_if_fail(to != NULL, NULL); + ++ if (timeout) { ++ g_get_current_time(&deadline); ++ g_time_val_add(&deadline, timeout); ++ } ++ + LOCK(session); + info.services = translate_session_get_services_for_translation(session, + TRANSLATE_PAIR_TEXT, +@@ -560,7 +570,8 @@ + chunks = translate_session_split(text, max_chunk_len); + + info.mutex = g_mutex_new(); +- info.progress_cond = progress_func ? g_cond_new() : NULL; ++ info.progress_cond = (progress_func||timeout) ? g_cond_new() : NULL; ++ info.deadline = timeout ? &deadline : NULL; + info.session = session; + info.chunks = NULL; + info.from = from; +@@ -614,6 +625,11 @@ + GSList *l; + int n_chunks; + ++ if (timeout) { ++ if (!g_cond_timed_wait(info.progress_cond, info.mutex, info.deadline)) ++ info.err = g_error_new(TRANSLATE_ERROR,TRANSLATE_ERROR_CANCELLED,_("timeout")); ++ break; ++ } else + g_cond_wait(info.progress_cond, info.mutex); + + if (info.err) +@@ -680,6 +696,18 @@ + return translated; + } + ++char * ++translate_session_translate_text (TranslateSession *session, ++ const char *text, ++ const char *from, ++ const char *to, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err) ++{ ++ return translate_session_timed_translate_text(session, text, from, to, 0, progress_func, user_data, err); ++} ++ + static void + translate_session_translate_thread (gpointer data, gpointer user_data) + { +@@ -709,10 +737,11 @@ + if (ret) + return; + +- chunk_info->translated = translate_service_translate_text(service, ++ chunk_info->translated = translate_service_timed_translate_text(service, + chunk_info->chunk, + info->from, + info->to, ++ info->deadline, + info->progress_cond ? translate_session_translate_progress_cb : NULL, + info->progress_cond ? chunk_info : NULL, + &tmp_err); +diff -dPNur libtranslate-0.99/src/translate-session.h libtranslate-0.99-new/src/translate-session.h +--- libtranslate-0.99/src/translate-session.h 2005-01-17 17:45:40.000000000 +0100 ++++ libtranslate-0.99-new/src/translate-session.h 2005-07-27 14:41:05.000000000 +0200 +@@ -93,6 +93,14 @@ + unsigned int translate_session_get_max_threads (TranslateSession *session); + int translate_session_get_max_retries (TranslateSession *session); + ++char *translate_session_timed_translate_text (TranslateSession *session, ++ const char *text, ++ const char *from, ++ const char *to, ++ gulong timeout, ++ TranslateProgressFunc progress_func, ++ gpointer user_data, ++ GError **err); + char *translate_session_translate_text (TranslateSession *session, + const char *text, + const char *from, diff --git a/patches/libtranslate/soup24/libtranslate-ds8-soup24inc.patch b/patches/libtranslate/soup24/libtranslate-ds8-soup24inc.patch new file mode 100644 index 0000000..8de7c07 --- /dev/null +++ b/patches/libtranslate/soup24/libtranslate-ds8-soup24inc.patch @@ -0,0 +1,533 @@ +diff -dPNur libtranslate-0.99/config.h.in libtranslate-0.99-1/config.h.in +--- libtranslate-0.99/config.h.in 2005-01-17 18:06:58.000000000 +0100 ++++ libtranslate-0.99-1/config.h.in 2010-02-14 03:55:56.000000000 +0100 +@@ -24,6 +24,12 @@ + /* Define if your <locale.h> file defines LC_MESSAGES. */ + #undef HAVE_LC_MESSAGES + ++/* Building with libsoup 2.2 */ ++#undef HAVE_LIBSOUP22 ++ ++/* Building with libsoup 2.4 */ ++#undef HAVE_LIBSOUP24 ++ + /* Define to 1 if you have the <locale.h> header file. */ + #undef HAVE_LOCALE_H + +diff -dPNur libtranslate-0.99/configure.ac libtranslate-0.99-1/configure.ac +--- libtranslate-0.99/configure.ac 2005-01-15 17:24:12.000000000 +0100 ++++ libtranslate-0.99-1/configure.ac 2010-02-14 03:55:56.000000000 +0100 +@@ -50,7 +50,11 @@ + ### optional libraries + + if TRANSLATE_FEATURE_ENABLED(generic); then +- PKG_CHECK_MODULES(SOUP, [libsoup-2.2],, [TRANSLATE_FEATURE_DISABLE(generic, [libsoup not found])]) ++ PKG_CHECK_MODULES(SOUP, [libsoup-2.4], ++ [AC_DEFINE(HAVE_LIBSOUP24, 1, [Building with libsoup 2.4])], ++ [PKG_CHECK_MODULES(SOUP, [libsoup-2.2], ++ [AC_DEFINE(HAVE_LIBSOUP22, 1, [Building with libsoup 2.2])], ++ [TRANSLATE_FEATURE_DISABLE(generic, [libsoup not found])])]) + fi + if TRANSLATE_FEATURE_ENABLED(generic); then + PKG_CHECK_MODULES(LIBXML, [libxml-2.0],, [TRANSLATE_FEATURE_DISABLE(generic, [libxml not found])]) +diff -dPNur libtranslate-0.99/src/modules/translate-generic-service.c libtranslate-0.99-1/src/modules/translate-generic-service.c +--- libtranslate-0.99/src/modules/translate-generic-service.c 2010-02-14 03:55:34.000000000 +0100 ++++ libtranslate-0.99-1/src/modules/translate-generic-service.c 2010-02-14 04:04:56.000000000 +0100 +@@ -35,7 +35,9 @@ + #include <stdlib.h> + #include <glib/gi18n-lib.h> + #include <libsoup/soup.h> ++#ifdef HAVE_LIBSOUP22 + #include <libsoup/soup-message-filter.h> ++#endif + #include <libxml/HTMLparser.h> + #include "translate.h" + #include "translate-generic-service.h" +@@ -43,6 +45,17 @@ + #include "translate-generic-parser.h" + #include "translate-generic-soup-cookie-jar.h" + ++#ifdef HAVE_LIBSOUP22 ++#define soup_message_headers_get soup_message_get_header ++#define soup_message_headers_append soup_message_add_header ++#define SoupURI SoupUri ++#define SOUP_MESSAGE_RESPONSE_BODY(msg) ((msg)->response.body) ++#define SOUP_MESSAGE_RESPONSE_LENGTH(msg) ((msg)->response.length) ++#else ++#define SOUP_MESSAGE_RESPONSE_BODY(msg) ((msg)->response_body->data) ++#define SOUP_MESSAGE_RESPONSE_LENGTH(msg) ((msg)->response_body->length) ++#endif ++ + #define MAKE_WARNING_PREFIX(service, group_pos, attribute, element) \ + g_strdup_printf(_("in %s, group %i, \"%s\" attribute of \"%s\" element"), \ + translate_service_get_name((service)), \ +@@ -142,6 +155,7 @@ + const char *name); + + static void translate_generic_service_log_connect (SoupMessage *message); ++#ifdef HAVE_LIBSOUP22 + static void translate_generic_service_log_wrote_headers_h (SoupMessage *message, + gpointer user_data); + static void translate_generic_service_log_wrote_body_h (SoupMessage *message, +@@ -153,10 +167,20 @@ + static void translate_generic_service_log_headers_cb (const char *key, + const char *value, + gpointer user_data); ++#else ++static void translate_generic_service_log_printer (SoupLogger *logger, ++ SoupLoggerLogLevel level, ++ char direction, ++ const char *data, ++ gpointer user_data); ++#endif + + static void translate_generic_service_progress_got_headers_h (SoupMessage *message, + gpointer user_data); + static void translate_generic_service_progress_got_chunk_h (SoupMessage *message, ++#ifdef HAVE_LIBSOUP24 ++ SoupBuffer *chunk, ++#endif + gpointer user_data); + + static void translate_generic_service_html_got_headers_h (SoupMessage *message, +@@ -172,8 +196,10 @@ + static void translate_generic_service_refresh_got_body_h (SoupMessage *message, + gpointer user_data); + ++#ifdef HAVE_LIBSOUP22 + static void translate_generic_service_redirect_handler (SoupMessage *message, + gpointer user_data); ++#endif + + static char *translate_generic_service_translate_text (TranslateService *service, + const char *text, +@@ -440,7 +466,11 @@ + g_return_val_if_fail(post_content_type != NULL, NULL); + soup_message_set_request(message, + post_content_type, ++#ifdef HAVE_LIBSOUP22 + SOUP_BUFFER_USER_OWNED, ++#else ++ SOUP_MEMORY_TEMPORARY, ++#endif + (char *) post, + strlen(post)); + } +@@ -448,7 +478,7 @@ + for (l = headers; l != NULL; l = l->next) + { + TranslateGenericHttpHeader *header = l->data; +- soup_message_add_header(message->request_headers, header->name, header->value); ++ soup_message_headers_append(message->request_headers, header->name, header->value); + } + + info.session = translate_generic_service_soup_session_sync_new(); +@@ -456,12 +486,21 @@ + info.html_http_equiv = NULL; + + if (translate_generic_debug_flags & TRANSLATE_GENERIC_DEBUG_LOG_TRANSFERS) +- g_object_connect(message, +- "signal::wrote-headers", translate_generic_service_log_wrote_headers_h, &info, +- "signal::wrote-body", translate_generic_service_log_wrote_body_h, &info, +- "signal::got-headers", translate_generic_service_log_got_headers_h, &info, +- "signal::got-body", translate_generic_service_log_got_body_h, &info, +- NULL); ++ { ++#ifdef HAVE_LIBSOUP22 ++ g_object_connect(message, ++ "signal::wrote-headers", translate_generic_service_log_wrote_headers_h, &info, ++ "signal::wrote-body", translate_generic_service_log_wrote_body_h, &info, ++ "signal::got-headers", translate_generic_service_log_got_headers_h, &info, ++ "signal::got-body", translate_generic_service_log_got_body_h, &info, ++ NULL); ++#else ++ SoupLogger *logger = soup_logger_new (SOUP_LOGGER_LOG_BODY, -1); ++ soup_logger_set_printer (logger, translate_generic_service_log_printer, NULL, NULL); ++ soup_logger_attach (logger, info.session); ++ g_object_unref (logger); ++#endif ++ } + + if (progress_func) + { +@@ -489,6 +528,7 @@ + if (flags & TRANSFER_FOLLOW_REFRESH) + g_signal_connect(message, "got-body", G_CALLBACK(translate_generic_service_refresh_got_body_h), &info); + ++#ifdef HAVE_LIBSOUP22 + /* http://bugzilla.ximian.com/show_bug.cgi?id=70688 */ + soup_message_set_flags(message, SOUP_MESSAGE_NO_REDIRECT); + soup_message_add_status_class_handler(message, +@@ -496,6 +536,7 @@ + SOUP_HANDLER_POST_BODY, + translate_generic_service_redirect_handler, + info.session); ++#endif + + if (translate_generic_debug_flags & TRANSLATE_GENERIC_DEBUG_LOG_TRANSFERS) + translate_generic_service_log_connect(message); +@@ -554,18 +595,18 @@ + + if ((charset)||(response_charset)) + { +- response = g_convert(message->response.body, message->response.length, "UTF-8", response_charset?response_charset:charset, NULL, NULL, err); ++ response = g_convert(SOUP_MESSAGE_RESPONSE_BODY (message), SOUP_MESSAGE_RESPONSE_LENGTH (message), "UTF-8", charset, NULL, NULL, err); + g_free(charset); + } + else + { +- if ((flags & TRANSFER_CONVERT) && ! g_utf8_validate(message->response.body, message->response.length, NULL)) ++ if ((flags & TRANSFER_CONVERT) && ! g_utf8_validate(SOUP_MESSAGE_RESPONSE_BODY (message), SOUP_MESSAGE_RESPONSE_LENGTH (message), NULL)) + g_set_error(err, + TRANSLATE_GENERIC_SERVICE_ERROR, + TRANSLATE_GENERIC_SERVICE_ERROR_TRANSFER, + _("invalid UTF-8")); + else +- response = g_strndup(message->response.body, message->response.length); ++ response = g_strndup(SOUP_MESSAGE_RESPONSE_BODY (message), SOUP_MESSAGE_RESPONSE_LENGTH (message)); + } + } + else +@@ -606,7 +647,7 @@ + : NULL; + + if (! value) +- value = soup_message_get_header(message->response_headers, name); ++ value = soup_message_headers_get(message->response_headers, name); + + return value; + } +@@ -614,12 +655,14 @@ + static void + translate_generic_service_log_connect (SoupMessage *message) + { +- const SoupUri *uri; ++ const SoupURI *uri; + + uri = soup_message_get_uri(message); + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, _("connecting to %s:%i"), uri->host, uri->port); + } + ++#ifdef HAVE_LIBSOUP22 ++ + static void + translate_generic_service_log_wrote_headers_h (SoupMessage *message, + gpointer user_data) +@@ -674,6 +717,20 @@ + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%s %s: %s", prefix, key, value); + } + ++#else /* !HAVE_LIBSOUP22 */ ++ ++static void ++translate_generic_service_log_printer (SoupLogger *logger, ++ SoupLoggerLogLevel level, ++ char direction, ++ const char *data, ++ gpointer user_data) ++{ ++ g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "%c %s", direction, data); ++} ++ ++#endif /* HAVE_LIBSOUP22 */ ++ + static void + translate_generic_service_progress_got_headers_h (SoupMessage *message, + gpointer user_data) +@@ -681,7 +738,7 @@ + TransferInfo *info = user_data; + const char *content_length; + +- content_length = soup_message_get_header(message->response_headers, "Content-Length"); ++ content_length = soup_message_headers_get(message->response_headers, "Content-Length"); + info->length = (content_length + && *content_length + && strspn(content_length, "0123456789") == strlen(content_length)) +@@ -691,6 +748,9 @@ + + static void + translate_generic_service_progress_got_chunk_h (SoupMessage *message, ++#ifdef HAVE_LIBSOUP24 ++ SoupBuffer *chunk, ++#endif + gpointer user_data) + { + TransferInfo *info = user_data; +@@ -700,7 +760,11 @@ + progress = -1; + else + { ++#ifdef HAVE_LIBSOUP22 + info->received += message->response.length; ++#else ++ info->received += chunk->length; ++#endif + progress = (double) info->received / info->length; + progress = CLAMP(progress, 0.0, 1.0); + } +@@ -716,7 +780,7 @@ + TransferInfo *info = user_data; + const char *content_type; + +- content_type = soup_message_get_header(message->response_headers, "Content-Type"); ++ content_type = soup_message_headers_get(message->response_headers, "Content-Type"); + info->parse_html = content_type + && (g_str_has_prefix(content_type, "text/html") + || g_str_has_prefix(content_type, "application/xhtml+xml") +@@ -736,7 +800,7 @@ + info->html_http_equiv = NULL; + } + +- if (info->parse_html && message->response.length > 0) ++ if (info->parse_html && SOUP_MESSAGE_RESPONSE_LENGTH (message) > 0) + { + char *body; + xmlSAXHandler sax_handler = { NULL }; +@@ -750,7 +814,7 @@ + sax_handler.startElement = translate_generic_service_html_start_element_cb; + sax_handler.endElement = translate_generic_service_html_end_element_cb; + +- body = g_strndup(message->response.body, message->response.length); ++ body = g_strndup(SOUP_MESSAGE_RESPONSE_BODY (message), SOUP_MESSAGE_RESPONSE_LENGTH (message)); + htmlSAXParseDoc(body, NULL, &sax_handler, user_data); + g_free(body); + } +@@ -817,7 +881,7 @@ + { + TransferInfo *info = user_data; + const char *refresh_uri; +- SoupUri *new_uri = NULL; ++ SoupURI *new_uri = NULL; + + refresh_uri = translate_generic_service_get_header(message, info, "Refresh"); + if (refresh_uri) +@@ -832,9 +896,9 @@ + new_uri = soup_uri_new(refresh_uri); + if (! new_uri) + { +- const SoupUri *base_uri; ++ SoupURI *base_uri; + +- base_uri = soup_message_get_uri(message); ++ base_uri = (SoupURI *)soup_message_get_uri(message); + new_uri = soup_uri_new_with_base(base_uri, refresh_uri); + } + } +@@ -851,6 +915,7 @@ + } + } + ++#ifdef HAVE_LIBSOUP22 + static void + translate_generic_service_redirect_handler (SoupMessage *message, + gpointer user_data) +@@ -887,6 +952,7 @@ + soup_session_requeue_message(session, message); + } + } ++#endif + + static char * + translate_generic_service_timed_translate_text (TranslateService *service, +@@ -1391,7 +1457,7 @@ + translate_generic_service_soup_session_sync_new (void) + { + char *proxy_text_uri; +- SoupUri *proxy_uri = NULL; ++ SoupURI *proxy_uri = NULL; + SoupSession *session; + TranslateGenericSoupCookieJar *cookie_jar; + +@@ -1411,7 +1477,7 @@ + soup_uri_free(proxy_uri); + + cookie_jar = translate_generic_soup_cookie_jar_new(); +- soup_session_add_filter(session, SOUP_MESSAGE_FILTER(cookie_jar)); ++ translate_generic_soup_cookie_jar_attach(cookie_jar, session); + g_object_unref(cookie_jar); + + return session; +diff -dPNur libtranslate-0.99/src/modules/translate-generic-soup-cookie-jar.c libtranslate-0.99-1/src/modules/translate-generic-soup-cookie-jar.c +--- libtranslate-0.99/src/modules/translate-generic-soup-cookie-jar.c 2005-01-17 17:46:53.000000000 +0100 ++++ libtranslate-0.99-1/src/modules/translate-generic-soup-cookie-jar.c 2010-02-14 03:55:56.000000000 +0100 +@@ -29,9 +29,12 @@ + * POSSIBILITY OF SUCH DAMAGE. + */ + ++#include "config.h" + #include <string.h> + #include <libsoup/soup.h> ++#ifdef HAVE_LIBSOUP22 + #include <libsoup/soup-message-filter.h> ++#endif + #include "translate-generic-soup-cookie-jar.h" + + struct _TranslateGenericSoupCookieJarPrivate +@@ -44,9 +47,12 @@ + static void translate_generic_soup_cookie_jar_register_type (GType *type); + static void translate_generic_soup_cookie_jar_class_init (TranslateGenericSoupCookieJarClass *class); + static void translate_generic_soup_cookie_jar_init (TranslateGenericSoupCookieJar *jar); ++#ifdef HAVE_LIBSOUP22 + static void translate_generic_soup_cookie_jar_filter_init (SoupMessageFilterClass *iface); ++#else ++#define SoupMessageFilter TranslateGenericSoupCookieJar ++#endif + static void translate_generic_soup_cookie_jar_finalize (GObject *object); +- + static void translate_generic_soup_cookie_jar_setup_message (SoupMessageFilter *filter, + SoupMessage *message); + +@@ -75,17 +81,21 @@ + 0, + (GInstanceInitFunc) translate_generic_soup_cookie_jar_init + }; ++#ifdef HAVE_LIBSOUP22 + static const GInterfaceInfo filter_info = { + (GInterfaceInitFunc) translate_generic_soup_cookie_jar_filter_init, + NULL, + NULL + }; ++#endif + + *type = g_type_register_static(G_TYPE_OBJECT, + "TranslateGenericSoupCookieJar", + &info, + 0); ++#ifdef HAVE_LIBSOUP22 + g_type_add_interface_static(*type, SOUP_TYPE_MESSAGE_FILTER, &filter_info); ++#endif + } + + static void +@@ -107,11 +117,13 @@ + TranslateGenericSoupCookieJarPrivate); + } + ++#ifdef HAVE_LIBSOUP22 + static void + translate_generic_soup_cookie_jar_filter_init (SoupMessageFilterClass *iface) + { + iface->setup_message = translate_generic_soup_cookie_jar_setup_message; + } ++#endif + + static void + translate_generic_soup_cookie_jar_finalize (GObject *object) +@@ -125,26 +137,46 @@ + } + + static void ++add_cookie_to_jar (TranslateGenericSoupCookieJar *jar, const char *cookie) ++{ ++ char *s; ++ ++ s = strchr(cookie, ';'); ++ if (s) ++ jar->priv->cookies = g_slist_append(jar->priv->cookies, g_strndup(cookie, s - cookie)); ++} ++ ++#ifdef HAVE_LIBSOUP24 ++static void ++maybe_add_cookie_to_jar (const char *header, const char *value, gpointer jar) ++{ ++ if (!g_ascii_strcasecmp (header, "Set-Cookie")) ++ add_cookie_to_jar (jar, value); ++} ++#endif ++ ++static void + translate_generic_soup_cookie_jar_setup_message (SoupMessageFilter *filter, +- SoupMessage *message) ++ SoupMessage *message) + { + TranslateGenericSoupCookieJar *jar = TRANSLATE_GENERIC_SOUP_COOKIE_JAR(filter); +- const GSList *cookies; + const GSList *l; + + /* FIXME: add full RFC 2965 support */ + ++#ifdef HAVE_LIBSOUP22 ++ const GSList *cookies; ++ + cookies = soup_message_get_header_list(message->response_headers, "Set-Cookie"); + for (l = cookies; l != NULL; l = l->next) + { + const char *cookie = l->data; +- char *s; +- +- s = strchr(cookie, ';'); +- if (s) +- jar->priv->cookies = g_slist_append(jar->priv->cookies, g_strndup(cookie, s - cookie)); ++ add_cookie_to_jar(jar, cookie); + } +- ++#else ++ soup_message_headers_foreach(message->response_headers, maybe_add_cookie_to_jar, jar); ++#endif ++ + if (jar->priv->cookies) + { + GString *string; +@@ -159,13 +191,44 @@ + g_string_append(string, "; "); + } + ++#ifdef HAVE_LIBSOUP22 + soup_message_add_header(message->request_headers, "Cookie", string->str); ++#else ++ soup_message_headers_append(message->request_headers, "Cookie", string->str); ++#endif + g_string_free(string, TRUE); + } + } + ++#ifdef HAVE_LIBSOUP24 ++static void ++translate_generic_soup_cookie_jar_request_started (SoupSession *session, ++ SoupMessage *message, ++ SoupSocket *socket, ++ gpointer cookie_jar) ++{ ++ translate_generic_soup_cookie_jar_setup_message (cookie_jar, message); ++} ++#endif ++ + TranslateGenericSoupCookieJar * + translate_generic_soup_cookie_jar_new (void) + { + return g_object_new(TRANSLATE_GENERIC_TYPE_SOUP_COOKIE_JAR, NULL); + } ++ ++void ++translate_generic_soup_cookie_jar_attach (TranslateGenericSoupCookieJar *cookie_jar, ++ SoupSession *session) ++{ ++#ifdef HAVE_LIBSOUP22 ++ soup_session_add_filter (session, SOUP_MESSAGE_FILTER(cookie_jar)); ++#else ++ g_signal_connect (session, "request_started", ++ G_CALLBACK (translate_generic_soup_cookie_jar_request_started), ++ cookie_jar); ++ g_object_set_data_full (G_OBJECT (session), "TranslateGenericSoupCookieJar", ++ g_object_ref (cookie_jar), g_object_unref); ++#endif ++} ++ +diff -dPNur libtranslate-0.99/src/modules/translate-generic-soup-cookie-jar.h libtranslate-0.99-1/src/modules/translate-generic-soup-cookie-jar.h +--- libtranslate-0.99/src/modules/translate-generic-soup-cookie-jar.h 2005-01-17 17:47:00.000000000 +0100 ++++ libtranslate-0.99-1/src/modules/translate-generic-soup-cookie-jar.h 2010-02-14 03:55:56.000000000 +0100 +@@ -33,6 +33,7 @@ + #define _TRANSLATE_GENERIC_SOUP_COOKIE_JAR_H + + #include <glib-object.h> ++#include <libsoup/soup-session.h> + + #define TRANSLATE_GENERIC_TYPE_SOUP_COOKIE_JAR (translate_generic_soup_cookie_jar_get_type()) + #define TRANSLATE_GENERIC_SOUP_COOKIE_JAR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), TRANSLATE_GENERIC_TYPE_SOUP_COOKIE_JAR, TranslateGenericSoupCookieJar)) +@@ -59,5 +60,6 @@ + + GType translate_generic_soup_cookie_jar_get_type (void); + TranslateGenericSoupCookieJar *translate_generic_soup_cookie_jar_new (void); ++void translate_generic_soup_cookie_jar_attach (TranslateGenericSoupCookieJar *cookie_jar, SoupSession *session); + + #endif /* _TRANSLATE_GENERIC_SOUP_COOKIE_JAR_H */ diff --git a/patches/mpg123/mpg123-ds-rcc.patch b/patches/mpg123/mpg123-ds-rcc.patch new file mode 100644 index 0000000..bbfd104 --- /dev/null +++ b/patches/mpg123/mpg123-ds-rcc.patch @@ -0,0 +1,151 @@ +diff -dPNur mpg123-0.59r/common.c mpg123-0.59r-new/common.c +--- mpg123-0.59r/common.c 1999-06-15 23:24:19.000000000 +0200 ++++ mpg123-0.59r-new/common.c 2005-09-16 02:48:11.000000000 +0200 +@@ -15,6 +15,7 @@ + #endif + #endif + ++#include "rccpatch.h" + #include "mpg123.h" + #include "genre.h" + #include "common.h" +@@ -484,6 +485,8 @@ + char comment[31]={0,}; + char genre[31]={0,}; + ++ char *ctitle, *cartist, *calbum, *ccomment; ++ + if(param.quiet) + return; + +@@ -492,16 +495,26 @@ + strncpy(album,tag->album,30); + strncpy(year,tag->year,4); + strncpy(comment,tag->comment,30); ++ ++ ctitle = rccPatchRecode(title); ++ cartist = rccPatchRecode(artist); ++ calbum = rccPatchRecode(album); ++ ccomment = rccPatchRecode(comment); + +- if ( tag->genre <= sizeof(genre_table)/sizeof(*genre_table) ) { ++ if ( tag->genre < sizeof(genre_table)/sizeof(*genre_table) ) { + strncpy(genre, genre_table[tag->genre], 30); + } else { + strncpy(genre,"Unknown",30); + } + +- fprintf(stderr,"Title : %-30s Artist: %s\n",title,artist); +- fprintf(stderr,"Album : %-30s Year : %4s\n",album,year); +- fprintf(stderr,"Comment: %-30s Genre : %s\n",comment,genre); ++ fprintf(stderr,"Title : %-30s Artist: %s\n",ctitle?ctitle:title,cartist?cartist:artist); ++ fprintf(stderr,"Album : %-30s Year : %4s\n",calbum?calbum:album,year); ++ fprintf(stderr,"Comment: %-30s Genre : %s\n",ccomment?ccomment:comment,genre); ++ ++ if (ctitle) free(ctitle); ++ if (cartist) free(cartist); ++ if (calbum) free(calbum); ++ if (ccomment) free(ccomment); + } + + #if 0 +diff -dPNur mpg123-0.59r/Makefile mpg123-0.59r-new/Makefile +--- mpg123-0.59r/Makefile 1999-06-18 14:18:58.000000000 +0200 ++++ mpg123-0.59r-new/Makefile 2005-09-16 02:47:47.000000000 +0200 +@@ -554,12 +554,12 @@ + mpg123-make: + @ $(MAKE) CFLAGS='$(CFLAGS)' BINNAME=mpg123 mpg123 + +-mpg123: mpg123.o common.o $(OBJECTS) decode_2to1.o decode_4to1.o \ ++mpg123: mpg123.o rccpatch.o common.o $(OBJECTS) decode_2to1.o decode_4to1.o \ + tabinit.o audio.o layer1.o layer2.o layer3.o buffer.o \ + getlopt.o httpget.o xfermem.o equalizer.o \ + decode_ntom.o Makefile wav.o readers.o getbits.o \ + control_generic.o +- $(CC) $(CFLAGS) $(LDFLAGS) mpg123.o tabinit.o common.o layer1.o \ ++ $(CC) $(CFLAGS) $(LDFLAGS) -lrcc mpg123.o tabinit.o rccpatch.o common.o layer1.o \ + layer2.o layer3.o audio.o buffer.o decode_2to1.o equalizer.o \ + decode_4to1.o getlopt.o httpget.o xfermem.o decode_ntom.o \ + wav.o readers.o getbits.o control_generic.o \ +diff -dPNur mpg123-0.59r/mpg123.c mpg123-0.59r-new/mpg123.c +--- mpg123-0.59r/mpg123.c 1999-06-18 14:18:11.000000000 +0200 ++++ mpg123-0.59r-new/mpg123.c 2005-09-16 02:47:47.000000000 +0200 +@@ -32,6 +32,8 @@ + #include "buffer.h" + #include "term.h" + ++#include "rccpatch.h" ++ + #include "version.h" + + static void usage(char *dummy); +@@ -903,6 +905,8 @@ + exit(0); + } + #endif ++ ++ rccPatchInit(); + + while ((fname = get_next_file(argc, argv))) { + char *dirname, *filename; +@@ -1068,6 +1072,8 @@ + intflag = FALSE; + } + } ++ rccPatchFree(); ++ + #ifndef NOXFERMEM + if (param.usebuffer) { + buffer_end(); +diff -dPNur mpg123-0.59r/rccpatch.c mpg123-0.59r-new/rccpatch.c +--- mpg123-0.59r/rccpatch.c 1970-01-01 01:00:00.000000000 +0100 ++++ mpg123-0.59r-new/rccpatch.c 2005-09-16 02:47:47.000000000 +0200 +@@ -0,0 +1,40 @@ ++#include <librcc.h> ++ ++#define ID3_CLASS 0 ++#define OUT_CLASS 1 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, NULL, NULL, "Output Encoding", 0 }, ++ { NULL } ++}; ++ ++static int rcc_initialized = 0; ++ ++void rccPatchFree() { ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++} ++ ++void rccPatchInit() { ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++} ++ ++static void rccPatchTryInit() { ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++} ++ ++char *rccPatchRecode(const char *str) { ++ char *res; ++ rccPatchTryInit(); ++ return rccRecode(NULL, ID3_CLASS, OUT_CLASS, str); ++} +diff -dPNur mpg123-0.59r/rccpatch.h mpg123-0.59r-new/rccpatch.h +--- mpg123-0.59r/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ mpg123-0.59r-new/rccpatch.h 2005-09-16 02:47:47.000000000 +0200 +@@ -0,0 +1,4 @@ ++void rccPatchFree(); ++void rccPatchInit(); ++char *rccPatchRecode(const char *str); ++ diff --git a/patches/mpg123/mpg123-ds-rcc1121.patch b/patches/mpg123/mpg123-ds-rcc1121.patch new file mode 100644 index 0000000..1335795 --- /dev/null +++ b/patches/mpg123/mpg123-ds-rcc1121.patch @@ -0,0 +1,247 @@ +diff -dPNur mpg123-1.12.1/configure.ac mpg123-1.12.1-new/configure.ac +--- mpg123-1.12.1/configure.ac 2010-03-31 10:27:37.000000000 +0200 ++++ mpg123-1.12.1-new/configure.ac 2010-07-07 23:44:57.000000000 +0200 +@@ -998,6 +998,21 @@ + AC_CHECK_LIB([m], [sqrt]) + AC_CHECK_LIB([mx], [powf]) + ++# LibRCC ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ + # attempt to make the signal stuff work... also with GENERIC - later + #if test x"$ac_cv_header_sys_signal_h" = xyes; then + # AC_CHECK_FUNCS( sigemptyset sigaddset sigprocmask sigaction ) +diff -dPNur mpg123-1.12.1/src/libmpg123/id3.c mpg123-1.12.1-new/src/libmpg123/id3.c +--- mpg123-1.12.1/src/libmpg123/id3.c 2010-03-31 10:27:35.000000000 +0200 ++++ mpg123-1.12.1-new/src/libmpg123/id3.c 2010-07-07 23:51:50.000000000 +0200 +@@ -9,6 +9,8 @@ + #include "mpg123lib_intern.h" + #include "id3.h" + #include "debug.h" ++#include "rccpatch.h" ++ + + #ifndef NO_ID3V2 /* Only the main parsing routine will always be there. */ + +@@ -829,6 +831,15 @@ + size_t length = l; + size_t i; + unsigned char *p; ++ char *ctitle; ++ ++ ctitle = mpg123_rcc_recode(s, l, &i); ++ if (ctitle) { ++ convert_utf8(sb, ctitle, i, 0); ++ free(ctitle); ++ return; ++ } ++ + /* determine real length, a latin1 character can at most take 2 in UTF8 */ + for(i=0; i<l; ++i) + if(s[i] >= 0x80) ++length; +diff -dPNur mpg123-1.12.1/src/libmpg123/Makefile.am mpg123-1.12.1-new/src/libmpg123/Makefile.am +--- mpg123-1.12.1/src/libmpg123/Makefile.am 2010-03-31 10:27:35.000000000 +0200 ++++ mpg123-1.12.1-new/src/libmpg123/Makefile.am 2010-07-07 23:44:57.000000000 +0200 +@@ -29,6 +29,8 @@ + libmpg123_la_DEPENDENCIES = @DECODER_LOBJ@ @LFS_LOBJ@ + + libmpg123_la_SOURCES = \ ++ rccpatch.c \ ++ rccpatch.h \ + compat.c \ + compat.h \ + parse.c \ +diff -dPNur mpg123-1.12.1/src/libmpg123/rccpatch.c mpg123-1.12.1-new/src/libmpg123/rccpatch.c +--- mpg123-1.12.1/src/libmpg123/rccpatch.c 1970-01-01 01:00:00.000000000 +0100 ++++ mpg123-1.12.1-new/src/libmpg123/rccpatch.c 2010-07-07 23:55:59.000000000 +0200 +@@ -0,0 +1,76 @@ ++#include <string.h> ++#include <librcc.h> ++#include "mpg123.h" ++ ++#define ID3_CLASS 0 ++#define UTF_CLASS 1 ++#define OUT_CLASS 2 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, NULL, NULL, "Output Encoding", 0 }, ++ { NULL } ++}; ++ ++static int rcc_initialized = 0; ++ ++void mpg123_rcc_free() { ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++} ++ ++void mpg123_rcc_init() { ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++} ++ ++static void mpg123_rcc_try_init() { ++ if (!rcc_initialized) { ++ mpg123_rcc_init(); ++ if (rcc_initialized) atexit(mpg123_rcc_free); ++ } ++} ++ ++ ++char *mpg123_rcc_recode(const char *str, size_t len, size_t *rlen) { ++ char *res; ++ mpg123_rcc_try_init(); ++ return rccSizedRecode(NULL, ID3_CLASS, UTF_CLASS, str, len, rlen); ++} ++ ++static void mpg123_rcc_recode_string(mpg123_string *str, rcc_class_id from, rcc_class_id to) { ++ size_t size; ++ char *res; ++ ++ if ((!str)||(str->fill<2)) return; ++ ++ mpg123_rcc_try_init(); ++ ++ res = rccSizedRecode(NULL, from, to, str->p, str->fill - 1, &size); ++ if (res) { ++ if (size+1>str->size) { ++ if (!mpg123_resize_string(str, size + 1)) { ++ // allocation failed ++ free(res); ++ return; ++ } ++ } ++ strncpy(str->p, res, size + 1); ++ str->fill = size + 1; ++ free(res); ++ } ++} ++ ++void mpg123_rcc_recode_utf_string(mpg123_string *str) { ++ mpg123_rcc_recode_string(str, UTF_CLASS, OUT_CLASS); ++} ++ ++void mpg123_rcc_recode_latin_string(mpg123_string *str) { ++ mpg123_rcc_recode_string(str, ID3_CLASS, OUT_CLASS); ++} +diff -dPNur mpg123-1.12.1/src/libmpg123/rccpatch.h mpg123-1.12.1-new/src/libmpg123/rccpatch.h +--- mpg123-1.12.1/src/libmpg123/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ mpg123-1.12.1-new/src/libmpg123/rccpatch.h 2010-07-07 23:44:57.000000000 +0200 +@@ -0,0 +1,5 @@ ++void mpg123_rcc_free(); ++void mpg123_rcc_init(); ++char *mpg123_rcc_recode(const char *str, size_t len, size_t *rlen); ++void mpg123_rcc_recode_utf_string(mpg123_string *str); ++void mpg123_rcc_recode_latin_string(mpg123_string *str); +diff -dPNur mpg123-1.12.1/src/Makefile.am mpg123-1.12.1-new/src/Makefile.am +--- mpg123-1.12.1/src/Makefile.am 2010-03-31 10:27:36.000000000 +0200 ++++ mpg123-1.12.1-new/src/Makefile.am 2010-07-07 23:46:10.000000000 +0200 +@@ -5,10 +5,10 @@ + ## initially written by Nicholas J. Humfrey + + AM_CPPFLAGS = -DPKGLIBDIR="\"$(pkglibdir)\"" +-mpg123_LDADD = $(LIBLTDL) libmpg123/libmpg123.la @MODULE_OBJ@ @OUTPUT_OBJ@ @OUTPUT_LIBS@ ++mpg123_LDADD = $(LIBLTDL) libmpg123/libmpg123.la @MODULE_OBJ@ @OUTPUT_OBJ@ @OUTPUT_LIBS@ @LIBRCC_LIBS@ + mpg123_LDFLAGS = @EXEC_LT_LDFLAGS@ @OUTPUT_LDFLAGS@ + # Just mpg123_INCLUDES has no effect on build! Trying that before reverting to AM_CPPFLAGS. +-INCLUDES = $(LTDLINCL) -I$(top_builddir)/src/libmpg123 -I$(top_srcdir)/src/libmpg123 ++INCLUDES = $(LTDLINCL) -I$(top_builddir)/src/libmpg123 -I$(top_srcdir)/src/libmpg123 @LIBRCC_INCLUDES@ + # libltdl is not mentioned here... it's not that trivial + mpg123_DEPENDENCIES = @OUTPUT_OBJ@ @MODULE_OBJ@ libmpg123/libmpg123.la + +diff -dPNur mpg123-1.12.1/src/metaprint.c mpg123-1.12.1-new/src/metaprint.c +--- mpg123-1.12.1/src/metaprint.c 2010-03-31 10:27:36.000000000 +0200 ++++ mpg123-1.12.1-new/src/metaprint.c 2010-07-07 23:54:21.000000000 +0200 +@@ -17,7 +17,11 @@ + if(source == NULL) return; + + if(utf8env) mpg123_copy_string(source, dest); +- else utf8_ascii(dest, source); ++ else { ++ mpg123_copy_string(source, dest); ++ mpg123_rcc_recode_utf_string(dest); ++// utf8_ascii(dest, source); ++ } + } + + /* print tags... limiting the UTF-8 to ASCII */ +@@ -53,6 +57,7 @@ + strncpy(tag[TITLE].p,v1->title,30); + tag[TITLE].p[30] = 0; + tag[TITLE].fill = strlen(tag[TITLE].p) + 1; ++ mpg123_rcc_recode_latin_string(&tag[TITLE]); + } + } + if(!tag[ARTIST].fill) +@@ -62,6 +67,7 @@ + strncpy(tag[ARTIST].p,v1->artist,30); + tag[ARTIST].p[30] = 0; + tag[ARTIST].fill = strlen(tag[ARTIST].p) + 1; ++ mpg123_rcc_recode_latin_string(&tag[ARTIST]); + } + } + if(!tag[ALBUM].fill) +@@ -71,6 +77,7 @@ + strncpy(tag[ALBUM].p,v1->album,30); + tag[ALBUM].p[30] = 0; + tag[ALBUM].fill = strlen(tag[ALBUM].p) + 1; ++ mpg123_rcc_recode_latin_string(&tag[ALBUM]); + } + } + if(!tag[COMMENT].fill) +@@ -80,6 +87,7 @@ + strncpy(tag[COMMENT].p,v1->comment,30); + tag[COMMENT].p[30] = 0; + tag[COMMENT].fill = strlen(tag[COMMENT].p) + 1; ++ mpg123_rcc_recode_latin_string(&tag[COMMENT]); + } + } + if(!tag[YEAR].fill) +diff -dPNur mpg123-1.12.1/src/mpg123.c mpg123-1.12.1-new/src/mpg123.c +--- mpg123-1.12.1/src/mpg123.c 2010-03-31 10:27:36.000000000 +0200 ++++ mpg123-1.12.1-new/src/mpg123.c 2010-07-07 23:52:58.000000000 +0200 +@@ -10,6 +10,7 @@ + #include "mpg123app.h" + #include "mpg123.h" + #include "local.h" ++#include "rccpatch.h" + + #ifdef HAVE_SYS_WAIT_H + #include <sys/wait.h> +@@ -973,6 +974,8 @@ + if(param.term_ctrl) + term_init(); + #endif ++ ++ mpg123_rcc_init(); + while ((fname = get_next_file())) + { + char *dirname, *filename; +@@ -1132,6 +1135,8 @@ + #endif + } + } /* end of loop over input files */ ++ mpg123_rcc_free(); ++ + /* Ensure we played everything. */ + if(param.smooth && param.usebuffer) + { diff --git a/patches/mpg123/mpg123-ds-rcc173.patch b/patches/mpg123/mpg123-ds-rcc173.patch new file mode 100644 index 0000000..ae814ff --- /dev/null +++ b/patches/mpg123/mpg123-ds-rcc173.patch @@ -0,0 +1,271 @@ +diff -dPNur mpg123-1.7.3/configure.ac mpg123-1.7.3-rusxmms/configure.ac +--- mpg123-1.7.3/configure.ac 2009-04-27 09:02:40.000000000 +0200 ++++ mpg123-1.7.3-rusxmms/configure.ac 2009-06-13 23:22:17.000000000 +0200 +@@ -759,6 +759,21 @@ + AC_CHECK_LIB([m], [sqrt]) + AC_CHECK_LIB([mx], [powf]) + ++# LibRCC ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ + # attempt to make the signal stuff work... also with GENERIC - later + #if test x"$ac_cv_header_sys_signal_h" = xyes; then + # AC_CHECK_FUNCS( sigemptyset sigaddset sigprocmask sigaction ) +diff -dPNur mpg123-1.7.3/src/libmpg123/id3.c mpg123-1.7.3-rusxmms/src/libmpg123/id3.c +--- mpg123-1.7.3/src/libmpg123/id3.c 2009-04-27 09:02:12.000000000 +0200 ++++ mpg123-1.7.3-rusxmms/src/libmpg123/id3.c 2009-06-14 00:34:23.000000000 +0200 +@@ -9,6 +9,8 @@ + #include "mpg123lib_intern.h" + #include "id3.h" + #include "debug.h" ++#include "rccpatch.h" ++ + + #ifndef NO_ID3V2 /* Only the main parsing routine will always be there. */ + +@@ -774,6 +776,15 @@ + size_t length = l; + size_t i; + unsigned char *p; ++ char *ctitle; ++ ++ ctitle = mpg123_rcc_recode(s, l, &i); ++ if (ctitle) { ++ convert_utf8(sb, ctitle, i); ++ free(ctitle); ++ return; ++ } ++ + /* determine real length, a latin1 character can at most take 2 in UTF8 */ + for(i=0; i<l; ++i) + if(s[i] >= 0x80) ++length; +diff -dPNur mpg123-1.7.3/src/libmpg123/libmpg123.sym mpg123-1.7.3-rusxmms/src/libmpg123/libmpg123.sym +--- mpg123-1.7.3/src/libmpg123/libmpg123.sym 2009-04-27 09:07:20.000000000 +0200 ++++ mpg123-1.7.3-rusxmms/src/libmpg123/libmpg123.sym 2009-06-14 01:53:25.000000000 +0200 +@@ -74,3 +74,8 @@ + mpg123_position + mpg123_length + mpg123_set_filesize ++mpg123_rcc_free ++mpg123_rcc_init ++mpg123_rcc_recode ++mpg123_rcc_recode_utf_string ++mpg123_rcc_recode_latin_string +diff -dPNur mpg123-1.7.3/src/libmpg123/libmpg123.sym.in mpg123-1.7.3-rusxmms/src/libmpg123/libmpg123.sym.in +--- mpg123-1.7.3/src/libmpg123/libmpg123.sym.in 2009-04-27 09:02:12.000000000 +0200 ++++ mpg123-1.7.3-rusxmms/src/libmpg123/libmpg123.sym.in 2009-06-14 01:51:45.000000000 +0200 +@@ -74,3 +74,8 @@ + mpg123_position@LARGEFILE_SUFFIX@ + mpg123_length@LARGEFILE_SUFFIX@ + mpg123_set_filesize@LARGEFILE_SUFFIX@ ++mpg123_rcc_free ++mpg123_rcc_init ++mpg123_rcc_recode ++mpg123_rcc_recode_utf_string ++mpg123_rcc_recode_latin_string +diff -dPNur mpg123-1.7.3/src/libmpg123/Makefile.am mpg123-1.7.3-rusxmms/src/libmpg123/Makefile.am +--- mpg123-1.7.3/src/libmpg123/Makefile.am 2009-04-27 09:02:12.000000000 +0200 ++++ mpg123-1.7.3-rusxmms/src/libmpg123/Makefile.am 2009-06-14 00:10:34.000000000 +0200 +@@ -31,6 +31,8 @@ + libmpg123_la_DEPENDENCIES = @DECODER_LOBJ@ libmpg123.sym + + libmpg123_la_SOURCES = \ ++ rccpatch.c \ ++ rccpatch.h \ + compat.c \ + compat.h \ + parse.c \ +diff -dPNur mpg123-1.7.3/src/libmpg123/rccpatch.c mpg123-1.7.3-rusxmms/src/libmpg123/rccpatch.c +--- mpg123-1.7.3/src/libmpg123/rccpatch.c 1970-01-01 01:00:00.000000000 +0100 ++++ mpg123-1.7.3-rusxmms/src/libmpg123/rccpatch.c 2009-06-14 01:54:37.000000000 +0200 +@@ -0,0 +1,76 @@ ++#include <string.h> ++#include <librcc.h> ++#include "mpg123.h" ++ ++#define ID3_CLASS 0 ++#define UTF_CLASS 1 ++#define OUT_CLASS 2 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, NULL, NULL, "Output Encoding", 0 }, ++ { NULL } ++}; ++ ++static int rcc_initialized = 0; ++ ++void mpg123_rcc_free() { ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++} ++ ++void mpg123_rcc_init() { ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++} ++ ++static void mpg123_rcc_try_init() { ++ if (!rcc_initialized) { ++ mpg123_rcc_init(); ++ if (rcc_initialized) atexit(mpg123_rcc_free); ++ } ++} ++ ++ ++char *mpg123_rcc_recode(const char *str, size_t len, size_t *rlen) { ++ char *res; ++ mpg123_rcc_try_init(); ++ return rccSizedRecode(NULL, ID3_CLASS, UTF_CLASS, str, len, rlen); ++} ++ ++static void mpg123_rcc_recode_string(mpg123_string *str, rcc_class_id from, rcc_class_id to) { ++ size_t size; ++ char *res; ++ ++ if ((!str)||(str->fill<2)) return; ++ ++ mpg123_rcc_try_init(); ++ ++ res = rccSizedRecode(NULL, from, to, str->p, str->fill - 1, &size); ++ if (res) { ++ if (size+1>str->size) { ++ if (!mpg123_resize_string(str, size + 1)) { ++ // allocation failed ++ free(res); ++ return; ++ } ++ } ++ strncpy(str->p, res, size + 1); ++ str->fill = size + 1; ++ free(res); ++ } ++} ++ ++void mpg123_rcc_recode_utf_string(mpg123_string *str) { ++ mpg123_rcc_recode_string(str, UTF_CLASS, OUT_CLASS); ++} ++ ++void mpg123_rcc_recode_latin_string(mpg123_string *str) { ++ mpg123_rcc_recode_string(str, ID3_CLASS, OUT_CLASS); ++} +diff -dPNur mpg123-1.7.3/src/libmpg123/rccpatch.h mpg123-1.7.3-rusxmms/src/libmpg123/rccpatch.h +--- mpg123-1.7.3/src/libmpg123/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ mpg123-1.7.3-rusxmms/src/libmpg123/rccpatch.h 2009-06-14 01:51:21.000000000 +0200 +@@ -0,0 +1,5 @@ ++void mpg123_rcc_free(); ++void mpg123_rcc_init(); ++char *mpg123_rcc_recode(const char *str, size_t len, size_t *rlen); ++void mpg123_rcc_recode_utf_string(mpg123_string *str); ++void mpg123_rcc_recode_latin_string(mpg123_string *str); +diff -dPNur mpg123-1.7.3/src/Makefile.am mpg123-1.7.3-rusxmms/src/Makefile.am +--- mpg123-1.7.3/src/Makefile.am 2009-04-27 09:02:12.000000000 +0200 ++++ mpg123-1.7.3-rusxmms/src/Makefile.am 2009-06-14 00:10:22.000000000 +0200 +@@ -5,10 +5,10 @@ + ## initially written by Nicholas J. Humfrey + + AM_CPPFLAGS = -DPKGLIBDIR="\"$(pkglibdir)\"" +-mpg123_LDADD = $(LIBLTDL) libmpg123/libmpg123.la @MODULE_OBJ@ @OUTPUT_OBJ@ @OUTPUT_LIBS@ ++mpg123_LDADD = $(LIBLTDL) libmpg123/libmpg123.la @MODULE_OBJ@ @OUTPUT_OBJ@ @OUTPUT_LIBS@ @LIBRCC_LIBS@ + mpg123_LDFLAGS = @LT_LDFLAGS@ @OUTPUT_LDFLAGS@ + # Just mpg123_INCLUDES has no effect on build! Trying that before reverting to AM_CPPFLAGS. +-INCLUDES = $(LTDLINCL) -I$(top_builddir)/src/libmpg123 -I$(top_srcdir)/src/libmpg123 ++INCLUDES = $(LTDLINCL) -I$(top_builddir)/src/libmpg123 -I$(top_srcdir)/src/libmpg123 @LIBRCC_INCLUDES@ + # libltdl is not mentioned here... it's not that trivial + mpg123_DEPENDENCIES = @OUTPUT_OBJ@ @MODULE_OBJ@ libmpg123/libmpg123.la + +diff -dPNur mpg123-1.7.3/src/metaprint.c mpg123-1.7.3-rusxmms/src/metaprint.c +--- mpg123-1.7.3/src/metaprint.c 2009-04-27 09:02:12.000000000 +0200 ++++ mpg123-1.7.3-rusxmms/src/metaprint.c 2009-06-14 01:59:09.000000000 +0200 +@@ -17,7 +17,11 @@ + if(source == NULL) return; + + if(utf8env) mpg123_copy_string(source, dest); +- else utf8_ascii(dest, source); ++ else { ++ mpg123_copy_string(source, dest); ++ mpg123_rcc_recode_utf_string(dest); ++// utf8_ascii(dest, source); ++ } + } + + /* print tags... limiting the UTF-8 to ASCII */ +@@ -53,6 +57,7 @@ + strncpy(tag[TITLE].p,v1->title,30); + tag[TITLE].p[30] = 0; + tag[TITLE].fill = strlen(tag[TITLE].p) + 1; ++ mpg123_rcc_recode_latin_string(&tag[TITLE]); + } + } + if(!tag[ARTIST].fill) +@@ -62,6 +67,7 @@ + strncpy(tag[ARTIST].p,v1->artist,30); + tag[ARTIST].p[30] = 0; + tag[ARTIST].fill = strlen(tag[ARTIST].p) + 1; ++ mpg123_rcc_recode_latin_string(&tag[ARTIST]); + } + } + if(!tag[ALBUM].fill) +@@ -71,6 +77,7 @@ + strncpy(tag[ALBUM].p,v1->album,30); + tag[ALBUM].p[30] = 0; + tag[ALBUM].fill = strlen(tag[ALBUM].p) + 1; ++ mpg123_rcc_recode_latin_string(&tag[ALBUM]); + } + } + if(!tag[COMMENT].fill) +@@ -80,6 +87,7 @@ + strncpy(tag[COMMENT].p,v1->comment,30); + tag[COMMENT].p[30] = 0; + tag[COMMENT].fill = strlen(tag[COMMENT].p) + 1; ++ mpg123_rcc_recode_latin_string(&tag[COMMENT]); + } + } + if(!tag[YEAR].fill) +diff -dPNur mpg123-1.7.3/src/mpg123.c mpg123-1.7.3-rusxmms/src/mpg123.c +--- mpg123-1.7.3/src/mpg123.c 2009-04-27 09:02:12.000000000 +0200 ++++ mpg123-1.7.3-rusxmms/src/mpg123.c 2009-06-14 00:35:14.000000000 +0200 +@@ -10,6 +10,7 @@ + #include "mpg123app.h" + #include "mpg123.h" + #include "local.h" ++#include "rccpatch.h" + + #ifdef HAVE_SYS_WAIT_H + #include <sys/wait.h> +@@ -893,6 +894,8 @@ + if(param.term_ctrl) + term_init(); + #endif ++ ++ mpg123_rcc_init(); + while ((fname = get_next_file())) + { + char *dirname, *filename; +@@ -1038,6 +1041,8 @@ + #endif + } + } /* end of loop over input files */ ++ mpg123_rcc_free(); ++ + /* Ensure we played everything. */ + if(param.smooth && param.usebuffer) + { diff --git a/patches/mpg123/mpg123-ds-rcc65.patch b/patches/mpg123/mpg123-ds-rcc65.patch new file mode 100644 index 0000000..41a4d33 --- /dev/null +++ b/patches/mpg123/mpg123-ds-rcc65.patch @@ -0,0 +1,240 @@ +diff -dPNur mpg123-0.65/configure.ac mpg123-0.65-new/configure.ac +--- mpg123-0.65/configure.ac 2007-02-07 10:24:33.000000000 +0100 ++++ mpg123-0.65-new/configure.ac 2007-04-15 13:36:52.000000000 +0200 +@@ -137,6 +137,21 @@ + AC_CHECK_LIB([m], [sqrt]) + AC_CHECK_LIB([mx], [powf]) + ++# LibRCC ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ + # Check for JACK + PKG_CHECK_MODULES(JACK, jack, HAVE_JACK=yes, HAVE_JACK=no) + +diff -dPNur mpg123-0.65/src/id3.c mpg123-0.65-new/src/id3.c +--- mpg123-0.65/src/id3.c 2007-02-07 10:24:33.000000000 +0100 ++++ mpg123-0.65-new/src/id3.c 2007-04-15 13:26:06.000000000 +0200 +@@ -6,6 +6,7 @@ + #include "stringbuf.h" + #include "genre.h" + #include "id3.h" ++#include "rccpatch.h" + + struct taginfo + { +@@ -499,6 +500,8 @@ + void print_id3_tag(unsigned char *id3v1buf) + { + char genre_from_v1 = 0; ++ char *ctitle, *cartist, *calbum, *ccomment; ++ + if(!(id3.version || id3v1buf)) return; + if(id3v1buf != NULL) + { +@@ -688,17 +691,26 @@ + free_stringbuf(&tmp); + } + ++ if (id3.title.fill) ctitle = rccPatchRecode(id3.title.p); ++ else ctitle = NULL; ++ if (id3.artist.fill) cartist = rccPatchRecode(id3.artist.p); ++ else cartist = NULL; ++ if (id3.album.fill) calbum = rccPatchRecode(id3.album.p); ++ else calbum = NULL; ++ if (id3.comment.fill) ccomment = rccPatchRecode(id3.comment.p); ++ else ccomment = NULL; ++ + if(param.long_id3) + { + fprintf(stderr,"\n"); + /* print id3v2 */ + /* dammed, I use pointers as bool again! It's so convenient... */ +- fprintf(stderr,"\tTitle: %s\n", id3.title.fill ? id3.title.p : ""); +- fprintf(stderr,"\tArtist: %s\n", id3.artist.fill ? id3.artist.p : ""); +- fprintf(stderr,"\tAlbum: %s\n", id3.album.fill ? id3.album.p : ""); ++ fprintf(stderr,"\tTitle: %s\n", ctitle?ctitle:(id3.title.fill ? id3.title.p : "")); ++ fprintf(stderr,"\tArtist: %s\n", cartist?cartist:(id3.artist.fill ? id3.artist.p : "")); ++ fprintf(stderr,"\tAlbum: %s\n", calbum?calbum:(id3.album.fill ? id3.album.p : "")); + fprintf(stderr,"\tYear: %s\n", id3.year.fill ? id3.year.p : ""); + fprintf(stderr,"\tGenre: %s\n", id3.genre.fill ? id3.genre.p : ""); +- fprintf(stderr,"\tComment: %s\n", id3.comment.fill ? id3.comment.p : ""); ++ fprintf(stderr,"\tComment: %s\n", ccomment?ccomment:(id3.comment.fill ? id3.comment.p : "")); + fprintf(stderr,"\n"); + } + else +@@ -708,23 +720,23 @@ + /* one _could_ circumvent the strlen calls... */ + if(id3.title.fill && id3.artist.fill && strlen(id3.title.p) <= 30 && strlen(id3.title.p) <= 30) + { +- fprintf(stderr,"Title: %-30s Artist: %s\n",id3.title.p,id3.artist.p); ++ fprintf(stderr,"Title: %-30s Artist: %s\n",ctitle?ctitle:id3.title.p,cartist?cartist:id3.artist.p); + } + else + { +- if(id3.title.fill) fprintf(stderr,"Title: %s\n", id3.title.p); +- if(id3.artist.fill) fprintf(stderr,"Artist: %s\n", id3.artist.p); ++ if(id3.title.fill) fprintf(stderr,"Title: %s\n", ctitle?ctitle:id3.title.p); ++ if(id3.artist.fill) fprintf(stderr,"Artist: %s\n", cartist?cartist:id3.artist.p); + } + if (id3.comment.fill && id3.album.fill && strlen(id3.comment.p) <= 30 && strlen(id3.album.p) <= 30) + { +- fprintf(stderr,"Comment: %-30s Album: %s\n",id3.comment.p,id3.album.p); ++ fprintf(stderr,"Comment: %-30s Album: %s\n",ccomment?ccomment:id3.comment.p,calbum?calbum:id3.album.p); + } + else + { + if (id3.comment.fill) +- fprintf(stderr,"Comment: %s\n", id3.comment.p); ++ fprintf(stderr,"Comment: %s\n", ccomment?ccomment:id3.comment.p); + if (id3.album.fill) +- fprintf(stderr,"Album: %s\n", id3.album.p); ++ fprintf(stderr,"Album: %s\n", calbum?calbum:id3.album.p); + } + if (id3.year.fill && id3.genre.fill && strlen(id3.year.p) <= 30 && strlen(id3.genre.p) <= 30) + { +@@ -738,6 +750,11 @@ + fprintf(stderr,"Genre: %s\n", id3.genre.p); + } + } ++ ++ if (ctitle) free(ctitle); ++ if (cartist) free(cartist); ++ if (calbum) free(calbum); ++ if (ccomment) free(ccomment); + } + + /* +diff -dPNur mpg123-0.65/src/Makefile.am mpg123-0.65-new/src/Makefile.am +--- mpg123-0.65/src/Makefile.am 2007-02-07 10:24:33.000000000 +0100 ++++ mpg123-0.65-new/src/Makefile.am 2007-04-15 13:38:44.000000000 +0200 +@@ -4,8 +4,8 @@ + ## see COPYING and AUTHORS files in distribution or http://mpg123.de + ## initially written by Nicholas J. Humfrey + +-AM_CFLAGS = @AUDIO_CFLAGS@ +-AM_LDFLAGS = @AUDIO_LIBS@ ++AM_CFLAGS = @AUDIO_CFLAGS@ @LIBRCC_INCLUDES@ ++AM_LDFLAGS = @AUDIO_LIBS@ @LIBRCC_LIBS@ + mpg123_LDADD = @AUDIO_OBJ@ @CPU_TYPE_LIB@ + mpg123_DEPENDENCIES = @AUDIO_OBJ@ @CPU_TYPE_LIB@ + +@@ -14,6 +14,8 @@ + + bin_PROGRAMS = mpg123 + mpg123_SOURCES = \ ++ rccpatch.c \ ++ rccpatch.h \ + audio.c \ + audio.h \ + buffer.c \ +diff -dPNur mpg123-0.65/src/mpg123.c mpg123-0.65-new/src/mpg123.c +--- mpg123-0.65/src/mpg123.c 2007-02-07 10:24:33.000000000 +0100 ++++ mpg123-0.65-new/src/mpg123.c 2007-04-15 13:30:42.000000000 +0200 +@@ -35,6 +35,7 @@ + #include "layer3.h" + #endif + #include "playlist.h" ++#include "rccpatch.h" + #include "id3.h" + #include "icy.h" + +@@ -814,15 +815,18 @@ + + if(param.remote) { + int ret; ++ rccPatchInit(); + init_id3(); + init_icy(); + ret = control_generic(&fr); + clear_icy(); + exit_id3(); ++ rccPatchFree(); + safe_exit(ret); + } + #endif + ++ rccPatchInit(); + init_icy(); + init_id3(); /* prepare id3 memory */ + while ((fname = get_next_file())) { +@@ -851,7 +855,7 @@ + } + } + #endif +- ++ + } + + #if !defined(WIN32) && !defined(GENERIC) +@@ -1031,6 +1035,7 @@ + } /* end of loop over input files */ + clear_icy(); + exit_id3(); /* free id3 memory */ ++ rccPatchFree(); + #ifndef NOXFERMEM + if (param.usebuffer) { + buffer_end(); +diff -dPNur mpg123-0.65/src/rccpatch.c mpg123-0.65-new/src/rccpatch.c +--- mpg123-0.65/src/rccpatch.c 1970-01-01 01:00:00.000000000 +0100 ++++ mpg123-0.65-new/src/rccpatch.c 2007-04-15 13:13:09.000000000 +0200 +@@ -0,0 +1,40 @@ ++#include <librcc.h> ++ ++#define ID3_CLASS 0 ++#define OUT_CLASS 1 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, NULL, NULL, "Output Encoding", 0 }, ++ { NULL } ++}; ++ ++static int rcc_initialized = 0; ++ ++void rccPatchFree() { ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++} ++ ++void rccPatchInit() { ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++} ++ ++static void rccPatchTryInit() { ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++} ++ ++char *rccPatchRecode(const char *str) { ++ char *res; ++ rccPatchTryInit(); ++ return rccRecode(NULL, ID3_CLASS, OUT_CLASS, str); ++} +diff -dPNur mpg123-0.65/src/rccpatch.h mpg123-0.65-new/src/rccpatch.h +--- mpg123-0.65/src/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ mpg123-0.65-new/src/rccpatch.h 2007-04-15 13:13:09.000000000 +0200 +@@ -0,0 +1,4 @@ ++void rccPatchFree(); ++void rccPatchInit(); ++char *rccPatchRecode(const char *str); ++ diff --git a/patches/p7zip/README b/patches/p7zip/README new file mode 100644 index 0000000..fe8ae08 --- /dev/null +++ b/patches/p7zip/README @@ -0,0 +1,13 @@ +Difference between 'rusxmms' and 'rusxmms-full' patches is following. The full patche besides makefile.machine fixes all +other architecure-oss specific make files. The 'rusxmms' patch does not. However, you could execute following commands +to have all makefiles adjusted. + +find . -maxdepth 1 -name "makefile.linux*" -print0 | xargs -0 sed -i -e "s/LOCAL_LIBS=-lpthread/LOCAL_LIBS=-lpthread -lrcc/" +find . -maxdepth 1 -name "makefile.machine" -print0 | xargs -0 sed -i -e "s/LOCAL_LIBS=-lpthread/LOCAL_LIBS=-lpthread -lrcc/" + + +Configuration +============= + - The patch uses "zip" configuration of RCC. This means settings could be + altered using "rcc-gtk2-config zip". + - ZIP OEM / Output - encodings are important for patch. diff --git a/patches/p7zip/p7zip_4.44-ds-rusxmms-full.patch b/patches/p7zip/p7zip_4.44-ds-rusxmms-full.patch new file mode 100644 index 0000000..98e7855 --- /dev/null +++ b/patches/p7zip/p7zip_4.44-ds-rusxmms-full.patch @@ -0,0 +1,314 @@ +diff -dPNur p7zip_4.44-old/C/rccrecode.c p7zip_4.44/C/rccrecode.c +--- p7zip_4.44-old/C/rccrecode.c 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.44/C/rccrecode.c 2007-04-14 19:47:03.000000000 +0200 +@@ -0,0 +1,69 @@ ++#include <pthread.h> ++#include <librcc.h> ++ ++static rcc_class_default_charset default_oem[] = { ++ { "ru", "IBM866" }, ++ { NULL, NULL } ++}; ++ ++static rcc_class_default_charset default_iso[] = { ++ { "ru", "CP1251" }, ++ { NULL, NULL } ++}; ++ ++#define ARC_CLASS 0 ++#define OUT_CLASS 1 ++#define ARCOUT_CLASS 0 ++static rcc_class classes[] = { ++ { "oem", RCC_CLASS_STANDARD, NULL, default_oem, "OEM Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, "Output", 0 }, ++ { NULL } ++}; ++ ++static int initialized = 0; ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void *rcc_init() { ++ rcc_context ctx; ++ ++ pthread_mutex_lock(&mutex); ++ if (!initialized) { ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccInitDb4(NULL, NULL, 0); ++ } ++ initialized++; ++ pthread_mutex_unlock(&mutex); ++ ++ ctx = rccCreateContext(NULL, 0, 0, classes, 0); ++ if (ctx) rccInitDb4(ctx, NULL, 0); ++ ++ return ctx; ++} ++ ++ ++void rcc_free(void *ctx) { ++ if (ctx) rccFreeContext((rcc_context)ctx); ++ ++ pthread_mutex_lock(&mutex); ++ if (initialized == 1) rccFree(); ++ initialized--; ++ pthread_mutex_unlock(&mutex); ++} ++ ++ ++char *rcc_read(void *ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, ARC_CLASS, OUT_CLASS, string, size, NULL); ++} ++ ++char *rcc_write(rcc_context ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, OUT_CLASS, ARCOUT_CLASS, string, size, NULL); ++} +diff -dPNur p7zip_4.44-old/C/rccrecode.h p7zip_4.44/C/rccrecode.h +--- p7zip_4.44-old/C/rccrecode.h 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.44/C/rccrecode.h 2007-04-14 19:34:20.000000000 +0200 +@@ -0,0 +1,17 @@ ++#ifndef _RCC_RECODE_H ++#define _RCC_RECODE_H ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++ void *rcc_init(); ++ void rcc_free(void *ctx); ++ char *rcc_read(void *ctx, const char *string, size_t size); ++ char *rcc_write(void *ctx, const char *string, size_t size); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++#endif /* _RCC_RECODE_H */ +diff -dPNur p7zip_4.44-old/CPP/7zip/Archive/Zip/makefile p7zip_4.44/CPP/7zip/Archive/Zip/makefile +--- p7zip_4.44-old/CPP/7zip/Archive/Zip/makefile 2007-01-23 21:29:41.000000000 +0100 ++++ p7zip_4.44/CPP/7zip/Archive/Zip/makefile 2007-04-14 18:36:44.000000000 +0200 +@@ -13,6 +13,7 @@ + LIBS=$(LOCAL_LIBS_DLL) + + OBJS = \ ++../../../../C/rccrecode.o \ + ../../../Common/MyWindows.o \ + ../../../Common/Vector.o\ + ../../../Common/Alloc.o\ +diff -dPNur p7zip_4.44-old/CPP/7zip/Archive/Zip/ZipIn.cpp p7zip_4.44/CPP/7zip/Archive/Zip/ZipIn.cpp +--- p7zip_4.44-old/CPP/7zip/Archive/Zip/ZipIn.cpp 2007-01-20 18:06:58.000000000 +0100 ++++ p7zip_4.44/CPP/7zip/Archive/Zip/ZipIn.cpp 2007-04-14 19:34:59.000000000 +0200 +@@ -9,11 +9,22 @@ + #include "../../Common/LimitedStreams.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { ++ ++CInArchive::CInArchive() { ++ rccctx = rcc_init(); ++} ++ ++CInArchive::~CInArchive() { ++ rcc_free(rccctx); ++} ++ + + // static const char kEndOfString = '\0'; +- ++ + bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) + { + m_Stream = inStream; +@@ -179,10 +190,18 @@ + + AString CInArchive::ReadFileName(UInt32 nameSize) + { ++ char *rccrec; + if (nameSize == 0) + return AString(); + SafeReadBytes(m_NameBuffer.GetBuffer(nameSize), nameSize); + m_NameBuffer.ReleaseBuffer(nameSize); ++ ++ rccrec = rcc_read(rccctx, (LPCSTR)m_NameBuffer, 0); ++ if (rccrec) { ++ m_NameBuffer = rccrec; ++ free(rccrec); ++ } ++ + return m_NameBuffer; + } + +diff -dPNur p7zip_4.44-old/CPP/7zip/Archive/Zip/ZipIn.h p7zip_4.44/CPP/7zip/Archive/Zip/ZipIn.h +--- p7zip_4.44-old/CPP/7zip/Archive/Zip/ZipIn.h 2007-01-20 18:06:28.000000000 +0100 ++++ p7zip_4.44/CPP/7zip/Archive/Zip/ZipIn.h 2007-04-14 19:05:31.000000000 +0200 +@@ -104,6 +104,10 @@ + bool SeekInArchive(UInt64 position); + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); + IInStream* CreateStream(); ++ ++ void *rccctx; ++ CInArchive(); ++ ~CInArchive(); + }; + + }} +diff -dPNur p7zip_4.44-old/CPP/7zip/Archive/Zip/ZipOut.cpp p7zip_4.44/CPP/7zip/Archive/Zip/ZipOut.cpp +--- p7zip_4.44-old/CPP/7zip/Archive/Zip/ZipOut.cpp 2007-01-20 18:06:57.000000000 +0100 ++++ p7zip_4.44/CPP/7zip/Archive/Zip/ZipOut.cpp 2007-04-14 19:44:44.000000000 +0200 +@@ -8,9 +8,19 @@ + #include "../../Common/OffsetStream.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { + ++COutArchive::COutArchive() { ++ rccctx = rcc_init(); ++} ++ ++COutArchive::~COutArchive() { ++ rcc_free(rccctx); ++} ++ + void COutArchive::Create(IOutStream *outStream) + { + m_Stream = outStream; +@@ -104,6 +114,8 @@ + + HRESULT COutArchive::WriteLocalHeader(const CLocalItem &item) + { ++ char *rccrec; ++ + m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); + + bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF; +@@ -124,6 +136,12 @@ + return E_FAIL; + } + WriteUInt16((UInt16)m_ExtraSize); // test it; ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("%u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + + UInt32 extraPos = 0; +@@ -147,6 +165,8 @@ + + void COutArchive::WriteCentralHeader(const CItem &item) + { ++ char *rccrec; ++ + m_Stream->Seek(m_BasePosition, STREAM_SEEK_SET, NULL); + + bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; +@@ -175,6 +195,13 @@ + WriteUInt16(item.InternalAttributes); + WriteUInt32(item.ExternalAttributes); + WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition); ++ ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("C: %u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + if (isZip64) + { +diff -dPNur p7zip_4.44-old/CPP/7zip/Archive/Zip/ZipOut.h p7zip_4.44/CPP/7zip/Archive/Zip/ZipOut.h +--- p7zip_4.44-old/CPP/7zip/Archive/Zip/ZipOut.h 2007-01-20 18:06:29.000000000 +0100 ++++ p7zip_4.44/CPP/7zip/Archive/Zip/ZipOut.h 2007-04-14 19:10:12.000000000 +0200 +@@ -44,6 +44,11 @@ + void CreateStreamForCompressing(IOutStream **outStream); + void CreateStreamForCopying(ISequentialOutStream **outStream); + void SeekToPackedDataPosition(); ++ ++ void *rccctx; ++ COutArchive(); ++ ~COutArchive(); ++ + }; + + }} +diff -dPNur p7zip_4.44-old/CPP/7zip/Bundles/Alone/makefile p7zip_4.44/CPP/7zip/Bundles/Alone/makefile +--- p7zip_4.44-old/CPP/7zip/Bundles/Alone/makefile 2007-01-23 21:29:43.000000000 +0100 ++++ p7zip_4.44/CPP/7zip/Bundles/Alone/makefile 2007-04-14 18:52:31.000000000 +0200 +@@ -41,6 +41,7 @@ + $(MY_HOME)/mySplitCommandLine.o + + OBJS=\ ++../../../../C/rccrecode.o \ + ../../../Common/MyWindows.o \ + 7zAES.o \ + 7zCompressionMode.o \ +diff -dPNur p7zip_4.44-old/makefile.linux_amd64 p7zip_4.44/makefile.linux_amd64 +--- p7zip_4.44-old/makefile.linux_amd64 2007-04-14 15:37:39.000000000 +0200 ++++ p7zip_4.44/makefile.linux_amd64 2007-04-14 18:50:13.000000000 +0200 +@@ -11,6 +11,6 @@ + CC=x86_64-pc-linux-gnu-gcc $(ALLFLAGS) + LINK_SHARED=-shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + +diff -dPNur p7zip_4.44-old/makefile.linux_gcc_2.95_no_need_for_libstdc p7zip_4.44/makefile.linux_gcc_2.95_no_need_for_libstdc +--- p7zip_4.44-old/makefile.linux_gcc_2.95_no_need_for_libstdc 2007-04-14 15:37:39.000000000 +0200 ++++ p7zip_4.44/makefile.linux_gcc_2.95_no_need_for_libstdc 2007-04-14 18:51:02.000000000 +0200 +@@ -10,6 +10,6 @@ + CC=x86_64-pc-linux-gnu-gcc $(ALLFLAGS) + LINK_SHARED=-shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + +diff -dPNur p7zip_4.44-old/makefile.linux_x86_ppc_alpha p7zip_4.44/makefile.linux_x86_ppc_alpha +--- p7zip_4.44-old/makefile.linux_x86_ppc_alpha 2007-04-14 15:37:39.000000000 +0200 ++++ p7zip_4.44/makefile.linux_x86_ppc_alpha 2007-04-14 18:51:15.000000000 +0200 +@@ -14,6 +14,6 @@ + CC=x86_64-pc-linux-gnu-gcc $(ALLFLAGS) + LINK_SHARED=-shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + +diff -dPNur p7zip_4.44-old/makefile.linux_x86_ppc_alpha__gcc_4.X p7zip_4.44/makefile.linux_x86_ppc_alpha__gcc_4.X +--- p7zip_4.44-old/makefile.linux_x86_ppc_alpha__gcc_4.X 2007-04-14 15:37:39.000000000 +0200 ++++ p7zip_4.44/makefile.linux_x86_ppc_alpha__gcc_4.X 2007-04-14 18:51:19.000000000 +0200 +@@ -14,6 +14,6 @@ + CC=x86_64-pc-linux-gnu-gcc $(ALLFLAGS) + LINK_SHARED=-shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + +diff -dPNur p7zip_4.44-old/makefile.machine p7zip_4.44/makefile.machine +--- p7zip_4.44-old/makefile.machine 2007-04-14 15:37:39.000000000 +0200 ++++ p7zip_4.44/makefile.machine 2007-04-14 18:49:24.000000000 +0200 +@@ -11,6 +11,6 @@ + CC=x86_64-pc-linux-gnu-gcc $(ALLFLAGS) + LINK_SHARED=-shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + diff --git a/patches/p7zip/p7zip_4.57-ds-rusxmms-full.patch b/patches/p7zip/p7zip_4.57-ds-rusxmms-full.patch new file mode 100644 index 0000000..24fa504 --- /dev/null +++ b/patches/p7zip/p7zip_4.57-ds-rusxmms-full.patch @@ -0,0 +1,419 @@ +diff -dPNur p7zip_4.57/C/rccrecode.c p7zip_4.57-new/C/rccrecode.c +--- p7zip_4.57/C/rccrecode.c 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.57-new/C/rccrecode.c 2008-04-11 22:02:20.000000000 +0200 +@@ -0,0 +1,71 @@ ++#include <pthread.h> ++#include <librcc.h> ++ ++static rcc_class_default_charset default_oem[] = { ++ { "ru", "IBM866" }, ++ { NULL, NULL } ++}; ++ ++static rcc_class_default_charset default_iso[] = { ++ { "ru", "CP1251" }, ++ { NULL, NULL } ++}; ++ ++#define ARC_CLASS 0 ++#define OUT_CLASS 1 ++#define ARCOUT_CLASS 0 ++static rcc_class classes[] = { ++ { "oem", RCC_CLASS_STANDARD, NULL, default_oem, "OEM Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, "Output", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int initialized = 0; ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void *rcc_init() { ++ rcc_context ctx; ++ ++ pthread_mutex_lock(&mutex); ++ if (!initialized) { ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "zip"); ++ rccInitDb4(NULL, NULL, 0); ++ } ++ initialized++; ++ pthread_mutex_unlock(&mutex); ++ ++ ctx = rccCreateContext(NULL, 0, 0, classes, 0); ++ if (ctx) rccInitDb4(ctx, NULL, 0); ++ if (ctx) rccLoad(ctx, "zip"); ++ ++ return ctx; ++} ++ ++ ++void rcc_free(void *ctx) { ++ if (ctx) rccFreeContext((rcc_context)ctx); ++ ++ pthread_mutex_lock(&mutex); ++ if (initialized == 1) rccFree(); ++ initialized--; ++ pthread_mutex_unlock(&mutex); ++} ++ ++ ++char *rcc_read(void *ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, ARC_CLASS, OUT_CLASS, string, size, NULL); ++} ++ ++char *rcc_write(rcc_context ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, OUT_CLASS, ARCOUT_CLASS, string, size, NULL); ++} +diff -dPNur p7zip_4.57/C/rccrecode.h p7zip_4.57-new/C/rccrecode.h +--- p7zip_4.57/C/rccrecode.h 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.57-new/C/rccrecode.h 2008-04-11 22:02:20.000000000 +0200 +@@ -0,0 +1,17 @@ ++#ifndef _RCC_RECODE_H ++#define _RCC_RECODE_H ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++ void *rcc_init(); ++ void rcc_free(void *ctx); ++ char *rcc_read(void *ctx, const char *string, size_t size); ++ char *rcc_write(void *ctx, const char *string, size_t size); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++#endif /* _RCC_RECODE_H */ +diff -dPNur p7zip_4.57/CPP/7zip/Archive/Zip/ZipIn.cpp p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipIn.cpp +--- p7zip_4.57/CPP/7zip/Archive/Zip/ZipIn.cpp 2007-12-08 11:19:00.000000000 +0100 ++++ p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipIn.cpp 2008-04-11 22:02:20.000000000 +0200 +@@ -9,11 +9,22 @@ + #include "../../Common/LimitedStreams.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { ++ ++CInArchive::CInArchive() { ++ rccctx = rcc_init(); ++} ++ ++CInArchive::~CInArchive() { ++ rcc_free(rccctx); ++} ++ + + // static const char kEndOfString = '\0'; +- ++ + bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) + { + m_Stream = inStream; +@@ -196,10 +207,18 @@ + + AString CInArchive::ReadFileName(UInt32 nameSize) + { ++ char *rccrec; + if (nameSize == 0) + return AString(); + SafeReadBytes(m_NameBuffer.GetBuffer(nameSize), nameSize); + m_NameBuffer.ReleaseBuffer(nameSize); ++ ++ rccrec = rcc_read(rccctx, (LPCSTR)m_NameBuffer, 0); ++ if (rccrec) { ++ m_NameBuffer = rccrec; ++ free(rccrec); ++ } ++ + return m_NameBuffer; + } + +diff -dPNur p7zip_4.57/CPP/7zip/Archive/Zip/ZipIn.h p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipIn.h +--- p7zip_4.57/CPP/7zip/Archive/Zip/ZipIn.h 2007-12-08 11:19:00.000000000 +0100 ++++ p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipIn.h 2008-04-11 22:02:20.000000000 +0200 +@@ -106,6 +106,10 @@ + bool SeekInArchive(UInt64 position); + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); + IInStream* CreateStream(); ++ ++ void *rccctx; ++ CInArchive(); ++ ~CInArchive(); + }; + + }} +diff -dPNur p7zip_4.57/CPP/7zip/Archive/Zip/ZipOut.cpp p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipOut.cpp +--- p7zip_4.57/CPP/7zip/Archive/Zip/ZipOut.cpp 2007-06-26 20:06:23.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipOut.cpp 2008-04-11 22:02:20.000000000 +0200 +@@ -7,9 +7,19 @@ + #include "../../Common/OffsetStream.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { + ++COutArchive::COutArchive() { ++ rccctx = rcc_init(); ++} ++ ++COutArchive::~COutArchive() { ++ rcc_free(rccctx); ++} ++ + void COutArchive::Create(IOutStream *outStream) + { + if (!m_OutBuffer.Create(1 << 16)) +@@ -112,6 +122,7 @@ + { + SeekTo(m_BasePosition); + ++ char *rccrec; + bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF; + + WriteUInt32(NSignature::kLocalFileHeader); +@@ -130,6 +141,12 @@ + throw CSystemException(E_FAIL); + } + WriteUInt16((UInt16)m_ExtraSize); // test it; ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("%u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + + UInt32 extraPos = 0; +@@ -154,6 +171,7 @@ + + void COutArchive::WriteCentralHeader(const CItem &item) + { ++ char *rccrec; + bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; + bool isPack64 = item.PackSize >= 0xFFFFFFFF; + bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF; +@@ -180,6 +198,13 @@ + WriteUInt16(item.InternalAttributes); + WriteUInt32(item.ExternalAttributes); + WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition); ++ ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("C: %u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + if (isZip64) + { +diff -dPNur p7zip_4.57/CPP/7zip/Archive/Zip/ZipOut.h p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipOut.h +--- p7zip_4.57/CPP/7zip/Archive/Zip/ZipOut.h 2007-06-26 20:06:22.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipOut.h 2008-04-11 22:02:20.000000000 +0200 +@@ -49,6 +49,11 @@ + void CreateStreamForCompressing(IOutStream **outStream); + void CreateStreamForCopying(ISequentialOutStream **outStream); + void SeekToPackedDataPosition(); ++ ++ void *rccctx; ++ COutArchive(); ++ ~COutArchive(); ++ + }; + + }} +diff -dPNur p7zip_4.57/CPP/7zip/Bundles/Alone/makefile p7zip_4.57-new/CPP/7zip/Bundles/Alone/makefile +--- p7zip_4.57/CPP/7zip/Bundles/Alone/makefile 2007-07-24 20:55:33.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Bundles/Alone/makefile 2008-04-11 22:02:20.000000000 +0200 +@@ -15,6 +15,7 @@ + LIBS=$(LOCAL_LIBS) + + OBJS=\ ++rccrecode.o \ + myGetTickCount.o \ + wine_date_and_time.o \ + myAddExeFlag.o \ +diff -dPNur p7zip_4.57/CPP/7zip/Bundles/Alone/makefile.list p7zip_4.57-new/CPP/7zip/Bundles/Alone/makefile.list +--- p7zip_4.57/CPP/7zip/Bundles/Alone/makefile.list 2007-07-24 20:56:10.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Bundles/Alone/makefile.list 2008-04-11 22:02:20.000000000 +0200 +@@ -196,6 +196,7 @@ + ../../../../C/Compress/Branch/BranchPPC.c \ + ../../../../C/Compress/Branch/BranchSPARC.c \ + ../../../../C/Compress/Branch/BranchX86.c \ ++ ../../../../C/rccrecode.c \ + ../../../../C/7zCrc.c \ + ../../../../C/Sort.c \ + ../../../../C/Threads.c \ +@@ -237,6 +238,8 @@ + $(CXX) $(CFLAGS) ../../../Common/IntToString.cpp + ListFileUtils.o : ../../../Common/ListFileUtils.cpp + $(CXX) $(CFLAGS) ../../../Common/ListFileUtils.cpp ++rccrecode.o : ../../../../C/rccrecode.c ++ $(CC) $(CFLAGS) ../../../../C/rccrecode.c + MyWindows.o : ../../../Common/MyWindows.cpp + $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp + Random.o : ../../../Common/Random.cpp +diff -dPNur p7zip_4.57/CPP/7zip/Bundles/Format7zFree/makefile p7zip_4.57-new/CPP/7zip/Bundles/Format7zFree/makefile +--- p7zip_4.57/CPP/7zip/Bundles/Format7zFree/makefile 2007-08-03 20:16:04.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Bundles/Format7zFree/makefile 2008-04-11 22:02:20.000000000 +0200 +@@ -14,6 +14,7 @@ + LIBS=$(LOCAL_LIBS_DLL) + + OBJS = \ ++rccrecode.o \ + wine_date_and_time.o \ + myGetTickCount.o \ + CRC.o \ +diff -dPNur p7zip_4.57/CPP/7zip/Bundles/Format7zFree/makefile.list p7zip_4.57-new/CPP/7zip/Bundles/Format7zFree/makefile.list +--- p7zip_4.57/CPP/7zip/Bundles/Format7zFree/makefile.list 2007-08-03 20:17:57.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Bundles/Format7zFree/makefile.list 2008-04-11 22:02:20.000000000 +0200 +@@ -218,6 +218,7 @@ + ../../../../C/Compress/Branch/BranchPPC.c \ + ../../../../C/Compress/Branch/BranchSPARC.c \ + ../../../../C/Compress/Branch/BranchX86.c \ ++ ../../../../C/rccrecode.c \ + ../../../../C/7zCrc.c \ + ../../../../C/Sort.c \ + ../../../../C/Threads.c \ +@@ -237,6 +238,8 @@ + $(CXX) $(CC_SHARED) $(CFLAGS) ../../../Common/ListFileUtils.cpp + MyWindows.o : ../../../Common/MyWindows.cpp + $(CXX) $(CC_SHARED) $(CFLAGS) ../../../Common/MyWindows.cpp ++rccrecode.o : ../../../../C/rccrecode.c ++ $(CC) $(CC_SHARED) $(CFLAGS) ../../../../C/rccrecode.c + Random.o : ../../../Common/Random.cpp + $(CXX) $(CC_SHARED) $(CFLAGS) ../../../Common/Random.cpp + StdInStream.o : ../../../Common/StdInStream.cpp +diff -dPNur p7zip_4.57/makefile.linux_amd64 p7zip_4.57-new/makefile.linux_amd64 +--- p7zip_4.57/makefile.linux_amd64 2007-06-28 09:32:20.000000000 +0200 ++++ p7zip_4.57-new/makefile.linux_amd64 2008-04-11 22:02:45.000000000 +0200 +@@ -12,7 +12,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.57/makefile.linux_amd64_asm p7zip_4.57-new/makefile.linux_amd64_asm +--- p7zip_4.57/makefile.linux_amd64_asm 2007-06-28 09:32:30.000000000 +0200 ++++ p7zip_4.57-new/makefile.linux_amd64_asm 2008-04-11 22:02:45.000000000 +0200 +@@ -13,7 +13,7 @@ + LINK_SHARED=-fPIC -shared + ASM=yasm -f elf -m amd64 + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x64 +diff -dPNur p7zip_4.57/makefile.linux_gcc_2.95_no_need_for_libstdc p7zip_4.57-new/makefile.linux_gcc_2.95_no_need_for_libstdc +--- p7zip_4.57/makefile.linux_gcc_2.95_no_need_for_libstdc 2007-06-24 20:49:31.000000000 +0200 ++++ p7zip_4.57-new/makefile.linux_gcc_2.95_no_need_for_libstdc 2008-04-11 22:02:45.000000000 +0200 +@@ -11,7 +11,7 @@ + LINK_SHARED=-shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip_4.57/makefile.linux_s390x p7zip_4.57-new/makefile.linux_s390x +--- p7zip_4.57/makefile.linux_s390x 2007-08-07 18:36:01.000000000 +0200 ++++ p7zip_4.57-new/makefile.linux_s390x 2008-04-11 22:02:45.000000000 +0200 +@@ -15,7 +15,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.57/makefile.linux_x86_asm_gcc_4.X p7zip_4.57-new/makefile.linux_x86_asm_gcc_4.X +--- p7zip_4.57/makefile.linux_x86_asm_gcc_4.X 2007-08-08 11:15:07.000000000 +0200 ++++ p7zip_4.57-new/makefile.linux_x86_asm_gcc_4.X 2008-04-11 22:02:45.000000000 +0200 +@@ -15,7 +15,7 @@ + LINK_SHARED=-fPIC -shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip_4.57/makefile.linux_x86_asm_gcc_4.X_fltk p7zip_4.57-new/makefile.linux_x86_asm_gcc_4.X_fltk +--- p7zip_4.57/makefile.linux_x86_asm_gcc_4.X_fltk 2007-08-08 11:15:10.000000000 +0200 ++++ p7zip_4.57-new/makefile.linux_x86_asm_gcc_4.X_fltk 2008-04-11 22:02:45.000000000 +0200 +@@ -15,7 +15,7 @@ + LINK_SHARED=-fPIC -shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread `fltk-config --ldflags` ++LOCAL_LIBS=-lpthread -lrcc `fltk-config --ldflags` + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip_4.57/makefile.linux_x86_asm_icc p7zip_4.57-new/makefile.linux_x86_asm_icc +--- p7zip_4.57/makefile.linux_x86_asm_icc 2007-08-08 11:15:15.000000000 +0200 ++++ p7zip_4.57-new/makefile.linux_x86_asm_icc 2008-04-11 22:02:45.000000000 +0200 +@@ -16,7 +16,7 @@ + LINK_SHARED=-fPIC -shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip_4.57/makefile.linux_x86_ppc_alpha p7zip_4.57-new/makefile.linux_x86_ppc_alpha +--- p7zip_4.57/makefile.linux_x86_ppc_alpha 2007-08-08 11:15:18.000000000 +0200 ++++ p7zip_4.57-new/makefile.linux_x86_ppc_alpha 2008-04-11 22:02:45.000000000 +0200 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.57/makefile.linux_x86_ppc_alpha_gcc_4.X p7zip_4.57-new/makefile.linux_x86_ppc_alpha_gcc_4.X +--- p7zip_4.57/makefile.linux_x86_ppc_alpha_gcc_4.X 2007-08-08 11:15:20.000000000 +0200 ++++ p7zip_4.57-new/makefile.linux_x86_ppc_alpha_gcc_4.X 2008-04-11 22:02:45.000000000 +0200 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.57/makefile.machine p7zip_4.57-new/makefile.machine +--- p7zip_4.57/makefile.machine 2007-12-15 18:19:48.000000000 +0100 ++++ p7zip_4.57-new/makefile.machine 2008-04-11 22:02:20.000000000 +0200 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) diff --git a/patches/p7zip/p7zip_4.57-ds-rusxmms.patch b/patches/p7zip/p7zip_4.57-ds-rusxmms.patch new file mode 100644 index 0000000..0913c13 --- /dev/null +++ b/patches/p7zip/p7zip_4.57-ds-rusxmms.patch @@ -0,0 +1,336 @@ +diff -dPNur p7zip_4.57/C/rccrecode.c p7zip_4.57-new/C/rccrecode.c +--- p7zip_4.57/C/rccrecode.c 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.57-new/C/rccrecode.c 2008-04-11 20:23:42.000000000 +0200 +@@ -0,0 +1,71 @@ ++#include <pthread.h> ++#include <librcc.h> ++ ++static rcc_class_default_charset default_oem[] = { ++ { "ru", "IBM866" }, ++ { NULL, NULL } ++}; ++ ++static rcc_class_default_charset default_iso[] = { ++ { "ru", "CP1251" }, ++ { NULL, NULL } ++}; ++ ++#define ARC_CLASS 0 ++#define OUT_CLASS 1 ++#define ARCOUT_CLASS 0 ++static rcc_class classes[] = { ++ { "oem", RCC_CLASS_STANDARD, NULL, default_oem, "OEM Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, "Output", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int initialized = 0; ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void *rcc_init() { ++ rcc_context ctx; ++ ++ pthread_mutex_lock(&mutex); ++ if (!initialized) { ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "zip"); ++ rccInitDb4(NULL, NULL, 0); ++ } ++ initialized++; ++ pthread_mutex_unlock(&mutex); ++ ++ ctx = rccCreateContext(NULL, 0, 0, classes, 0); ++ if (ctx) rccInitDb4(ctx, NULL, 0); ++ if (ctx) rccLoad(ctx, "zip"); ++ ++ return ctx; ++} ++ ++ ++void rcc_free(void *ctx) { ++ if (ctx) rccFreeContext((rcc_context)ctx); ++ ++ pthread_mutex_lock(&mutex); ++ if (initialized == 1) rccFree(); ++ initialized--; ++ pthread_mutex_unlock(&mutex); ++} ++ ++ ++char *rcc_read(void *ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, ARC_CLASS, OUT_CLASS, string, size, NULL); ++} ++ ++char *rcc_write(rcc_context ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, OUT_CLASS, ARCOUT_CLASS, string, size, NULL); ++} +diff -dPNur p7zip_4.57/C/rccrecode.h p7zip_4.57-new/C/rccrecode.h +--- p7zip_4.57/C/rccrecode.h 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.57-new/C/rccrecode.h 2008-04-11 20:23:42.000000000 +0200 +@@ -0,0 +1,17 @@ ++#ifndef _RCC_RECODE_H ++#define _RCC_RECODE_H ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++ void *rcc_init(); ++ void rcc_free(void *ctx); ++ char *rcc_read(void *ctx, const char *string, size_t size); ++ char *rcc_write(void *ctx, const char *string, size_t size); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++#endif /* _RCC_RECODE_H */ +diff -dPNur p7zip_4.57/CPP/7zip/Archive/Zip/ZipIn.cpp p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipIn.cpp +--- p7zip_4.57/CPP/7zip/Archive/Zip/ZipIn.cpp 2007-12-08 11:19:00.000000000 +0100 ++++ p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipIn.cpp 2008-04-11 20:23:42.000000000 +0200 +@@ -9,11 +9,22 @@ + #include "../../Common/LimitedStreams.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { ++ ++CInArchive::CInArchive() { ++ rccctx = rcc_init(); ++} ++ ++CInArchive::~CInArchive() { ++ rcc_free(rccctx); ++} ++ + + // static const char kEndOfString = '\0'; +- ++ + bool CInArchive::Open(IInStream *inStream, const UInt64 *searchHeaderSizeLimit) + { + m_Stream = inStream; +@@ -196,10 +207,18 @@ + + AString CInArchive::ReadFileName(UInt32 nameSize) + { ++ char *rccrec; + if (nameSize == 0) + return AString(); + SafeReadBytes(m_NameBuffer.GetBuffer(nameSize), nameSize); + m_NameBuffer.ReleaseBuffer(nameSize); ++ ++ rccrec = rcc_read(rccctx, (LPCSTR)m_NameBuffer, 0); ++ if (rccrec) { ++ m_NameBuffer = rccrec; ++ free(rccrec); ++ } ++ + return m_NameBuffer; + } + +diff -dPNur p7zip_4.57/CPP/7zip/Archive/Zip/ZipIn.h p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipIn.h +--- p7zip_4.57/CPP/7zip/Archive/Zip/ZipIn.h 2007-12-08 11:19:00.000000000 +0100 ++++ p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipIn.h 2008-04-11 20:23:42.000000000 +0200 +@@ -106,6 +106,10 @@ + bool SeekInArchive(UInt64 position); + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); + IInStream* CreateStream(); ++ ++ void *rccctx; ++ CInArchive(); ++ ~CInArchive(); + }; + + }} +diff -dPNur p7zip_4.57/CPP/7zip/Archive/Zip/ZipOut.cpp p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipOut.cpp +--- p7zip_4.57/CPP/7zip/Archive/Zip/ZipOut.cpp 2007-06-26 20:06:23.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipOut.cpp 2008-04-11 20:23:42.000000000 +0200 +@@ -7,9 +7,19 @@ + #include "../../Common/OffsetStream.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { + ++COutArchive::COutArchive() { ++ rccctx = rcc_init(); ++} ++ ++COutArchive::~COutArchive() { ++ rcc_free(rccctx); ++} ++ + void COutArchive::Create(IOutStream *outStream) + { + if (!m_OutBuffer.Create(1 << 16)) +@@ -112,6 +122,7 @@ + { + SeekTo(m_BasePosition); + ++ char *rccrec; + bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF; + + WriteUInt32(NSignature::kLocalFileHeader); +@@ -130,6 +141,12 @@ + throw CSystemException(E_FAIL); + } + WriteUInt16((UInt16)m_ExtraSize); // test it; ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("%u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + + UInt32 extraPos = 0; +@@ -154,6 +171,7 @@ + + void COutArchive::WriteCentralHeader(const CItem &item) + { ++ char *rccrec; + bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; + bool isPack64 = item.PackSize >= 0xFFFFFFFF; + bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF; +@@ -180,6 +198,13 @@ + WriteUInt16(item.InternalAttributes); + WriteUInt32(item.ExternalAttributes); + WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition); ++ ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("C: %u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + if (isZip64) + { +diff -dPNur p7zip_4.57/CPP/7zip/Archive/Zip/ZipOut.h p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipOut.h +--- p7zip_4.57/CPP/7zip/Archive/Zip/ZipOut.h 2007-06-26 20:06:22.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Archive/Zip/ZipOut.h 2008-04-11 20:23:42.000000000 +0200 +@@ -49,6 +49,11 @@ + void CreateStreamForCompressing(IOutStream **outStream); + void CreateStreamForCopying(ISequentialOutStream **outStream); + void SeekToPackedDataPosition(); ++ ++ void *rccctx; ++ COutArchive(); ++ ~COutArchive(); ++ + }; + + }} +diff -dPNur p7zip_4.57/CPP/7zip/Bundles/Alone/makefile p7zip_4.57-new/CPP/7zip/Bundles/Alone/makefile +--- p7zip_4.57/CPP/7zip/Bundles/Alone/makefile 2007-07-24 20:55:33.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Bundles/Alone/makefile 2008-04-11 20:23:42.000000000 +0200 +@@ -15,6 +15,7 @@ + LIBS=$(LOCAL_LIBS) + + OBJS=\ ++rccrecode.o \ + myGetTickCount.o \ + wine_date_and_time.o \ + myAddExeFlag.o \ +diff -dPNur p7zip_4.57/CPP/7zip/Bundles/Alone/makefile.list p7zip_4.57-new/CPP/7zip/Bundles/Alone/makefile.list +--- p7zip_4.57/CPP/7zip/Bundles/Alone/makefile.list 2007-07-24 20:56:10.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Bundles/Alone/makefile.list 2008-04-11 20:23:42.000000000 +0200 +@@ -196,6 +196,7 @@ + ../../../../C/Compress/Branch/BranchPPC.c \ + ../../../../C/Compress/Branch/BranchSPARC.c \ + ../../../../C/Compress/Branch/BranchX86.c \ ++ ../../../../C/rccrecode.c \ + ../../../../C/7zCrc.c \ + ../../../../C/Sort.c \ + ../../../../C/Threads.c \ +@@ -237,6 +238,8 @@ + $(CXX) $(CFLAGS) ../../../Common/IntToString.cpp + ListFileUtils.o : ../../../Common/ListFileUtils.cpp + $(CXX) $(CFLAGS) ../../../Common/ListFileUtils.cpp ++rccrecode.o : ../../../../C/rccrecode.c ++ $(CC) $(CFLAGS) ../../../../C/rccrecode.c + MyWindows.o : ../../../Common/MyWindows.cpp + $(CXX) $(CFLAGS) ../../../Common/MyWindows.cpp + Random.o : ../../../Common/Random.cpp +diff -dPNur p7zip_4.57/CPP/7zip/Bundles/Format7zFree/makefile p7zip_4.57-new/CPP/7zip/Bundles/Format7zFree/makefile +--- p7zip_4.57/CPP/7zip/Bundles/Format7zFree/makefile 2007-08-03 20:16:04.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Bundles/Format7zFree/makefile 2008-04-11 20:30:53.000000000 +0200 +@@ -14,6 +14,7 @@ + LIBS=$(LOCAL_LIBS_DLL) + + OBJS = \ ++rccrecode.o \ + wine_date_and_time.o \ + myGetTickCount.o \ + CRC.o \ +diff -dPNur p7zip_4.57/CPP/7zip/Bundles/Format7zFree/makefile.list p7zip_4.57-new/CPP/7zip/Bundles/Format7zFree/makefile.list +--- p7zip_4.57/CPP/7zip/Bundles/Format7zFree/makefile.list 2007-08-03 20:17:57.000000000 +0200 ++++ p7zip_4.57-new/CPP/7zip/Bundles/Format7zFree/makefile.list 2008-04-11 20:32:11.000000000 +0200 +@@ -218,6 +218,7 @@ + ../../../../C/Compress/Branch/BranchPPC.c \ + ../../../../C/Compress/Branch/BranchSPARC.c \ + ../../../../C/Compress/Branch/BranchX86.c \ ++ ../../../../C/rccrecode.c \ + ../../../../C/7zCrc.c \ + ../../../../C/Sort.c \ + ../../../../C/Threads.c \ +@@ -237,6 +238,8 @@ + $(CXX) $(CC_SHARED) $(CFLAGS) ../../../Common/ListFileUtils.cpp + MyWindows.o : ../../../Common/MyWindows.cpp + $(CXX) $(CC_SHARED) $(CFLAGS) ../../../Common/MyWindows.cpp ++rccrecode.o : ../../../../C/rccrecode.c ++ $(CC) $(CC_SHARED) $(CFLAGS) ../../../../C/rccrecode.c + Random.o : ../../../Common/Random.cpp + $(CXX) $(CC_SHARED) $(CFLAGS) ../../../Common/Random.cpp + StdInStream.o : ../../../Common/StdInStream.cpp +diff -dPNur p7zip_4.57/makefile.machine p7zip_4.57-new/makefile.machine +--- p7zip_4.57/makefile.machine 2007-12-15 18:19:48.000000000 +0100 ++++ p7zip_4.57-new/makefile.machine 2008-04-11 20:23:42.000000000 +0200 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.57/makefile.machine.orig p7zip_4.57-new/makefile.machine.orig +--- p7zip_4.57/makefile.machine.orig 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.57-new/makefile.machine.orig 2007-12-15 18:19:48.000000000 +0100 +@@ -0,0 +1,21 @@ ++# ++# makefile for Linux (x86, PPC, alpha ...) ++# ++ ++OPTFLAGS=-O ++ ++ALLFLAGS=${OPTFLAGS} -s \ ++ -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \ ++ -DNDEBUG -D_REENTRANT -DENV_UNIX \ ++ $(LOCAL_FLAGS) ++ ++CXX=g++ $(ALLFLAGS) ++CC=gcc $(ALLFLAGS) ++CC_SHARED=-fPIC ++LINK_SHARED=-fPIC -shared ++ ++LOCAL_LIBS=-lpthread ++LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl ++ ++OBJ_CRC32=$(OBJ_CRC32_C) ++ diff --git a/patches/p7zip/p7zip_4.65-ds-rusxmms-full.patch b/patches/p7zip/p7zip_4.65-ds-rusxmms-full.patch new file mode 100644 index 0000000..a7ab04e --- /dev/null +++ b/patches/p7zip/p7zip_4.65-ds-rusxmms-full.patch @@ -0,0 +1,425 @@ +diff -dPNur p7zip_4.65/C/rccrecode.c p7zip_4.65-new/C/rccrecode.c +--- p7zip_4.65/C/rccrecode.c 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.65-new/C/rccrecode.c 2009-06-14 02:44:19.000000000 +0200 +@@ -0,0 +1,71 @@ ++#include <pthread.h> ++#include <librcc.h> ++ ++static rcc_class_default_charset default_oem[] = { ++ { "ru", "IBM866" }, ++ { NULL, NULL } ++}; ++ ++static rcc_class_default_charset default_iso[] = { ++ { "ru", "CP1251" }, ++ { NULL, NULL } ++}; ++ ++#define ARC_CLASS 0 ++#define OUT_CLASS 1 ++#define ARCOUT_CLASS 0 ++static rcc_class classes[] = { ++ { "oem", RCC_CLASS_STANDARD, NULL, default_oem, "OEM Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, "Output", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int initialized = 0; ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void *rcc_init() { ++ rcc_context ctx; ++ ++ pthread_mutex_lock(&mutex); ++ if (!initialized) { ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "zip"); ++ rccInitDb4(NULL, NULL, 0); ++ } ++ initialized++; ++ pthread_mutex_unlock(&mutex); ++ ++ ctx = rccCreateContext(NULL, 0, 0, classes, 0); ++ if (ctx) rccInitDb4(ctx, NULL, 0); ++ if (ctx) rccLoad(ctx, "zip"); ++ ++ return ctx; ++} ++ ++ ++void rcc_free(void *ctx) { ++ if (ctx) rccFreeContext((rcc_context)ctx); ++ ++ pthread_mutex_lock(&mutex); ++ if (initialized == 1) rccFree(); ++ initialized--; ++ pthread_mutex_unlock(&mutex); ++} ++ ++ ++char *rcc_read(void *ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, ARC_CLASS, OUT_CLASS, string, size, NULL); ++} ++ ++char *rcc_write(rcc_context ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, OUT_CLASS, ARCOUT_CLASS, string, size, NULL); ++} +diff -dPNur p7zip_4.65/C/rccrecode.h p7zip_4.65-new/C/rccrecode.h +--- p7zip_4.65/C/rccrecode.h 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.65-new/C/rccrecode.h 2009-06-14 02:44:19.000000000 +0200 +@@ -0,0 +1,17 @@ ++#ifndef _RCC_RECODE_H ++#define _RCC_RECODE_H ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++ void *rcc_init(); ++ void rcc_free(void *ctx); ++ char *rcc_read(void *ctx, const char *string, size_t size); ++ char *rcc_write(void *ctx, const char *string, size_t size); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++#endif /* _RCC_RECODE_H */ +diff -dPNur p7zip_4.65/CPP/7zip/Archive/Zip/ZipIn.cpp p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipIn.cpp +--- p7zip_4.65/CPP/7zip/Archive/Zip/ZipIn.cpp 2008-11-28 23:03:44.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipIn.cpp 2009-06-14 02:47:28.000000000 +0200 +@@ -9,6 +9,8 @@ + #include "../../Common/LimitedStreams.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + extern "C" + { + #include "../../../../C/CpuArch.h" +@@ -23,6 +25,14 @@ + + // static const char kEndOfString = '\0'; + ++CInArchive::CInArchive() { ++ rccctx = rcc_init(); ++} ++ ++CInArchive::~CInArchive() { ++ rcc_free(rccctx); ++} ++ + HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) + { + Close(); +@@ -198,12 +208,21 @@ + + AString CInArchive::ReadFileName(UInt32 nameSize) + { ++ char *rccrec; ++ + if (nameSize == 0) + return AString(); + char *p = m_NameBuffer.GetBuffer(nameSize); + SafeReadBytes(p, nameSize); + p[nameSize] = 0; + m_NameBuffer.ReleaseBuffer(); ++ ++ rccrec = rcc_read(rccctx, (LPCSTR)m_NameBuffer, 0); ++ if (rccrec) { ++ m_NameBuffer = rccrec; ++ free(rccrec); ++ } ++ + return m_NameBuffer; + } + +diff -dPNur p7zip_4.65/CPP/7zip/Archive/Zip/ZipIn.h p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipIn.h +--- p7zip_4.65/CPP/7zip/Archive/Zip/ZipIn.h 2008-08-14 11:11:13.000000000 +0200 ++++ p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipIn.h 2009-06-14 02:48:32.000000000 +0200 +@@ -108,6 +108,10 @@ + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); + IInStream* CreateStream(); + ++ void *rccctx; ++ CInArchive(); ++ ~CInArchive(); ++ + bool IsOpen() const { return m_Stream != NULL; } + }; + +diff -dPNur p7zip_4.65/CPP/7zip/Archive/Zip/ZipOut.cpp p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipOut.cpp +--- p7zip_4.65/CPP/7zip/Archive/Zip/ZipOut.cpp 2008-08-14 11:11:26.000000000 +0200 ++++ p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipOut.cpp 2009-06-14 02:44:19.000000000 +0200 +@@ -7,9 +7,19 @@ + #include "../../Common/OffsetStream.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { + ++COutArchive::COutArchive() { ++ rccctx = rcc_init(); ++} ++ ++COutArchive::~COutArchive() { ++ rcc_free(rccctx); ++} ++ + void COutArchive::Create(IOutStream *outStream) + { + if (!m_OutBuffer.Create(1 << 16)) +@@ -112,6 +122,7 @@ + { + SeekTo(m_BasePosition); + ++ char *rccrec; + bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF; + + WriteUInt32(NSignature::kLocalFileHeader); +@@ -130,6 +141,12 @@ + throw CSystemException(E_FAIL); + } + WriteUInt16((UInt16)m_ExtraSize); // test it; ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("%u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + + UInt32 extraPos = 0; +@@ -154,6 +171,7 @@ + + void COutArchive::WriteCentralHeader(const CItem &item) + { ++ char *rccrec; + bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; + bool isPack64 = item.PackSize >= 0xFFFFFFFF; + bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF; +@@ -181,6 +199,13 @@ + WriteUInt16(item.InternalAttributes); + WriteUInt32(item.ExternalAttributes); + WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition); ++ ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("C: %u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + if (isZip64) + { +diff -dPNur p7zip_4.65/CPP/7zip/Archive/Zip/ZipOut.h p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipOut.h +--- p7zip_4.65/CPP/7zip/Archive/Zip/ZipOut.h 2008-08-14 11:11:13.000000000 +0200 ++++ p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipOut.h 2009-06-14 02:44:19.000000000 +0200 +@@ -49,6 +49,11 @@ + void CreateStreamForCompressing(IOutStream **outStream); + void CreateStreamForCopying(ISequentialOutStream **outStream); + void SeekToPackedDataPosition(); ++ ++ void *rccctx; ++ COutArchive(); ++ ~COutArchive(); ++ + }; + + }} +diff -dPNur p7zip_4.65/CPP/7zip/Bundles/Alone/makefile p7zip_4.65-new/CPP/7zip/Bundles/Alone/makefile +--- p7zip_4.65/CPP/7zip/Bundles/Alone/makefile 2009-02-07 19:39:04.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Bundles/Alone/makefile 2009-06-14 02:44:19.000000000 +0200 +@@ -250,6 +250,7 @@ + Sha256.o + + OBJS=\ ++rccrecode.o \ + myGetTickCount.o \ + wine_date_and_time.o \ + myAddExeFlag.o \ +diff -dPNur p7zip_4.65/CPP/7zip/Bundles/Alone/makefile.list p7zip_4.65-new/CPP/7zip/Bundles/Alone/makefile.list +--- p7zip_4.65/CPP/7zip/Bundles/Alone/makefile.list 2009-02-09 21:04:57.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Bundles/Alone/makefile.list 2009-06-14 02:51:45.000000000 +0200 +@@ -204,6 +204,7 @@ + ../../Crypto/ZipStrong.cpp + + SRCS_C=\ ++ ../../../../C/rccrecode.c \ + ../../../../C/Bra.c \ + ../../../../C/Bra86.c \ + ../../../../C/BraIA64.c \ +diff -dPNur p7zip_4.65/CPP/7zip/Bundles/Format7zFree/makefile p7zip_4.65-new/CPP/7zip/Bundles/Format7zFree/makefile +--- p7zip_4.65/CPP/7zip/Bundles/Format7zFree/makefile 2009-02-09 21:47:24.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Bundles/Format7zFree/makefile 2009-06-14 03:00:06.000000000 +0200 +@@ -296,6 +296,7 @@ + Sha256.o \ + + OBJS = \ ++ rccrecode.o \ + wine_date_and_time.o \ + myGetTickCount.o \ + $(COMMON_OBJS) \ +diff -dPNur p7zip_4.65/CPP/7zip/Bundles/Format7zFree/makefile.list p7zip_4.65-new/CPP/7zip/Bundles/Format7zFree/makefile.list +--- p7zip_4.65/CPP/7zip/Bundles/Format7zFree/makefile.list 2009-02-09 21:04:32.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Bundles/Format7zFree/makefile.list 2009-06-14 03:00:39.000000000 +0200 +@@ -235,6 +235,7 @@ + ../../Crypto/ZipStrong.cpp + + SRCS_C=\ ++ ../../../../C/rccrecode.c \ + ../../../../C/Bra.c \ + ../../../../C/Bra86.c \ + ../../../../C/BraIA64.c \ +diff -dPNur p7zip_4.65/makefile.linux_amd64 p7zip_4.65-new/makefile.linux_amd64 +--- p7zip_4.65/makefile.linux_amd64 2007-06-28 09:32:20.000000000 +0200 ++++ p7zip_4.65-new/makefile.linux_amd64 2009-06-14 05:08:19.000000000 +0200 +@@ -12,7 +12,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.65/makefile.linux_amd64_asm p7zip_4.65-new/makefile.linux_amd64_asm +--- p7zip_4.65/makefile.linux_amd64_asm 2007-06-28 09:32:30.000000000 +0200 ++++ p7zip_4.65-new/makefile.linux_amd64_asm 2009-06-14 05:08:19.000000000 +0200 +@@ -13,7 +13,7 @@ + LINK_SHARED=-fPIC -shared + ASM=yasm -f elf -m amd64 + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x64 +diff -dPNur p7zip_4.65/makefile.linux_amd64_asm_icc p7zip_4.65-new/makefile.linux_amd64_asm_icc +--- p7zip_4.65/makefile.linux_amd64_asm_icc 2009-02-09 22:12:36.000000000 +0100 ++++ p7zip_4.65-new/makefile.linux_amd64_asm_icc 2009-06-14 05:08:19.000000000 +0200 +@@ -16,7 +16,7 @@ + LINK_SHARED=-fPIC -shared + ASM=yasm -f elf -m amd64 + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x64 +diff -dPNur p7zip_4.65/makefile.linux_gcc_2.95_no_need_for_libstdc p7zip_4.65-new/makefile.linux_gcc_2.95_no_need_for_libstdc +--- p7zip_4.65/makefile.linux_gcc_2.95_no_need_for_libstdc 2007-06-24 20:49:31.000000000 +0200 ++++ p7zip_4.65-new/makefile.linux_gcc_2.95_no_need_for_libstdc 2009-06-14 05:08:19.000000000 +0200 +@@ -11,7 +11,7 @@ + LINK_SHARED=-shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip_4.65/makefile.linux_s390x p7zip_4.65-new/makefile.linux_s390x +--- p7zip_4.65/makefile.linux_s390x 2007-08-07 18:36:01.000000000 +0200 ++++ p7zip_4.65-new/makefile.linux_s390x 2009-06-14 05:08:19.000000000 +0200 +@@ -15,7 +15,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.65/makefile.linux_x86_asm_gcc_4.X p7zip_4.65-new/makefile.linux_x86_asm_gcc_4.X +--- p7zip_4.65/makefile.linux_x86_asm_gcc_4.X 2007-08-08 11:15:07.000000000 +0200 ++++ p7zip_4.65-new/makefile.linux_x86_asm_gcc_4.X 2009-06-14 05:08:19.000000000 +0200 +@@ -15,7 +15,7 @@ + LINK_SHARED=-fPIC -shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip_4.65/makefile.linux_x86_asm_gcc_4.X_fltk p7zip_4.65-new/makefile.linux_x86_asm_gcc_4.X_fltk +--- p7zip_4.65/makefile.linux_x86_asm_gcc_4.X_fltk 2007-08-08 11:15:10.000000000 +0200 ++++ p7zip_4.65-new/makefile.linux_x86_asm_gcc_4.X_fltk 2009-06-14 05:08:19.000000000 +0200 +@@ -15,7 +15,7 @@ + LINK_SHARED=-fPIC -shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread `fltk-config --ldflags` ++LOCAL_LIBS=-lpthread -lrcc `fltk-config --ldflags` + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip_4.65/makefile.linux_x86_asm_icc p7zip_4.65-new/makefile.linux_x86_asm_icc +--- p7zip_4.65/makefile.linux_x86_asm_icc 2007-08-08 11:15:15.000000000 +0200 ++++ p7zip_4.65-new/makefile.linux_x86_asm_icc 2009-06-14 05:08:19.000000000 +0200 +@@ -16,7 +16,7 @@ + LINK_SHARED=-fPIC -shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip_4.65/makefile.linux_x86_ppc_alpha p7zip_4.65-new/makefile.linux_x86_ppc_alpha +--- p7zip_4.65/makefile.linux_x86_ppc_alpha 2007-08-08 11:15:18.000000000 +0200 ++++ p7zip_4.65-new/makefile.linux_x86_ppc_alpha 2009-06-14 05:08:19.000000000 +0200 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.65/makefile.linux_x86_ppc_alpha_gcc_4.X p7zip_4.65-new/makefile.linux_x86_ppc_alpha_gcc_4.X +--- p7zip_4.65/makefile.linux_x86_ppc_alpha_gcc_4.X 2007-08-08 11:15:20.000000000 +0200 ++++ p7zip_4.65-new/makefile.linux_x86_ppc_alpha_gcc_4.X 2009-06-14 05:08:19.000000000 +0200 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.65/makefile.machine p7zip_4.65-new/makefile.machine +--- p7zip_4.65/makefile.machine 2009-02-14 18:19:09.000000000 +0100 ++++ p7zip_4.65-new/makefile.machine 2009-06-14 02:44:19.000000000 +0200 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.65/makefile.rules p7zip_4.65-new/makefile.rules +--- p7zip_4.65/makefile.rules 2009-02-09 21:03:16.000000000 +0100 ++++ p7zip_4.65-new/makefile.rules 2009-06-14 02:52:48.000000000 +0200 +@@ -558,3 +558,5 @@ + 7zCrcT8.o : ../../../../C/7zCrcT8.c + $(CC) $(CFLAGS) ../../../../C/7zCrcT8.c + ++rccrecode.o : ../../../../C/rccrecode.c ++ $(CC) $(CFLAGS) ../../../../C/rccrecode.c diff --git a/patches/p7zip/p7zip_4.65-ds-rusxmms.patch b/patches/p7zip/p7zip_4.65-ds-rusxmms.patch new file mode 100644 index 0000000..7072522 --- /dev/null +++ b/patches/p7zip/p7zip_4.65-ds-rusxmms.patch @@ -0,0 +1,305 @@ +diff -dPNur p7zip_4.65/C/rccrecode.c p7zip_4.65-new/C/rccrecode.c +--- p7zip_4.65/C/rccrecode.c 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.65-new/C/rccrecode.c 2009-06-14 02:44:19.000000000 +0200 +@@ -0,0 +1,71 @@ ++#include <pthread.h> ++#include <librcc.h> ++ ++static rcc_class_default_charset default_oem[] = { ++ { "ru", "IBM866" }, ++ { NULL, NULL } ++}; ++ ++static rcc_class_default_charset default_iso[] = { ++ { "ru", "CP1251" }, ++ { NULL, NULL } ++}; ++ ++#define ARC_CLASS 0 ++#define OUT_CLASS 1 ++#define ARCOUT_CLASS 0 ++static rcc_class classes[] = { ++ { "oem", RCC_CLASS_STANDARD, NULL, default_oem, "OEM Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, "Output", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int initialized = 0; ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void *rcc_init() { ++ rcc_context ctx; ++ ++ pthread_mutex_lock(&mutex); ++ if (!initialized) { ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "zip"); ++ rccInitDb4(NULL, NULL, 0); ++ } ++ initialized++; ++ pthread_mutex_unlock(&mutex); ++ ++ ctx = rccCreateContext(NULL, 0, 0, classes, 0); ++ if (ctx) rccInitDb4(ctx, NULL, 0); ++ if (ctx) rccLoad(ctx, "zip"); ++ ++ return ctx; ++} ++ ++ ++void rcc_free(void *ctx) { ++ if (ctx) rccFreeContext((rcc_context)ctx); ++ ++ pthread_mutex_lock(&mutex); ++ if (initialized == 1) rccFree(); ++ initialized--; ++ pthread_mutex_unlock(&mutex); ++} ++ ++ ++char *rcc_read(void *ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, ARC_CLASS, OUT_CLASS, string, size, NULL); ++} ++ ++char *rcc_write(rcc_context ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, OUT_CLASS, ARCOUT_CLASS, string, size, NULL); ++} +diff -dPNur p7zip_4.65/C/rccrecode.h p7zip_4.65-new/C/rccrecode.h +--- p7zip_4.65/C/rccrecode.h 1970-01-01 01:00:00.000000000 +0100 ++++ p7zip_4.65-new/C/rccrecode.h 2009-06-14 02:44:19.000000000 +0200 +@@ -0,0 +1,17 @@ ++#ifndef _RCC_RECODE_H ++#define _RCC_RECODE_H ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++ void *rcc_init(); ++ void rcc_free(void *ctx); ++ char *rcc_read(void *ctx, const char *string, size_t size); ++ char *rcc_write(void *ctx, const char *string, size_t size); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++#endif /* _RCC_RECODE_H */ +diff -dPNur p7zip_4.65/CPP/7zip/Archive/Zip/ZipIn.cpp p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipIn.cpp +--- p7zip_4.65/CPP/7zip/Archive/Zip/ZipIn.cpp 2008-11-28 23:03:44.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipIn.cpp 2009-06-14 02:47:28.000000000 +0200 +@@ -9,6 +9,8 @@ + #include "../../Common/LimitedStreams.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + extern "C" + { + #include "../../../../C/CpuArch.h" +@@ -23,6 +25,14 @@ + + // static const char kEndOfString = '\0'; + ++CInArchive::CInArchive() { ++ rccctx = rcc_init(); ++} ++ ++CInArchive::~CInArchive() { ++ rcc_free(rccctx); ++} ++ + HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) + { + Close(); +@@ -198,12 +208,21 @@ + + AString CInArchive::ReadFileName(UInt32 nameSize) + { ++ char *rccrec; ++ + if (nameSize == 0) + return AString(); + char *p = m_NameBuffer.GetBuffer(nameSize); + SafeReadBytes(p, nameSize); + p[nameSize] = 0; + m_NameBuffer.ReleaseBuffer(); ++ ++ rccrec = rcc_read(rccctx, (LPCSTR)m_NameBuffer, 0); ++ if (rccrec) { ++ m_NameBuffer = rccrec; ++ free(rccrec); ++ } ++ + return m_NameBuffer; + } + +diff -dPNur p7zip_4.65/CPP/7zip/Archive/Zip/ZipIn.h p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipIn.h +--- p7zip_4.65/CPP/7zip/Archive/Zip/ZipIn.h 2008-08-14 11:11:13.000000000 +0200 ++++ p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipIn.h 2009-06-14 02:48:32.000000000 +0200 +@@ -108,6 +108,10 @@ + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); + IInStream* CreateStream(); + ++ void *rccctx; ++ CInArchive(); ++ ~CInArchive(); ++ + bool IsOpen() const { return m_Stream != NULL; } + }; + +diff -dPNur p7zip_4.65/CPP/7zip/Archive/Zip/ZipOut.cpp p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipOut.cpp +--- p7zip_4.65/CPP/7zip/Archive/Zip/ZipOut.cpp 2008-08-14 11:11:26.000000000 +0200 ++++ p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipOut.cpp 2009-06-14 02:44:19.000000000 +0200 +@@ -7,9 +7,19 @@ + #include "../../Common/OffsetStream.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { + ++COutArchive::COutArchive() { ++ rccctx = rcc_init(); ++} ++ ++COutArchive::~COutArchive() { ++ rcc_free(rccctx); ++} ++ + void COutArchive::Create(IOutStream *outStream) + { + if (!m_OutBuffer.Create(1 << 16)) +@@ -112,6 +122,7 @@ + { + SeekTo(m_BasePosition); + ++ char *rccrec; + bool isZip64 = m_IsZip64 || item.PackSize >= 0xFFFFFFFF || item.UnPackSize >= 0xFFFFFFFF; + + WriteUInt32(NSignature::kLocalFileHeader); +@@ -130,6 +141,12 @@ + throw CSystemException(E_FAIL); + } + WriteUInt16((UInt16)m_ExtraSize); // test it; ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("%u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + + UInt32 extraPos = 0; +@@ -154,6 +171,7 @@ + + void COutArchive::WriteCentralHeader(const CItem &item) + { ++ char *rccrec; + bool isUnPack64 = item.UnPackSize >= 0xFFFFFFFF; + bool isPack64 = item.PackSize >= 0xFFFFFFFF; + bool isPosition64 = item.LocalHeaderPosition >= 0xFFFFFFFF; +@@ -181,6 +199,13 @@ + WriteUInt16(item.InternalAttributes); + WriteUInt32(item.ExternalAttributes); + WriteUInt32(isPosition64 ? 0xFFFFFFFF: (UInt32)item.LocalHeaderPosition); ++ ++ rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) { ++ printf("C: %u, %s.\n", item.Name.Length(), rccrec); ++ WriteBytes(rccrec, strlen(rccrec)); ++ free(rccrec); ++ } else + WriteBytes((const char *)item.Name, item.Name.Length()); + if (isZip64) + { +diff -dPNur p7zip_4.65/CPP/7zip/Archive/Zip/ZipOut.h p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipOut.h +--- p7zip_4.65/CPP/7zip/Archive/Zip/ZipOut.h 2008-08-14 11:11:13.000000000 +0200 ++++ p7zip_4.65-new/CPP/7zip/Archive/Zip/ZipOut.h 2009-06-14 02:44:19.000000000 +0200 +@@ -49,6 +49,11 @@ + void CreateStreamForCompressing(IOutStream **outStream); + void CreateStreamForCopying(ISequentialOutStream **outStream); + void SeekToPackedDataPosition(); ++ ++ void *rccctx; ++ COutArchive(); ++ ~COutArchive(); ++ + }; + + }} +diff -dPNur p7zip_4.65/CPP/7zip/Bundles/Alone/makefile p7zip_4.65-new/CPP/7zip/Bundles/Alone/makefile +--- p7zip_4.65/CPP/7zip/Bundles/Alone/makefile 2009-02-07 19:39:04.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Bundles/Alone/makefile 2009-06-14 02:44:19.000000000 +0200 +@@ -250,6 +250,7 @@ + Sha256.o + + OBJS=\ ++rccrecode.o \ + myGetTickCount.o \ + wine_date_and_time.o \ + myAddExeFlag.o \ +diff -dPNur p7zip_4.65/CPP/7zip/Bundles/Alone/makefile.list p7zip_4.65-new/CPP/7zip/Bundles/Alone/makefile.list +--- p7zip_4.65/CPP/7zip/Bundles/Alone/makefile.list 2009-02-09 21:04:57.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Bundles/Alone/makefile.list 2009-06-14 02:51:45.000000000 +0200 +@@ -204,6 +204,7 @@ + ../../Crypto/ZipStrong.cpp + + SRCS_C=\ ++ ../../../../C/rccrecode.c \ + ../../../../C/Bra.c \ + ../../../../C/Bra86.c \ + ../../../../C/BraIA64.c \ +diff -dPNur p7zip_4.65/CPP/7zip/Bundles/Format7zFree/makefile p7zip_4.65-new/CPP/7zip/Bundles/Format7zFree/makefile +--- p7zip_4.65/CPP/7zip/Bundles/Format7zFree/makefile 2009-02-09 21:47:24.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Bundles/Format7zFree/makefile 2009-06-14 03:00:06.000000000 +0200 +@@ -296,6 +296,7 @@ + Sha256.o \ + + OBJS = \ ++ rccrecode.o \ + wine_date_and_time.o \ + myGetTickCount.o \ + $(COMMON_OBJS) \ +diff -dPNur p7zip_4.65/CPP/7zip/Bundles/Format7zFree/makefile.list p7zip_4.65-new/CPP/7zip/Bundles/Format7zFree/makefile.list +--- p7zip_4.65/CPP/7zip/Bundles/Format7zFree/makefile.list 2009-02-09 21:04:32.000000000 +0100 ++++ p7zip_4.65-new/CPP/7zip/Bundles/Format7zFree/makefile.list 2009-06-14 03:00:39.000000000 +0200 +@@ -235,6 +235,7 @@ + ../../Crypto/ZipStrong.cpp + + SRCS_C=\ ++ ../../../../C/rccrecode.c \ + ../../../../C/Bra.c \ + ../../../../C/Bra86.c \ + ../../../../C/BraIA64.c \ +diff -dPNur p7zip_4.65/makefile.machine p7zip_4.65-new/makefile.machine +--- p7zip_4.65/makefile.machine 2009-02-14 18:19:09.000000000 +0100 ++++ p7zip_4.65-new/makefile.machine 2009-06-14 02:44:19.000000000 +0200 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip_4.65/makefile.rules p7zip_4.65-new/makefile.rules +--- p7zip_4.65/makefile.rules 2009-02-09 21:03:16.000000000 +0100 ++++ p7zip_4.65-new/makefile.rules 2009-06-14 02:52:48.000000000 +0200 +@@ -558,3 +558,5 @@ + 7zCrcT8.o : ../../../../C/7zCrcT8.c + $(CC) $(CFLAGS) ../../../../C/7zCrcT8.c + ++rccrecode.o : ../../../../C/rccrecode.c ++ $(CC) $(CFLAGS) ../../../../C/rccrecode.c diff --git a/patches/p7zip/p7zip_9.04-ds-rusxmms-full.patch b/patches/p7zip/p7zip_9.04-ds-rusxmms-full.patch new file mode 100644 index 0000000..d44a16f --- /dev/null +++ b/patches/p7zip/p7zip_9.04-ds-rusxmms-full.patch @@ -0,0 +1,414 @@ +diff -dPNur p7zip-9.04~dfsg.1/C/rccrecode.c p7zip-9.04~dfsg.1-ds/C/rccrecode.c +--- p7zip-9.04~dfsg.1/C/rccrecode.c 1970-01-01 03:00:00.000000000 +0300 ++++ p7zip-9.04~dfsg.1-ds/C/rccrecode.c 2009-10-28 03:29:23.000000000 +0300 +@@ -0,0 +1,71 @@ ++#include <pthread.h> ++#include <librcc.h> ++ ++static rcc_class_default_charset default_oem[] = { ++ { "ru", "IBM866" }, ++ { NULL, NULL } ++}; ++ ++static rcc_class_default_charset default_iso[] = { ++ { "ru", "CP1251" }, ++ { NULL, NULL } ++}; ++ ++#define ARC_CLASS 0 ++#define OUT_CLASS 1 ++#define ARCOUT_CLASS 0 ++static rcc_class classes[] = { ++ { "oem", RCC_CLASS_STANDARD, NULL, default_oem, "OEM Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, "Output", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int initialized = 0; ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void *rcc_init() { ++ rcc_context ctx; ++ ++ pthread_mutex_lock(&mutex); ++ if (!initialized) { ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "zip"); ++ rccInitDb4(NULL, NULL, 0); ++ } ++ initialized++; ++ pthread_mutex_unlock(&mutex); ++ ++ ctx = rccCreateContext(NULL, 0, 0, classes, 0); ++ if (ctx) rccInitDb4(ctx, NULL, 0); ++ if (ctx) rccLoad(ctx, "zip"); ++ ++ return ctx; ++} ++ ++ ++void rcc_free(void *ctx) { ++ if (ctx) rccFreeContext((rcc_context)ctx); ++ ++ pthread_mutex_lock(&mutex); ++ if (initialized == 1) rccFree(); ++ initialized--; ++ pthread_mutex_unlock(&mutex); ++} ++ ++ ++char *rcc_read(void *ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, ARC_CLASS, OUT_CLASS, string, size, NULL); ++} ++ ++char *rcc_write(rcc_context ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, OUT_CLASS, ARCOUT_CLASS, string, size, NULL); ++} +diff -dPNur p7zip-9.04~dfsg.1/C/rccrecode.h p7zip-9.04~dfsg.1-ds/C/rccrecode.h +--- p7zip-9.04~dfsg.1/C/rccrecode.h 1970-01-01 03:00:00.000000000 +0300 ++++ p7zip-9.04~dfsg.1-ds/C/rccrecode.h 2009-10-28 03:29:23.000000000 +0300 +@@ -0,0 +1,17 @@ ++#ifndef _RCC_RECODE_H ++#define _RCC_RECODE_H ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++ void *rcc_init(); ++ void rcc_free(void *ctx); ++ char *rcc_read(void *ctx, const char *string, size_t size); ++ char *rcc_write(void *ctx, const char *string, size_t size); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++#endif /* _RCC_RECODE_H */ +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipIn.cpp p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipIn.cpp +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipIn.cpp 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipIn.cpp 2009-10-28 03:49:06.000000000 +0300 +@@ -9,6 +9,8 @@ + #include "../../Common/LimitedStreams.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + #include "ZipIn.h" + + #define Get16(p) GetUi16(p) +@@ -17,7 +19,17 @@ + + namespace NArchive { + namespace NZip { +- ++ ++CInArchive::CInArchive() ++{ ++ rccctx = rcc_init(); ++} ++ ++CInArchive::~CInArchive() ++{ ++ rcc_free(rccctx); ++} ++ + HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) + { + _inBufMode = false; +@@ -200,12 +212,20 @@ + + void CInArchive::ReadFileName(UInt32 nameSize, AString &dest) + { ++ char *rccrec; ++ + if (nameSize == 0) + dest.Empty(); + char *p = dest.GetBuffer((int)nameSize); + SafeReadBytes(p, nameSize); + p[nameSize] = 0; + dest.ReleaseBuffer(); ++ ++ rccrec = rcc_read(rccctx, (LPCSTR)dest, 0); ++ if (rccrec) { ++ dest = rccrec; ++ free(rccrec); ++ } + } + + void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipIn.h p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipIn.h +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipIn.h 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipIn.h 2009-10-28 03:29:23.000000000 +0300 +@@ -114,6 +114,10 @@ + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); + IInStream* CreateStream(); + ++ void *rccctx; ++ CInArchive(); ++ ~CInArchive(); ++ + bool IsOpen() const { return m_Stream != NULL; } + }; + +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipOut.h p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipOut.h +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipOut.h 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipOut.h 2009-10-28 05:49:05.000000000 +0300 +@@ -49,6 +49,11 @@ + void CreateStreamForCompressing(IOutStream **outStream); + void CreateStreamForCopying(ISequentialOutStream **outStream); + void SeekToPackedDataPosition(); ++ ++ void *rccctx; ++ COutArchive(); ++ ~COutArchive(); ++ void Recode(CItem &item); + }; + + }} +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipUpdate.cpp p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipUpdate.cpp +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2009-10-28 05:48:04.000000000 +0300 +@@ -87,6 +87,7 @@ + item.NtfsATime = ui.NtfsATime; + item.NtfsCTime = ui.NtfsCTime; + item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; ++ archive.Recode(item); + } + else + isDir = item.IsDir(); +@@ -359,9 +360,11 @@ + item.NtfsCTime = ui.NtfsCTime; + item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; + ++ archive.Recode(item); ++ + item.CentralExtra.RemoveUnknownSubBlocks(); + item.LocalExtra.RemoveUnknownSubBlocks(); +- ++ + archive.PrepareWriteCompressedData2((UInt16)item.Name.Length(), item.UnPackSize, item.PackSize, item.LocalExtra.HasWzAesField()); + item.LocalHeaderPosition = archive.GetCurrentPosition(); + archive.SeekToPackedDataPosition(); +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Alone/makefile p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Alone/makefile +--- p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Alone/makefile 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Alone/makefile 2009-10-28 03:29:24.000000000 +0300 +@@ -244,6 +244,7 @@ + + + OBJS=\ ++rccrecode.o \ + myGetTickCount.o \ + wine_date_and_time.o \ + myAddExeFlag.o \ +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Alone/makefile.list p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Alone/makefile.list +--- p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Alone/makefile.list 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Alone/makefile.list 2009-10-28 03:40:17.000000000 +0300 +@@ -192,6 +192,7 @@ + ../../Crypto/ZipStrong.cpp + + SRCS_C=\ ++ ../../../../C/rccrecode.c \ + ../../../../C/Aes.c \ + ../../../../C/7zStream.c \ + ../../../../C/Bra.c \ +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Format7zFree/makefile p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Format7zFree/makefile +--- p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Format7zFree/makefile 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Format7zFree/makefile 2009-10-28 03:29:24.000000000 +0300 +@@ -284,6 +284,7 @@ + + + OBJS = \ ++ rccrecode.o \ + wine_date_and_time.o \ + myGetTickCount.o \ + $(COMMON_OBJS) \ +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Format7zFree/makefile.list p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Format7zFree/makefile.list +--- p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Format7zFree/makefile.list 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Format7zFree/makefile.list 2009-10-28 03:34:02.000000000 +0300 +@@ -218,6 +218,7 @@ + ../../Crypto/ZipStrong.cpp + + SRCS_C=\ ++ ../../../../C/rccrecode.c \ + ../../../../C/7zBuf2.c \ + ../../../../C/7zStream.c \ + ../../../../C/Aes.c \ +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_amd64 p7zip-9.04~dfsg.1-ds/makefile.linux_amd64 +--- p7zip-9.04~dfsg.1/makefile.linux_amd64 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_amd64 2009-10-28 03:54:47.000000000 +0300 +@@ -12,7 +12,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_amd64_asm p7zip-9.04~dfsg.1-ds/makefile.linux_amd64_asm +--- p7zip-9.04~dfsg.1/makefile.linux_amd64_asm 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_amd64_asm 2009-10-28 03:54:47.000000000 +0300 +@@ -13,7 +13,7 @@ + LINK_SHARED=-fPIC -shared + ASM=yasm -f elf -m amd64 + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x64 +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_amd64_asm_icc p7zip-9.04~dfsg.1-ds/makefile.linux_amd64_asm_icc +--- p7zip-9.04~dfsg.1/makefile.linux_amd64_asm_icc 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_amd64_asm_icc 2009-10-28 03:54:47.000000000 +0300 +@@ -16,7 +16,7 @@ + LINK_SHARED=-fPIC -shared + ASM=yasm -f elf -m amd64 + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x64 +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_gcc_2.95_no_need_for_libstdc p7zip-9.04~dfsg.1-ds/makefile.linux_gcc_2.95_no_need_for_libstdc +--- p7zip-9.04~dfsg.1/makefile.linux_gcc_2.95_no_need_for_libstdc 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_gcc_2.95_no_need_for_libstdc 2009-10-28 03:54:47.000000000 +0300 +@@ -11,7 +11,7 @@ + LINK_SHARED=-shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_s390x p7zip-9.04~dfsg.1-ds/makefile.linux_s390x +--- p7zip-9.04~dfsg.1/makefile.linux_s390x 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_s390x 2009-10-28 03:54:47.000000000 +0300 +@@ -15,7 +15,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_x86_asm_gcc_4.X p7zip-9.04~dfsg.1-ds/makefile.linux_x86_asm_gcc_4.X +--- p7zip-9.04~dfsg.1/makefile.linux_x86_asm_gcc_4.X 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_x86_asm_gcc_4.X 2009-10-28 03:54:47.000000000 +0300 +@@ -15,7 +15,7 @@ + LINK_SHARED=-fPIC -shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_x86_asm_gcc_4.X_fltk p7zip-9.04~dfsg.1-ds/makefile.linux_x86_asm_gcc_4.X_fltk +--- p7zip-9.04~dfsg.1/makefile.linux_x86_asm_gcc_4.X_fltk 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_x86_asm_gcc_4.X_fltk 2009-10-28 03:54:47.000000000 +0300 +@@ -15,7 +15,7 @@ + LINK_SHARED=-fPIC -shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread `fltk-config --ldflags` ++LOCAL_LIBS=-lpthread -lrcc `fltk-config --ldflags` + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_x86_asm_icc p7zip-9.04~dfsg.1-ds/makefile.linux_x86_asm_icc +--- p7zip-9.04~dfsg.1/makefile.linux_x86_asm_icc 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_x86_asm_icc 2009-10-28 03:54:47.000000000 +0300 +@@ -16,7 +16,7 @@ + LINK_SHARED=-fPIC -shared + ASM=nasm -f elf + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + CPU=x86 +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_x86_ppc_alpha p7zip-9.04~dfsg.1-ds/makefile.linux_x86_ppc_alpha +--- p7zip-9.04~dfsg.1/makefile.linux_x86_ppc_alpha 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_x86_ppc_alpha 2009-10-28 03:54:47.000000000 +0300 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip-9.04~dfsg.1/makefile.linux_x86_ppc_alpha_gcc_4.X p7zip-9.04~dfsg.1-ds/makefile.linux_x86_ppc_alpha_gcc_4.X +--- p7zip-9.04~dfsg.1/makefile.linux_x86_ppc_alpha_gcc_4.X 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.linux_x86_ppc_alpha_gcc_4.X 2009-10-28 03:54:47.000000000 +0300 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip-9.04~dfsg.1/makefile.machine p7zip-9.04~dfsg.1-ds/makefile.machine +--- p7zip-9.04~dfsg.1/makefile.machine 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.machine 2009-10-28 03:29:24.000000000 +0300 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip-9.04~dfsg.1/makefile.rules p7zip-9.04~dfsg.1-ds/makefile.rules +--- p7zip-9.04~dfsg.1/makefile.rules 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.rules 2009-10-28 03:29:24.000000000 +0300 +@@ -586,3 +586,5 @@ + 7zCrcT8.o : ../../../../C/7zCrcT8.c + $(CC) $(CFLAGS) ../../../../C/7zCrcT8.c + ++rccrecode.o : ../../../../C/rccrecode.c ++ $(CC) $(CFLAGS) ../../../../C/rccrecode.c +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipOut.cpp p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipOut.cpp +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipOut.cpp 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipOut.cpp 2009-10-28 05:49:01.000000000 +0300 +@@ -7,9 +7,24 @@ + #include "../../Common/OffsetStream.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { + ++COutArchive::COutArchive() { ++ rccctx = rcc_init(); ++} ++ ++COutArchive::~COutArchive() { ++ rcc_free(rccctx); ++} ++ ++void COutArchive::Recode(CItem &item) { ++ char *rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) item.Name = rccrec; ++} ++ + void COutArchive::Create(IOutStream *outStream) + { + if (!m_OutBuffer.Create(1 << 16)) diff --git a/patches/p7zip/p7zip_9.04-ds-rusxmms.patch b/patches/p7zip/p7zip_9.04-ds-rusxmms.patch new file mode 100644 index 0000000..7678241 --- /dev/null +++ b/patches/p7zip/p7zip_9.04-ds-rusxmms.patch @@ -0,0 +1,294 @@ +diff -dPNur p7zip-9.04~dfsg.1/C/rccrecode.c p7zip-9.04~dfsg.1-ds/C/rccrecode.c +--- p7zip-9.04~dfsg.1/C/rccrecode.c 1970-01-01 03:00:00.000000000 +0300 ++++ p7zip-9.04~dfsg.1-ds/C/rccrecode.c 2009-10-28 03:29:23.000000000 +0300 +@@ -0,0 +1,71 @@ ++#include <pthread.h> ++#include <librcc.h> ++ ++static rcc_class_default_charset default_oem[] = { ++ { "ru", "IBM866" }, ++ { NULL, NULL } ++}; ++ ++static rcc_class_default_charset default_iso[] = { ++ { "ru", "CP1251" }, ++ { NULL, NULL } ++}; ++ ++#define ARC_CLASS 0 ++#define OUT_CLASS 1 ++#define ARCOUT_CLASS 0 ++static rcc_class classes[] = { ++ { "oem", RCC_CLASS_STANDARD, NULL, default_oem, "OEM Encoding", 0 }, ++ { "out", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, "Output", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int initialized = 0; ++static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void *rcc_init() { ++ rcc_context ctx; ++ ++ pthread_mutex_lock(&mutex); ++ if (!initialized) { ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "zip"); ++ rccInitDb4(NULL, NULL, 0); ++ } ++ initialized++; ++ pthread_mutex_unlock(&mutex); ++ ++ ctx = rccCreateContext(NULL, 0, 0, classes, 0); ++ if (ctx) rccInitDb4(ctx, NULL, 0); ++ if (ctx) rccLoad(ctx, "zip"); ++ ++ return ctx; ++} ++ ++ ++void rcc_free(void *ctx) { ++ if (ctx) rccFreeContext((rcc_context)ctx); ++ ++ pthread_mutex_lock(&mutex); ++ if (initialized == 1) rccFree(); ++ initialized--; ++ pthread_mutex_unlock(&mutex); ++} ++ ++ ++char *rcc_read(void *ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, ARC_CLASS, OUT_CLASS, string, size, NULL); ++} ++ ++char *rcc_write(rcc_context ctx, const char *string, size_t size) { ++ if (!initialized) { ++ rcc_init(); ++ if (!initialized) return NULL; ++ } ++ return rccSizedRecode((rcc_context)ctx, OUT_CLASS, ARCOUT_CLASS, string, size, NULL); ++} +diff -dPNur p7zip-9.04~dfsg.1/C/rccrecode.h p7zip-9.04~dfsg.1-ds/C/rccrecode.h +--- p7zip-9.04~dfsg.1/C/rccrecode.h 1970-01-01 03:00:00.000000000 +0300 ++++ p7zip-9.04~dfsg.1-ds/C/rccrecode.h 2009-10-28 03:29:23.000000000 +0300 +@@ -0,0 +1,17 @@ ++#ifndef _RCC_RECODE_H ++#define _RCC_RECODE_H ++ ++# ifdef __cplusplus ++extern "C" { ++# endif ++ ++ void *rcc_init(); ++ void rcc_free(void *ctx); ++ char *rcc_read(void *ctx, const char *string, size_t size); ++ char *rcc_write(void *ctx, const char *string, size_t size); ++ ++# ifdef __cplusplus ++} ++# endif ++ ++#endif /* _RCC_RECODE_H */ +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipIn.cpp p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipIn.cpp +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipIn.cpp 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipIn.cpp 2009-10-28 03:49:06.000000000 +0300 +@@ -9,6 +9,8 @@ + #include "../../Common/LimitedStreams.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + #include "ZipIn.h" + + #define Get16(p) GetUi16(p) +@@ -17,7 +19,17 @@ + + namespace NArchive { + namespace NZip { +- ++ ++CInArchive::CInArchive() ++{ ++ rccctx = rcc_init(); ++} ++ ++CInArchive::~CInArchive() ++{ ++ rcc_free(rccctx); ++} ++ + HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit) + { + _inBufMode = false; +@@ -200,12 +212,20 @@ + + void CInArchive::ReadFileName(UInt32 nameSize, AString &dest) + { ++ char *rccrec; ++ + if (nameSize == 0) + dest.Empty(); + char *p = dest.GetBuffer((int)nameSize); + SafeReadBytes(p, nameSize); + p[nameSize] = 0; + dest.ReleaseBuffer(); ++ ++ rccrec = rcc_read(rccctx, (LPCSTR)dest, 0); ++ if (rccrec) { ++ dest = rccrec; ++ free(rccrec); ++ } + } + + void CInArchive::GetArchiveInfo(CInArchiveInfo &archiveInfo) const +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipIn.h p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipIn.h +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipIn.h 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipIn.h 2009-10-28 03:29:23.000000000 +0300 +@@ -114,6 +114,10 @@ + ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); + IInStream* CreateStream(); + ++ void *rccctx; ++ CInArchive(); ++ ~CInArchive(); ++ + bool IsOpen() const { return m_Stream != NULL; } + }; + +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipOut.h p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipOut.h +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipOut.h 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipOut.h 2009-10-28 05:49:05.000000000 +0300 +@@ -49,6 +49,11 @@ + void CreateStreamForCompressing(IOutStream **outStream); + void CreateStreamForCopying(ISequentialOutStream **outStream); + void SeekToPackedDataPosition(); ++ ++ void *rccctx; ++ COutArchive(); ++ ~COutArchive(); ++ void Recode(CItem &item); + }; + + }} +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipUpdate.cpp p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipUpdate.cpp +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipUpdate.cpp 2009-10-28 05:48:04.000000000 +0300 +@@ -87,6 +87,7 @@ + item.NtfsATime = ui.NtfsATime; + item.NtfsCTime = ui.NtfsCTime; + item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; ++ archive.Recode(item); + } + else + isDir = item.IsDir(); +@@ -359,9 +360,11 @@ + item.NtfsCTime = ui.NtfsCTime; + item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined; + ++ archive.Recode(item); ++ + item.CentralExtra.RemoveUnknownSubBlocks(); + item.LocalExtra.RemoveUnknownSubBlocks(); +- ++ + archive.PrepareWriteCompressedData2((UInt16)item.Name.Length(), item.UnPackSize, item.PackSize, item.LocalExtra.HasWzAesField()); + item.LocalHeaderPosition = archive.GetCurrentPosition(); + archive.SeekToPackedDataPosition(); +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Alone/makefile p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Alone/makefile +--- p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Alone/makefile 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Alone/makefile 2009-10-28 03:29:24.000000000 +0300 +@@ -244,6 +244,7 @@ + + + OBJS=\ ++rccrecode.o \ + myGetTickCount.o \ + wine_date_and_time.o \ + myAddExeFlag.o \ +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Alone/makefile.list p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Alone/makefile.list +--- p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Alone/makefile.list 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Alone/makefile.list 2009-10-28 03:40:17.000000000 +0300 +@@ -192,6 +192,7 @@ + ../../Crypto/ZipStrong.cpp + + SRCS_C=\ ++ ../../../../C/rccrecode.c \ + ../../../../C/Aes.c \ + ../../../../C/7zStream.c \ + ../../../../C/Bra.c \ +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Format7zFree/makefile p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Format7zFree/makefile +--- p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Format7zFree/makefile 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Format7zFree/makefile 2009-10-28 03:29:24.000000000 +0300 +@@ -284,6 +284,7 @@ + + + OBJS = \ ++ rccrecode.o \ + wine_date_and_time.o \ + myGetTickCount.o \ + $(COMMON_OBJS) \ +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Format7zFree/makefile.list p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Format7zFree/makefile.list +--- p7zip-9.04~dfsg.1/CPP/7zip/Bundles/Format7zFree/makefile.list 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Bundles/Format7zFree/makefile.list 2009-10-28 03:34:02.000000000 +0300 +@@ -218,6 +218,7 @@ + ../../Crypto/ZipStrong.cpp + + SRCS_C=\ ++ ../../../../C/rccrecode.c \ + ../../../../C/7zBuf2.c \ + ../../../../C/7zStream.c \ + ../../../../C/Aes.c \ +diff -dPNur p7zip-9.04~dfsg.1/makefile.machine p7zip-9.04~dfsg.1-ds/makefile.machine +--- p7zip-9.04~dfsg.1/makefile.machine 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.machine 2009-10-28 03:29:24.000000000 +0300 +@@ -14,7 +14,7 @@ + CC_SHARED=-fPIC + LINK_SHARED=-fPIC -shared + +-LOCAL_LIBS=-lpthread ++LOCAL_LIBS=-lpthread -lrcc + LOCAL_LIBS_DLL=$(LOCAL_LIBS) -ldl + + OBJ_CRC32=$(OBJ_CRC32_C) +diff -dPNur p7zip-9.04~dfsg.1/makefile.rules p7zip-9.04~dfsg.1-ds/makefile.rules +--- p7zip-9.04~dfsg.1/makefile.rules 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/makefile.rules 2009-10-28 03:29:24.000000000 +0300 +@@ -586,3 +586,5 @@ + 7zCrcT8.o : ../../../../C/7zCrcT8.c + $(CC) $(CFLAGS) ../../../../C/7zCrcT8.c + ++rccrecode.o : ../../../../C/rccrecode.c ++ $(CC) $(CFLAGS) ../../../../C/rccrecode.c +diff -dPNur p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipOut.cpp p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipOut.cpp +--- p7zip-9.04~dfsg.1/CPP/7zip/Archive/Zip/ZipOut.cpp 2009-06-27 18:18:14.000000000 +0400 ++++ p7zip-9.04~dfsg.1-ds/CPP/7zip/Archive/Zip/ZipOut.cpp 2009-10-28 05:49:01.000000000 +0300 +@@ -7,9 +7,24 @@ + #include "../../Common/OffsetStream.h" + #include "../../Common/StreamUtils.h" + ++#include "../../../../C/rccrecode.h" ++ + namespace NArchive { + namespace NZip { + ++COutArchive::COutArchive() { ++ rccctx = rcc_init(); ++} ++ ++COutArchive::~COutArchive() { ++ rcc_free(rccctx); ++} ++ ++void COutArchive::Recode(CItem &item) { ++ char *rccrec = rcc_write(rccctx, (const char *)item.Name, item.Name.Length()); ++ if (rccrec) item.Name = rccrec; ++} ++ + void COutArchive::Create(IOutStream *outStream) + { + if (!m_OutBuffer.Create(1 << 16)) diff --git a/patches/taglib/README b/patches/taglib/README new file mode 100644 index 0000000..0d3e78e --- /dev/null +++ b/patches/taglib/README @@ -0,0 +1,36 @@ +taglib-*-ds-rusxmms-enforce.patch will prevent applications from +overloading taglib ID3 v.1 parser/renderer. For instance, kid3 +has it's onw recoder and bypasses RusXMMS unless this patch is +applied. + +If you want to set unicode ID3v.2 titles, please, set in the +LibRCC configuration (xmms.xml) "id3v2" class to point appropriate +unicode encoding. + +1. Some Info Encoding Handling +1.1 Reading encodings + - Unicode ID3 v.2 tags are read as defined by ID3V2 tag, no RusXMMS + is envolved. + - Latin1 ID3 v.2 and ID3 v.1 tags are read using RusXMMS library. + The 'id3' and 'id3v2' classes are used corespondingly. +1.2 Writing ID3 v.1 encodings + - ID3 v.1 tag is written using RusXMMS library. The 'id3' class + selects output encoding. +1.3 Writting ID3 v.2 encodings + - ID3 v.2 tag output encodings is selected with help of 'id3v2' class of + RusXMMS. + - If unicode encoding is set (UTF-8, UTF-16, UTF-16BE, UTF-16LE) + the tag is written using selected encoding (independent of original one). + - Otherwise, original unicode encodings are kept. + - If original encoding is also non-unicode, than the tag is stored + in 'id3v2' class encoding. However, it is really a bad idea! Set an + unicode encoding. +2. Recomended class settings + - id3 = CP1251 + - id3v2 = UTF-16 +3. Notes + - TagLib supports UTF-16LE encodings within ID3 v.2 tags (described by + number 4). The UTF-16LE is not part of standard and probably added for + compatibility with some nasty Windows applications. RusXMMS will not + allow to write tags in UTF-16LE. +
\ No newline at end of file diff --git a/patches/taglib/taglib-1.10-ds-rusxmms.patch b/patches/taglib/taglib-1.10-ds-rusxmms.patch new file mode 100644 index 0000000..584c237 --- /dev/null +++ b/patches/taglib/taglib-1.10-ds-rusxmms.patch @@ -0,0 +1,1339 @@ +diff -dPNur taglib-1.10/config.h.cmake taglib-1.10-ds/config.h.cmake +--- taglib-1.10/config.h.cmake 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/config.h.cmake 2015-11-26 23:03:07.058061207 +0100 +@@ -25,4 +25,7 @@ + /* Indicates whether debug messages are shown even in release mode */ + #cmakedefine TRACE_IN_RELEASE 1 + ++/* Defined if you have LibRCC from RusXMMS project */ ++#cmakedefine HAVE_LIBRCC 1 ++ + #cmakedefine TESTS_DIR "@TESTS_DIR@" +diff -dPNur taglib-1.10/ConfigureChecks.cmake taglib-1.10-ds/ConfigureChecks.cmake +--- taglib-1.10/ConfigureChecks.cmake 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/ConfigureChecks.cmake 2015-11-26 23:03:07.058061207 +0100 +@@ -201,6 +201,8 @@ + endif() + endif() + ++SET(HAVE_LIBRCC 1) ++ + if(BUILD_TESTS) + find_package(CppUnit) + if(NOT CppUnit_FOUND) +diff -dPNur taglib-1.10/examples/tagreader_c.c taglib-1.10-ds/examples/tagreader_c.c +--- taglib-1.10/examples/tagreader_c.c 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/examples/tagreader_c.c 2015-11-26 23:03:07.059061228 +0100 +@@ -38,7 +38,7 @@ + TagLib_Tag *tag; + const TagLib_AudioProperties *properties; + +- taglib_set_strings_unicode(FALSE); ++ //taglib_set_strings_unicode(FALSE); + + for(i = 1; i < argc; i++) { + printf("******************** \"%s\" ********************\n", argv[i]); +diff -dPNur taglib-1.10/examples/tagwriter.cpp taglib-1.10-ds/examples/tagwriter.cpp +--- taglib-1.10/examples/tagwriter.cpp 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/examples/tagwriter.cpp 2015-11-26 23:03:07.059061228 +0100 +@@ -115,7 +115,7 @@ + if(isArgument(argv[i]) && i + 1 < argc && !isArgument(argv[i + 1])) { + + char field = argv[i][1]; +- TagLib::String value = argv[i + 1]; ++ TagLib::String value(argv[i + 1], TagLib::String::Locale); + + TagLib::List<TagLib::FileRef>::ConstIterator it; + for(it = fileList.begin(); it != fileList.end(); ++it) { +diff -dPNur taglib-1.10/taglib/CMakeLists.txt taglib-1.10-ds/taglib/CMakeLists.txt +--- taglib-1.10/taglib/CMakeLists.txt 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/taglib/CMakeLists.txt 2015-11-26 23:03:07.059061228 +0100 +@@ -38,6 +38,7 @@ + audioproperties.h + taglib_export.h + ${CMAKE_CURRENT_BINARY_DIR}/../taglib_config.h ++ toolkit/rccpatch.h + toolkit/taglib.h + toolkit/tstring.h + toolkit/tlist.h +@@ -291,6 +292,7 @@ + ) + + set(toolkit_SRCS ++ toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -337,7 +339,7 @@ + add_library(tag ${tag_LIB_SRCS} ${tag_HDRS}) + + if(ZLIB_FOUND) +- target_link_libraries(tag ${ZLIB_LIBRARIES}) ++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES}) + endif() + + set_target_properties(tag PROPERTIES +diff -dPNur taglib-1.10/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.10-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.10/taglib/mpeg/id3v1/id3v1tag.cpp 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2015-11-26 23:03:07.059061228 +0100 +@@ -64,17 +64,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { + if(!s.isLatin1()) + { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); + } + +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -257,7 +258,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.10/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.10-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.10/taglib/mpeg/id3v2/frames/commentsframe.cpp 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2015-11-26 23:03:07.059061228 +0100 +@@ -150,10 +150,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -173,11 +173,13 @@ + ByteVector v; + + String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); + + encoding = checkTextEncoding(d->description, encoding); + encoding = checkTextEncoding(d->text, encoding); + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-1.10/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.10-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.10/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2015-11-26 23:03:07.059061228 +0100 +@@ -187,12 +187,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -223,11 +223,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkTextEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-1.10/taglib/mpeg/id3v2/id3v2frame.cpp taglib-1.10-ds/taglib/mpeg/id3v2/id3v2frame.cpp +--- taglib-1.10/taglib/mpeg/id3v2/id3v2frame.cpp 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/taglib/mpeg/id3v2/id3v2frame.cpp 2015-11-26 23:03:07.060061249 +0100 +@@ -339,7 +339,7 @@ + if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4) + return String::UTF16; + +- if(encoding != String::Latin1) ++ if((encoding != String::Latin1)&&(encoding != String::Latin1ID3V2)) + return encoding; + + for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) { +diff -dPNur taglib-1.10/taglib/toolkit/rccpatch.cpp taglib-1.10-ds/taglib/toolkit/rccpatch.cpp +--- taglib-1.10/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.10-ds/taglib/toolkit/rccpatch.cpp 2015-11-26 23:03:07.060061249 +0100 +@@ -0,0 +1,237 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++//#define RCC_DEBUG ++ ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# ifdef RCC_DEBUG ++# include <stdio.h> ++# endif /* RCC_DEBUG */ ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccTaglibPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccTaglibPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccTaglibPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccTaglibPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccTaglibPatchInit(); ++ if (rcc_initialized) atexit(rccTaglibPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" Output: %s - %s\n", s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else v.setData("", 0); ++ //v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" OutputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else v.setData("", 0); ++ //v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" Input: %s - %s\n", s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" InputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ if (res) v.setData(res, rlen + 1); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::String::Type rccTaglibPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccTaglibPatchTryInit(); ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccTaglibPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccTaglibPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } else { ++ // Error or no-language configured: If Latin1ID3V2 is returned we normally will use the default unicode encoding unless Latin1 is selected by taglib ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.10/taglib/toolkit/rccpatch.h taglib-1.10-ds/taglib/toolkit/rccpatch.h +--- taglib-1.10/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.10-ds/taglib/toolkit/rccpatch.h 2015-11-26 23:03:07.060061249 +0100 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccTaglibPatchFree(); ++void rccTaglibPatchInit(); ++void rccTaglibPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccTaglibPatchGetLocaleType(); ++TagLib::String::Type rccTaglibPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.10/taglib/toolkit/tstring.cpp taglib-1.10-ds/taglib/toolkit/tstring.cpp +--- taglib-1.10/taglib/toolkit/tstring.cpp 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/taglib/toolkit/tstring.cpp 2015-11-26 23:10:01.286853654 +0100 +@@ -29,6 +29,7 @@ + #include <config.h> + #endif + ++#include "rccpatch.h" + #include "tstring.h" + #include "tdebug.h" + #include "tstringlist.h" +@@ -167,8 +168,11 @@ + String::String(const std::string &s, Type t) + : d(new StringPrivate()) + { +- if(t == Latin1) +- copyFromLatin1(s.c_str(), s.length()); ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) ++ copyFromLatin1(&s[0], s.length(), true, t); + else if(t == String::UTF8) + copyFromUTF8(s.c_str(), s.length()); + else { +@@ -215,8 +219,11 @@ + String::String(const char *s, Type t) + : d(new StringPrivate()) + { +- if(t == Latin1) +- copyFromLatin1(s, ::strlen(s)); ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) ++ copyFromLatin1(s, ::strlen(s), true, t); + else if(t == String::UTF8) + copyFromUTF8(s, ::strlen(s)); + else { +@@ -237,7 +244,10 @@ + String::String(char c, Type t) + : d(new StringPrivate(1, static_cast<uchar>(c))) + { +- if(t != Latin1 && t != UTF8) { ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t != Latin1 && t != Latin1ID3 && t != Latin1ID3V2 && t != UTF8) { + debug("String::String() -- char should not contain UTF16."); + } + } +@@ -248,8 +258,11 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1) +- copyFromLatin1(v.data(), v.size()); ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) ++ copyFromLatin1(v.data(), v.size(), true, t); + else if(t == UTF8) + copyFromUTF8(v.data(), v.size()); + else +@@ -396,8 +409,38 @@ + + ByteVector String::data(Type t) const + { +- switch(t) +- { ++ ByteVector v; ++ ++ if (t == Locale) { ++ // The source is either Unicode or real Latin1 (if rcc is bypassed) ++ std::string s = to8Bit(true); ++ ++ // In case of UTF8 locale, this probably will return NULL (no recoding needed), but we will take UTF8 path in the next swtich ++ v = rccTaglibPatchRecodeOutput(s); ++ if (v.size()) return v; ++ ++ t = rccTaglibPatchGetLocaleType(); ++ } ++ ++ switch(t) { ++ case Latin1ID3: ++ case Latin1ID3V2: ++ { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccTaglibPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeOutputID3(s, true); ++ if (v.size()) ++ return v; ++ ++ // we don't know if we got NULL because rcc is disabled (error) or UTF8 output is required ++ if ((t == Latin1ID3V2)&&(rccTaglibPatchGetID3Type() == UTF8)) { ++ v.setData(s.c_str(), s.length()); ++ } else { ++ for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) ++ v.append(char(*it)); ++ } ++ return v; ++ } + case Latin1: + { + ByteVector v(size(), 0); +@@ -738,12 +781,30 @@ + // private members + //////////////////////////////////////////////////////////////////////////////// + +-void String::copyFromLatin1(const char *s, size_t length) ++void String::copyFromLatin1(const char *s, size_t length, bool prepare, Type t) + { + d->data.resize(length); + + for(size_t i = 0; i < length; ++i) + d->data[i] = static_cast<uchar>(s[i]); ++ ++ // librcc conversation ++ if (prepare) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccTaglibPatchRecodeInputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeInputID3(s, true); ++ else /* Latin1 converted from Locale */ v = rccTaglibPatchRecodeInput(s); ++ ++ if (v.size()) { ++ copyFromUTF8(v.data(), v.size()); ++ } else { ++ // We don't know if we got UTF-8 encoded string or either rcc is disable or something is failed, ++ // since standard applications are really expecting here Latin1, it is safe to just check if we have violations of UTF8 ++ //if (Unicode::isLegalUTF8(s)) t = UTF8; ++ } ++ } + } + + void String::copyFromUTF8(const char *s, size_t length) +@@ -859,7 +920,33 @@ + + std::ostream &operator<<(std::ostream &s, const TagLib::String &str) + { +- s << str.to8Bit(); ++ TagLib::ByteVector bv = str.data(TagLib::String::Locale); ++ s << bv; + return s; + } + ++TagLib::String::Type TagLib::String::ID3Type(int i) ++{ ++ if(i == Latin1) ++ return Latin1ID3V2; ++ return Type(i); ++}; ++ ++TagLib::String::Type TagLib::String::ID3WType(Type type) ++{ ++ Type rcc_type = rccTaglibPatchGetID3Type(); ++ if((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)||(rcc_type == Latin1)) { ++ if(type == Latin1) return ++ rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++TagLib::String::Type TagLib::String::ID3RealType(Type type) ++{ ++ if((type == Latin1ID3) || (type == Latin1ID3V2)) ++ return Latin1; ++ return type; ++} +diff -dPNur taglib-1.10/taglib/toolkit/tstring.h taglib-1.10-ds/taglib/toolkit/tstring.h +--- taglib-1.10/taglib/toolkit/tstring.h 2015-11-11 22:41:59.000000000 +0100 ++++ taglib-1.10-ds/taglib/toolkit/tstring.h 2015-11-26 23:03:07.061061271 +0100 +@@ -96,6 +96,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3v2 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -117,6 +129,10 @@ + */ + UTF16LE = 4 + }; ++ ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); + + /*! + * Constructs an empty String. +@@ -519,7 +535,7 @@ + * Converts a \e Latin-1 string into \e UTF-16(without BOM/CPU byte order) + * and copies it to the internal buffer. + */ +- void copyFromLatin1(const char *s, size_t length); ++ void copyFromLatin1(const char *s, size_t length, bool prepare = false, Type t = Latin1); + + /*! + * Converts a \e UTF-8 string into \e UTF-16(without BOM/CPU byte order) +diff -dPNur taglib-1.10/taglib-1.10-ds-rusxmms.patch taglib-1.10-ds/taglib-1.10-ds-rusxmms.patch +--- taglib-1.10/taglib-1.10-ds-rusxmms.patch 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.10-ds/taglib-1.10-ds-rusxmms.patch 2015-11-14 15:40:37.000000000 +0100 +@@ -0,0 +1,669 @@ ++diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake ++index 88980ea..e4f44d3 100644 ++--- a/ConfigureChecks.cmake +++++ b/ConfigureChecks.cmake ++@@ -201,6 +201,8 @@ if(NOT ZLIB_SOURCE) ++ endif() ++ endif() ++ +++SET(HAVE_LIBRCC 1) +++ ++ if(BUILD_TESTS) ++ find_package(CppUnit) ++ if(NOT CppUnit_FOUND) ++diff --git a/config.h.cmake b/config.h.cmake ++index ee0e67a..2abd49c 100644 ++--- a/config.h.cmake +++++ b/config.h.cmake ++@@ -25,4 +25,7 @@ ++ /* Indicates whether debug messages are shown even in release mode */ ++ #cmakedefine TRACE_IN_RELEASE 1 ++ +++/* Defined if you have LibRCC from RusXMMS project */ +++#cmakedefine HAVE_LIBRCC 1 +++ ++ #cmakedefine TESTS_DIR "@TESTS_DIR@" ++diff --git a/examples/tagreader_c.c b/examples/tagreader_c.c ++index 0436992..e0f17d8 100644 ++--- a/examples/tagreader_c.c +++++ b/examples/tagreader_c.c ++@@ -38,7 +38,7 @@ int main(int argc, char *argv[]) ++ TagLib_Tag *tag; ++ const TagLib_AudioProperties *properties; ++ ++- taglib_set_strings_unicode(FALSE); +++ //taglib_set_strings_unicode(FALSE); ++ ++ for(i = 1; i < argc; i++) { ++ printf("******************** \"%s\" ********************\n", argv[i]); ++diff --git a/examples/tagwriter.cpp b/examples/tagwriter.cpp ++index ed8b0d7..6a7a263 100644 ++--- a/examples/tagwriter.cpp +++++ b/examples/tagwriter.cpp ++@@ -115,7 +115,7 @@ int main(int argc, char *argv[]) ++ if(isArgument(argv[i]) && i + 1 < argc && !isArgument(argv[i + 1])) { ++ ++ char field = argv[i][1]; ++- TagLib::String value = argv[i + 1]; +++ TagLib::String value(argv[i + 1], TagLib::String::Locale); ++ ++ TagLib::List<TagLib::FileRef>::ConstIterator it; ++ for(it = fileList.begin(); it != fileList.end(); ++it) { ++diff --git a/taglib/CMakeLists.txt b/taglib/CMakeLists.txt ++index 73c1a2f..cd7ea22 100644 ++--- a/taglib/CMakeLists.txt +++++ b/taglib/CMakeLists.txt ++@@ -38,6 +38,7 @@ set(tag_HDRS ++ audioproperties.h ++ taglib_export.h ++ ${CMAKE_CURRENT_BINARY_DIR}/../taglib_config.h +++ toolkit/rccpatch.h ++ toolkit/taglib.h ++ toolkit/tstring.h ++ toolkit/tlist.h ++@@ -291,6 +292,7 @@ set(xm_SRCS ++ ) ++ ++ set(toolkit_SRCS +++ toolkit/rccpatch.cpp ++ toolkit/tstring.cpp ++ toolkit/tstringlist.cpp ++ toolkit/tbytevector.cpp ++@@ -337,7 +339,7 @@ set(tag_LIB_SRCS ++ add_library(tag ${tag_LIB_SRCS} ${tag_HDRS}) ++ ++ if(ZLIB_FOUND) ++- target_link_libraries(tag ${ZLIB_LIBRARIES}) +++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES}) ++ endif() ++ ++ set_target_properties(tag PROPERTIES ++diff --git a/taglib/mpeg/id3v1/id3v1tag.cpp b/taglib/mpeg/id3v1/id3v1tag.cpp ++index 9fc8cfd..5352acc 100644 ++--- a/taglib/mpeg/id3v1/id3v1tag.cpp +++++ b/taglib/mpeg/id3v1/id3v1tag.cpp ++@@ -64,17 +64,18 @@ StringHandler::StringHandler() ++ ++ String ID3v1::StringHandler::parse(const ByteVector &data) const ++ { ++- return String(data, String::Latin1).stripWhiteSpace(); +++ return String(data, String::Latin1ID3).stripWhiteSpace(); ++ } ++ ++ ByteVector ID3v1::StringHandler::render(const String &s) const ++ { ++ if(!s.isLatin1()) ++ { +++ if (String::ID3WType(String::Latin1) == String::Latin1) ++ return ByteVector(); ++ } ++ ++- return s.data(String::Latin1); +++ return s.data(String::Latin1ID3); ++ } ++ ++ //////////////////////////////////////////////////////////////////////////////// ++@@ -257,7 +258,7 @@ void ID3v1::Tag::parse(const ByteVector &data) ++ d->track = uchar(data[offset + 29]); ++ } ++ else ++- d->comment = data.mid(offset, 30); +++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); ++ ++ offset += 30; ++ ++diff --git a/taglib/mpeg/id3v2/frames/commentsframe.cpp b/taglib/mpeg/id3v2/frames/commentsframe.cpp ++index deaa9d9..c0aba2b 100644 ++--- a/taglib/mpeg/id3v2/frames/commentsframe.cpp +++++ b/taglib/mpeg/id3v2/frames/commentsframe.cpp ++@@ -150,10 +150,10 @@ void CommentsFrame::parseFields(const ByteVector &data) ++ return; ++ } ++ ++- d->textEncoding = String::Type(data[0]); +++ d->textEncoding = String::ID3Type(data[0]); ++ d->language = data.mid(1, 3); ++ ++- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; +++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; ++ ++ ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); ++ ++@@ -173,11 +173,13 @@ ByteVector CommentsFrame::renderFields() const ++ ByteVector v; ++ ++ String::Type encoding = d->textEncoding; +++ +++ encoding = String::ID3WType(encoding); ++ ++ encoding = checkTextEncoding(d->description, encoding); ++ encoding = checkTextEncoding(d->text, encoding); ++ ++- v.append(char(encoding)); +++ v.append(char(String::ID3RealType(encoding))); ++ v.append(d->language.size() == 3 ? d->language : "XXX"); ++ v.append(d->description.data(encoding)); ++ v.append(textDelimiter(encoding)); ++diff --git a/taglib/mpeg/id3v2/frames/textidentificationframe.cpp b/taglib/mpeg/id3v2/frames/textidentificationframe.cpp ++index b77dd54..a4a7277 100644 ++--- a/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +++++ b/taglib/mpeg/id3v2/frames/textidentificationframe.cpp ++@@ -187,12 +187,12 @@ void TextIdentificationFrame::parseFields(const ByteVector &data) ++ ++ // read the string data type (the first byte of the field data) ++ ++- d->textEncoding = String::Type(data[0]); +++ d->textEncoding = String::ID3Type(data[0]); ++ ++ // split the byte array into chunks based on the string type (two byte delimiter ++ // for unicode encodings) ++ ++- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; +++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; ++ ++ // build a small counter to strip nulls off the end of the field ++ ++@@ -223,11 +223,14 @@ void TextIdentificationFrame::parseFields(const ByteVector &data) ++ ++ ByteVector TextIdentificationFrame::renderFields() const ++ { ++- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding); +++ String::Type encoding = d->textEncoding; +++ +++ encoding = String::ID3WType(encoding); +++ encoding = checkTextEncoding(d->fieldList, encoding); ++ ++ ByteVector v; ++ ++- v.append(char(encoding)); +++ v.append(char(String::ID3RealType(encoding))); ++ ++ for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { ++ ++diff --git a/taglib/mpeg/id3v2/id3v2frame.cpp b/taglib/mpeg/id3v2/id3v2frame.cpp ++index bee5375..fea5ab3 100644 ++--- a/taglib/mpeg/id3v2/id3v2frame.cpp +++++ b/taglib/mpeg/id3v2/id3v2frame.cpp ++@@ -339,7 +339,7 @@ String::Type Frame::checkEncoding(const StringList &fields, String::Type encodin ++ if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4) ++ return String::UTF16; ++ ++- if(encoding != String::Latin1) +++ if((encoding != String::Latin1)&&(encoding != String::Latin1ID3V2)) ++ return encoding; ++ ++ for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) { ++diff --git a/taglib/toolkit/rccpatch.cpp b/taglib/toolkit/rccpatch.cpp ++new file mode 100644 ++index 0000000..af99323 ++--- /dev/null +++++ b/taglib/toolkit/rccpatch.cpp ++@@ -0,0 +1,237 @@ +++#include <stdlib.h> +++ +++#include <string> +++#include "tstring.h" +++#include "tbytevector.h" +++ +++//#define RCC_DEBUG +++ +++ +++#ifndef HAVE_LIBRCC +++# include <config.h> +++#endif +++ +++#ifdef HAVE_LIBRCC +++# ifdef RCC_DEBUG +++# include <stdio.h> +++# endif /* RCC_DEBUG */ +++# include <librcc.h> +++# include <string.h> +++#endif /* HAVE_LIBRCC */ +++ +++ +++#ifdef HAVE_LIBRCC +++# define ID3_CLASS 0 +++# define ID3V2_CLASS 1 +++# define UTF_CLASS 2 +++# define OUT_CLASS 3 +++static rcc_class classes[] = { +++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, +++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, +++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, +++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, +++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } +++}; +++ +++static int rcc_initialized = 0; +++ +++static rcc_context ctx = NULL; +++#endif /* HAVE_LIBRCC */ +++ +++ +++void rccTaglibPatchFree() { +++#ifdef HAVE_LIBRCC +++ if (rcc_initialized) { +++ rccFree(); +++ rcc_initialized = 0; +++ } +++#endif /* HAVE_LIBRCC */ +++} +++ +++void rccTaglibPatchInit() { +++#ifdef HAVE_LIBRCC +++ if (rcc_initialized) return; +++ rccInit(); +++ rccInitDefaultContext(NULL, 0, 0, classes, 0); +++ rccLoad(NULL, "xmms"); +++ rccInitDb4(NULL, NULL, 0); +++ rcc_initialized = 1; +++#endif /* HAVE_LIBRCC */ +++} +++ +++void rccTaglibPatchSetContext(void *newctx) { +++#ifdef HAVE_LIBRCC +++ if (newctx) { +++ ctx = (rcc_context)newctx; +++ rcc_initialized = 1; +++ } +++#endif /* HAVE_LIBRCC */ +++} +++ +++static void rccTaglibPatchTryInit() { +++#ifdef HAVE_LIBRCC +++ if (!rcc_initialized) { +++ rccTaglibPatchInit(); +++ if (rcc_initialized) atexit(rccTaglibPatchFree); +++ } +++#endif /* HAVE_LIBRCC */ +++} +++ +++ +++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s) { +++ TagLib::ByteVector v; +++#ifdef HAVE_LIBRCC +++ size_t rlen; +++ char *res; +++ +++ rccTaglibPatchTryInit(); +++ +++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); +++#ifdef RCC_DEBUG +++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { +++ if (*c > 127) { +++ printf(" Output: %s - %s\n", s.c_str(), res?res:"null"); +++ break; +++ } +++ } +++#endif /* RCC_DEBUG */ +++ +++ if (res) v.setData(res, rlen); +++ else v.setData("", 0); +++ //v.setData(s.c_str(), s.length()); +++ +++ return v; +++#else +++ v.setData("", 0); +++ +++ return v; +++#endif /* HAVE_LIBRCC */ +++} +++ +++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false) { +++ TagLib::ByteVector v; +++#ifdef HAVE_LIBRCC +++ size_t rlen; +++ char *res; +++ +++ rccTaglibPatchTryInit(); +++ +++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); +++#ifdef RCC_DEBUG +++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { +++ if (*c > 127) { +++ printf(" OutputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); +++ break; +++ } +++ } +++#endif /* RCC_DEBUG */ +++ +++ if (res) v.setData(res, rlen); +++ else v.setData("", 0); +++ //v.setData(s.c_str(), s.length()); +++ +++ return v; +++#else +++ v.setData("", 0); +++ +++ return v; +++#endif /* HAVE_LIBRCC */ +++} +++ +++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s) { +++ TagLib::ByteVector v; +++#ifdef HAVE_LIBRCC +++ size_t rlen; +++ char *res; +++ +++ rccTaglibPatchTryInit(); +++ +++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); +++#ifdef RCC_DEBUG +++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { +++ if (*c > 127) { +++ printf(" Input: %s - %s\n", s.c_str(), res?res:"null"); +++ break; +++ } +++ } +++#endif /* RCC_DEBUG */ +++ +++ if (res) v.setData(res, rlen); +++ else +++#endif /* HAVE_LIBRCC */ +++ v.setData("", 0); +++ +++ return v; +++} +++ +++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false) { +++ TagLib::ByteVector v; +++#ifdef HAVE_LIBRCC +++ size_t rlen; +++ char *res; +++ +++ rccTaglibPatchTryInit(); +++ +++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); +++#ifdef RCC_DEBUG +++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { +++ if (*c > 127) { +++ printf(" InputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); +++ break; +++ } +++ } +++#endif /* RCC_DEBUG */ +++ if (res) v.setData(res, rlen + 1); +++ else +++#endif /* HAVE_LIBRCC */ +++ v.setData("", 0); +++ +++ return v; +++} +++ +++TagLib::String::Type rccTaglibPatchGetLocaleType() { +++#ifdef HAVE_LIBRCC +++ size_t len; +++ char charset[32]; +++ +++ rccTaglibPatchTryInit(); +++ if (!rccLocaleGetCharset(charset, NULL, 31)) { +++ if (!strncmp(charset, "UTF", 3)) { +++ len = strlen(charset); +++ +++ if (charset[len-1]=='8') return TagLib::String::UTF8; +++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; +++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; +++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; +++ } +++ return TagLib::String::Latin1; +++ } +++#endif /* HAVE_LIBRCC */ +++ return TagLib::String::UTF8; +++} +++ +++TagLib::String::Type rccTaglibPatchGetID3Type() { +++#ifdef HAVE_LIBRCC +++ size_t len; +++ const char *charset; +++ +++ rccTaglibPatchTryInit(); +++ +++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); +++ if (charset) { +++ if (!strncmp(charset, "UTF", 3)) { +++ len = strlen(charset); +++ +++ if (charset[len-1]=='8') return TagLib::String::UTF8; +++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; +++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; +++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; +++ } +++ return TagLib::String::Latin1ID3V2; +++ } else { +++ // Error or no-language configured: If Latin1ID3V2 is returned we normally will use the default unicode encoding unless Latin1 is selected by taglib +++ return TagLib::String::Latin1ID3V2; +++ } +++#endif /* HAVE_LIBRCC */ +++ return TagLib::String::Latin1; +++} ++diff --git a/taglib/toolkit/rccpatch.h b/taglib/toolkit/rccpatch.h ++new file mode 100644 ++index 0000000..31f4410 ++--- /dev/null +++++ b/taglib/toolkit/rccpatch.h ++@@ -0,0 +1,20 @@ +++#ifndef _RCC_PATCH_H +++#define _RCC_PATCH_H +++ +++#include <string.h> +++#include "tstring.h" +++#include "tbytevector.h" +++ +++void rccTaglibPatchFree(); +++void rccTaglibPatchInit(); +++void rccTaglibPatchSetContext(void *newctx); +++ +++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s); +++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s); +++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false); +++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false); +++ +++TagLib::String::Type rccTaglibPatchGetLocaleType(); +++TagLib::String::Type rccTaglibPatchGetID3Type(); +++ +++#endif /* _RCC_PATCH_H */ ++diff --git a/taglib/toolkit/tstring.cpp b/taglib/toolkit/tstring.cpp ++index 258e1fc..70ff160 100644 ++--- a/taglib/toolkit/tstring.cpp +++++ b/taglib/toolkit/tstring.cpp ++@@ -29,6 +29,7 @@ ++ #include <config.h> ++ #endif ++ +++#include "rccpatch.h" ++ #include "tstring.h" ++ #include "tdebug.h" ++ #include "tstringlist.h" ++@@ -167,8 +168,11 @@ String::String(const String &s) ++ String::String(const std::string &s, Type t) ++ : d(new StringPrivate()) ++ { ++- if(t == Latin1) ++- copyFromLatin1(s.c_str(), s.length()); +++ if(t == Locale) +++ t = rccTaglibPatchGetLocaleType(); +++ +++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) +++ copyFromLatin1(&s[0], s.length(), true, t); ++ else if(t == String::UTF8) ++ copyFromUTF8(s.c_str(), s.length()); ++ else { ++@@ -215,8 +219,11 @@ String::String(const wchar_t *s, Type t) ++ String::String(const char *s, Type t) ++ : d(new StringPrivate()) ++ { ++- if(t == Latin1) ++- copyFromLatin1(s, ::strlen(s)); +++ if(t == Locale) +++ t = rccTaglibPatchGetLocaleType(); +++ +++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) +++ copyFromLatin1(s, ::strlen(s), true, t); ++ else if(t == String::UTF8) ++ copyFromUTF8(s, ::strlen(s)); ++ else { ++@@ -248,8 +255,11 @@ String::String(const ByteVector &v, Type t) ++ if(v.isEmpty()) ++ return; ++ ++- if(t == Latin1) ++- copyFromLatin1(v.data(), v.size()); +++ if(t == Locale) +++ t = rccTaglibPatchGetLocaleType(); +++ +++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) +++ copyFromLatin1(v.data(), v.size(), true, t); ++ else if(t == UTF8) ++ copyFromUTF8(v.data(), v.size()); ++ else ++@@ -396,8 +406,38 @@ bool String::isNull() const ++ ++ ByteVector String::data(Type t) const ++ { ++- switch(t) ++- { +++ ByteVector v; +++ +++ if (t == Locale) { +++ // The source is either Unicode or real Latin1 (if rcc is bypassed) +++ std::string s = to8Bit(true); +++ +++ // In case of UTF8 locale, this probably will return NULL (no recoding needed), but we will take UTF8 path in the next swtich +++ v = rccTaglibPatchRecodeOutput(s); +++ if (v.size()) return v; +++ +++ t = rccTaglibPatchGetLocaleType(); +++ } +++ +++ switch(t) { +++ case Latin1ID3: +++ case Latin1ID3V2: +++ { +++ std::string s = to8Bit(true); +++ if (t == Latin1ID3) v = rccTaglibPatchRecodeOutputID3(s, false); +++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeOutputID3(s, true); +++ if (v.size()) +++ return v; +++ +++ // we don't know if we got NULL because rcc is disabled (error) or UTF8 output is required +++ if ((t == Latin1ID3V2)&&(rccTaglibPatchGetID3Type() == UTF8)) { +++ v.setData(s.c_str(), s.length()); +++ } else { +++ for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) +++ v.append(char(*it)); +++ } +++ return v; +++ } ++ case Latin1: ++ { ++ ByteVector v(size(), 0); ++@@ -738,12 +778,30 @@ void String::detach() ++ // private members ++ //////////////////////////////////////////////////////////////////////////////// ++ ++-void String::copyFromLatin1(const char *s, size_t length) +++void String::copyFromLatin1(const char *s, size_t length, bool prepare, Type t) ++ { ++ d->data.resize(length); ++ ++ for(size_t i = 0; i < length; ++i) ++ d->data[i] = static_cast<uchar>(s[i]); +++ +++ // librcc conversation +++ if (prepare) { +++ std::string s = to8Bit(false); +++ ByteVector v; +++ +++ if (t == Latin1ID3) v = rccTaglibPatchRecodeInputID3(s, false); +++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeInputID3(s, true); +++ else /* Latin1 converted from Locale */ v = rccTaglibPatchRecodeInput(s); +++ +++ if (v.size()) { +++ copyFromUTF8(v.data(), v.size()); +++ } else { +++ // We don't know if we got UTF-8 encoded string or either rcc is disable or something is failed, +++ // since standard applications are really expecting here Latin1, it is safe to just check if we have violations of UTF8 +++ //if (Unicode::isLegalUTF8(s)) t = UTF8; +++ } +++ } ++ } ++ ++ void String::copyFromUTF8(const char *s, size_t length) ++@@ -859,7 +917,33 @@ const TagLib::String operator+(const TagLib::String &s1, const char *s2) ++ ++ std::ostream &operator<<(std::ostream &s, const TagLib::String &str) ++ { ++- s << str.to8Bit(); +++ TagLib::ByteVector bv = str.data(TagLib::String::Locale); +++ s << bv; ++ return s; ++ } ++ +++TagLib::String::Type TagLib::String::ID3Type(int i) +++{ +++ if(i == Latin1) +++ return Latin1ID3V2; +++ return Type(i); +++}; +++ +++TagLib::String::Type TagLib::String::ID3WType(Type type) +++{ +++ Type rcc_type = rccTaglibPatchGetID3Type(); +++ if((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)||(rcc_type == Latin1)) { +++ if(type == Latin1) return +++ rcc_type; +++ return type; +++ } +++ +++ return rcc_type; +++}; +++ +++TagLib::String::Type TagLib::String::ID3RealType(Type type) +++{ +++ if((type == Latin1ID3) || (type == Latin1ID3V2)) +++ return Latin1; +++ return type; +++} ++diff --git a/taglib/toolkit/tstring.h b/taglib/toolkit/tstring.h ++index 8b73988..8efca25 100644 ++--- a/taglib/toolkit/tstring.h +++++ b/taglib/toolkit/tstring.h ++@@ -96,6 +96,18 @@ namespace TagLib { ++ */ ++ enum Type { ++ /*! +++ * Determine using current locale settings +++ */ +++ Locale = -1, +++ /*! +++ * Latin1 for ID3 tags. +++ */ +++ Latin1ID3 = 65, +++ /*! +++ * Latin1 for ID3v2 tags. +++ */ +++ Latin1ID3V2 = 66, +++ /*! ++ * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. ++ */ ++ Latin1 = 0, ++@@ -117,6 +129,10 @@ namespace TagLib { ++ */ ++ UTF16LE = 4 ++ }; +++ +++ static Type ID3Type(int i); +++ static Type ID3WType(Type type); +++ static Type ID3RealType(Type type); ++ ++ /*! ++ * Constructs an empty String. ++@@ -519,7 +535,7 @@ namespace TagLib { ++ * Converts a \e Latin-1 string into \e UTF-16(without BOM/CPU byte order) ++ * and copies it to the internal buffer. ++ */ ++- void copyFromLatin1(const char *s, size_t length); +++ void copyFromLatin1(const char *s, size_t length, bool prepare = false, Type t = Latin1); ++ ++ /*! ++ * Converts a \e UTF-8 string into \e UTF-16(without BOM/CPU byte order) diff --git a/patches/taglib/taglib-1.11-ds-rusxmms.patch b/patches/taglib/taglib-1.11-ds-rusxmms.patch new file mode 100644 index 0000000..9f777c8 --- /dev/null +++ b/patches/taglib/taglib-1.11-ds-rusxmms.patch @@ -0,0 +1,684 @@ +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/config.h.cmake taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/config.h.cmake +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/config.h.cmake 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/config.h.cmake 2019-09-01 08:32:29.569443643 +0200 +@@ -30,6 +30,9 @@ + /* Indicates whether debug messages are shown even in release mode */ + #cmakedefine TRACE_IN_RELEASE 1 + ++/* Defined if you have LibRCC from RusXMMS project */ ++#cmakedefine HAVE_LIBRCC 1 ++ + #cmakedefine TESTS_DIR "@TESTS_DIR@" + + #endif +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/ConfigureChecks.cmake taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/ConfigureChecks.cmake +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/ConfigureChecks.cmake 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/ConfigureChecks.cmake 2019-09-01 08:32:29.577443787 +0200 +@@ -213,3 +213,5 @@ + if(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore") + set(PLATFORM WINRT 1) + endif() ++ ++SET(HAVE_LIBRCC 1) +\ No newline at end of file +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/examples/tagreader_c.c taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/examples/tagreader_c.c +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/examples/tagreader_c.c 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/examples/tagreader_c.c 2019-09-01 08:32:29.577443787 +0200 +@@ -38,7 +38,7 @@ + TagLib_Tag *tag; + const TagLib_AudioProperties *properties; + +- taglib_set_strings_unicode(FALSE); ++ //taglib_set_strings_unicode(FALSE); + + for(i = 1; i < argc; i++) { + printf("******************** \"%s\" ********************\n", argv[i]); +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/examples/tagwriter.cpp taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/examples/tagwriter.cpp +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/examples/tagwriter.cpp 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/examples/tagwriter.cpp 2019-09-01 08:32:29.577443787 +0200 +@@ -115,7 +115,7 @@ + if(isArgument(argv[i]) && i + 1 < argc && !isArgument(argv[i + 1])) { + + char field = argv[i][1]; +- TagLib::String value = argv[i + 1]; ++ TagLib::String value(argv[i + 1], TagLib::String::Locale); + + TagLib::List<TagLib::FileRef>::ConstIterator it; + for(it = fileList.begin(); it != fileList.end(); ++it) { +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/CMakeLists.txt taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/CMakeLists.txt +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/CMakeLists.txt 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/CMakeLists.txt 2019-09-01 08:32:29.577443787 +0200 +@@ -41,6 +41,7 @@ + audioproperties.h + taglib_export.h + ${CMAKE_CURRENT_BINARY_DIR}/../taglib_config.h ++ toolkit/rccpatch.h + toolkit/taglib.h + toolkit/tstring.h + toolkit/tlist.h +@@ -312,6 +313,7 @@ + ) + + set(toolkit_SRCS ++ toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -354,7 +356,9 @@ + add_library(tag ${tag_LIB_SRCS} ${tag_HDRS}) + + if(HAVE_ZLIB AND NOT HAVE_ZLIB_SOURCE) +- target_link_libraries(tag ${ZLIB_LIBRARIES}) ++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES}) ++else () ++ target_link_libraries(tag rcc) + endif() + + set_target_properties(tag PROPERTIES +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/mpeg/id3v1/id3v1tag.cpp taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/mpeg/id3v1/id3v1tag.cpp 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2019-09-01 08:32:29.577443787 +0200 +@@ -69,15 +69,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { +- if(s.isLatin1()) +- return s.data(String::Latin1); +- else ++ if(!s.isLatin1()) ++ { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); ++ } ++ ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -262,7 +265,7 @@ + d->track = static_cast<unsigned char>(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/mpeg/id3v2/frames/commentsframe.cpp 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2019-09-01 08:32:29.578443805 +0200 +@@ -150,10 +150,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -173,11 +173,13 @@ + ByteVector v; + + String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); + + encoding = checkTextEncoding(d->description, encoding); + encoding = checkTextEncoding(d->text, encoding); + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2019-09-01 08:32:29.578443805 +0200 +@@ -191,12 +191,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -227,11 +227,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkTextEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/mpeg/id3v2/id3v2frame.cpp taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/mpeg/id3v2/id3v2frame.cpp +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/mpeg/id3v2/id3v2frame.cpp 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/mpeg/id3v2/id3v2frame.cpp 2019-09-01 08:32:29.578443805 +0200 +@@ -297,7 +297,7 @@ + if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4) + return String::UTF16; + +- if(encoding != String::Latin1) ++ if((encoding != String::Latin1)&&(encoding != String::Latin1ID3V2)) + return encoding; + + for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) { +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/toolkit/rccpatch.cpp taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/toolkit/rccpatch.cpp +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/toolkit/rccpatch.cpp 2019-09-01 08:32:29.578443805 +0200 +@@ -0,0 +1,237 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++//#define RCC_DEBUG ++ ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# ifdef RCC_DEBUG ++# include <stdio.h> ++# endif /* RCC_DEBUG */ ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccTaglibPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccTaglibPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccTaglibPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccTaglibPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccTaglibPatchInit(); ++ if (rcc_initialized) atexit(rccTaglibPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" Output: %s - %s\n", s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else v.setData("", 0); ++ //v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" OutputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else v.setData("", 0); ++ //v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" Input: %s - %s\n", s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" InputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ if (res) v.setData(res, rlen + 1); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::String::Type rccTaglibPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccTaglibPatchTryInit(); ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccTaglibPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccTaglibPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } else { ++ // Error or no-language configured: If Latin1ID3V2 is returned we normally will use the default unicode encoding unless Latin1 is selected by taglib ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/toolkit/rccpatch.h taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/toolkit/rccpatch.h +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/toolkit/rccpatch.h 2019-09-01 08:32:29.578443805 +0200 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccTaglibPatchFree(); ++void rccTaglibPatchInit(); ++void rccTaglibPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccTaglibPatchGetLocaleType(); ++TagLib::String::Type rccTaglibPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/toolkit/tstring.cpp taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/toolkit/tstring.cpp +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/toolkit/tstring.cpp 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/toolkit/tstring.cpp 2019-09-01 08:27:18.763821274 +0200 +@@ -33,6 +33,7 @@ + #include <trefcounter.h> + #include <tutils.h> + ++#include "rccpatch.h" + #include "tstring.h" + + namespace +@@ -48,16 +49,6 @@ + return String::UTF16BE; + } + +- // Converts a Latin-1 string into UTF-16(without BOM/CPU byte order) +- // and copies it to the internal buffer. +- void copyFromLatin1(std::wstring &data, const char *s, size_t length) +- { +- data.resize(length); +- +- for(size_t i = 0; i < length; ++i) +- data[i] = static_cast<unsigned char>(s[i]); +- } +- + // Converts a UTF-8 string into UTF-16(without BOM/CPU byte order) + // and copies it to the internal buffer. + void copyFromUTF8(std::wstring &data, const char *s, size_t length) +@@ -73,6 +64,36 @@ + debug("String::copyFromUTF8() - UTF8-CPP error: " + message); + data.clear(); + } ++ ++ } ++ ++ // Converts a Latin-1 string into UTF-16(without BOM/CPU byte order) ++ // and copies it to the internal buffer. ++ void copyFromLatin1(std::wstring &data, const char *s, size_t length, bool prepare, String::Type t) ++ { ++ // librcc conversation ++ if (prepare) { ++ ByteVector v; ++ std::string std_s(s); ++ ++ if (t == String::Latin1ID3) v = rccTaglibPatchRecodeInputID3(std_s, false); ++ else if (t == String::Latin1ID3V2) v = rccTaglibPatchRecodeInputID3(std_s, true); ++ else /* Latin1 converted from Locale */ v = rccTaglibPatchRecodeInput(std_s); ++ ++ if (v.size()) { ++ copyFromUTF8(data, v.data(), v.size()); ++ return; ++ } else { ++ // We don't know if we got UTF-8 encoded string or either rcc is disable or something is failed, ++ // since standard applications are really expecting here Latin1, it is safe to just check if we have violations of UTF8 ++ //if (Unicode::isLegalUTF8(s)) t = UTF8; ++ } ++ } ++ ++ data.resize(length); ++ ++ for(size_t i = 0; i < length; ++i) ++ data[i] = static_cast<unsigned char>(s[i]); + } + + // Helper functions to read a UTF-16 character from an array. +@@ -175,8 +196,11 @@ + String::String(const std::string &s, Type t) : + d(new StringPrivate()) + { ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ + if(t == Latin1) +- copyFromLatin1(d->data, s.c_str(), s.length()); ++ copyFromLatin1(d->data, s.c_str(), s.length(), true, t); + else if(t == String::UTF8) + copyFromUTF8(d->data, s.c_str(), s.length()); + else { +@@ -223,8 +247,11 @@ + String::String(const char *s, Type t) : + d(new StringPrivate()) + { +- if(t == Latin1) +- copyFromLatin1(d->data, s, ::strlen(s)); ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) ++ copyFromLatin1(d->data, s, ::strlen(s), true, t); + else if(t == String::UTF8) + copyFromUTF8(d->data, s, ::strlen(s)); + else { +@@ -245,8 +272,11 @@ + String::String(char c, Type t) : + d(new StringPrivate()) + { +- if(t == Latin1) +- copyFromLatin1(d->data, &c, 1); ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) ++ copyFromLatin1(d->data, &c, 1, true, t); + else if(t == String::UTF8) + copyFromUTF8(d->data, &c, 1); + else { +@@ -260,8 +290,11 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1) +- copyFromLatin1(d->data, v.data(), v.size()); ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) ++ copyFromLatin1(d->data, v.data(), v.size(), true, t); + else if(t == UTF8) + copyFromUTF8(d->data, v.data(), v.size()); + else +@@ -416,8 +449,38 @@ + + ByteVector String::data(Type t) const + { +- switch(t) +- { ++ ByteVector v; ++ ++ if (t == Locale) { ++ // The source is either Unicode or real Latin1 (if rcc is bypassed) ++ std::string s = to8Bit(true); ++ ++ // In case of UTF8 locale, this probably will return NULL (no recoding needed), but we will take UTF8 path in the next swtich ++ v = rccTaglibPatchRecodeOutput(s); ++ if (v.size()) return v; ++ ++ t = rccTaglibPatchGetLocaleType(); ++ } ++ ++ switch(t) { ++ case Latin1ID3: ++ case Latin1ID3V2: ++ { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccTaglibPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeOutputID3(s, true); ++ if (v.size()) ++ return v; ++ ++ // we don't know if we got NULL because rcc is disabled (error) or UTF8 output is required ++ if ((t == Latin1ID3V2)&&(rccTaglibPatchGetID3Type() == UTF8)) { ++ v.setData(s.c_str(), s.length()); ++ } else { ++ for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) ++ v.append(char(*it)); ++ } ++ return v; ++ } + case Latin1: + { + ByteVector v(size(), 0); +@@ -741,7 +804,33 @@ + + std::ostream &operator<<(std::ostream &s, const TagLib::String &str) + { +- s << str.to8Bit(); ++ TagLib::ByteVector bv = str.data(TagLib::String::Locale); ++ s << bv; + return s; + } + ++TagLib::String::Type TagLib::String::ID3Type(int i) ++{ ++ if(i == Latin1) ++ return Latin1ID3V2; ++ return Type(i); ++}; ++ ++TagLib::String::Type TagLib::String::ID3WType(Type type) ++{ ++ Type rcc_type = rccTaglibPatchGetID3Type(); ++ if((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)||(rcc_type == Latin1)) { ++ if(type == Latin1) return ++ rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++TagLib::String::Type TagLib::String::ID3RealType(Type type) ++{ ++ if((type == Latin1ID3) || (type == Latin1ID3V2)) ++ return Latin1; ++ return type; ++} +diff -dPNur taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/toolkit/tstring.h taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/toolkit/tstring.h +--- taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c/taglib/toolkit/tstring.h 2018-10-28 14:43:45.000000000 +0100 ++++ taglib-5cb589a5b82c13ba8f0542e5e79629da7645cb3c-ds/taglib/toolkit/tstring.h 2019-09-01 08:32:29.579443823 +0200 +@@ -96,6 +96,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3v2 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -117,6 +129,10 @@ + */ + UTF16LE = 4 + }; ++ ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); + + /*! + * Constructs an empty String. diff --git a/patches/taglib/taglib-1.4-ds-rusxmms.patch b/patches/taglib/taglib-1.4-ds-rusxmms.patch new file mode 100644 index 0000000..5b67c7c --- /dev/null +++ b/patches/taglib/taglib-1.4-ds-rusxmms.patch @@ -0,0 +1,504 @@ +diff -dPNur taglib-1.4/configure.in taglib-1.4-new/configure.in +--- taglib-1.4/configure.in 2005-07-27 02:45:33.000000000 +0200 ++++ taglib-1.4-new/configure.in 2005-09-16 01:45:30.000000000 +0200 +@@ -98,6 +98,20 @@ + + AC_SUBST(AUTODIRS) + ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ + dnl ======================================================= + dnl FILE: ./taglib/configure.in.in + dnl ======================================================= +diff -dPNur taglib-1.4/configure.in.in taglib-1.4-new/configure.in.in +--- taglib-1.4/configure.in.in 2005-07-23 23:43:58.000000000 +0200 ++++ taglib-1.4-new/configure.in.in 2005-09-16 01:45:30.000000000 +0200 +@@ -94,3 +94,16 @@ + + AC_SUBST(AUTODIRS) + ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) +diff -dPNur taglib-1.4/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.4-new/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.4/taglib/mpeg/id3v1/id3v1tag.cpp 2005-05-17 22:17:16.000000000 +0200 ++++ taglib-1.4-new/taglib/mpeg/id3v1/id3v1tag.cpp 2005-09-16 01:46:37.000000000 +0200 +@@ -55,12 +55,12 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1); ++ return String(data, String::Latin1ID3); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -231,7 +231,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.4/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.4-new/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.4/taglib/mpeg/id3v2/frames/commentsframe.cpp 2005-07-25 23:16:32.000000000 +0200 ++++ taglib-1.4-new/taglib/mpeg/id3v2/frames/commentsframe.cpp 2005-09-16 01:45:30.000000000 +0200 +@@ -115,7 +115,7 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + + int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; +@@ -131,12 +131,13 @@ + ByteVector CommentsFrame::renderFields() const + { + ByteVector v; ++ String::Type textEncoding = String::ID3WType(d->textEncoding); + +- v.append(char(d->textEncoding)); ++ v.append(char(textEncoding)); + v.append(d->language.size() == 3 ? d->language : " "); +- v.append(d->description.data(d->textEncoding)); +- v.append(textDelimiter(d->textEncoding)); +- v.append(d->text.data(d->textEncoding)); ++ v.append(d->description.data(textEncoding)); ++ v.append(textDelimiter(textEncoding)); ++ v.append(d->text.data(textEncoding)); + + return v; + } +diff -dPNur taglib-1.4/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.4-new/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.4/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2005-05-17 22:17:26.000000000 +0200 ++++ taglib-1.4-new/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2005-09-16 01:45:30.000000000 +0200 +@@ -96,7 +96,7 @@ + { + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) +@@ -121,8 +121,9 @@ + ByteVector v; + + if(d->fieldList.size() > 0) { ++ String::Type textEncoding = String::ID3WType(d->textEncoding); + +- v.append(char(d->textEncoding)); ++ v.append(char(textEncoding)); + + for(StringList::Iterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +@@ -131,9 +132,9 @@ + // encoding. + + if(it != d->fieldList.begin()) +- v.append(textDelimiter(d->textEncoding)); ++ v.append(textDelimiter(textEncoding)); + +- v.append((*it).data(d->textEncoding)); ++ v.append((*it).data(textEncoding)); + } + } + +diff -dPNur taglib-1.4/taglib/toolkit/Makefile.am taglib-1.4-new/taglib/toolkit/Makefile.am +--- taglib-1.4/taglib/toolkit/Makefile.am 2005-07-25 23:16:32.000000000 +0200 ++++ taglib-1.4-new/taglib/toolkit/Makefile.am 2005-09-16 01:45:30.000000000 +0200 +@@ -1,12 +1,15 @@ +-INCLUDES = $(all_includes) ++INCLUDES = $(all_includes) @LIBRCC_INCLUDES@ ++libtoolkit_la_LDFLAGS = @LIBRCC_LIBS@ + + noinst_LTLIBRARIES = libtoolkit.la + + libtoolkit_la_SOURCES = \ ++ rccpatch.cpp \ + tstring.cpp tstringlist.cpp tbytevector.cpp \ + tbytevectorlist.cpp tfile.cpp tdebug.cpp unicode.cpp + + taglib_include_HEADERS = \ ++ rccpatch.h \ + taglib.h tstring.h tlist.h tlist.tcc tstringlist.h \ + tbytevector.h tbytevectorlist.h tfile.h \ + tmap.h tmap.tcc +diff -dPNur taglib-1.4/taglib/toolkit/rccpatch.cpp taglib-1.4-new/taglib/toolkit/rccpatch.cpp +--- taglib-1.4/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.4-new/taglib/toolkit/rccpatch.cpp 2005-09-16 01:45:30.000000000 +0200 +@@ -0,0 +1,202 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++char *rccPatchRecode(const char *str, size_t len, size_t *rlen) { ++#ifdef HAVE_LIBRCC ++ rccPatchTryInit(); ++ ++ return rccSizedRecode(ctx, ID3_CLASS, OUT_CLASS, str, len, rlen); ++#else ++ return NULL; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, ID3_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::String::Type rccPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccPatchTryInit(); ++ ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.4/taglib/toolkit/rccpatch.h taglib-1.4-new/taglib/toolkit/rccpatch.h +--- taglib-1.4/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.4-new/taglib/toolkit/rccpatch.h 2005-09-16 01:45:30.000000000 +0200 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccPatchFree(); ++void rccPatchInit(); ++void rccPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s); ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s); ++ ++TagLib::String::Type rccPatchGetLocaleType(); ++TagLib::String::Type rccPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.4/taglib/toolkit/tstring.cpp taglib-1.4-new/taglib/toolkit/tstring.cpp +--- taglib-1.4/taglib/toolkit/tstring.cpp 2005-07-25 23:31:15.000000000 +0200 ++++ taglib-1.4-new/taglib/toolkit/tstring.cpp 2005-09-16 01:45:30.000000000 +0200 +@@ -19,6 +19,7 @@ + * USA * + ***************************************************************************/ + ++#include "rccpatch.h" + #include "tstring.h" + #include "unicode.h" + #include "tdebug.h" +@@ -161,7 +162,7 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1 || t == UTF8) { ++ if(t == Latin1 || t == Latin1ID3 || t == UTF8) { + + int length = 0; + d->data.resize(v.size()); +@@ -334,10 +335,18 @@ + { + ByteVector v; + +- switch(t) { ++ if (t == Locale) t = rccPatchGetLocaleType(); + ++ switch(t) { ++ case Locale: ++ case Latin1ID3: + case Latin1: + { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccPatchRecodeOutputID3(s); ++ else v = rccPatchRecodeOutput(s); ++ if (v.size()) return v; ++ + for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + v.append(char(*it)); + break; +@@ -649,6 +658,30 @@ + + void String::prepare(Type t) + { ++ if (t == Locale) t = rccPatchGetLocaleType(); ++ ++ if ((t == Latin1)||(t == Latin1ID3)) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccPatchRecodeInputID3(s); ++ else v = rccPatchRecodeInput(s); ++ ++ if (v.size()) { ++ int length = 0; ++ d->data.resize(v.size()); ++ wstring::iterator targetIt = d->data.begin(); ++ for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { ++ *targetIt = uchar(*it); ++ ++targetIt; ++ ++length; ++ } ++ d->data.resize(length); ++ } ++ ++ t = UTF8; ++ } ++ + switch(t) { + case UTF16: + { +@@ -738,6 +771,17 @@ + + std::ostream &operator<<(std::ostream &s, const String &str) + { +- s << str.to8Bit(); ++ ByteVector bv = str.data(String::Locale); ++ s << bv; + return s; + } ++ ++String::Type String::ID3Type(int i) { ++ if (i == Latin1) return Latin1ID3; ++ return Type(i); ++}; ++ ++String::Type String::ID3WType(Type type) { ++ if ((type == Latin1)||(type == Latin1ID3)) return rccPatchGetID3Type(); ++ return type; ++}; +diff -dPNur taglib-1.4/taglib/toolkit/tstring.h taglib-1.4-new/taglib/toolkit/tstring.h +--- taglib-1.4/taglib/toolkit/tstring.h 2005-07-25 23:55:14.000000000 +0200 ++++ taglib-1.4-new/taglib/toolkit/tstring.h 2005-09-16 01:45:30.000000000 +0200 +@@ -75,6 +75,14 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 5, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -97,6 +105,9 @@ + UTF16LE = 4 + }; + ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ + /*! + * Constructs an empty String. + */ diff --git a/patches/taglib/taglib-1.5-ds-rusxmms.patch b/patches/taglib/taglib-1.5-ds-rusxmms.patch new file mode 100644 index 0000000..0d80fb5 --- /dev/null +++ b/patches/taglib/taglib-1.5-ds-rusxmms.patch @@ -0,0 +1,584 @@ +diff -dPNur taglib-1.5/config-taglib.h.cmake taglib-1.5-ds/config-taglib.h.cmake +--- taglib-1.5/config-taglib.h.cmake 2008-01-11 01:56:23.000000000 +0100 ++++ taglib-1.5-ds/config-taglib.h.cmake 2008-11-20 15:58:31.000000000 +0100 +@@ -6,4 +6,6 @@ + /* Define if you have libz */ + #cmakedefine HAVE_ZLIB 1 + ++#cmakedefine HAVE_LIBRCC 1 ++ + #cmakedefine NO_ITUNES_HACKS 1 +diff -dPNur taglib-1.5/ConfigureChecks.cmake taglib-1.5-ds/ConfigureChecks.cmake +--- taglib-1.5/ConfigureChecks.cmake 2008-01-11 01:56:23.000000000 +0100 ++++ taglib-1.5-ds/ConfigureChecks.cmake 2008-11-20 15:58:31.000000000 +0100 +@@ -14,6 +14,8 @@ + #check for libz using the cmake supplied FindZLIB.cmake + FIND_PACKAGE(ZLIB) + ++SET(HAVE_LIBRCC 1) ++ + IF(ZLIB_FOUND) + SET(HAVE_ZLIB 1) + ELSE(ZLIB_FOUND) +diff -dPNur taglib-1.5/configure.in taglib-1.5-ds/configure.in +--- taglib-1.5/configure.in 2008-02-13 00:53:05.000000000 +0100 ++++ taglib-1.5-ds/configure.in 2008-11-20 15:24:19.000000000 +0100 +@@ -98,6 +98,20 @@ + + AC_SUBST(AUTODIRS) + ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ + #AM_INIT_AUTOMAKE(taglib,1.0) + dnl don't remove the below + dnl AC_OUTPUT(taglib-config) +diff -dPNur taglib-1.5/configure.in.in taglib-1.5-ds/configure.in.in +--- taglib-1.5/configure.in.in 2008-01-30 02:34:06.000000000 +0100 ++++ taglib-1.5-ds/configure.in.in 2008-11-20 15:24:19.000000000 +0100 +@@ -94,6 +94,21 @@ + + AC_SUBST(AUTODIRS) + ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ ++ + #AM_INIT_AUTOMAKE(taglib,1.0) + dnl don't remove the below + dnl AC_OUTPUT(taglib-config) +diff -dPNur taglib-1.5/taglib/CMakeLists.txt taglib-1.5-ds/taglib/CMakeLists.txt +--- taglib-1.5/taglib/CMakeLists.txt 2008-02-12 05:15:20.000000000 +0100 ++++ taglib-1.5-ds/taglib/CMakeLists.txt 2008-11-20 15:58:31.000000000 +0100 +@@ -119,6 +119,7 @@ + ) + + SET(toolkit_SRCS ++toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -140,7 +141,7 @@ + + ADD_LIBRARY(tag SHARED ${tag_LIB_SRCS}) + +-TARGET_LINK_LIBRARIES(tag ) ++TARGET_LINK_LIBRARIES(tag rcc) + if(ZLIB_FOUND) + TARGET_LINK_LIBRARIES(tag ${ZLIB_LIBRARIES}) + endif(ZLIB_FOUND) +diff -dPNur taglib-1.5/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.5-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.5/taglib/mpeg/id3v1/id3v1tag.cpp 2008-02-04 16:14:45.000000000 +0100 ++++ taglib-1.5-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2008-11-20 15:24:19.000000000 +0100 +@@ -59,17 +59,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { + if(!s.isLatin1()) + { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); + } + +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -240,7 +241,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.5/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.5-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.5/taglib/mpeg/id3v2/frames/commentsframe.cpp 2008-02-04 16:14:46.000000000 +0100 ++++ taglib-1.5-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2008-11-20 15:24:19.000000000 +0100 +@@ -136,10 +136,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = d->textEncoding == (String::Latin1 || String::Latin1ID3 || String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -155,10 +155,12 @@ + + String::Type encoding = d->textEncoding; + ++ encoding = String::ID3WType(encoding); ++ + encoding = checkEncoding(d->description, encoding); + encoding = checkEncoding(d->text, encoding); +- +- v.append(char(encoding)); ++ ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-1.5/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.5-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.5/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2008-02-04 16:14:46.000000000 +0100 ++++ taglib-1.5-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2008-11-20 15:24:19.000000000 +0100 +@@ -105,12 +105,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -139,11 +139,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-1.5/taglib/toolkit/CMakeLists.txt taglib-1.5-ds/taglib/toolkit/CMakeLists.txt +--- taglib-1.5/taglib/toolkit/CMakeLists.txt 2008-01-11 01:54:01.000000000 +0100 ++++ taglib-1.5-ds/taglib/toolkit/CMakeLists.txt 2008-11-20 15:58:31.000000000 +0100 +@@ -1 +1 @@ +-INSTALL( FILES taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) ++INSTALL( FILES rccpatch.h taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) +diff -dPNur taglib-1.5/taglib/toolkit/Makefile.am taglib-1.5-ds/taglib/toolkit/Makefile.am +--- taglib-1.5/taglib/toolkit/Makefile.am 2008-01-11 01:54:01.000000000 +0100 ++++ taglib-1.5-ds/taglib/toolkit/Makefile.am 2008-11-20 15:24:19.000000000 +0100 +@@ -1,14 +1,20 @@ + INCLUDES = \ + -I$(top_srcdir)/taglib \ +- $(all_includes) ++ $(all_includes) \ ++ @LIBRCC_INCLUDES@ + + noinst_LTLIBRARIES = libtoolkit.la + ++libtoolkit_la_LDFLAGS = @LIBRCC_LIBS@ ++ + libtoolkit_la_SOURCES = \ ++ rccpatch.cpp \ + tstring.cpp tstringlist.cpp tbytevector.cpp \ + tbytevectorlist.cpp tfile.cpp tdebug.cpp unicode.cpp + ++ + taglib_include_HEADERS = \ ++ rccpatch.h \ + taglib.h tstring.h tlist.h tlist.tcc tstringlist.h \ + tbytevector.h tbytevectorlist.h tfile.h \ + tmap.h tmap.tcc +diff -dPNur taglib-1.5/taglib/toolkit/rccpatch.cpp taglib-1.5-ds/taglib/toolkit/rccpatch.cpp +--- taglib-1.5/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.5-ds/taglib/toolkit/rccpatch.cpp 2008-11-20 15:58:31.000000000 +0100 +@@ -0,0 +1,198 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::String::Type rccPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccPatchTryInit(); ++ ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.5/taglib/toolkit/rccpatch.h taglib-1.5-ds/taglib/toolkit/rccpatch.h +--- taglib-1.5/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.5-ds/taglib/toolkit/rccpatch.h 2008-11-20 15:24:19.000000000 +0100 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccPatchFree(); ++void rccPatchInit(); ++void rccPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccPatchGetLocaleType(); ++TagLib::String::Type rccPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.5/taglib/toolkit/tstring.cpp taglib-1.5-ds/taglib/toolkit/tstring.cpp +--- taglib-1.5/taglib/toolkit/tstring.cpp 2008-02-04 16:14:45.000000000 +0100 ++++ taglib-1.5-ds/taglib/toolkit/tstring.cpp 2008-11-20 15:24:21.000000000 +0100 +@@ -23,6 +23,7 @@ + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + ++#include "rccpatch.h" + #include "tstring.h" + #include "unicode.h" + #include "tdebug.h" +@@ -167,7 +168,7 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1 || t == UTF8) { ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2 || t == UTF8) { + + int length = 0; + d->data.resize(v.size()); +@@ -358,10 +359,21 @@ + { + ByteVector v; + +- switch(t) { ++ if (t == Locale) t = rccPatchGetLocaleType(); + ++ switch(t) { ++ case Locale: + case Latin1: ++ case Latin1ID3: ++ case Latin1ID3V2: + { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeOutputID3(s, true); ++ else /* if (t == Latin1(Locale) */ v = rccPatchRecodeOutput(s); ++ ++ if (v.size()) return v; ++ + for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + v.append(char(*it)); + break; +@@ -692,6 +704,31 @@ + + void String::prepare(Type t) + { ++ if (t == Locale) t = rccPatchGetLocaleType(); ++ ++ if ((t == Latin1)||(t == Latin1ID3)||(t == Latin1ID3V2)) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccPatchRecodeInputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeInputID3(s, true); ++ else /* Latin1 converted from Locale */ v = rccPatchRecodeInput(s); ++ ++ if (v.size()) { ++ int length = 0; ++ d->data.resize(v.size()); ++ wstring::iterator targetIt = d->data.begin(); ++ for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { ++ *targetIt = uchar(*it); ++ ++targetIt; ++ ++length; ++ } ++ d->data.resize(length); ++ } ++ ++ t = UTF8; ++ } ++ + switch(t) { + case UTF16: + { +@@ -781,6 +818,27 @@ + + std::ostream &operator<<(std::ostream &s, const String &str) + { +- s << str.to8Bit(); ++ ByteVector bv = str.data(String::Locale); ++ s << bv; + return s; + } ++ ++String::Type String::ID3Type(int i) { ++ if (i == Latin1) return Latin1ID3V2; ++ return Type(i); ++}; ++ ++String::Type String::ID3WType(Type type) { ++ Type rcc_type = rccPatchGetID3Type(); ++ if ((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)) { ++ if (type == Latin1) return rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++String::Type String::ID3RealType(Type type) { ++ if ((type == Latin1ID3)||(type == Latin1ID3V2)) return Latin1; ++ return type; ++} +diff -dPNur taglib-1.5/taglib/toolkit/tstring.h taglib-1.5-ds/taglib/toolkit/tstring.h +--- taglib-1.5/taglib/toolkit/tstring.h 2008-02-04 16:14:45.000000000 +0100 ++++ taglib-1.5-ds/taglib/toolkit/tstring.h 2008-11-20 15:24:21.000000000 +0100 +@@ -81,6 +81,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -103,6 +115,10 @@ + UTF16LE = 4 + }; + ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); ++ + /*! + * Constructs an empty String. + */ diff --git a/patches/taglib/taglib-1.6-ds-rusxmms.patch b/patches/taglib/taglib-1.6-ds-rusxmms.patch new file mode 100644 index 0000000..5eb1a2a --- /dev/null +++ b/patches/taglib/taglib-1.6-ds-rusxmms.patch @@ -0,0 +1,587 @@ +diff -dPNur taglib-1.6/config-taglib.h.cmake taglib-1.6-ds/config-taglib.h.cmake +--- taglib-1.6/config-taglib.h.cmake 2008-11-12 09:17:11.000000000 +0100 ++++ taglib-1.6-ds/config-taglib.h.cmake 2009-10-02 17:53:08.000000000 +0200 +@@ -6,6 +6,8 @@ + /* Define if you have libz */ + #cmakedefine HAVE_ZLIB 1 + ++#cmakedefine HAVE_LIBRCC 1 ++ + #cmakedefine NO_ITUNES_HACKS 1 + #cmakedefine WITH_ASF 1 + #cmakedefine WITH_MP4 1 +diff -dPNur taglib-1.6/ConfigureChecks.cmake taglib-1.6-ds/ConfigureChecks.cmake +--- taglib-1.6/ConfigureChecks.cmake 2008-12-21 22:46:41.000000000 +0100 ++++ taglib-1.6-ds/ConfigureChecks.cmake 2009-10-02 17:53:08.000000000 +0200 +@@ -14,6 +14,8 @@ + #check for libz using the cmake supplied FindZLIB.cmake + FIND_PACKAGE(ZLIB) + ++SET(HAVE_LIBRCC 1) ++ + IF(ZLIB_FOUND) + SET(HAVE_ZLIB 1) + ELSE(ZLIB_FOUND) +diff -dPNur taglib-1.6/configure.in taglib-1.6-ds/configure.in +--- taglib-1.6/configure.in 2009-09-13 13:58:46.000000000 +0200 ++++ taglib-1.6-ds/configure.in 2009-10-02 17:53:08.000000000 +0200 +@@ -99,6 +99,20 @@ + + AC_SUBST(AUTODIRS) + ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ + #AM_INIT_AUTOMAKE(taglib,1.0) + dnl don't remove the below + dnl AC_OUTPUT(taglib-config) +diff -dPNur taglib-1.6/configure.in.in taglib-1.6-ds/configure.in.in +--- taglib-1.6/configure.in.in 2009-09-13 13:30:19.000000000 +0200 ++++ taglib-1.6-ds/configure.in.in 2009-10-02 17:53:08.000000000 +0200 +@@ -95,6 +95,21 @@ + + AC_SUBST(AUTODIRS) + ++AC_CHECK_LIB(rcc, rccInit,[ ++ AC_CHECK_HEADERS(librcc.h,[ ++ LIBRCC_LIBS="-lrcc" ++ LIBRCC_INCLUDES="-DHAVE_LIBRCC" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) ++ ++ + #AM_INIT_AUTOMAKE(taglib,1.0) + dnl don't remove the below + dnl AC_OUTPUT(taglib-config) +diff -dPNur taglib-1.6/taglib/CMakeLists.txt taglib-1.6-ds/taglib/CMakeLists.txt +--- taglib-1.6/taglib/CMakeLists.txt 2009-09-13 12:19:34.000000000 +0200 ++++ taglib-1.6-ds/taglib/CMakeLists.txt 2009-10-02 17:53:08.000000000 +0200 +@@ -163,6 +163,7 @@ + ) + + SET(toolkit_SRCS ++toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -190,7 +191,7 @@ + add_library(tag SHARED ${tag_LIB_SRCS}) + endif(ENABLE_STATIC) + +-TARGET_LINK_LIBRARIES(tag ) ++TARGET_LINK_LIBRARIES(tag rcc) + if(ZLIB_FOUND) + TARGET_LINK_LIBRARIES(tag ${ZLIB_LIBRARIES}) + endif(ZLIB_FOUND) +diff -dPNur taglib-1.6/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.6-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.6/taglib/mpeg/id3v1/id3v1tag.cpp 2008-02-04 16:11:56.000000000 +0100 ++++ taglib-1.6-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -59,17 +59,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { + if(!s.isLatin1()) + { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); + } + +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -240,7 +241,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.6/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.6-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.6/taglib/mpeg/id3v2/frames/commentsframe.cpp 2008-02-04 16:11:56.000000000 +0100 ++++ taglib-1.6-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -136,10 +136,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = d->textEncoding == (String::Latin1 || String::Latin1ID3 || String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -155,10 +155,12 @@ + + String::Type encoding = d->textEncoding; + ++ encoding = String::ID3WType(encoding); ++ + encoding = checkEncoding(d->description, encoding); + encoding = checkEncoding(d->text, encoding); +- +- v.append(char(encoding)); ++ ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-1.6/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.6-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.6/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2008-02-04 16:11:56.000000000 +0100 ++++ taglib-1.6-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -105,12 +105,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -139,11 +139,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-1.6/taglib/toolkit/CMakeLists.txt taglib-1.6-ds/taglib/toolkit/CMakeLists.txt +--- taglib-1.6/taglib/toolkit/CMakeLists.txt 2006-09-20 14:52:28.000000000 +0200 ++++ taglib-1.6-ds/taglib/toolkit/CMakeLists.txt 2009-10-02 17:53:08.000000000 +0200 +@@ -1 +1 @@ +-INSTALL( FILES taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) ++INSTALL( FILES rccpatch.h taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) +diff -dPNur taglib-1.6/taglib/toolkit/Makefile.am taglib-1.6-ds/taglib/toolkit/Makefile.am +--- taglib-1.6/taglib/toolkit/Makefile.am 2009-09-04 11:07:27.000000000 +0200 ++++ taglib-1.6-ds/taglib/toolkit/Makefile.am 2009-10-03 02:34:01.000000000 +0200 +@@ -1,15 +1,21 @@ + DEFS = -DMAKE_TAGLIB_LIB @DEFS@ + INCLUDES = \ + -I$(top_srcdir)/taglib \ +- $(all_includes) ++ $(all_includes) \ ++ @LIBRCC_INCLUDES@ ++ ++libtoolkit_la_LIBADD = @LIBRCC_LIBS@ + + noinst_LTLIBRARIES = libtoolkit.la + + libtoolkit_la_SOURCES = \ ++ rccpatch.cpp \ + tstring.cpp tstringlist.cpp tbytevector.cpp \ + tbytevectorlist.cpp tfile.cpp tdebug.cpp unicode.cpp + ++ + taglib_include_HEADERS = \ ++ rccpatch.h \ + taglib.h tstring.h tlist.h tlist.tcc tstringlist.h \ + tbytevector.h tbytevectorlist.h tfile.h \ + tmap.h tmap.tcc +diff -dPNur taglib-1.6/taglib/toolkit/rccpatch.cpp taglib-1.6-ds/taglib/toolkit/rccpatch.cpp +--- taglib-1.6/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.6-ds/taglib/toolkit/rccpatch.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -0,0 +1,198 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::String::Type rccPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccPatchTryInit(); ++ ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.6/taglib/toolkit/rccpatch.h taglib-1.6-ds/taglib/toolkit/rccpatch.h +--- taglib-1.6/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.6-ds/taglib/toolkit/rccpatch.h 2009-10-02 17:53:08.000000000 +0200 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccPatchFree(); ++void rccPatchInit(); ++void rccPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccPatchGetLocaleType(); ++TagLib::String::Type rccPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.6/taglib/toolkit/tstring.cpp taglib-1.6-ds/taglib/toolkit/tstring.cpp +--- taglib-1.6/taglib/toolkit/tstring.cpp 2009-04-29 17:57:05.000000000 +0200 ++++ taglib-1.6-ds/taglib/toolkit/tstring.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -23,6 +23,7 @@ + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + ++#include "rccpatch.h" + #include "tstring.h" + #include "unicode.h" + #include "tdebug.h" +@@ -167,7 +168,7 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1 || t == UTF8) { ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2 || t == UTF8) { + + int length = 0; + d->data.resize(v.size()); +@@ -369,10 +370,21 @@ + { + ByteVector v; + +- switch(t) { ++ if (t == Locale) t = rccPatchGetLocaleType(); + ++ switch(t) { ++ case Locale: + case Latin1: ++ case Latin1ID3: ++ case Latin1ID3V2: + { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeOutputID3(s, true); ++ else /* if (t == Latin1(Locale) */ v = rccPatchRecodeOutput(s); ++ ++ if (v.size()) return v; ++ + for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + v.append(char(*it)); + break; +@@ -707,6 +719,31 @@ + + void String::prepare(Type t) + { ++ if (t == Locale) t = rccPatchGetLocaleType(); ++ ++ if ((t == Latin1)||(t == Latin1ID3)||(t == Latin1ID3V2)) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccPatchRecodeInputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeInputID3(s, true); ++ else /* Latin1 converted from Locale */ v = rccPatchRecodeInput(s); ++ ++ if (v.size()) { ++ int length = 0; ++ d->data.resize(v.size()); ++ wstring::iterator targetIt = d->data.begin(); ++ for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { ++ *targetIt = uchar(*it); ++ ++targetIt; ++ ++length; ++ } ++ d->data.resize(length); ++ } ++ ++ t = UTF8; ++ } ++ + switch(t) { + case UTF16: + { +@@ -796,6 +833,27 @@ + + std::ostream &operator<<(std::ostream &s, const String &str) + { +- s << str.to8Bit(); ++ ByteVector bv = str.data(String::Locale); ++ s << bv; + return s; + } ++ ++String::Type String::ID3Type(int i) { ++ if (i == Latin1) return Latin1ID3V2; ++ return Type(i); ++}; ++ ++String::Type String::ID3WType(Type type) { ++ Type rcc_type = rccPatchGetID3Type(); ++ if ((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)) { ++ if (type == Latin1) return rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++String::Type String::ID3RealType(Type type) { ++ if ((type == Latin1ID3)||(type == Latin1ID3V2)) return Latin1; ++ return type; ++} +diff -dPNur taglib-1.6/taglib/toolkit/tstring.h taglib-1.6-ds/taglib/toolkit/tstring.h +--- taglib-1.6/taglib/toolkit/tstring.h 2009-07-02 22:54:32.000000000 +0200 ++++ taglib-1.6-ds/taglib/toolkit/tstring.h 2009-10-02 17:53:08.000000000 +0200 +@@ -81,6 +81,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -103,6 +115,10 @@ + UTF16LE = 4 + }; + ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); ++ + /*! + * Constructs an empty String. + */ diff --git a/patches/taglib/taglib-1.7-ds-rusxmms-r2.patch b/patches/taglib/taglib-1.7-ds-rusxmms-r2.patch new file mode 100644 index 0000000..0757692 --- /dev/null +++ b/patches/taglib/taglib-1.7-ds-rusxmms-r2.patch @@ -0,0 +1,506 @@ +diff -dPNur taglib-1.7.2/config-taglib.h.cmake taglib-1.7.2-ds/config-taglib.h.cmake +--- taglib-1.7.2/config-taglib.h.cmake 2012-04-20 17:57:13.000000000 +0200 ++++ taglib-1.7.2-ds/config-taglib.h.cmake 2013-01-29 12:30:59.000000000 +0100 +@@ -6,6 +6,8 @@ + /* Define if you have libz */ + #cmakedefine HAVE_ZLIB 1 + ++#cmakedefine HAVE_LIBRCC 1 ++ + #cmakedefine NO_ITUNES_HACKS 1 + #cmakedefine WITH_ASF 1 + #cmakedefine WITH_MP4 1 +diff -dPNur taglib-1.7.2/ConfigureChecks.cmake taglib-1.7.2-ds/ConfigureChecks.cmake +--- taglib-1.7.2/ConfigureChecks.cmake 2012-04-20 17:57:13.000000000 +0200 ++++ taglib-1.7.2-ds/ConfigureChecks.cmake 2013-01-29 12:30:59.000000000 +0100 +@@ -14,6 +14,8 @@ + #check for libz using the cmake supplied FindZLIB.cmake + FIND_PACKAGE(ZLIB) + ++SET(HAVE_LIBRCC 1) ++ + IF(ZLIB_FOUND) + SET(HAVE_ZLIB 1) + ELSE(ZLIB_FOUND) +diff -dPNur taglib-1.7.2/taglib/CMakeLists.txt taglib-1.7.2-ds/taglib/CMakeLists.txt +--- taglib-1.7.2/taglib/CMakeLists.txt 2012-04-20 17:57:13.000000000 +0200 ++++ taglib-1.7.2-ds/taglib/CMakeLists.txt 2013-01-29 12:30:59.000000000 +0100 +@@ -171,6 +171,7 @@ + ) + + SET(toolkit_SRCS ++toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -198,7 +199,7 @@ + add_library(tag SHARED ${tag_LIB_SRCS}) + endif(ENABLE_STATIC) + +-TARGET_LINK_LIBRARIES(tag ) ++TARGET_LINK_LIBRARIES(tag rcc) + if(ZLIB_FOUND) + TARGET_LINK_LIBRARIES(tag ${ZLIB_LIBRARIES}) + endif(ZLIB_FOUND) +diff -dPNur taglib-1.7.2/taglib/CMakeLists.txt.orig taglib-1.7.2-ds/taglib/CMakeLists.txt.orig +diff -dPNur taglib-1.7.2/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.7.2-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.7.2/taglib/mpeg/id3v1/id3v1tag.cpp 2012-04-20 17:57:13.000000000 +0200 ++++ taglib-1.7.2-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2013-01-29 12:30:59.000000000 +0100 +@@ -59,17 +59,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { + if(!s.isLatin1()) + { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); + } + +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -240,7 +241,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.7.2/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.7.2-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.7.2/taglib/mpeg/id3v2/frames/commentsframe.cpp 2012-04-20 17:57:13.000000000 +0200 ++++ taglib-1.7.2-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2013-01-29 12:30:59.000000000 +0100 +@@ -136,10 +136,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -155,10 +155,12 @@ + + String::Type encoding = d->textEncoding; + ++ encoding = String::ID3WType(encoding); ++ + encoding = checkEncoding(d->description, encoding); + encoding = checkEncoding(d->text, encoding); +- +- v.append(char(encoding)); ++ ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-1.7.2/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.7.2-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.7.2/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2012-04-20 17:57:13.000000000 +0200 ++++ taglib-1.7.2-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2013-01-29 12:30:59.000000000 +0100 +@@ -105,12 +105,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -139,11 +139,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-1.7.2/taglib/toolkit/CMakeLists.txt taglib-1.7.2-ds/taglib/toolkit/CMakeLists.txt +--- taglib-1.7.2/taglib/toolkit/CMakeLists.txt 2012-04-20 17:57:13.000000000 +0200 ++++ taglib-1.7.2-ds/taglib/toolkit/CMakeLists.txt 2013-01-29 12:30:59.000000000 +0100 +@@ -1 +1 @@ +-INSTALL( FILES taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) ++INSTALL( FILES rccpatch.h taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) +diff -dPNur taglib-1.7.2/taglib/toolkit/rccpatch.cpp taglib-1.7.2-ds/taglib/toolkit/rccpatch.cpp +--- taglib-1.7.2/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.7.2-ds/taglib/toolkit/rccpatch.cpp 2013-01-29 12:35:45.000000000 +0100 +@@ -0,0 +1,192 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::String::Type rccPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccPatchTryInit(); ++ ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.7.2/taglib/toolkit/rccpatch.h taglib-1.7.2-ds/taglib/toolkit/rccpatch.h +--- taglib-1.7.2/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.7.2-ds/taglib/toolkit/rccpatch.h 2013-01-29 12:30:59.000000000 +0100 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccPatchFree(); ++void rccPatchInit(); ++void rccPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccPatchGetLocaleType(); ++TagLib::String::Type rccPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.7.2/taglib/toolkit/tstring.cpp taglib-1.7.2-ds/taglib/toolkit/tstring.cpp +--- taglib-1.7.2/taglib/toolkit/tstring.cpp 2012-04-20 17:57:13.000000000 +0200 ++++ taglib-1.7.2-ds/taglib/toolkit/tstring.cpp 2013-01-29 12:34:24.000000000 +0100 +@@ -23,6 +23,7 @@ + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + ++#include "rccpatch.h" + #include "tstring.h" + #include "unicode.h" + #include "tdebug.h" +@@ -167,7 +168,7 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1 || t == UTF8) { ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2 || t == UTF8) { + + int length = 0; + d->data.resize(v.size()); +@@ -369,10 +370,21 @@ + { + ByteVector v; + +- switch(t) { ++ if (t == Locale) t = rccPatchGetLocaleType(); + ++ switch(t) { ++ case Locale: + case Latin1: ++ case Latin1ID3: ++ case Latin1ID3V2: + { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeOutputID3(s, true); ++ else /* if (t == Latin1(Locale) */ v = rccPatchRecodeOutput(s); ++ ++ if (v.size()) return v; ++ + for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + v.append(char(*it)); + break; +@@ -717,6 +729,30 @@ + + void String::prepare(Type t) + { ++ if (t == Locale) t = rccPatchGetLocaleType(); ++ ++ if ((t == Latin1)||(t == Latin1ID3)||(t == Latin1ID3V2)) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccPatchRecodeInputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeInputID3(s, true); ++ else /* Latin1 converted from Locale */ v = rccPatchRecodeInput(s); ++ ++ if (v.size()) { ++ int length = 0; ++ d->data.resize(v.size()); ++ wstring::iterator targetIt = d->data.begin(); ++ for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { ++ *targetIt = uchar(*it); ++ ++targetIt; ++ ++length; ++ } ++ d->data.resize(length); ++ t = UTF8; ++ } ++ } ++ + switch(t) { + case UTF16: + { +@@ -806,6 +842,27 @@ + + std::ostream &operator<<(std::ostream &s, const String &str) + { +- s << str.to8Bit(); ++ ByteVector bv = str.data(String::Locale); ++ s << bv; + return s; + } ++ ++String::Type String::ID3Type(int i) { ++ if (i == Latin1) return Latin1ID3V2; ++ return Type(i); ++}; ++ ++String::Type String::ID3WType(Type type) { ++ Type rcc_type = rccPatchGetID3Type(); ++ if ((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)) { ++ if (type == Latin1) return rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++String::Type String::ID3RealType(Type type) { ++ if ((type == Latin1ID3)||(type == Latin1ID3V2)) return Latin1; ++ return type; ++} +diff -dPNur taglib-1.7.2/taglib/toolkit/tstring.h taglib-1.7.2-ds/taglib/toolkit/tstring.h +--- taglib-1.7.2/taglib/toolkit/tstring.h 2012-04-20 17:57:13.000000000 +0200 ++++ taglib-1.7.2-ds/taglib/toolkit/tstring.h 2013-01-29 12:30:59.000000000 +0100 +@@ -88,6 +88,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -110,6 +122,10 @@ + UTF16LE = 4 + }; + ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); ++ + /*! + * Constructs an empty String. + */ diff --git a/patches/taglib/taglib-1.7-ds-rusxmms.patch b/patches/taglib/taglib-1.7-ds-rusxmms.patch new file mode 100644 index 0000000..fce777f --- /dev/null +++ b/patches/taglib/taglib-1.7-ds-rusxmms.patch @@ -0,0 +1,515 @@ +diff -dPNur taglib-1.6/config-taglib.h.cmake taglib-1.6-ds/config-taglib.h.cmake +--- taglib-1.6/config-taglib.h.cmake 2008-11-12 09:17:11.000000000 +0100 ++++ taglib-1.6-ds/config-taglib.h.cmake 2009-10-02 17:53:08.000000000 +0200 +@@ -6,6 +6,8 @@ + /* Define if you have libz */ + #cmakedefine HAVE_ZLIB 1 + ++#cmakedefine HAVE_LIBRCC 1 ++ + #cmakedefine NO_ITUNES_HACKS 1 + #cmakedefine WITH_ASF 1 + #cmakedefine WITH_MP4 1 +diff -dPNur taglib-1.6/ConfigureChecks.cmake taglib-1.6-ds/ConfigureChecks.cmake +--- taglib-1.6/ConfigureChecks.cmake 2008-12-21 22:46:41.000000000 +0100 ++++ taglib-1.6-ds/ConfigureChecks.cmake 2009-10-02 17:53:08.000000000 +0200 +@@ -14,6 +14,8 @@ + #check for libz using the cmake supplied FindZLIB.cmake + FIND_PACKAGE(ZLIB) + ++SET(HAVE_LIBRCC 1) ++ + IF(ZLIB_FOUND) + SET(HAVE_ZLIB 1) + ELSE(ZLIB_FOUND) +diff -dPNur taglib-1.6/configure.in taglib-1.6-ds/configure.in +diff -dPNur taglib-1.6/configure.in.in taglib-1.6-ds/configure.in.in +diff -dPNur taglib-1.6/taglib/CMakeLists.txt taglib-1.6-ds/taglib/CMakeLists.txt +--- taglib-1.6/taglib/CMakeLists.txt 2009-09-13 12:19:34.000000000 +0200 ++++ taglib-1.6-ds/taglib/CMakeLists.txt 2009-10-02 17:53:08.000000000 +0200 +@@ -163,6 +163,7 @@ + ) + + SET(toolkit_SRCS ++toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -190,7 +191,7 @@ + add_library(tag SHARED ${tag_LIB_SRCS}) + endif(ENABLE_STATIC) + +-TARGET_LINK_LIBRARIES(tag ) ++TARGET_LINK_LIBRARIES(tag rcc) + if(ZLIB_FOUND) + TARGET_LINK_LIBRARIES(tag ${ZLIB_LIBRARIES}) + endif(ZLIB_FOUND) +diff -dPNur taglib-1.6/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.6-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.6/taglib/mpeg/id3v1/id3v1tag.cpp 2008-02-04 16:11:56.000000000 +0100 ++++ taglib-1.6-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -59,17 +59,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { + if(!s.isLatin1()) + { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); + } + +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -240,7 +241,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.6/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.6-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.6/taglib/mpeg/id3v2/frames/commentsframe.cpp 2008-02-04 16:11:56.000000000 +0100 ++++ taglib-1.6-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -136,10 +136,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -155,10 +155,12 @@ + + String::Type encoding = d->textEncoding; + ++ encoding = String::ID3WType(encoding); ++ + encoding = checkEncoding(d->description, encoding); + encoding = checkEncoding(d->text, encoding); +- +- v.append(char(encoding)); ++ ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-1.6/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.6-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.6/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2008-02-04 16:11:56.000000000 +0100 ++++ taglib-1.6-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -105,12 +105,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -139,11 +139,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-1.6/taglib/toolkit/CMakeLists.txt taglib-1.6-ds/taglib/toolkit/CMakeLists.txt +--- taglib-1.6/taglib/toolkit/CMakeLists.txt 2006-09-20 14:52:28.000000000 +0200 ++++ taglib-1.6-ds/taglib/toolkit/CMakeLists.txt 2009-10-02 17:53:08.000000000 +0200 +@@ -1 +1 @@ +-INSTALL( FILES taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) ++INSTALL( FILES rccpatch.h taglib.h tstring.h tlist.h tlist.tcc tstringlist.h tbytevector.h tbytevectorlist.h tfile.h tmap.h tmap.tcc DESTINATION ${INCLUDE_INSTALL_DIR}/taglib) +diff -dPNur taglib-1.6/taglib/toolkit/Makefile.am taglib-1.6-ds/taglib/toolkit/Makefile.am +diff -dPNur taglib-1.6/taglib/toolkit/rccpatch.cpp taglib-1.6-ds/taglib/toolkit/rccpatch.cpp +--- taglib-1.6/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.6-ds/taglib/toolkit/rccpatch.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -0,0 +1,198 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::String::Type rccPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccPatchTryInit(); ++ ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.6/taglib/toolkit/rccpatch.h taglib-1.6-ds/taglib/toolkit/rccpatch.h +--- taglib-1.6/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.6-ds/taglib/toolkit/rccpatch.h 2009-10-02 17:53:08.000000000 +0200 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccPatchFree(); ++void rccPatchInit(); ++void rccPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccPatchGetLocaleType(); ++TagLib::String::Type rccPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.6/taglib/toolkit/tstring.cpp taglib-1.6-ds/taglib/toolkit/tstring.cpp +--- taglib-1.6/taglib/toolkit/tstring.cpp 2009-04-29 17:57:05.000000000 +0200 ++++ taglib-1.6-ds/taglib/toolkit/tstring.cpp 2009-10-02 17:53:08.000000000 +0200 +@@ -23,6 +23,7 @@ + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + ++#include "rccpatch.h" + #include "tstring.h" + #include "unicode.h" + #include "tdebug.h" +@@ -167,7 +168,7 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1 || t == UTF8) { ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2 || t == UTF8) { + + int length = 0; + d->data.resize(v.size()); +@@ -369,10 +370,21 @@ + { + ByteVector v; + +- switch(t) { ++ if (t == Locale) t = rccPatchGetLocaleType(); + ++ switch(t) { ++ case Locale: + case Latin1: ++ case Latin1ID3: ++ case Latin1ID3V2: + { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeOutputID3(s, true); ++ else /* if (t == Latin1(Locale) */ v = rccPatchRecodeOutput(s); ++ ++ if (v.size()) return v; ++ + for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + v.append(char(*it)); + break; +@@ -707,6 +719,31 @@ + + void String::prepare(Type t) + { ++ if (t == Locale) t = rccPatchGetLocaleType(); ++ ++ if ((t == Latin1)||(t == Latin1ID3)||(t == Latin1ID3V2)) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccPatchRecodeInputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeInputID3(s, true); ++ else /* Latin1 converted from Locale */ v = rccPatchRecodeInput(s); ++ ++ if (v.size()) { ++ int length = 0; ++ d->data.resize(v.size()); ++ wstring::iterator targetIt = d->data.begin(); ++ for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { ++ *targetIt = uchar(*it); ++ ++targetIt; ++ ++length; ++ } ++ d->data.resize(length); ++ } ++ ++ t = UTF8; ++ } ++ + switch(t) { + case UTF16: + { +@@ -796,6 +833,27 @@ + + std::ostream &operator<<(std::ostream &s, const String &str) + { +- s << str.to8Bit(); ++ ByteVector bv = str.data(String::Locale); ++ s << bv; + return s; + } ++ ++String::Type String::ID3Type(int i) { ++ if (i == Latin1) return Latin1ID3V2; ++ return Type(i); ++}; ++ ++String::Type String::ID3WType(Type type) { ++ Type rcc_type = rccPatchGetID3Type(); ++ if ((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)) { ++ if (type == Latin1) return rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++String::Type String::ID3RealType(Type type) { ++ if ((type == Latin1ID3)||(type == Latin1ID3V2)) return Latin1; ++ return type; ++} +diff -dPNur taglib-1.6/taglib/toolkit/tstring.h taglib-1.6-ds/taglib/toolkit/tstring.h +--- taglib-1.6/taglib/toolkit/tstring.h 2009-07-02 22:54:32.000000000 +0200 ++++ taglib-1.6-ds/taglib/toolkit/tstring.h 2009-10-02 17:53:08.000000000 +0200 +@@ -81,6 +81,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -103,6 +115,10 @@ + UTF16LE = 4 + }; + ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); ++ + /*! + * Constructs an empty String. + */ diff --git a/patches/taglib/taglib-1.8-ds-rusxmms-r2.patch b/patches/taglib/taglib-1.8-ds-rusxmms-r2.patch new file mode 100644 index 0000000..bed92a2 --- /dev/null +++ b/patches/taglib/taglib-1.8-ds-rusxmms-r2.patch @@ -0,0 +1,507 @@ +diff -dPNur taglib-1.8/config-taglib.h.cmake taglib-1.8-ds/config-taglib.h.cmake +--- taglib-1.8/config-taglib.h.cmake 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/config-taglib.h.cmake 2013-01-29 12:45:48.000000000 +0100 +@@ -3,6 +3,8 @@ + /* Define if you have libz */ + #cmakedefine HAVE_ZLIB 1 + ++#cmakedefine HAVE_LIBRCC 1 ++ + #cmakedefine NO_ITUNES_HACKS 1 + #cmakedefine WITH_ASF 1 + #cmakedefine WITH_MP4 1 +diff -dPNur taglib-1.8/ConfigureChecks.cmake taglib-1.8-ds/ConfigureChecks.cmake +--- taglib-1.8/ConfigureChecks.cmake 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/ConfigureChecks.cmake 2013-01-29 12:45:48.000000000 +0100 +@@ -14,6 +14,8 @@ + set(HAVE_ZLIB 0) + endif() + ++SET(HAVE_LIBRCC 1) ++ + set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) + find_package(CppUnit) + if(NOT CppUnit_FOUND AND BUILD_TESTS) +diff -dPNur taglib-1.8/taglib/CMakeLists.txt taglib-1.8-ds/taglib/CMakeLists.txt +--- taglib-1.8/taglib/CMakeLists.txt 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/CMakeLists.txt 2013-01-29 12:45:48.000000000 +0100 +@@ -35,6 +35,7 @@ + audioproperties.h + taglib_export.h + ${CMAKE_BINARY_DIR}/taglib_config.h ++ toolkit/rccpatch.h + toolkit/taglib.h + toolkit/tstring.h + toolkit/tlist.h +@@ -269,6 +270,7 @@ + ) + + set(toolkit_SRCS ++ toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -296,7 +298,7 @@ + add_library(tag ${tag_LIB_SRCS} ${tag_HDRS}) + + if(ZLIB_FOUND) +- target_link_libraries(tag ${ZLIB_LIBRARIES}) ++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES}) + endif() + + set_target_properties(tag PROPERTIES +diff -dPNur taglib-1.8/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.8-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.8/taglib/mpeg/id3v1/id3v1tag.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2013-01-29 12:45:48.000000000 +0100 +@@ -64,17 +64,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { + if(!s.isLatin1()) + { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); + } + +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -247,7 +248,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.8-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2013-01-29 12:45:48.000000000 +0100 +@@ -150,10 +150,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -174,10 +174,12 @@ + + String::Type encoding = d->textEncoding; + ++ encoding = String::ID3WType(encoding); ++ + encoding = checkTextEncoding(d->description, encoding); + encoding = checkTextEncoding(d->text, encoding); +- +- v.append(char(encoding)); ++ ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.8-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2013-01-29 12:45:48.000000000 +0100 +@@ -187,12 +187,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -223,11 +223,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkTextEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-1.8/taglib/toolkit/rccpatch.cpp taglib-1.8-ds/taglib/toolkit/rccpatch.cpp +--- taglib-1.8/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.8-ds/taglib/toolkit/rccpatch.cpp 2013-01-29 12:35:45.000000000 +0100 +@@ -0,0 +1,192 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::String::Type rccPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccPatchTryInit(); ++ ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.8/taglib/toolkit/rccpatch.h taglib-1.8-ds/taglib/toolkit/rccpatch.h +--- taglib-1.8/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.8-ds/taglib/toolkit/rccpatch.h 2013-01-29 12:45:48.000000000 +0100 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccPatchFree(); ++void rccPatchInit(); ++void rccPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccPatchGetLocaleType(); ++TagLib::String::Type rccPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.8/taglib/toolkit/tstring.cpp taglib-1.8-ds/taglib/toolkit/tstring.cpp +--- taglib-1.8/taglib/toolkit/tstring.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/toolkit/tstring.cpp 2013-01-29 12:46:14.000000000 +0100 +@@ -23,6 +23,7 @@ + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + ++#include "rccpatch.h" + #include "tstring.h" + #include "unicode.h" + #include "tdebug.h" +@@ -168,7 +169,7 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1 || t == UTF8) { ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2 || t == UTF8) { + + int length = 0; + d->data.resize(v.size()); +@@ -397,10 +398,21 @@ + { + ByteVector v; + +- switch(t) { ++ if (t == Locale) t = rccPatchGetLocaleType(); + ++ switch(t) { ++ case Locale: + case Latin1: ++ case Latin1ID3: ++ case Latin1ID3V2: + { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeOutputID3(s, true); ++ else /* if (t == Latin1(Locale) */ v = rccPatchRecodeOutput(s); ++ ++ if (v.size()) return v; ++ + for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + v.append(char(*it)); + break; +@@ -750,6 +762,30 @@ + + void String::prepare(Type t) + { ++ if (t == Locale) t = rccPatchGetLocaleType(); ++ ++ if ((t == Latin1)||(t == Latin1ID3)||(t == Latin1ID3V2)) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccPatchRecodeInputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeInputID3(s, true); ++ else /* Latin1 converted from Locale */ v = rccPatchRecodeInput(s); ++ ++ if (v.size()) { ++ int length = 0; ++ d->data.resize(v.size()); ++ wstring::iterator targetIt = d->data.begin(); ++ for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { ++ *targetIt = uchar(*it); ++ ++targetIt; ++ ++length; ++ } ++ d->data.resize(length); ++ t = UTF8; ++ } ++ } ++ + switch(t) { + case UTF16: + { +@@ -839,6 +875,27 @@ + + std::ostream &operator<<(std::ostream &s, const String &str) + { +- s << str.to8Bit(); ++ ByteVector bv = str.data(String::Locale); ++ s << bv; + return s; + } ++ ++String::Type String::ID3Type(int i) { ++ if (i == Latin1) return Latin1ID3V2; ++ return Type(i); ++}; ++ ++String::Type String::ID3WType(Type type) { ++ Type rcc_type = rccPatchGetID3Type(); ++ if ((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)) { ++ if (type == Latin1) return rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++String::Type String::ID3RealType(Type type) { ++ if ((type == Latin1ID3)||(type == Latin1ID3V2)) return Latin1; ++ return type; ++} +diff -dPNur taglib-1.8/taglib/toolkit/tstring.h taglib-1.8-ds/taglib/toolkit/tstring.h +--- taglib-1.8/taglib/toolkit/tstring.h 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/toolkit/tstring.h 2013-01-29 12:45:48.000000000 +0100 +@@ -90,6 +90,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -112,6 +124,10 @@ + UTF16LE = 4 + }; + ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); ++ + /*! + * Constructs an empty String. + */ diff --git a/patches/taglib/taglib-1.8-ds-rusxmms-r9.patch b/patches/taglib/taglib-1.8-ds-rusxmms-r9.patch new file mode 100644 index 0000000..28a7b84 --- /dev/null +++ b/patches/taglib/taglib-1.8-ds-rusxmms-r9.patch @@ -0,0 +1,609 @@ +diff -dPNur taglib-1.8/config-taglib.h.cmake taglib-1.8-ds/config-taglib.h.cmake +--- taglib-1.8/config-taglib.h.cmake 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/config-taglib.h.cmake 2013-05-22 20:13:15.000000000 +0200 +@@ -3,6 +3,8 @@ + /* Define if you have libz */ + #cmakedefine HAVE_ZLIB 1 + ++#cmakedefine HAVE_LIBRCC 1 ++ + #cmakedefine NO_ITUNES_HACKS 1 + #cmakedefine WITH_ASF 1 + #cmakedefine WITH_MP4 1 +diff -dPNur taglib-1.8/ConfigureChecks.cmake taglib-1.8-ds/ConfigureChecks.cmake +--- taglib-1.8/ConfigureChecks.cmake 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/ConfigureChecks.cmake 2013-05-22 20:13:15.000000000 +0200 +@@ -14,6 +14,8 @@ + set(HAVE_ZLIB 0) + endif() + ++SET(HAVE_LIBRCC 1) ++ + set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) + find_package(CppUnit) + if(NOT CppUnit_FOUND AND BUILD_TESTS) +diff -dPNur taglib-1.8/examples/tagreader_c.c taglib-1.8-ds/examples/tagreader_c.c +--- taglib-1.8/examples/tagreader_c.c 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/examples/tagreader_c.c 2013-05-22 20:13:15.000000000 +0200 +@@ -38,7 +38,7 @@ + TagLib_Tag *tag; + const TagLib_AudioProperties *properties; + +- taglib_set_strings_unicode(FALSE); ++// taglib_set_strings_unicode(FALSE); + + for(i = 1; i < argc; i++) { + printf("******************** \"%s\" ********************\n", argv[i]); +diff -dPNur taglib-1.8/examples/tagwriter.cpp taglib-1.8-ds/examples/tagwriter.cpp +--- taglib-1.8/examples/tagwriter.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/examples/tagwriter.cpp 2013-05-22 20:13:15.000000000 +0200 +@@ -92,7 +92,7 @@ + if(isArgument(argv[i]) && i + 1 < argc && !isArgument(argv[i + 1])) { + + char field = argv[i][1]; +- TagLib::String value = argv[i + 1]; ++ TagLib::String value(argv[i + 1], TagLib::String::Locale); + + TagLib::List<TagLib::FileRef>::Iterator it; + for(it = fileList.begin(); it != fileList.end(); ++it) { +diff -dPNur taglib-1.8/taglib/CMakeLists.txt taglib-1.8-ds/taglib/CMakeLists.txt +--- taglib-1.8/taglib/CMakeLists.txt 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/CMakeLists.txt 2013-05-22 20:13:15.000000000 +0200 +@@ -35,6 +35,7 @@ + audioproperties.h + taglib_export.h + ${CMAKE_BINARY_DIR}/taglib_config.h ++ toolkit/rccpatch.h + toolkit/taglib.h + toolkit/tstring.h + toolkit/tlist.h +@@ -269,6 +270,7 @@ + ) + + set(toolkit_SRCS ++ toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -296,7 +298,7 @@ + add_library(tag ${tag_LIB_SRCS} ${tag_HDRS}) + + if(ZLIB_FOUND) +- target_link_libraries(tag ${ZLIB_LIBRARIES}) ++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES}) + endif() + + set_target_properties(tag PROPERTIES +diff -dPNur taglib-1.8/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.8-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.8/taglib/mpeg/id3v1/id3v1tag.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2013-05-22 20:13:15.000000000 +0200 +@@ -64,17 +64,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { + if(!s.isLatin1()) + { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); + } + +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -247,7 +248,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.8-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2013-05-22 20:13:16.000000000 +0200 +@@ -150,10 +150,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -174,10 +174,12 @@ + + String::Type encoding = d->textEncoding; + ++ encoding = String::ID3WType(encoding); ++ + encoding = checkTextEncoding(d->description, encoding); + encoding = checkTextEncoding(d->text, encoding); +- +- v.append(char(encoding)); ++ ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.8-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2013-05-22 20:13:16.000000000 +0200 +@@ -187,12 +187,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -223,11 +223,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkTextEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-1.8/taglib/mpeg/id3v2/id3v2frame.cpp taglib-1.8-ds/taglib/mpeg/id3v2/id3v2frame.cpp +--- taglib-1.8/taglib/mpeg/id3v2/id3v2frame.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v2/id3v2frame.cpp 2013-05-22 20:10:07.000000000 +0200 +@@ -295,7 +295,7 @@ + if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4) + return String::UTF16; + +- if(encoding != String::Latin1) ++ if((encoding != String::Latin1)&&(encoding != String::Latin1ID3V2)) + return encoding; + + for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) { +diff -dPNur taglib-1.8/taglib/toolkit/rccpatch.cpp taglib-1.8-ds/taglib/toolkit/rccpatch.cpp +--- taglib-1.8/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.8-ds/taglib/toolkit/rccpatch.cpp 2013-05-22 20:13:16.000000000 +0200 +@@ -0,0 +1,237 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++//#define RCC_DEBUG ++ ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# ifdef RCC_DEBUG ++# include <stdio.h> ++# endif /* RCC_DEBUG */ ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccTaglibPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccTaglibPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccTaglibPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccTaglibPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccTaglibPatchInit(); ++ if (rcc_initialized) atexit(rccTaglibPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" Output: %s - %s\n", s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else v.setData("", 0); ++ //v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" OutputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else v.setData("", 0); ++ //v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" Input: %s - %s\n", s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" InputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ if (res) v.setData(res, rlen); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::String::Type rccTaglibPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccTaglibPatchTryInit(); ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccTaglibPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccTaglibPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } else { ++ // Error or no-language configured: If Latin1ID3V2 is returned we normally will use the default unicode encoding unless Latin1 is selected by taglib ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.8/taglib/toolkit/rccpatch.h taglib-1.8-ds/taglib/toolkit/rccpatch.h +--- taglib-1.8/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.8-ds/taglib/toolkit/rccpatch.h 2013-05-22 20:13:16.000000000 +0200 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccTaglibPatchFree(); ++void rccTaglibPatchInit(); ++void rccTaglibPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccTaglibPatchGetLocaleType(); ++TagLib::String::Type rccTaglibPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.8/taglib/toolkit/tstring.cpp taglib-1.8-ds/taglib/toolkit/tstring.cpp +--- taglib-1.8/taglib/toolkit/tstring.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/toolkit/tstring.cpp 2013-05-22 20:13:16.000000000 +0200 +@@ -23,6 +23,7 @@ + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + ++#include "rccpatch.h" + #include "tstring.h" + #include "unicode.h" + #include "tdebug.h" +@@ -168,7 +169,7 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1 || t == UTF8) { ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2 || t == UTF8) { + + int length = 0; + d->data.resize(v.size()); +@@ -397,10 +398,38 @@ + { + ByteVector v; + +- switch(t) { ++ if (t == Locale) { ++ // The source is either Unicode or real Latin1 (if rcc is bypassed) ++ std::string s = to8Bit(true); ++ ++ // In case of UTF8 locale, this probably will return NULL (no recoding needed), but we will take UTF8 path in the next swtich ++ v = rccTaglibPatchRecodeOutput(s); ++ if (v.size()) return v; + ++ t = rccTaglibPatchGetLocaleType(); ++ } ++ ++ switch(t) { ++ case Latin1ID3: ++ case Latin1ID3V2: ++ { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccTaglibPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeOutputID3(s, true); ++ if (v.size()) break; ++ ++ // we don't know if we got NULL because rcc is disabled (error) or UTF8 output is required ++ if ((t == Latin1ID3V2)&&(rccTaglibPatchGetID3Type() == UTF8)) { ++ v.setData(s.c_str(), s.length()); ++ } else { ++ for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) ++ v.append(char(*it)); ++ } ++ break; ++ } + case Latin1: + { ++ // We can have the UTF16 inside, but first 256 positions is equal to Latin1 + for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + v.append(char(*it)); + break; +@@ -750,6 +779,34 @@ + + void String::prepare(Type t) + { ++ if (t == Locale) t = rccTaglibPatchGetLocaleType(); ++ ++ if ((t == Latin1)||(t == Latin1ID3)||(t == Latin1ID3V2)) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccTaglibPatchRecodeInputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeInputID3(s, true); ++ else /* Latin1 converted from Locale */ v = rccTaglibPatchRecodeInput(s); ++ ++ if (v.size()) { ++ int length = 0; ++ d->data.resize(v.size()); ++ wstring::iterator targetIt = d->data.begin(); ++ for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { ++ *targetIt = uchar(*it); ++ ++targetIt; ++ ++length; ++ } ++ d->data.resize(length); ++ t = UTF8; ++ } else { ++ // We don't know if we got UTF-8 encoded string or either rcc is disable or something is failed, ++ // since standard applications are really expecting here Latin1, it is safe to just check if we have violations of UTF8 ++ //if (Unicode::isLegalUTF8(s)) t = UTF8; ++ } ++ } ++ + switch(t) { + case UTF16: + { +@@ -839,6 +896,27 @@ + + std::ostream &operator<<(std::ostream &s, const String &str) + { +- s << str.to8Bit(); ++ ByteVector bv = str.data(String::Locale); ++ s << bv; + return s; + } ++ ++String::Type String::ID3Type(int i) { ++ if (i == Latin1) return Latin1ID3V2; ++ return Type(i); ++}; ++ ++String::Type String::ID3WType(Type type) { ++ Type rcc_type = rccTaglibPatchGetID3Type(); ++ if ((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)||(rcc_type == Latin1)) { ++ if (type == Latin1) return rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++String::Type String::ID3RealType(Type type) { ++ if ((type == Latin1ID3)||(type == Latin1ID3V2)) return Latin1; ++ return type; ++} +diff -dPNur taglib-1.8/taglib/toolkit/tstring.h taglib-1.8-ds/taglib/toolkit/tstring.h +--- taglib-1.8/taglib/toolkit/tstring.h 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/toolkit/tstring.h 2013-05-22 20:13:16.000000000 +0200 +@@ -90,6 +90,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -112,6 +124,10 @@ + UTF16LE = 4 + }; + ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); ++ + /*! + * Constructs an empty String. + */ diff --git a/patches/taglib/taglib-1.8-ds-rusxmms.patch b/patches/taglib/taglib-1.8-ds-rusxmms.patch new file mode 100644 index 0000000..a5c04a5 --- /dev/null +++ b/patches/taglib/taglib-1.8-ds-rusxmms.patch @@ -0,0 +1,519 @@ +diff -dPNur taglib-1.8/config-taglib.h.cmake taglib-1.8-ds/config-taglib.h.cmake +--- taglib-1.8/config-taglib.h.cmake 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/config-taglib.h.cmake 2012-11-11 09:59:50.000000000 +0100 +@@ -3,6 +3,8 @@ + /* Define if you have libz */ + #cmakedefine HAVE_ZLIB 1 + ++#cmakedefine HAVE_LIBRCC 1 ++ + #cmakedefine NO_ITUNES_HACKS 1 + #cmakedefine WITH_ASF 1 + #cmakedefine WITH_MP4 1 +diff -dPNur taglib-1.8/ConfigureChecks.cmake taglib-1.8-ds/ConfigureChecks.cmake +--- taglib-1.8/ConfigureChecks.cmake 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/ConfigureChecks.cmake 2012-11-11 10:01:48.000000000 +0100 +@@ -14,6 +14,8 @@ + set(HAVE_ZLIB 0) + endif() + ++SET(HAVE_LIBRCC 1) ++ + set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) + find_package(CppUnit) + if(NOT CppUnit_FOUND AND BUILD_TESTS) +diff -dPNur taglib-1.8/taglib/CMakeLists.txt taglib-1.8-ds/taglib/CMakeLists.txt +--- taglib-1.8/taglib/CMakeLists.txt 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/CMakeLists.txt 2012-11-11 10:04:40.000000000 +0100 +@@ -35,6 +35,7 @@ + audioproperties.h + taglib_export.h + ${CMAKE_BINARY_DIR}/taglib_config.h ++ toolkit/rccpatch.h + toolkit/taglib.h + toolkit/tstring.h + toolkit/tlist.h +@@ -269,6 +270,7 @@ + ) + + set(toolkit_SRCS ++ toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -296,7 +298,7 @@ + add_library(tag ${tag_LIB_SRCS} ${tag_HDRS}) + + if(ZLIB_FOUND) +- target_link_libraries(tag ${ZLIB_LIBRARIES}) ++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES}) + endif() + + set_target_properties(tag PROPERTIES +diff -dPNur taglib-1.8/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.8-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.8/taglib/mpeg/id3v1/id3v1tag.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2012-11-11 09:59:50.000000000 +0100 +@@ -64,17 +64,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { + if(!s.isLatin1()) + { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); + } + +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -247,7 +248,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.8/taglib/mpeg/id3v1/id3v1tag.cpp.orig taglib-1.8-ds/taglib/mpeg/id3v1/id3v1tag.cpp.orig +diff -dPNur taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.8-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2012-11-11 09:59:50.000000000 +0100 +@@ -150,10 +150,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -174,10 +174,12 @@ + + String::Type encoding = d->textEncoding; + ++ encoding = String::ID3WType(encoding); ++ + encoding = checkTextEncoding(d->description, encoding); + encoding = checkTextEncoding(d->text, encoding); +- +- v.append(char(encoding)); ++ ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-1.8/taglib/mpeg/id3v2/frames/commentsframe.cpp.orig taglib-1.8-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp.orig +diff -dPNur taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.8-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2012-11-11 09:59:50.000000000 +0100 +@@ -187,12 +187,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -223,11 +223,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkTextEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-1.8/taglib/mpeg/id3v2/frames/textidentificationframe.cpp.orig taglib-1.8-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp.orig +diff -dPNur taglib-1.8/taglib/toolkit/rccpatch.cpp taglib-1.8-ds/taglib/toolkit/rccpatch.cpp +--- taglib-1.8/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.8-ds/taglib/toolkit/rccpatch.cpp 2012-11-11 10:00:09.000000000 +0100 +@@ -0,0 +1,198 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccPatchInit(); ++ if (rcc_initialized) atexit(rccPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++ if (res) v.setData(res, rlen); ++ else v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::String::Type rccPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccPatchTryInit(); ++ ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.8/taglib/toolkit/rccpatch.h taglib-1.8-ds/taglib/toolkit/rccpatch.h +--- taglib-1.8/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.8-ds/taglib/toolkit/rccpatch.h 2012-11-11 10:00:09.000000000 +0100 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccPatchFree(); ++void rccPatchInit(); ++void rccPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccPatchGetLocaleType(); ++TagLib::String::Type rccPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.8/taglib/toolkit/tstring.cpp taglib-1.8-ds/taglib/toolkit/tstring.cpp +--- taglib-1.8/taglib/toolkit/tstring.cpp 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/toolkit/tstring.cpp 2012-11-11 10:00:09.000000000 +0100 +@@ -23,6 +23,7 @@ + * http://www.mozilla.org/MPL/ * + ***************************************************************************/ + ++#include "rccpatch.h" + #include "tstring.h" + #include "unicode.h" + #include "tdebug.h" +@@ -168,7 +169,7 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1 || t == UTF8) { ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2 || t == UTF8) { + + int length = 0; + d->data.resize(v.size()); +@@ -397,10 +398,21 @@ + { + ByteVector v; + +- switch(t) { ++ if (t == Locale) t = rccPatchGetLocaleType(); + ++ switch(t) { ++ case Locale: + case Latin1: ++ case Latin1ID3: ++ case Latin1ID3V2: + { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeOutputID3(s, true); ++ else /* if (t == Latin1(Locale) */ v = rccPatchRecodeOutput(s); ++ ++ if (v.size()) return v; ++ + for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + v.append(char(*it)); + break; +@@ -750,6 +762,31 @@ + + void String::prepare(Type t) + { ++ if (t == Locale) t = rccPatchGetLocaleType(); ++ ++ if ((t == Latin1)||(t == Latin1ID3)||(t == Latin1ID3V2)) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccPatchRecodeInputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccPatchRecodeInputID3(s, true); ++ else /* Latin1 converted from Locale */ v = rccPatchRecodeInput(s); ++ ++ if (v.size()) { ++ int length = 0; ++ d->data.resize(v.size()); ++ wstring::iterator targetIt = d->data.begin(); ++ for(ByteVector::ConstIterator it = v.begin(); it != v.end() && (*it); ++it) { ++ *targetIt = uchar(*it); ++ ++targetIt; ++ ++length; ++ } ++ d->data.resize(length); ++ } ++ ++ t = UTF8; ++ } ++ + switch(t) { + case UTF16: + { +@@ -839,6 +876,27 @@ + + std::ostream &operator<<(std::ostream &s, const String &str) + { +- s << str.to8Bit(); ++ ByteVector bv = str.data(String::Locale); ++ s << bv; + return s; + } ++ ++String::Type String::ID3Type(int i) { ++ if (i == Latin1) return Latin1ID3V2; ++ return Type(i); ++}; ++ ++String::Type String::ID3WType(Type type) { ++ Type rcc_type = rccPatchGetID3Type(); ++ if ((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)) { ++ if (type == Latin1) return rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++String::Type String::ID3RealType(Type type) { ++ if ((type == Latin1ID3)||(type == Latin1ID3V2)) return Latin1; ++ return type; ++} +diff -dPNur taglib-1.8/taglib/toolkit/tstring.cpp.orig taglib-1.8-ds/taglib/toolkit/tstring.cpp.orig +diff -dPNur taglib-1.8/taglib/toolkit/tstring.h taglib-1.8-ds/taglib/toolkit/tstring.h +--- taglib-1.8/taglib/toolkit/tstring.h 2012-09-06 20:03:15.000000000 +0200 ++++ taglib-1.8-ds/taglib/toolkit/tstring.h 2012-11-11 10:00:09.000000000 +0100 +@@ -90,6 +90,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -112,6 +124,10 @@ + UTF16LE = 4 + }; + ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); ++ + /*! + * Constructs an empty String. + */ +diff -dPNur taglib-1.8/taglib/toolkit/tstring.h.orig taglib-1.8-ds/taglib/toolkit/tstring.h.orig diff --git a/patches/taglib/taglib-1.9.1-ds-rusxmms-enforce.patch b/patches/taglib/taglib-1.9.1-ds-rusxmms-enforce.patch new file mode 100644 index 0000000..e980b7a --- /dev/null +++ b/patches/taglib/taglib-1.9.1-ds-rusxmms-enforce.patch @@ -0,0 +1,20 @@ +--- taglib-1.9.1/taglib/mpeg/id3v1/id3v1tag.h 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-taurus/taglib/mpeg/id3v1/id3v1tag.h 2013-11-12 00:24:31.206495291 +0100 +@@ -68,7 +68,7 @@ + * Decode a string from \a data. The default implementation assumes that + * \a data is an ISO-8859-1 (Latin1) character array. + */ +- virtual String parse(const ByteVector &data) const; ++ String parse(const ByteVector &data) const; + + /*! + * Encode a ByteVector with the data from \a s. The default implementation +@@ -79,7 +79,7 @@ + * instead do not write an ID3v1 tag in the case that the data is not + * ISO-8859-1. + */ +- virtual ByteVector render(const String &s) const; ++ ByteVector render(const String &s) const; + }; + + //! The main class in the ID3v1 implementation diff --git a/patches/taglib/taglib-1.9.1-ds-rusxmms.patch b/patches/taglib/taglib-1.9.1-ds-rusxmms.patch new file mode 100644 index 0000000..b64b5b5 --- /dev/null +++ b/patches/taglib/taglib-1.9.1-ds-rusxmms.patch @@ -0,0 +1,676 @@ +diff -dPNur taglib-1.9.1/config.h.cmake taglib-1.9.1-ds/config.h.cmake +--- taglib-1.9.1/config.h.cmake 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/config.h.cmake 2013-11-11 13:43:48.500304915 +0100 +@@ -31,6 +31,9 @@ + /* Defined if you have libz */ + #cmakedefine HAVE_ZLIB 1 + ++/* Defined if you have LibRCC from RusXMMS project */ ++#cmakedefine HAVE_LIBRCC 1 ++ + /* Indicates whether debug messages are shown even in release mode */ + #cmakedefine TRACE_IN_RELEASE 1 + +diff -dPNur taglib-1.9.1/ConfigureChecks.cmake taglib-1.9.1-ds/ConfigureChecks.cmake +--- taglib-1.9.1/ConfigureChecks.cmake 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/ConfigureChecks.cmake 2013-11-11 13:42:53.017126134 +0100 +@@ -216,6 +216,7 @@ + set(HAVE_ZLIB 0) + endif() + ++SET(HAVE_LIBRCC 1) + + set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) + +diff -dPNur taglib-1.9.1/examples/tagreader_c.c taglib-1.9.1-ds/examples/tagreader_c.c +--- taglib-1.9.1/examples/tagreader_c.c 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/examples/tagreader_c.c 2013-11-11 13:42:53.017126134 +0100 +@@ -38,7 +38,7 @@ + TagLib_Tag *tag; + const TagLib_AudioProperties *properties; + +- taglib_set_strings_unicode(FALSE); ++// taglib_set_strings_unicode(FALSE); + + for(i = 1; i < argc; i++) { + printf("******************** \"%s\" ********************\n", argv[i]); +diff -dPNur taglib-1.9.1/examples/tagwriter.cpp taglib-1.9.1-ds/examples/tagwriter.cpp +--- taglib-1.9.1/examples/tagwriter.cpp 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/examples/tagwriter.cpp 2013-11-11 13:42:53.028126368 +0100 +@@ -92,7 +92,7 @@ + if(isArgument(argv[i]) && i + 1 < argc && !isArgument(argv[i + 1])) { + + char field = argv[i][1]; +- TagLib::String value = argv[i + 1]; ++ TagLib::String value(argv[i + 1], TagLib::String::Locale); + + TagLib::List<TagLib::FileRef>::Iterator it; + for(it = fileList.begin(); it != fileList.end(); ++it) { +diff -dPNur taglib-1.9.1/taglib/CMakeLists.txt taglib-1.9.1-ds/taglib/CMakeLists.txt +--- taglib-1.9.1/taglib/CMakeLists.txt 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/taglib/CMakeLists.txt 2013-11-11 13:42:53.042126665 +0100 +@@ -36,6 +36,7 @@ + audioproperties.h + taglib_export.h + ${CMAKE_BINARY_DIR}/taglib_config.h ++ toolkit/rccpatch.h + toolkit/taglib.h + toolkit/tstring.h + toolkit/tlist.h +@@ -281,6 +282,7 @@ + ) + + set(toolkit_SRCS ++ toolkit/rccpatch.cpp + toolkit/tstring.cpp + toolkit/tstringlist.cpp + toolkit/tbytevector.cpp +@@ -310,7 +312,7 @@ + add_library(tag ${tag_LIB_SRCS} ${tag_HDRS}) + + if(ZLIB_FOUND) +- target_link_libraries(tag ${ZLIB_LIBRARIES}) ++ target_link_libraries(tag rcc ${ZLIB_LIBRARIES}) + endif() + + set_target_properties(tag PROPERTIES +diff -dPNur taglib-1.9.1/taglib/mpeg/id3v1/id3v1tag.cpp taglib-1.9.1-ds/taglib/mpeg/id3v1/id3v1tag.cpp +--- taglib-1.9.1/taglib/mpeg/id3v1/id3v1tag.cpp 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/taglib/mpeg/id3v1/id3v1tag.cpp 2013-11-11 13:42:53.043126686 +0100 +@@ -64,17 +64,18 @@ + + String ID3v1::StringHandler::parse(const ByteVector &data) const + { +- return String(data, String::Latin1).stripWhiteSpace(); ++ return String(data, String::Latin1ID3).stripWhiteSpace(); + } + + ByteVector ID3v1::StringHandler::render(const String &s) const + { + if(!s.isLatin1()) + { ++ if (String::ID3WType(String::Latin1) == String::Latin1) + return ByteVector(); + } + +- return s.data(String::Latin1); ++ return s.data(String::Latin1ID3); + } + + //////////////////////////////////////////////////////////////////////////////// +@@ -257,7 +258,7 @@ + d->track = uchar(data[offset + 29]); + } + else +- d->comment = data.mid(offset, 30); ++ d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 30)); + + offset += 30; + +diff -dPNur taglib-1.9.1/taglib/mpeg/id3v2/frames/commentsframe.cpp taglib-1.9.1-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp +--- taglib-1.9.1/taglib/mpeg/id3v2/frames/commentsframe.cpp 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/taglib/mpeg/id3v2/frames/commentsframe.cpp 2013-11-11 13:42:53.043126686 +0100 +@@ -150,10 +150,10 @@ + return; + } + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + d->language = data.mid(1, 3); + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign, 2); + +@@ -174,10 +174,12 @@ + + String::Type encoding = d->textEncoding; + ++ encoding = String::ID3WType(encoding); ++ + encoding = checkTextEncoding(d->description, encoding); + encoding = checkTextEncoding(d->text, encoding); + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + v.append(d->language.size() == 3 ? d->language : "XXX"); + v.append(d->description.data(encoding)); + v.append(textDelimiter(encoding)); +diff -dPNur taglib-1.9.1/taglib/mpeg/id3v2/frames/textidentificationframe.cpp taglib-1.9.1-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp +--- taglib-1.9.1/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/taglib/mpeg/id3v2/frames/textidentificationframe.cpp 2013-11-11 13:42:53.044126708 +0100 +@@ -187,12 +187,12 @@ + + // read the string data type (the first byte of the field data) + +- d->textEncoding = String::Type(data[0]); ++ d->textEncoding = String::ID3Type(data[0]); + + // split the byte array into chunks based on the string type (two byte delimiter + // for unicode encodings) + +- int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2; ++ int byteAlign = (d->textEncoding == String::Latin1 || d->textEncoding == String::Latin1ID3 || d->textEncoding == String::Latin1ID3V2 || d->textEncoding == String::UTF8) ? 1 : 2; + + // build a small counter to strip nulls off the end of the field + +@@ -223,11 +223,14 @@ + + ByteVector TextIdentificationFrame::renderFields() const + { +- String::Type encoding = checkTextEncoding(d->fieldList, d->textEncoding); ++ String::Type encoding = d->textEncoding; ++ ++ encoding = String::ID3WType(encoding); ++ encoding = checkTextEncoding(d->fieldList, encoding); + + ByteVector v; + +- v.append(char(encoding)); ++ v.append(char(String::ID3RealType(encoding))); + + for(StringList::ConstIterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) { + +diff -dPNur taglib-1.9.1/taglib/mpeg/id3v2/id3v2frame.cpp taglib-1.9.1-ds/taglib/mpeg/id3v2/id3v2frame.cpp +--- taglib-1.9.1/taglib/mpeg/id3v2/id3v2frame.cpp 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/taglib/mpeg/id3v2/id3v2frame.cpp 2013-11-11 13:42:53.045126729 +0100 +@@ -302,7 +302,7 @@ + if((encoding == String::UTF8 || encoding == String::UTF16BE) && version != 4) + return String::UTF16; + +- if(encoding != String::Latin1) ++ if((encoding != String::Latin1)&&(encoding != String::Latin1ID3V2)) + return encoding; + + for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) { +diff -dPNur taglib-1.9.1/taglib/toolkit/rccpatch.cpp taglib-1.9.1-ds/taglib/toolkit/rccpatch.cpp +--- taglib-1.9.1/taglib/toolkit/rccpatch.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.9.1-ds/taglib/toolkit/rccpatch.cpp 2013-11-11 13:42:53.045126729 +0100 +@@ -0,0 +1,237 @@ ++#include <stdlib.h> ++ ++#include <string> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++//#define RCC_DEBUG ++ ++ ++#ifndef HAVE_LIBRCC ++# include <config.h> ++#endif ++ ++#ifdef HAVE_LIBRCC ++# ifdef RCC_DEBUG ++# include <stdio.h> ++# endif /* RCC_DEBUG */ ++# include <librcc.h> ++# include <string.h> ++#endif /* HAVE_LIBRCC */ ++ ++ ++#ifdef HAVE_LIBRCC ++# define ID3_CLASS 0 ++# define ID3V2_CLASS 1 ++# define UTF_CLASS 2 ++# define OUT_CLASS 3 ++static rcc_class classes[] = { ++ { "id3", RCC_CLASS_STANDARD, NULL, NULL, "ID3 Encoding", 0 }, ++ { "id3v2", RCC_CLASS_STANDARD, "id3", NULL, "ID3 v.2 Encoding", 0 }, ++ { "utf", RCC_CLASS_KNOWN, "UTF-8", NULL, "Unicode Encoding", 0}, ++ { "out", RCC_CLASS_TRANSLATE_LOCALE, "LC_CTYPE", NULL, "Output Encoding", 0 }, ++ { NULL, RCC_CLASS_STANDARD, NULL, NULL, NULL, 0 } ++}; ++ ++static int rcc_initialized = 0; ++ ++static rcc_context ctx = NULL; ++#endif /* HAVE_LIBRCC */ ++ ++ ++void rccTaglibPatchFree() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) { ++ rccFree(); ++ rcc_initialized = 0; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccTaglibPatchInit() { ++#ifdef HAVE_LIBRCC ++ if (rcc_initialized) return; ++ rccInit(); ++ rccInitDefaultContext(NULL, 0, 0, classes, 0); ++ rccLoad(NULL, "xmms"); ++ rccInitDb4(NULL, NULL, 0); ++ rcc_initialized = 1; ++#endif /* HAVE_LIBRCC */ ++} ++ ++void rccTaglibPatchSetContext(void *newctx) { ++#ifdef HAVE_LIBRCC ++ if (newctx) { ++ ctx = (rcc_context)newctx; ++ rcc_initialized = 1; ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++static void rccTaglibPatchTryInit() { ++#ifdef HAVE_LIBRCC ++ if (!rcc_initialized) { ++ rccTaglibPatchInit(); ++ if (rcc_initialized) atexit(rccTaglibPatchFree); ++ } ++#endif /* HAVE_LIBRCC */ ++} ++ ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, OUT_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" Output: %s - %s\n", s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else v.setData("", 0); ++ //v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, UTF_CLASS, v2?ID3V2_CLASS:ID3_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" OutputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else v.setData("", 0); ++ //v.setData(s.c_str(), s.length()); ++ ++ return v; ++#else ++ v.setData("", 0); ++ ++ return v; ++#endif /* HAVE_LIBRCC */ ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, OUT_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" Input: %s - %s\n", s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ ++ if (res) v.setData(res, rlen); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false) { ++ TagLib::ByteVector v; ++#ifdef HAVE_LIBRCC ++ size_t rlen; ++ char *res; ++ ++ rccTaglibPatchTryInit(); ++ ++ res = rccSizedRecode(ctx, v2?ID3V2_CLASS:ID3_CLASS, UTF_CLASS, s.c_str(), s.length(), &rlen); ++#ifdef RCC_DEBUG ++ for (const unsigned char *c = (const unsigned char*)s.c_str(); *c; c++) { ++ if (*c > 127) { ++ printf(" InputID3(%i): %s - %s\n", v2, s.c_str(), res?res:"null"); ++ break; ++ } ++ } ++#endif /* RCC_DEBUG */ ++ if (res) v.setData(res, rlen + 1); ++ else ++#endif /* HAVE_LIBRCC */ ++ v.setData("", 0); ++ ++ return v; ++} ++ ++TagLib::String::Type rccTaglibPatchGetLocaleType() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ char charset[32]; ++ ++ rccTaglibPatchTryInit(); ++ if (!rccLocaleGetCharset(charset, NULL, 31)) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::UTF8; ++} ++ ++TagLib::String::Type rccTaglibPatchGetID3Type() { ++#ifdef HAVE_LIBRCC ++ size_t len; ++ const char *charset; ++ ++ rccTaglibPatchTryInit(); ++ ++ charset = rccGetCurrentCharsetName(ctx, ID3V2_CLASS); ++ if (charset) { ++ if (!strncmp(charset, "UTF", 3)) { ++ len = strlen(charset); ++ ++ if (charset[len-1]=='8') return TagLib::String::UTF8; ++ if (!strcmp(charset+(len-2),"16")) return TagLib::String::UTF16; ++ if (!strcmp(charset+(len-4),"16LE")) return TagLib::String::UTF16LE; ++ if (!strcmp(charset+(len-4),"16BE")) return TagLib::String::UTF16BE; ++ } ++ return TagLib::String::Latin1ID3V2; ++ } else { ++ // Error or no-language configured: If Latin1ID3V2 is returned we normally will use the default unicode encoding unless Latin1 is selected by taglib ++ return TagLib::String::Latin1ID3V2; ++ } ++#endif /* HAVE_LIBRCC */ ++ return TagLib::String::Latin1; ++} +diff -dPNur taglib-1.9.1/taglib/toolkit/rccpatch.h taglib-1.9.1-ds/taglib/toolkit/rccpatch.h +--- taglib-1.9.1/taglib/toolkit/rccpatch.h 1970-01-01 01:00:00.000000000 +0100 ++++ taglib-1.9.1-ds/taglib/toolkit/rccpatch.h 2013-11-11 13:42:53.045126729 +0100 +@@ -0,0 +1,20 @@ ++#ifndef _RCC_PATCH_H ++#define _RCC_PATCH_H ++ ++#include <string.h> ++#include "tstring.h" ++#include "tbytevector.h" ++ ++void rccTaglibPatchFree(); ++void rccTaglibPatchInit(); ++void rccTaglibPatchSetContext(void *newctx); ++ ++TagLib::ByteVector rccTaglibPatchRecodeOutput(const std::string &s); ++TagLib::ByteVector rccTaglibPatchRecodeInput(const std::string &s); ++TagLib::ByteVector rccTaglibPatchRecodeOutputID3(const std::string &s, bool v2 = false); ++TagLib::ByteVector rccTaglibPatchRecodeInputID3(const std::string &s, bool v2 = false); ++ ++TagLib::String::Type rccTaglibPatchGetLocaleType(); ++TagLib::String::Type rccTaglibPatchGetID3Type(); ++ ++#endif /* _RCC_PATCH_H */ +diff -dPNur taglib-1.9.1/taglib/toolkit/tstring.cpp taglib-1.9.1-ds/taglib/toolkit/tstring.cpp +--- taglib-1.9.1/taglib/toolkit/tstring.cpp 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/taglib/toolkit/tstring.cpp 2013-11-11 13:42:53.046126750 +0100 +@@ -29,6 +29,7 @@ + #include <config.h> + #endif + ++#include "rccpatch.h" + #include "tstring.h" + #include "tdebug.h" + #include "tstringlist.h" +@@ -197,8 +198,11 @@ + String::String(const std::string &s, Type t) + : d(new StringPrivate()) + { +- if(t == Latin1) +- copyFromLatin1(&s[0], s.length()); ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) ++ copyFromLatin1(&s[0], s.length(), true, t); + else if(t == String::UTF8) + copyFromUTF8(&s[0], s.length()); + else { +@@ -229,8 +233,11 @@ + String::String(const char *s, Type t) + : d(new StringPrivate()) + { +- if(t == Latin1) +- copyFromLatin1(s, ::strlen(s)); ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) ++ copyFromLatin1(s, ::strlen(s), true, t); + else if(t == String::UTF8) + copyFromUTF8(s, ::strlen(s)); + else { +@@ -251,7 +258,10 @@ + String::String(char c, Type t) + : d(new StringPrivate(1, static_cast<uchar>(c))) + { +- if(t != Latin1 && t != UTF8) { ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t != Latin1 && t != Latin1ID3 && t != Latin1ID3V2 && t != UTF8) { + debug("String::String() -- A char should not contain UTF16."); + } + } +@@ -262,8 +272,11 @@ + if(v.isEmpty()) + return; + +- if(t == Latin1) +- copyFromLatin1(v.data(), v.size()); ++ if(t == Locale) ++ t = rccTaglibPatchGetLocaleType(); ++ ++ if(t == Latin1 || t == Latin1ID3 || t == Latin1ID3V2) ++ copyFromLatin1(v.data(), v.size(), true, t); + else if(t == UTF8) + copyFromUTF8(v.data(), v.size()); + else +@@ -428,16 +441,46 @@ + + ByteVector String::data(Type t) const + { +- switch(t) +- { ++ ByteVector v; ++ ++ if (t == Locale) { ++ // The source is either Unicode or real Latin1 (if rcc is bypassed) ++ std::string s = to8Bit(true); ++ ++ // In case of UTF8 locale, this probably will return NULL (no recoding needed), but we will take UTF8 path in the next swtich ++ v = rccTaglibPatchRecodeOutput(s); ++ if (v.size()) return v; ++ ++ t = rccTaglibPatchGetLocaleType(); ++ } ++ ++ switch(t) { ++ case Latin1ID3: ++ case Latin1ID3V2: ++ { ++ std::string s = to8Bit(true); ++ if (t == Latin1ID3) v = rccTaglibPatchRecodeOutputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeOutputID3(s, true); ++ if (v.size()) ++ return v; ++ ++ // we don't know if we got NULL because rcc is disabled (error) or UTF8 output is required ++ if ((t == Latin1ID3V2)&&(rccTaglibPatchGetID3Type() == UTF8)) { ++ v.setData(s.c_str(), s.length()); ++ } else { ++ for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) ++ v.append(char(*it)); ++ } ++ return v; ++ } + case Latin1: + { + ByteVector v(size(), 0); + char *p = v.data(); +- ++ + for(wstring::const_iterator it = d->data.begin(); it != d->data.end(); it++) + *p++ = static_cast<char>(*it); +- ++ + return v; + } + case UTF8: +@@ -763,12 +806,29 @@ + // private members + //////////////////////////////////////////////////////////////////////////////// + +-void String::copyFromLatin1(const char *s, size_t length) ++void String::copyFromLatin1(const char *s, size_t length, bool prepare, Type t) + { + d->data.resize(length); +- + for(size_t i = 0; i < length; ++i) + d->data[i] = static_cast<uchar>(s[i]); ++ ++ // librcc conversation ++ if (prepare) { ++ std::string s = to8Bit(false); ++ ByteVector v; ++ ++ if (t == Latin1ID3) v = rccTaglibPatchRecodeInputID3(s, false); ++ else if (t == Latin1ID3V2) v = rccTaglibPatchRecodeInputID3(s, true); ++ else /* Latin1 converted from Locale */ v = rccTaglibPatchRecodeInput(s); ++ ++ if (v.size()) { ++ copyFromUTF8(v.data(), v.size()); ++ } else { ++ // We don't know if we got UTF-8 encoded string or either rcc is disable or something is failed, ++ // since standard applications are really expecting here Latin1, it is safe to just check if we have violations of UTF8 ++ //if (Unicode::isLegalUTF8(s)) t = UTF8; ++ } ++ } + } + + void String::copyFromUTF8(const char *s, size_t length) +@@ -874,7 +934,33 @@ + + std::ostream &operator<<(std::ostream &s, const TagLib::String &str) + { +- s << str.to8Bit(); ++ TagLib::ByteVector bv = str.data(TagLib::String::Locale); ++ s << bv; + return s; + } + ++TagLib::String::Type TagLib::String::ID3Type(int i) ++{ ++ if(i == Latin1) ++ return Latin1ID3V2; ++ return Type(i); ++}; ++ ++TagLib::String::Type TagLib::String::ID3WType(Type type) ++{ ++ Type rcc_type = rccTaglibPatchGetID3Type(); ++ if((rcc_type == Latin1ID3)||(rcc_type == Latin1ID3V2)||(rcc_type == Latin1)) { ++ if(type == Latin1) return ++ rcc_type; ++ return type; ++ } ++ ++ return rcc_type; ++}; ++ ++TagLib::String::Type TagLib::String::ID3RealType(Type type) ++{ ++ if((type == Latin1ID3) || (type == Latin1ID3V2)) ++ return Latin1; ++ return type; ++} +diff -dPNur taglib-1.9.1/taglib/toolkit/tstring.h taglib-1.9.1-ds/taglib/toolkit/tstring.h +--- taglib-1.9.1/taglib/toolkit/tstring.h 2013-10-08 17:50:01.000000000 +0200 ++++ taglib-1.9.1-ds/taglib/toolkit/tstring.h 2013-11-11 13:42:53.047126771 +0100 +@@ -90,6 +90,18 @@ + */ + enum Type { + /*! ++ * Determine using current locale settings ++ */ ++ Locale = -1, ++ /*! ++ * Latin1 for ID3 tags. ++ */ ++ Latin1ID3 = 65, ++ /*! ++ * Latin1 for ID3v2 tags. ++ */ ++ Latin1ID3V2 = 66, ++ /*! + * IS08859-1, or <i>Latin1</i> encoding. 8 bit characters. + */ + Latin1 = 0, +@@ -112,6 +124,10 @@ + UTF16LE = 4 + }; + ++ static Type ID3Type(int i); ++ static Type ID3WType(Type type); ++ static Type ID3RealType(Type type); ++ + /*! + * Constructs an empty String. + */ +@@ -479,7 +495,7 @@ + * Converts a \e Latin-1 string into \e UTF-16(without BOM/CPU byte order) + * and copies it to the internal buffer. + */ +- void copyFromLatin1(const char *s, size_t length); ++ void copyFromLatin1(const char *s, size_t length, bool prepare = false, Type t = Latin1); + + /*! + * Converts a \e UTF-8 string into \e UTF-16(without BOM/CPU byte order) diff --git a/patches/unzip/README b/patches/unzip/README new file mode 100644 index 0000000..03c08f6 --- /dev/null +++ b/patches/unzip/README @@ -0,0 +1,30 @@ +You can use patch in two modes: + standard: The unzip will be dynamically linked with librcc (In that case + some problems with building OpenOffice from sources may arise) + + lazy: In this case the librcc will be dynamically loaded (with help of + dlopen, dlsym) during execution. + + +Usage +===== +1. Apply patches: unzip-*-ds-rusxmms.patch, unzip-ds-unixenc.patch +2. In the root of `unzip` source tree run either `update_shared` for standard +mode or `update_lazy` for lazy mode. + + +Configuration +============= + - The patch uses "zip" configuration of RCC. This means settings could be + altered using "rcc-gtk2-config zip". + - ZIP OEM / ZIP ISO / Output - encodings are important for patch. + + +Build +===== + On Unix, call following command to get list of possible targets: + make -f unix/Makefile list + and then just build with: + make -f unix/Makefile <target> + for example: + make -f unix/Makefile linux_noasm diff --git a/patches/unzip/unzip-5.52-ds-rusxmms.patch b/patches/unzip/unzip-5.52-ds-rusxmms.patch new file mode 100644 index 0000000..87835f0 --- /dev/null +++ b/patches/unzip/unzip-5.52-ds-rusxmms.patch @@ -0,0 +1,159 @@ +diff -dPNur unzip-5.52/dsrecode.h unzip-5.52-ds/dsrecode.h +--- unzip-5.52/dsrecode.h 1970-01-01 01:00:00.000000000 +0100 ++++ unzip-5.52-ds/dsrecode.h 2008-04-11 22:24:24.000000000 +0200 +@@ -0,0 +1,128 @@ ++#include <librcc.h> ++ ++static rcc_class_default_charset default_oem[] = { ++ { "ru", "IBM866" }, ++ { NULL, NULL } ++}; ++ ++static rcc_class_default_charset default_iso[] = { ++ { "ru", "CP1251" }, ++ { NULL, NULL } ++}; ++ ++#define OEM_CLASS 0 ++#define ISO_CLASS 1 ++#define OUT_CLASS 2 ++static rcc_class classes[] = { ++ { "oem", RCC_CLASS_STANDARD, NULL, default_oem, "OEM_INTERN", 0 }, ++ { "iso", RCC_CLASS_STANDARD, NULL, default_iso, "ISO_INTERN", 0 }, ++ { "out", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, "Output", 0 }, ++ { NULL } ++}; ++ ++int initialized = 0; ++ ++#ifdef RCC_LAZY ++#include <dlfcn.h> ++# define RCC_LIBRARY "librcc.so.0" ++int (*rccInit2)(); ++int (*rccFree2)(); ++int (*rccInitDefaultContext2)(const char *locale_variable, unsigned int max_languages, unsigned int max_classes, rcc_class_ptr defclasses, rcc_init_flags flags); ++int (*rccInitDb42)(rcc_context ctx, const char *name, rcc_db4_flags flags); ++char* (*rccSizedRecode2)(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char *buf, size_t len, size_t *rlen); ++int (*rccLoad2)(rcc_context ctx, const char *name); ++ ++ ++static char *rccRecode2(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char *buf) { ++ return rccSizedRecode2(ctx, from, to, buf, 0, NULL); ++} ++ ++void *rcc_handle; ++#else /* RCC_LAZY */ ++#define rccInit2 rccInit ++#define rccFree2 rccFree ++#define rccInitDefaultContext2 rccInitDefaultContext ++#define rccInitDb42 rccInitDb4 ++#define rccRecode2 rccRecode ++#define rccLoad2 rccLoad ++#endif /* RCC_LAZY */ ++ ++static void rccUnzipFree() { ++ if (initialized > 0) { ++ rccFree2(); ++#ifdef RCC_LAZY ++ dlclose(rcc_handle); ++#endif /* RCC_LAZY */ ++ initialized = 0; ++ } ++} ++ ++ ++static int rccUnzipInit() { ++ if (initialized) return 0; ++ ++#ifdef RCC_LAZY ++ if (sizeof(size_t) == 8) { ++ rcc_handle = dlopen("/usr/lib64/" RCC_LIBRARY, RTLD_NOW); ++ if (!rcc_handle) rcc_handle = dlopen("/usr/local/lib64/" RCC_LIBRARY, RTLD_NOW); ++ } else { ++ rcc_handle = dlopen("/usr/lib32/" RCC_LIBRARY, RTLD_NOW); ++ if (!rcc_handle) rcc_handle = dlopen("/usr/local/lib32/" RCC_LIBRARY, RTLD_NOW); ++ } ++ if (!rcc_handle) { ++ rcc_handle = dlopen("/usr/lib/" RCC_LIBRARY, RTLD_NOW); ++ if (!rcc_handle) rcc_handle = dlopen("/usr/local/lib/" RCC_LIBRARY, RTLD_NOW); ++ } ++ if (!rcc_handle) { ++ initialized = -1; ++ return 1; ++ } ++ ++ rccInit2 = dlsym(rcc_handle, "rccInit"); ++ rccFree2 = dlsym(rcc_handle, "rccFree"); ++ rccInitDefaultContext2 = dlsym(rcc_handle, "rccInitDefaultContext"); ++ rccInitDb42 = dlsym(rcc_handle, "rccInitDb4"); ++ rccSizedRecode2 = dlsym(rcc_handle, "rccSizedRecode"); ++ rccLoad2 = dlsym(rcc_handle, "rccLoad"); ++ ++ if ((!rccInit2)||(!rccFree2)||(!rccInitDefaultContext2)||(!rccInitDb42)||(!rccSizedRecode2)||(!rccLoad2)) { ++ dlclose(rcc_handle); ++ initialized = -1; ++ return 1; ++ } ++#endif /* RCC_LAZY */ ++ ++ rccInit2(); ++ rccInitDefaultContext2(NULL, 0, 0, classes, 0); ++ rccLoad2(NULL, "zip"); ++ rccInitDb42(NULL, NULL, 0); ++ atexit(rccUnzipFree); ++ initialized = 1; ++ return 0; ++} ++ ++ ++ ++void _DS_OEM_INTERN(char *string) { ++ char *str; ++ rccUnzipInit(); ++ if (initialized>0) { ++ str = rccRecode2(NULL, OEM_CLASS, OUT_CLASS, string); ++ if (str) { ++ strncpy(string,str,FILNAMSIZ); ++ free(str); ++ } ++ } ++} ++ ++void _DS_ISO_INTERN(char *string) { ++ char *str; ++ rccUnzipInit(); ++ if (initialized>0) { ++ str = rccRecode2(NULL, ISO_CLASS, OUT_CLASS, string); ++ if (str) { ++ strncpy(string,str,FILNAMSIZ); ++ free(str); ++ } ++ } ++} +diff -dPNur unzip-5.52/fileio.c unzip-5.52-ds/fileio.c +--- unzip-5.52/fileio.c 2005-02-27 03:10:12.000000000 +0100 ++++ unzip-5.52-ds/fileio.c 2008-04-11 22:25:31.000000000 +0200 +@@ -78,7 +78,7 @@ + # endif + #endif + #include "ebcdic.h" /* definition/initialization of ebcdic[] */ +- ++#include "dsrecode.h" + + /* + Note: Under Windows, the maximum size of the buffer that can be used +diff -dPNur unzip-5.52/unzpriv.h unzip-5.52-ds/unzpriv.h +--- unzip-5.52/unzpriv.h 2005-02-04 00:26:42.000000000 +0100 ++++ unzip-5.52-ds/unzpriv.h 2008-04-11 22:25:31.000000000 +0200 +@@ -2564,9 +2564,9 @@ + ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \ + (hostnum) == FS_HPFS_ || \ + ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \ +- _OEM_INTERN((string)); \ ++ _DS_OEM_INTERN((string)); \ + } else { \ +- _ISO_INTERN((string)); \ ++ _DS_ISO_INTERN((string)); \ + } + #endif + diff --git a/patches/unzip/unzip-5.52-ds-rusxmms2.patch b/patches/unzip/unzip-5.52-ds-rusxmms2.patch new file mode 100644 index 0000000..6670a10 --- /dev/null +++ b/patches/unzip/unzip-5.52-ds-rusxmms2.patch @@ -0,0 +1,149 @@ +diff -dPNur unzip-5.52/fileio.c unzip-5.52-ds/fileio.c +--- unzip-5.52/fileio.c 2005-02-27 03:10:12.000000000 +0100 ++++ unzip-5.52-ds/fileio.c 2008-04-11 22:25:31.000000000 +0200 +@@ -78,7 +78,7 @@ + # endif + #endif + #include "ebcdic.h" /* definition/initialization of ebcdic[] */ +- ++#include "dsrecode.h" + + /* + Note: Under Windows, the maximum size of the buffer that can be used +diff -dPNur unzip-5.52/unzpriv.h unzip-5.52-ds/unzpriv.h +--- unzip-5.52/unzpriv.h 2005-02-04 00:26:42.000000000 +0100 ++++ unzip-5.52-ds/unzpriv.h 2008-04-11 22:25:31.000000000 +0200 +@@ -2564,9 +2564,9 @@ + ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \ + (hostnum) == FS_HPFS_ || \ + ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \ +- _OEM_INTERN((string)); \ ++ _DS_OEM_INTERN((string)); \ + } else { \ +- _ISO_INTERN((string)); \ ++ _DS_ISO_INTERN((string)); \ + } + #endif + +diff -dPNur unzip-5.52/dsrecode.h unzip-5.52-ds/dsrecode.h +--- unzip-5.52/dsrecode.h 1970-01-01 01:00:00.000000000 +0100 ++++ unzip-5.52-ds/dsrecode.h 2008-04-11 22:24:24.000000000 +0200 +@@ -0,0 +1,118 @@ ++#include "librcc.h" ++ ++static rcc_class_default_charset default_oem[] = { ++ { "ru", "IBM866" }, ++ { NULL, NULL } ++}; ++ ++static rcc_class_default_charset default_iso[] = { ++ { "ru", "CP1251" }, ++ { NULL, NULL } ++}; ++ ++#define OEM_CLASS 0 ++#define ISO_CLASS 1 ++#define OUT_CLASS 2 ++static rcc_class classes[] = { ++ { "oem", RCC_CLASS_STANDARD, NULL, default_oem, "OEM_INTERN", 0 }, ++ { "iso", RCC_CLASS_STANDARD, NULL, default_iso, "ISO_INTERN", 0 }, ++ { "out", RCC_CLASS_STANDARD, "LC_CTYPE", NULL, "Output", 0 }, ++ { NULL } ++}; ++ ++int initialized = 0; ++ ++#ifdef RCC_LAZY ++#include <dlfcn.h> ++# define RCC_LIBRARY "librcc.so.0" ++int (*rccInit2)(); ++int (*rccFree2)(); ++int (*rccInitDefaultContext2)(const char *locale_variable, unsigned int max_languages, unsigned int max_classes, rcc_class_ptr defclasses, rcc_init_flags flags); ++int (*rccInitDb42)(rcc_context ctx, const char *name, rcc_db4_flags flags); ++char* (*rccSizedRecode2)(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char *buf, size_t len, size_t *rlen); ++int (*rccLoad2)(rcc_context ctx, const char *name); ++ ++ ++static char *rccRecode2(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char *buf) { ++ return rccSizedRecode2(ctx, from, to, buf, 0, NULL); ++} ++ ++void *rcc_handle; ++#else /* RCC_LAZY */ ++#define rccInit2 rccInit ++#define rccFree2 rccFree ++#define rccInitDefaultContext2 rccInitDefaultContext ++#define rccInitDb42 rccInitDb4 ++#define rccRecode2 rccRecode ++#define rccLoad2 rccLoad ++#endif /* RCC_LAZY */ ++ ++static void rccUnzipFree() { ++ if (initialized > 0) { ++ rccFree2(); ++#ifdef RCC_LAZY ++ dlclose(rcc_handle); ++#endif /* RCC_LAZY */ ++ initialized = 0; ++ } ++} ++ ++ ++static int rccUnzipInit() { ++ if (initialized) return 0; ++ ++#ifdef RCC_LAZY ++ rcc_handle = dlopen(RCC_LIBRARY, RTLD_NOW); ++ if (!rcc_handle) { ++ initialized = -1; ++ return 1; ++ } ++ ++ rccInit2 = dlsym(rcc_handle, "rccInit"); ++ rccFree2 = dlsym(rcc_handle, "rccFree"); ++ rccInitDefaultContext2 = dlsym(rcc_handle, "rccInitDefaultContext"); ++ rccInitDb42 = dlsym(rcc_handle, "rccInitDb4"); ++ rccSizedRecode2 = dlsym(rcc_handle, "rccSizedRecode"); ++ rccLoad2 = dlsym(rcc_handle, "rccLoad"); ++ ++ if ((!rccInit2)||(!rccFree2)||(!rccInitDefaultContext2)||(!rccInitDb42)||(!rccSizedRecode2)||(!rccLoad2)) { ++ dlclose(rcc_handle); ++ initialized = -1; ++ return 1; ++ } ++#endif /* RCC_LAZY */ ++ ++ rccInit2(); ++ rccInitDefaultContext2(NULL, 0, 0, classes, 0); ++ rccLoad2(NULL, "zip"); ++ rccInitDb42(NULL, NULL, 0); ++ atexit(rccUnzipFree); ++ initialized = 1; ++ return 0; ++} ++ ++ ++ ++void _DS_OEM_INTERN(char *string) { ++ char *str; ++ rccUnzipInit(); ++ if (initialized>0) { ++ str = rccRecode2(NULL, OEM_CLASS, OUT_CLASS, string); ++ if (str) { ++ strncpy(string,str,FILNAMSIZ); ++ free(str); ++ } ++ } ++} ++ ++void _DS_ISO_INTERN(char *string) { ++ char *str; ++ rccUnzipInit(); ++ if (initialized>0) { ++ str = rccRecode2(NULL, ISO_CLASS, OUT_CLASS, string); ++ if (str) { ++ strncpy(string,str,FILNAMSIZ); ++ free(str); ++ } ++ } ++} diff --git a/patches/unzip/unzip-ds-unixenc.patch b/patches/unzip/unzip-ds-unixenc.patch new file mode 100644 index 0000000..e33e6ba --- /dev/null +++ b/patches/unzip/unzip-ds-unixenc.patch @@ -0,0 +1,9 @@ +diff -dPNur unzip-5.50/unzpriv.h unzip-5.50-new/unzpriv.h +--- unzip-5.50/unzpriv.h Sun Feb 17 21:01:48 2002 ++++ unzip-5.50-new/unzpriv.h Tue Jun 10 07:16:23 2003 +@@ -2424,4 +2424,5 @@ + !(((islochdr) || (isuxatt)) && \ + ((hostver) == 25 || (hostver) == 26 || (hostver) == 40))) || \ + (hostnum) == FS_HPFS_ || \ ++ (hostnum) == UNIX_ || \ + ((hostnum) == FS_NTFS_ && (hostver) == 50)) { \ diff --git a/patches/unzip/unzip60-ds-isprint.patch b/patches/unzip/unzip60-ds-isprint.patch new file mode 100644 index 0000000..64ea1ee --- /dev/null +++ b/patches/unzip/unzip60-ds-isprint.patch @@ -0,0 +1,12 @@ +diff -dPNur unzip60/extract.c unzip60-ds/extract.c +--- unzip60/extract.c 2009-03-14 02:32:52.000000000 +0100 ++++ unzip60-ds/extract.c 2010-07-06 16:34:09.000000000 +0200 +@@ -2596,7 +2596,7 @@ + */ + # define UZ_FNFILTER_REPLACECHAR '?' + # endif +- if (!isprint(*r)) { ++ if (*r < 32) { //(!isprint(*r)) { + if (*r < 32) { + /* ASCII control codes are escaped as "^{letter}". */ + if (se != NULL && (s > (space + (size-4)))) { diff --git a/patches/unzip/update_lazy b/patches/unzip/update_lazy new file mode 100755 index 0000000..de1b04a --- /dev/null +++ b/patches/unzip/update_lazy @@ -0,0 +1,9 @@ +#!/bin/bash + + sed -i \ + -e "s:-O3:\${CFLAGS}:" \ + -e "s:CC=gcc :CC=\"gcc -DRCC_LAZY=1\":" \ + -e "s:LD=gcc :LD=\"gcc \${LDFLAGS} -ldl\" :" \ + -e "s:-O :\${CFLAGS} :" \ + -e "s:LF2 = -s:LF2 = :" \ + unix/Makefile \ diff --git a/patches/unzip/update_shared b/patches/unzip/update_shared new file mode 100755 index 0000000..1dd8b2a --- /dev/null +++ b/patches/unzip/update_shared @@ -0,0 +1,9 @@ +#!/bin/bash + + sed -i \ + -e "s:-O3:\${CFLAGS}:" \ + -e "s:CC=gcc :CC=gcc :" \ + -e "s:LD=gcc :LD=\"gcc \${LDFLAGS} -lrcc\" :" \ + -e "s:-O :\${CFLAGS} :" \ + -e "s:LF2 = -s:LF2 = :" \ + unix/Makefile \ diff --git a/patches/xmms-plugins/xmms-wma-csa1.tar.bz2 b/patches/xmms-plugins/xmms-wma-csa1.tar.bz2 Binary files differnew file mode 100644 index 0000000..de6968c --- /dev/null +++ b/patches/xmms-plugins/xmms-wma-csa1.tar.bz2 diff --git a/patches/xmms/extra/xmms-ds-mpg123-wrongencoding.patch b/patches/xmms/extra/xmms-ds-mpg123-wrongencoding.patch new file mode 100644 index 0000000..66a2100 --- /dev/null +++ b/patches/xmms/extra/xmms-ds-mpg123-wrongencoding.patch @@ -0,0 +1,157 @@ +diff -dPNur xmms-1.2.11-orig/Input/mpg123/id3_frame_text.c xmms-1.2.11/Input/mpg123/id3_frame_text.c +--- xmms-1.2.11-orig/Input/mpg123/id3_frame_text.c 2008-04-11 15:44:34.000000000 +0200 ++++ xmms-1.2.11/Input/mpg123/id3_frame_text.c 2008-04-11 15:52:25.000000000 +0200 +@@ -46,6 +46,7 @@ + break; + case ID3_ENCODING_UTF16: + case ID3_ENCODING_UTF16BE: ++ case ID3_ENCODING_UTF16LE: + while (*text != 0 || *(text + 1) != 0) + { + text += 2; +@@ -73,6 +74,8 @@ + return xmms_charset_from_utf16(text); + case ID3_ENCODING_UTF16BE: + return xmms_charset_from_utf16be(text); ++ case ID3_ENCODING_UTF16LE: ++ return xmms_charset_from_utf16le(text); + default: + return NULL; + } +@@ -88,6 +91,8 @@ + */ + gint8 id3_get_encoding(struct id3_frame *frame) + { ++ gint8 encoding; ++ + /* Type check */ + if (!id3_frame_is_text(frame) && + frame->fr_desc->fd_id != ID3_WXXX && +@@ -106,7 +111,21 @@ + if (id3_decompress_frame(frame) == -1) + return -1; + +- return *(gint8 *) frame->fr_data; ++ encoding = *(gint8 *) frame->fr_data; ++ ++ switch (encoding) { ++ case ID3_ENCODING_ISO_8859_1: ++ case ID3_ENCODING_UTF8: ++ case ID3_ENCODING_UTF16: ++ case ID3_ENCODING_UTF16BE: ++ return encoding; ++ case ID3_ENCODING_UTF16LE: ++ printf("ID3V2 frame (%.4s) has invalid encoding (%u). Assuming UTF-16LE.\n", frame->fr_desc->fd_idstr?frame->fr_desc->fd_idstr:"UNKN", encoding); ++ return encoding; ++ default: ++ printf("ID3V2 frame (%.4s) has invalid encoding (%u). Assuming Latin1.\n", frame->fr_desc->fd_idstr?frame->fr_desc->fd_idstr:"UNKN", encoding); ++ return ID3_ENCODING_ISO_8859_1; ++ } + } + + +@@ -269,6 +288,7 @@ + else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); + else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); + else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); ++ else if (encoding == ID3_ENCODING_UTF16LE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16LE"); + else ctext = NULL; + + if (ctext) text = ctext; +@@ -433,6 +453,7 @@ + else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); + else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); + else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); ++ else if (encoding == ID3_ENCODING_UTF16LE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16LE"); + else ctext = NULL; + + if (ctext) text = ctext; +@@ -453,11 +474,12 @@ + *(gint8 *) frame->fr_raw_data = encoding; + memcpy((char*)frame->fr_raw_data + 1, xmms_rcc_get_language(), 3); + +- if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) { ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)||(encoding == ID3_ENCODING_UTF16LE)) { + int i; + lang = "Comments"; + if (encoding == ID3_ENCODING_UTF16) cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16"); +- else cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16BE"); ++ else if (encoding == ID3_ENCODING_UTF16BE) cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16BE"); ++ else cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16LE"); + memcpy((char *) frame->fr_raw_data + 4, cdata, 20); + g_free(cdata); + } else +diff -dPNur xmms-1.2.11-orig/Input/mpg123/id3.h xmms-1.2.11/Input/mpg123/id3.h +--- xmms-1.2.11-orig/Input/mpg123/id3.h 2008-04-11 15:44:34.000000000 +0200 ++++ xmms-1.2.11/Input/mpg123/id3.h 2008-04-11 15:50:58.000000000 +0200 +@@ -141,6 +141,7 @@ + #define ID3_ENCODING_UTF16 0x01 + #define ID3_ENCODING_UTF16BE 0x02 + #define ID3_ENCODING_UTF8 0x03 ++#define ID3_ENCODING_UTF16LE 0x04 + + /* + * ID3 frame id numbers. +@@ -312,7 +313,7 @@ + + + #define ID3_TEXT_FRAME_ENCODING(frame) \ +- (*(guint8*)(frame)->fr_data) ++ id3_get_encoding(frame) + + #define ID3_TEXT_FRAME_PTR(frame) \ + ((char *)(frame)->fr_data + 1) +diff -dPNur xmms-1.2.11-orig/libxmms/charset.c xmms-1.2.11/libxmms/charset.c +--- xmms-1.2.11-orig/libxmms/charset.c 2008-04-10 22:49:57.000000000 +0200 ++++ xmms-1.2.11/libxmms/charset.c 2008-04-11 15:50:21.000000000 +0200 +@@ -141,6 +141,14 @@ + return xmms_charset_convert(string, utf16_strlen(string), "UTF-16BE", NULL); + } + ++char *xmms_charset_from_utf16le(const unsigned char *string) ++{ ++ if (!string) ++ return NULL; ++ ++ return xmms_charset_convert(string, utf16_strlen(string), "UTF-16LE", NULL); ++} ++ + char* xmms_charset_from_latin1(const char *string) + { + char *cstring; +@@ -174,6 +182,9 @@ + if (!strcmp(from, "UTF-16BE") && !to) + return xmms_charset_from_utf16be(string); + ++ if (!strcmp(from, "UTF-16LE") && !to) ++ return xmms_charset_from_utf16le(string); ++ + return g_strdup(string); + } + +@@ -275,6 +286,14 @@ + return utf16_to_ascii(string, FALSE); + } + ++char *xmms_charset_from_utf16le(const unsigned char *string) ++{ ++ if (!string) ++ return NULL; ++ ++ return utf16_to_ascii(string, TRUE); ++} ++ + char* xmms_charset_from_latin1(const char *string) + { + char *cstring; +diff -dPNur xmms-1.2.11-orig/libxmms/charset.h xmms-1.2.11/libxmms/charset.h +--- xmms-1.2.11-orig/libxmms/charset.h 2008-04-10 22:49:57.000000000 +0200 ++++ xmms-1.2.11/libxmms/charset.h 2008-04-11 15:49:47.000000000 +0200 +@@ -14,6 +14,7 @@ + char* xmms_charset_from_utf8(const char *string); + char* xmms_charset_from_utf16(const unsigned char *string); + char* xmms_charset_from_utf16be(const unsigned char *string); ++char *xmms_charset_from_utf16le(const unsigned char *string); + char* xmms_charset_from_latin1(const char *string); + + size_t utf16_strlen(const char *string); diff --git a/patches/xmms/plugins/xmms-ds-mpg123-editor-keys.patch b/patches/xmms/plugins/xmms-ds-mpg123-editor-keys.patch new file mode 100644 index 0000000..38a74e2 --- /dev/null +++ b/patches/xmms/plugins/xmms-ds-mpg123-editor-keys.patch @@ -0,0 +1,164 @@ +diff -dPNur rusxmms-new/Input/mpg123/fileinfo.c rusxmms-new-keys/Input/mpg123/fileinfo.c +--- rusxmms-new/Input/mpg123/fileinfo.c 2005-07-17 11:46:05.000000000 +0200 ++++ rusxmms-new-keys/Input/mpg123/fileinfo.c 2005-07-18 01:12:36.000000000 +0200 +@@ -31,6 +31,10 @@ + #define MAX_STR_LEN 100 + #define MAX_ENTRY_LEN2 1023 + ++#include <gdk/gdkkeysyms.h> ++#include <gdk/gdktypes.h> ++#include "../../xmms/xmms.h" ++ + static GtkWidget *window = NULL; + static GtkWidget *notebook = NULL; + static GtkWidget *filename_entry, *id3v1_frame, *id3v2_frame; +@@ -507,6 +511,106 @@ + gtk_widget_destroy(w); + } + ++static int restore_focus; ++static GtkWidget *save; ++ ++ ++static GtkWidget **widgets1[] = { &v1_title_entry, &v1_artist_entry, &v1_album_entry, &v1_comment_entry, &v1_year_entry, NULL }; ++static GtkWidget **widgets2[] = { &v2_title_entry, &v2_artist_entry, &v2_album_entry, &v2_comment_entry, &v2_year_entry, &v2_composer_entry, &v2_orig_artist_entry, &v2_url_entry, &v2_encoded_by_entry, NULL }; ++/* Info: gdktypes.h, gdkkeysyms.h */ ++gboolean mpg123_keypress_cb(GtkWidget * w, GdkEventKey * event, gpointer close) { ++ gint pos; ++ GtkWidget ***widgets, *widget, *focused; ++ ++ switch(event->keyval) { ++ case GDK_Return: ++ restore_focus=1; ++ gtk_signal_emit_by_name(GTK_OBJECT(save), "clicked", NULL); ++ gtk_signal_emit_by_name(GTK_OBJECT(close), "clicked", NULL); ++ return TRUE; ++ break; ++ case GDK_Escape: ++ restore_focus=1; ++ return TRUE; ++ break; ++ } ++ ++ if (event->state&GDK_CONTROL_MASK) { ++ switch(event->keyval) { ++ case GDK_Left: ++ gtk_notebook_prev_page(GTK_NOTEBOOK(notebook)); ++ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); ++ if (pos == 0) gtk_window_set_focus(GTK_WINDOW(window), *widgets2[0]); ++ else if (pos == 1) gtk_window_set_focus(GTK_WINDOW(window), *widgets1[0]); ++ gtk_window_activate_focus(GTK_WINDOW(window)); ++ return TRUE; ++ break; ++ case GDK_Right: ++ gtk_notebook_next_page(GTK_NOTEBOOK(notebook)); ++ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); ++ if (pos == 0) gtk_window_set_focus(GTK_WINDOW(window), *widgets2[0]); ++ else if (pos == 1) gtk_window_set_focus(GTK_WINDOW(window), *widgets1[0]); ++ gtk_window_activate_focus(GTK_WINDOW(window)); ++ return TRUE; ++ break; ++ } ++ } ++ { ++ switch(event->keyval) { ++ case GDK_Page_Up: ++ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); ++ ++ focused = GTK_WINDOW(window)->focus_widget; ++ if (pos == 1) widgets = widgets1; ++ else if (pos == 0) widgets = widgets2; ++ else return FALSE; ++ ++ for (pos = 0; widgets[pos]; pos++) { ++ if (focused == *widgets[pos]) { ++ if (pos == 0) { ++ while (widgets[pos+1]) pos++; ++ widget = *widgets[pos]; ++ } else widget = *widgets[pos - 1]; ++ ++ gtk_window_set_focus(GTK_WINDOW(window), widget); ++ return TRUE; ++ } ++ } ++ break; ++ case GDK_Page_Down: ++ case GDK_Tab: ++ pos = gtk_notebook_get_current_page(GTK_NOTEBOOK(notebook)); ++ ++ focused = GTK_WINDOW(window)->focus_widget; ++ if (pos == 1) widgets = widgets1; ++ else if (pos == 0) widgets = widgets2; ++ else return FALSE; ++ ++ for (pos = 0; widgets[pos]; pos++) { ++ if (focused == *widgets[pos]) { ++ if (widgets[pos + 1]) widget = *widgets[pos + 1]; ++ else widget = *widgets[0]; ++ ++ gtk_window_set_focus(GTK_WINDOW(window), widget); ++ return TRUE; ++ } ++ } ++ ++ break; ++ } ++ } ++ ++ return FALSE; ++} ++ ++void gtk_widget_destroyed_focus(GtkWidget *widget, GtkWidget **widget_pointer) { ++ gtk_widget_destroyed(widget,widget_pointer); ++ if (restore_focus) { ++ gtk_widget_hide(playlistwin); ++ gtk_widget_show(playlistwin); ++ } ++} ++ + void mpg123_file_info_box(char *filename) + { + int i; +@@ -517,6 +621,8 @@ + const char *emphasis[4]; + const char *bool_label[2]; + ++ restore_focus = 0; ++ + emphasis[0] = _("None"); + emphasis[1] = _("50/15 ms"); + emphasis[2] = ""; +@@ -529,15 +635,16 @@ + GtkWidget *window_vbox, + *id3v1_vbox, *id3v2_vbox, *id3v1_frame_vbox, *id3v2_frame_vbox, + *mpeg_lvbox, *mpeg_rvbox, *mpeg_hbox, *mpeg_box, *mpeg_frame, +- *bbox, *save, *close, *copy_to, *copy_from, ++ *bbox, *close, *copy_to, *copy_from, + *table, *label, *filename_hbox; ++ GtkAccelGroup *ag; + + v1_labels_list = g_ptr_array_new(); + v2_labels_list = g_ptr_array_new(); + + window = gtk_window_new(GTK_WINDOW_DIALOG); +- gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window); +- gtk_signal_connect(GTK_OBJECT(window), "key_press_event", file_info_box_keypress_cb, NULL); ++ gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed_focus), &window); ++// gtk_signal_connect(GTK_OBJECT(window),"key_press_event",file_info_box_keypress_cb, NULL); + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + window_vbox = gtk_vbox_new(FALSE,10); +@@ -916,6 +1023,13 @@ + GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(window)); + gtk_box_pack_start(GTK_BOX(bbox), close, TRUE, TRUE, 5); + ++ ag = gtk_accel_group_new(); ++ gtk_accel_group_add(ag, GDK_Escape, 0, 0, GTK_OBJECT(close), "clicked"); ++ gtk_accel_group_add(ag, GDK_Return, 0, 0, GTK_OBJECT(save), "clicked"); ++ gtk_window_add_accel_group(GTK_WINDOW(window), ag); ++ ++ gtk_signal_connect(GTK_OBJECT(window), "key_press_event", GTK_SIGNAL_FUNC(mpg123_keypress_cb), close); ++ + gtk_container_add(GTK_CONTAINER(window), window_vbox); + gtk_widget_show_all(window); + } diff --git a/patches/xmms/plugins/xmms-ds-mpg123-editor.patch b/patches/xmms/plugins/xmms-ds-mpg123-editor.patch new file mode 100644 index 0000000..a4afb70 --- /dev/null +++ b/patches/xmms/plugins/xmms-ds-mpg123-editor.patch @@ -0,0 +1,202 @@ +diff -dPNur xmms-1.2.10/Input/mpg123/fileinfo.c xmms-1.2.10-new/Input/mpg123/fileinfo.c +--- rusxmms/Input/mpg123/fileinfo.c 2005-07-17 01:54:55.000000000 +0200 ++++ rusxmms-new/Input/mpg123/fileinfo.c 2005-07-17 11:46:05.000000000 +0200 +@@ -24,6 +24,7 @@ + #include <string.h> + #include <errno.h> + #include <libxmms/xentry.h> ++#include <libxmms/rcc.h> + #include <gdk/gdkkeysyms.h> + #include "mpg123.h" + +@@ -60,19 +61,33 @@ + + static void set_entry_tag_v1(GtkEntry * entry, const char * tag, int length) + { +- char *text = g_strchomp(g_strndup(tag, length)); ++ char *text; ++ ++ text = xmms_rcc_sized_recode(XMMS_RCC_ID3, XMMS_RCC_CTYPE, tag, length); ++ if (!text) text = g_strchomp(g_strndup(tag, length)); ++ + gtk_entry_set_text(entry, text); + g_free(text); + } + + static void get_entry_tag_v1(GtkEntry * entry, char * tag, int length) + { ++ gchar *ctext; ++ ++ ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_ID3, gtk_entry_get_text(entry)); ++ ++ if (ctext) { ++ strncpy(tag, ctext, length); ++ free(ctext); ++ } else + strncpy(tag, gtk_entry_get_text(entry), length); + } + + void copy_entry_tag_v1(GtkEntry * src, GtkEntry * dest, int length) + { +- set_entry_tag_v1(dest, gtk_entry_get_text(src), length); ++ char *text = g_strchomp(g_strndup(gtk_entry_get_text(src), length)); ++ gtk_entry_set_text(dest, text); ++ g_free(text); + return; + } + +@@ -497,6 +512,7 @@ + int i; + struct id3v1tag_t id3v1tag; + FILE *fh; ++ gchar *cfilename; + char *tmp, *title; + const char *emphasis[4]; + const char *bool_label[2]; +@@ -908,6 +924,9 @@ + g_free(current_filename); + current_filename = g_strdup(filename); + ++ cfilename = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_OUT, filename); ++ if (cfilename) filename=cfilename; ++ + title = g_strdup_printf(_("File Info - %s"), g_basename(filename)); + gtk_window_set_title(GTK_WINDOW(window), title); + g_free(title); +@@ -922,6 +941,8 @@ + gtk_entry_set_text(GTK_ENTRY(v2_title_entry), title); + g_free(title); + ++ if (cfilename) g_free(cfilename); ++ + gtk_entry_set_text(GTK_ENTRY(v1_artist_entry), ""); + gtk_entry_set_text(GTK_ENTRY(v1_album_entry), ""); + gtk_entry_set_text(GTK_ENTRY(v1_year_entry), ""); +diff -dPNur xmms-1.2.10/Input/mpg123/id3_frame_text.c xmms-1.2.10-new/Input/mpg123/id3_frame_text.c +--- xmms-1.2.10/Input/mpg123/id3_frame_text.c 2005-08-10 03:20:03.000000000 +0200 ++++ xmms-1.2.10-new/Input/mpg123/id3_frame_text.c 2005-08-10 03:29:40.000000000 +0200 +@@ -28,6 +28,7 @@ + #include "id3_header.h" + + #include "libxmms/charset.h" ++#include "libxmms/rcc.h" + + /* For extern mpg123_cfg */ + #include "mpg123.h" +@@ -247,6 +248,9 @@ + */ + int id3_set_text(struct id3_frame *frame, char *text) + { ++ char *ctext; ++ gint8 encoding; ++ + /* Type check */ + if (frame->fr_desc->fd_idstr[0] != 'T') + return -1; +@@ -256,18 +260,36 @@ + */ + id3_frame_clear_data(frame); + ++ ++ /* ++ * Recoding. ++ */ ++ encoding = (gint8)xmms_rcc_get_id3v2_encoding(); ++ if (encoding == ID3_ENCODING_ISO_8859_1) ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_ID3V2, text); ++ else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); ++ else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); ++ else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); ++ else ctext = NULL; ++ ++ if (ctext) text = ctext; ++ + /* + * Allocate memory for new data. + */ ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) ++ frame->fr_raw_size = utf16_strlen(text) + 2; ++ else + frame->fr_raw_size = strlen(text) + 1; + frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); + + /* + * Copy contents. + */ +- *(gint8 *) frame->fr_raw_data = ID3_ENCODING_ISO_8859_1; ++ *(gint8 *) frame->fr_raw_data = encoding; + memcpy((char *) frame->fr_raw_data + 1, text, frame->fr_raw_size); + ++ if (ctext) free(ctext); ++ + frame->fr_altered = 1; + frame->fr_owner->id3_altered = 1; + +@@ -389,7 +411,10 @@ + */ + int id3_set_comment(struct id3_frame *frame, char *text) + { ++ char *ctext, *cdata; ++ const char *lang; + int *intp; ++ gint8 encoding; + + /* Type check */ + if (frame->fr_desc->fd_id != ID3_COMM) +@@ -401,8 +426,23 @@ + id3_frame_clear_data(frame); + + /* ++ * Recoding. ++ */ ++ encoding = (gint8)xmms_rcc_get_id3v2_encoding(); ++ if (encoding == ID3_ENCODING_ISO_8859_1) ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_ID3V2, text); ++ else if (encoding == ID3_ENCODING_UTF8) ctext = xmms_charset_to_utf8(text); ++ else if (encoding == ID3_ENCODING_UTF16) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16"); ++ else if (encoding == ID3_ENCODING_UTF16BE) ctext = xmms_charset_convert(text, strlen(text), NULL, "UTF-16BE"); ++ else ctext = NULL; ++ ++ if (ctext) text = ctext; ++ ++ /* + * Allocate memory for new data. + */ ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) ++ frame->fr_raw_size = 25 + utf16_strlen(text); ++ else + frame->fr_raw_size = 13 + strlen(text); + frame->fr_raw_data = g_malloc(frame->fr_raw_size + 1); /* <encode>XXXComments\0<comment><\0> + +@@ -410,18 +450,29 @@ + * block, so don't waste time with a calloc() + */ + +- ((guint8 *)frame->fr_raw_data)[0] = ID3_ENCODING_ISO_8859_1; +- ((guint8 *)frame->fr_raw_data)[1] = 0x58; +- ((guint8 *)frame->fr_raw_data)[2] = 0x58; +- ((guint8 *)frame->fr_raw_data)[3] = 0x58; ++ *(gint8 *) frame->fr_raw_data = encoding; ++ memcpy((char*)frame->fr_raw_data + 1, xmms_rcc_get_language(), 3); + ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) { ++ int i; ++ lang = "Comments"; ++ if (encoding == ID3_ENCODING_UTF16) cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16"); ++ else cdata = xmms_charset_convert(lang, strlen(lang), NULL, "UTF-16BE"); ++ memcpy((char *) frame->fr_raw_data + 4, cdata, 20); ++ g_free(cdata); ++ } else + memcpy((char *) frame->fr_raw_data + 4, "Comments", 9); + + /* + * Copy contents. + */ ++ if ((encoding == ID3_ENCODING_UTF16)||(encoding == ID3_ENCODING_UTF16BE)) ++ memcpy((char *) frame->fr_raw_data + 24, text, utf16_strlen(text) + 2); ++ else + memcpy((char *) frame->fr_raw_data + 13, text, strlen(text) + 1); + ++ if (ctext) free(ctext); ++ + frame->fr_altered = 1; + frame->fr_owner->id3_altered = 1; + diff --git a/patches/xmms/plugins/xmms-ds-mpg123.patch b/patches/xmms/plugins/xmms-ds-mpg123.patch new file mode 100644 index 0000000..fc9c42e --- /dev/null +++ b/patches/xmms/plugins/xmms-ds-mpg123.patch @@ -0,0 +1,20 @@ +diff -dPNur xmms-1.2.11/Input/mpg123/mpg123.c xmms-1.2.11-new/Input/mpg123/mpg123.c +--- xmms-1.2.11/Input/mpg123/mpg123.c 2007-11-25 00:04:27.000000000 +0100 ++++ xmms-1.2.11-new/Input/mpg123/mpg123.c 2007-11-25 01:18:57.000000000 +0100 +@@ -3,6 +3,7 @@ + #include "libxmms/configfile.h" + #include "libxmms/titlestring.h" + #include "libxmms/charset.h" ++#include "libxmms/rcc.h" + #include <string.h> + #include <stdlib.h> + #include <pthread.h> +@@ -496,6 +497,8 @@ + /* + * Format according to filename. + */ ++ ret = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, g_basename(filename)); ++ if (!ret) + ret = g_strdup(g_basename(filename)); + if (extname(ret) != NULL) + *(extname(ret) - 1) = '\0'; /* removes period */ diff --git a/patches/xmms/plugins/xmms-ds-vorbis-editor-keys.patch b/patches/xmms/plugins/xmms-ds-vorbis-editor-keys.patch new file mode 100644 index 0000000..bf59951 --- /dev/null +++ b/patches/xmms/plugins/xmms-ds-vorbis-editor-keys.patch @@ -0,0 +1,78 @@ +diff -dPNur xmms-1.2.11/Input/vorbis/fileinfo.c xmms-1.2.11-new/Input/vorbis/fileinfo.c +--- xmms-1.2.11/Input/vorbis/fileinfo.c 2007-11-25 01:23:31.000000000 +0100 ++++ xmms-1.2.11-new/Input/vorbis/fileinfo.c 2007-11-25 01:24:01.000000000 +0100 +@@ -39,6 +39,9 @@ + #include "libxmms/charset.h" + #include <xmms/i18n.h> + ++#include "../../xmms/xmms.h" ++#include <gdk/gdkkeysyms.h> ++ + #include "vorbis.h" + #include "vcedit.h" + +@@ -444,6 +447,28 @@ + } + + /***********************************************************************/ ++static int restore_focus; ++ ++gboolean vorbis_keypress_cb(GtkWidget * w, GdkEventKey * event, gpointer save) { ++ switch(event->keyval) { ++ case GDK_Return: ++ restore_focus=1; ++ gtk_signal_emit_by_name(GTK_OBJECT(save), "clicked", NULL); ++ break; ++ case GDK_Escape: ++ restore_focus=1; ++ break; ++ } ++ return TRUE; ++} ++ ++void gtk_widget_destroyed_focus(GtkWidget *widget, GtkWidget **widget_pointer) { ++ gtk_widget_destroyed(widget,widget_pointer); ++ if (restore_focus) { ++ gtk_widget_hide(playlistwin); ++ gtk_widget_show(playlistwin); ++ } ++} + + void vorbis_file_info_box(char *fn) + { +@@ -465,6 +490,8 @@ + + g_free(vte.filename); + vte.filename = g_strdup(fn); ++ ++ restore_focus = 0; + + if (!window) + { +@@ -472,11 +499,12 @@ + GtkWidget *hbox, *label, *filename_hbox, *vbox, *left_vbox; + GtkWidget *table, *bbox, *cancel_button; + GtkWidget *save_button, *remove_button; ++ GtkAccelGroup *ag; + + window = gtk_window_new(GTK_WINDOW_DIALOG); + gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE); + gtk_signal_connect(GTK_OBJECT(window), "destroy", +- GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window); ++ GTK_SIGNAL_FUNC(gtk_widget_destroyed_focus), &window); + gtk_signal_connect(GTK_OBJECT(window), "key_press_event", + keypress_cb, NULL); + gtk_container_set_border_width(GTK_CONTAINER(window), 10); +@@ -809,6 +837,12 @@ + FALSE, 0); + + gtk_widget_show_all(window); ++ ++ ag = gtk_accel_group_new(); ++ gtk_accel_group_add(ag, GDK_Escape, 0, 0, GTK_OBJECT(cancel_button), "clicked"); ++ gtk_accel_group_add(ag, GDK_Return, 0, 0, GTK_OBJECT(save_button), "clicked"); ++ gtk_window_add_accel_group(GTK_WINDOW(window), ag); ++ gtk_signal_connect(GTK_OBJECT(window),"key_press_event",GTK_SIGNAL_FUNC(vorbis_keypress_cb),save_button); + } else + gdk_window_raise(window->window); + diff --git a/patches/xmms/plugins/xmms-ds-vorbis-editor.patch b/patches/xmms/plugins/xmms-ds-vorbis-editor.patch new file mode 100644 index 0000000..47a7ba9 --- /dev/null +++ b/patches/xmms/plugins/xmms-ds-vorbis-editor.patch @@ -0,0 +1,51 @@ +diff -dPNur xmms-1.2.11/Input/vorbis/fileinfo.c xmms-1.2.11-new/Input/vorbis/fileinfo.c +--- xmms-1.2.11/Input/vorbis/fileinfo.c 2007-11-25 00:04:27.000000000 +0100 ++++ xmms-1.2.11-new/Input/vorbis/fileinfo.c 2007-11-25 01:20:57.000000000 +0100 +@@ -34,6 +34,7 @@ + #include <vorbis/codec.h> + #include <vorbis/vorbisfile.h> + ++#include "libxmms/rcc.h" + #include "libxmms/util.h" + #include "libxmms/charset.h" + #include <xmms/i18n.h> +@@ -451,6 +452,7 @@ + char *description, *version, *isrc, *copyright, *organization; + char *location, *vendor = "N/A"; + char *rg_track_gain, *rg_album_gain, *rg_track_peak, *rg_album_peak; ++ gchar *cfilename; + + int time, minutes, seconds, bitrate, avgbitrate, rate, channels; + int filesize, i; +@@ -931,6 +933,11 @@ + gtk_entry_set_text(GTK_ENTRY(isrc_entry), isrc); + gtk_entry_set_text(GTK_ENTRY(location_entry), location); + #endif ++ cfilename = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, vte.filename); ++ if (cfilename) { ++ gtk_entry_set_text(GTK_ENTRY(filename_entry), cfilename); ++ g_free(cfilename); ++ } else + gtk_entry_set_text(GTK_ENTRY(filename_entry), vte.filename); + gtk_editable_set_position(GTK_EDITABLE(filename_entry), -1); + +diff -dPNur xmms-1.2.11/Input/vorbis/vorbis.c xmms-1.2.11-new/Input/vorbis/vorbis.c +--- xmms-1.2.11/Input/vorbis/vorbis.c 2007-11-25 00:04:27.000000000 +0100 ++++ xmms-1.2.11-new/Input/vorbis/vorbis.c 2007-11-25 01:20:57.000000000 +0100 +@@ -46,6 +46,7 @@ + #include "xmms/plugin.h" + #include "libxmms/util.h" + #include "libxmms/configfile.h" ++#include "libxmms/rcc.h" + #include "libxmms/titlestring.h" + #include "libxmms/charset.h" + #include <xmms/i18n.h> +@@ -754,6 +755,8 @@ + if (!vorbis_is_streaming) + { + char *tmp; ++ displaytitle = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_OUT, g_basename(fn)); ++ if (!displaytitle) + displaytitle = g_strdup(g_basename(fn)); + if ((tmp = strrchr(displaytitle, '.')) != NULL) + *tmp = '\0'; diff --git a/patches/xmms/xmms-ds-playlist.patch b/patches/xmms/xmms-ds-playlist.patch new file mode 100644 index 0000000..b72c8d0 --- /dev/null +++ b/patches/xmms/xmms-ds-playlist.patch @@ -0,0 +1,526 @@ +diff -dPNur xmms-1.2.11/xmms/input.c xmms-1.2.11-new/xmms/input.c +--- xmms-1.2.11/xmms/input.c 2005-05-15 02:01:21.000000000 +0200 ++++ xmms-1.2.11-new/xmms/input.c 2008-10-27 18:14:08.000000000 +0100 +@@ -22,6 +22,7 @@ + #include "libxmms/titlestring.h" + #include "libxmms/util.h" + #include "libxmms/xentry.h" ++#include "libxmms/rcc.h" + + static pthread_mutex_t vis_mutex = PTHREAD_MUTEX_INITIALIZER; + +@@ -372,8 +373,12 @@ + + (*title) = xmms_get_titlestring(xmms_get_gentitle_format(), + input); +- if ( (*title) == NULL ) ++ if ( (*title) == NULL ) { ++ (*title) = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, input->file_name); ++ if (!*title) + (*title) = g_strdup(input->file_name); ++ } ++ + (*length) = -1; + g_free(temp); + g_free(input); +diff -dPNur xmms-1.2.11/xmms/main.c xmms-1.2.11-new/xmms/main.c +--- xmms-1.2.11/xmms/main.c 2006-07-16 15:40:04.000000000 +0200 ++++ xmms-1.2.11-new/xmms/main.c 2008-10-27 18:14:08.000000000 +0100 +@@ -36,6 +36,7 @@ + #include "libxmms/xmmsctrl.h" + #include "libxmms/util.h" + #include "libxmms/dirbrowser.h" ++#include "libxmms/rcc.h" + #include "xmms_mini.xpm" + + #define RANDTABLE_SIZE 128 +@@ -899,6 +900,7 @@ + gtk_timeout_remove(mainwin_timeout_tag); + util_set_cursor(NULL); + save_config(); ++ xmms_rcc_free(); + cleanup_ctrlsocket(); + playlist_stop_get_info_thread(); + playlist_clear(); +@@ -1036,8 +1038,14 @@ + + void mainwin_lock_info_text(char *text) + { ++ gchar *ctext; ++ ctext = xmms_rcc_recode(XMMS_RCC_CTYPE, XMMS_RCC_OUT, text); ++ if (ctext) text=ctext; ++ + mainwin_info_text_locked = TRUE; + textbox_set_text(mainwin_info, text); ++ ++ if (ctext) g_free(ctext); + } + + void mainwin_release_info_text(void) +@@ -1695,9 +1703,10 @@ + int match = 0; + char *title, *filename; + +- title = ((PlaylistEntry *) playlist->data)->title; +- filename = ((PlaylistEntry *) playlist->data)->filename; +- ++ title = playlist_check_entrytitle((PlaylistEntry *) playlist->data); ++ filename = xmms_rcc_get(XMMS_RCC_OUT, ((PlaylistEntry *) playlist->data)->fnstring); ++ if (!filename) filename = g_strdup(((PlaylistEntry *) playlist->data)->filename); ++ + if (title) + desc_buf[1] = title; + else if (strchr(filename, '/')) +@@ -1749,7 +1758,7 @@ + */ + match = mainwin_jump_to_file_match(song, words, nw); + } +- ++ + if (match) + { + int row, queue_pos, *data_buf; +@@ -1772,6 +1781,10 @@ + row_to_select = row; + } + ++ g_free(filename); ++ g_free(title); ++ ++ + songnr++; + playlist = playlist->next; + } +@@ -2072,8 +2085,10 @@ + int row, *data_buf; + char *title, *filename, *tmp_buf, *desc_buf[2]; + +- title = ((PlaylistEntry *) queue->data)->title; +- filename = ((PlaylistEntry *) queue->data)->filename; ++ title = playlist_check_entrytitle((PlaylistEntry *) queue->data); ++ filename = xmms_rcc_get(XMMS_RCC_OUT, ((PlaylistEntry *) queue->data)->fnstring); ++ if (!filename) filename = g_strdup(((PlaylistEntry *) queue->data)->filename); ++ + if (title) + desc_buf[1] = title; + else if (strchr(filename, '/')) +@@ -2086,6 +2101,9 @@ + row = gtk_clist_append(GTK_CLIST(qlist), desc_buf); + g_free(tmp_buf); + ++ g_free(filename); ++ g_free(title); ++ + data_buf = g_malloc(sizeof (int)); + *data_buf = pos; + gtk_clist_set_row_data_full(qlist, row, data_buf, g_free); +@@ -4217,6 +4235,7 @@ + #endif + + read_config(); ++ xmms_rcc_init(); + + #if defined(HAVE_SCHED_SETSCHEDULER) && defined(HAVE_SCHED_GET_PRIORITY_MAX) + if (cfg.use_realtime) +diff -dPNur xmms-1.2.11/xmms/playlist.c xmms-1.2.11-new/xmms/playlist.c +--- xmms-1.2.11/xmms/playlist.c 2007-11-16 22:51:30.000000000 +0100 ++++ xmms-1.2.11-new/xmms/playlist.c 2008-10-27 18:14:31.000000000 +0100 +@@ -20,6 +20,8 @@ + #include "xmms.h" + #include <time.h> + #include "libxmms/util.h" ++#include <locale.h> ++#include "libxmms/rcc.h" + #include <sys/stat.h> + #include <unistd.h> + +@@ -91,6 +93,8 @@ + entry = node->data; + if (entry->filename) + g_free(entry->filename); ++ if (entry->fnstring) ++ g_free(entry->fnstring); + if (entry->title) + g_free(entry->title); + g_free(entry); +@@ -166,6 +170,8 @@ + + if (entry->filename) + g_free(entry->filename); ++ if (entry->fnstring) ++ g_free(entry->fnstring); + if (entry->title) + g_free(entry->title); + shuffle_list = g_list_remove(shuffle_list, entry); +@@ -280,9 +286,17 @@ + PlaylistEntry *entry; + + entry = g_malloc0(sizeof (PlaylistEntry)); ++ + entry->filename = g_strdup(filename); ++ entry->fnstring = xmms_rcc_put(XMMS_RCC_FS, filename); ++ if (!entry->fnstring) entry->fnstring = g_strdup(filename); ++ + if (title) ++ { ++ entry->title = xmms_rcc_put(XMMS_RCC_CTYPE, title); ++ if (!entry->title) + entry->title = g_strdup(title); ++ } + entry->length = len; + + PL_LOCK(); +@@ -624,6 +638,8 @@ + if (playlist_position) + { + g_free(playlist_position->title); ++ playlist_position->title = xmms_rcc_put(XMMS_RCC_CTYPE, title); ++ if (!playlist_position->title) + playlist_position->title = g_strdup(title); + playlist_position->length = length; + } +@@ -1015,6 +1031,7 @@ + char *playlist_get_info_text(void) + { + char *text, *title, *tmp, *numbers, *length; ++ char *ctitle; + + PL_LOCK(); + if (!playlist_position) +@@ -1023,10 +1040,20 @@ + return NULL; + } + +- if (playlist_position->title) ++ if (playlist_position->title) { ++ ctitle = xmms_rcc_get(XMMS_RCC_OUT, playlist_position->title); ++ if (ctitle) title = ctitle; ++ else + title = playlist_position->title; +- else ++ } else { ++ ctitle = xmms_rcc_get(XMMS_RCC_OUT, playlist_position->fnstring); ++ if (ctitle) { ++ title = g_strdup(g_basename(ctitle)); ++ g_free(ctitle); ++ ctitle = title; ++ } else + title = g_basename(playlist_position->filename); ++ } + + /* + * If the user don't want numbers in the playlist, don't +@@ -1048,6 +1075,7 @@ + text = g_strdup_printf("%s%s%s", numbers, title, length); + g_free(numbers); + g_free(length); ++ if (ctitle) g_free(ctitle); + + PL_UNLOCK(); + +@@ -1083,6 +1111,7 @@ + { + GList *node; + FILE *file; ++ gchar *ctitle, *cfn; + + if ((file = fopen(filename, "w")) == NULL) + return FALSE; +@@ -1101,10 +1130,12 @@ + while (node) + { + PlaylistEntry *entry = node->data; ++ if (!strstr(entry->filename,"://")) cfn = xmms_rcc_fs2pl(entry->fnstring, entry->filename); ++ else cfn=NULL; + if (is_pls) + fprintf(file, "File%d=%s\n", + g_list_position(playlist, node) + 1, +- entry->filename); ++ cfn?cfn:entry->filename); + else + { + if (entry->title && cfg.use_pl_metadata) +@@ -1116,11 +1147,14 @@ + else + seconds = -1; + ++ ctitle = xmms_rcc_get(XMMS_RCC_PL, entry->title); + fprintf(file, "#EXTINF:%d,%s\n", +- seconds, entry->title); ++ seconds, ctitle?ctitle:entry->title); ++ if (ctitle) g_free(ctitle); + } +- fprintf(file, "%s\n", entry->filename); ++ fprintf(file, "%s\n", cfn?cfn:entry->filename); + } ++ if (cfn) g_free(cfn); + node = g_list_next(node); + } + PL_UNLOCK(); +@@ -1151,16 +1185,32 @@ + *temp = '\0'; + else + { ++ if ((!strstr(filename,"://"))&&(!strstr(playlist_name, "://"))) { ++ temp = xmms_rcc_fs(XMMS_RCC_PLFS, XMMS_RCC_FS, NULL, NULL, filename); ++ if (temp) filename = temp; ++ } else temp = NULL; + __playlist_ins_with_info(filename, pos, title, len); ++ if (temp) g_free(temp); + return; + } ++ if ((!strstr(filename,"://"))&&(!strstr(playlist_name, "://"))) { ++ temp = xmms_rcc_fs(XMMS_RCC_PLFS, XMMS_RCC_FS, path, path, filename); ++ if (temp) filename = temp; ++ } else temp = NULL; ++ if (!temp) + temp = g_strdup_printf("%s/%s", path, filename); + __playlist_ins_with_info(temp, pos, title, len); + g_free(temp); + g_free(path); + } +- else ++ else { ++ if ((filename[0] == '/')&&(!strstr(playlist_name, "://"))) { ++ temp = xmms_rcc_fs(XMMS_RCC_PLFS, XMMS_RCC_FS, NULL, NULL, filename); ++ if (temp) filename = temp; ++ } else temp = NULL; + __playlist_ins_with_info(filename, pos, title, len); ++ if (temp) g_free(temp); ++ } + } + + static void parse_extm3u_info(char *info, char **title, int *length) +@@ -1182,6 +1232,10 @@ + *length *= 1000; + if ((str = strchr(info, ',')) != NULL) + { ++ if (*str) ++ while ((*(str+1)==' ')||(*(str+1)=='\t')) str++; /* g_strstrip removes leading and ending whitespaces */ ++ *title = xmms_rcc_put(XMMS_RCC_PL, str + 1); ++ if (!*title) + *title = g_strdup(str + 1); + g_strstrip(*title); + if (strlen(*title) < 1) +@@ -1210,7 +1264,7 @@ + line = read_ini_string(filename, "playlist", "NumberOfEntries"); + if (line == NULL) + return 0; +- ++ + noe = atoi(line); + g_free(line); + +@@ -1372,9 +1426,27 @@ + return ret; + } + ++gchar* playlist_check_entrytitle(PlaylistEntry *entry) { ++ gchar *title, *fn; ++ ++ if (!entry) return NULL; ++ ++ title = xmms_rcc_get(XMMS_RCC_OUT, entry->title); ++ if (!title) { ++ fn = xmms_rcc_get(XMMS_RCC_OUT, entry->fnstring); ++ if (fn) { ++ title = g_strdup(g_basename(fn)); ++ g_free(fn); ++ } else title = g_strdup(g_basename(entry->filename)); ++ } ++ ++ return title; ++} ++ + char * playlist_get_songtitle(int pos) + { + char *title = NULL, *filename; ++ char *ctitle; + PlaylistEntry *entry; + GList *node; + +@@ -1396,19 +1468,30 @@ + + if (entry->title == NULL && entry->length == -1) + { +- if (playlist_get_info_entry(entry)) ++ if (playlist_get_info_entry(entry)&&(entry->title)) { ++ title = xmms_rcc_get(XMMS_RCC_OUT, entry->title); ++ if (!title) + title = g_strdup(entry->title); ++ } + + PL_UNLOCK(); + } + else + { ++ title = xmms_rcc_get(XMMS_RCC_OUT, entry->title); ++ if (!title) + title = g_strdup(entry->title); + PL_UNLOCK(); + } + +- if (title == NULL) ++ if (title == NULL) { ++ ctitle = xmms_rcc_get(XMMS_RCC_OUT, entry->filename); ++ if (ctitle) { ++ title = g_strdup(g_basename(ctitle)); ++ g_free(ctitle); ++ } else + title = g_strdup(g_basename(filename)); ++ } + + g_free(filename); + +@@ -1453,36 +1536,41 @@ + + static int playlist_sort_by_title_cmpfunc(PlaylistEntry * a, PlaylistEntry * b) + { +- char *a_title, *b_title; ++ const char *a_title, *b_title; + + if (a->title) +- a_title = a->title; ++ a_title = xmms_rcc_string(a->title); + else + { +- if (strrchr(a->filename, '/')) +- a_title = strrchr(a->filename, '/') + 1; ++ if (strrchr(xmms_rcc_string(a->fnstring), '/')) ++ a_title = strrchr(xmms_rcc_string(a->fnstring), '/') + 1; + else +- a_title = a->filename; ++ a_title = xmms_rcc_string(a->filename); + } + + if (b->title) +- b_title = b->title; ++ b_title = xmms_rcc_string(b->title); + else + { +- if (strrchr(a->filename, '/')) +- b_title = strrchr(b->filename, '/') + 1; ++ if (strrchr(xmms_rcc_string(a->fnstring), '/')) ++ b_title = strrchr(xmms_rcc_string(b->fnstring), '/') + 1; + else +- b_title = b->filename; +- ++ b_title = xmms_rcc_string(b->filename); + } +- return strcasecmp(a_title, b_title); ++ return strcoll(a_title, b_title); + } + + void playlist_sort_by_title(void) + { ++ char *locale; ++ locale = setlocale(LC_COLLATE,"en_US.UTF-8"); ++ playlist_select_all(1); ++ playlist_read_info_selection(); ++ playlist_select_all(0); + PL_LOCK(); + playlist = g_list_sort(playlist, (GCompareFunc) playlist_sort_by_title_cmpfunc); + PL_UNLOCK(); ++ setlocale(LC_COLLATE,locale); + } + + static int playlist_sort_by_filename_cmpfunc(PlaylistEntry * a, PlaylistEntry * b) +@@ -1640,9 +1728,13 @@ + + void playlist_sort_selected_by_title(void) + { ++ char *locale; ++ locale = setlocale(LC_COLLATE,"en_US.UTF-8"); ++ playlist_read_info_selection(); + PL_LOCK(); + playlist = playlist_sort_selected(playlist, (GCompareFunc) playlist_sort_by_title_cmpfunc); + PL_UNLOCK(); ++ setlocale(LC_COLLATE,locale); + } + + void playlist_sort_selected_by_filename(void) +@@ -1859,6 +1951,8 @@ + return FALSE; + + /* entry is still around */ ++ entry->title = xmms_rcc_put(XMMS_RCC_CTYPE, temp_title); ++ if (!entry->title) + entry->title = temp_title; + entry->length = temp_length; + +diff -dPNur xmms-1.2.11/xmms/playlist.h xmms-1.2.11-new/xmms/playlist.h +--- xmms-1.2.11/xmms/playlist.h 2007-11-16 22:51:30.000000000 +0100 ++++ xmms-1.2.11-new/xmms/playlist.h 2008-10-27 18:14:08.000000000 +0100 +@@ -23,6 +23,7 @@ + typedef struct + { + gchar *filename; ++ gchar *fnstring; + gchar *title; + gint length; + gboolean selected; +@@ -86,6 +87,7 @@ + void playlist_fileinfo(gint pos); + void playlist_delete_index(glong index); + void playlist_delete_filenames(GList *filenames); ++gchar* playlist_check_entrytitle(PlaylistEntry *entry); + gchar* playlist_get_filename(gint pos); + gchar* playlist_get_songtitle(gint pos); + gint playlist_get_songtime(gint pos); +diff -dPNur xmms-1.2.11/xmms/playlist_list.c xmms-1.2.11-new/xmms/playlist_list.c +--- xmms-1.2.11/xmms/playlist_list.c 2003-06-11 20:44:17.000000000 +0200 ++++ xmms-1.2.11-new/xmms/playlist_list.c 2008-10-27 18:14:08.000000000 +0100 +@@ -451,10 +451,8 @@ + else + gdk_gc_set_foreground(gc, get_skin_color(SKIN_PLEDIT_NORMAL)); + +- if (entry->title) +- title = entry->title; +- else +- title = g_basename(entry->filename); ++ ++ title = playlist_check_entrytitle(entry); + + pos = playlist_get_queue_position(entry); + +@@ -497,6 +495,8 @@ + playlist_list_draw_string(pl, playlist_list_font, + i - pl->pl_first, tw, text); + g_free(text); ++ ++ g_free(title); + } + PL_UNLOCK(); + } +diff -dPNur xmms-1.2.11/xmms/prefswin.c xmms-1.2.11-new/xmms/prefswin.c +--- xmms-1.2.11/xmms/prefswin.c 2007-11-16 22:51:30.000000000 +0100 ++++ xmms-1.2.11-new/xmms/prefswin.c 2008-10-27 18:14:08.000000000 +0100 +@@ -18,6 +18,7 @@ + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + #include "xmms.h" ++#include "libxmms/rcc.h" + #include "libxmms/util.h" + #include "libxmms/titlestring.h" + +@@ -397,6 +398,8 @@ + draw_playlist_window(TRUE); + draw_equalizer_window(TRUE); + ++ xmms_rcc_prefswin_apply(); ++ + save_config(); + } + +@@ -1105,6 +1108,11 @@ + gtk_notebook_append_page(GTK_NOTEBOOK(prefswin_notebook), prefswin_fonts_vbox, gtk_label_new(_("Fonts"))); + + /* ++ * Coding Conversion page ++ */ ++ xmms_rcc_prefswin_create(prefswin_notebook); ++ ++ /* + * Title page + */ + prefswin_title_vbox = gtk_vbox_new(FALSE, 0); diff --git a/patches/xmms/xmms-ds-rusxmms-charset.patch b/patches/xmms/xmms-ds-rusxmms-charset.patch new file mode 100644 index 0000000..670f9e3 --- /dev/null +++ b/patches/xmms/xmms-ds-rusxmms-charset.patch @@ -0,0 +1,87 @@ +diff -dPNur xmms-1.2.10/libxmms/charset.c xmms-1.2.10-new/libxmms/charset.c +--- xmms-1.2.10/libxmms/charset.c 2005-08-10 03:20:03.000000000 +0200 ++++ xmms-1.2.10-new/libxmms/charset.c 2005-08-10 02:54:12.000000000 +0200 +@@ -20,6 +20,7 @@ + #include <langinfo.h> + #endif + ++#include "rcc.h" + #include "charset.h" + + char* xmms_charset_get_current(void) +@@ -37,7 +38,7 @@ + return charset; + } + +-static size_t utf16_strlen(const char *string) ++size_t utf16_strlen(const char *string) + { + size_t len = 0; + +@@ -78,7 +79,7 @@ + /* + 1 for nul in case len == 1 */ + outsize = ((insize + 3) & ~3) + 1; + out = g_malloc(outsize); +- outleft = outsize - 1; ++ outleft = outsize - 2; + outptr = out; + + retry: +@@ -92,7 +93,7 @@ + outsize = (outsize - 1) * 2 + 1; + out = g_realloc(out, outsize); + outptr = out + used; +- outleft = outsize - 1 - used; ++ outleft = outsize - 2 - used; + goto retry; + case EINVAL: + break; +@@ -110,6 +111,7 @@ + } + } + *outptr = '\0'; ++ *(outptr+1) = '\0'; + + iconv_close(cd); + return out; +@@ -141,10 +143,14 @@ + + char* xmms_charset_from_latin1(const char *string) + { ++ char *cstring; + char *to = xmms_charset_get_current(); + + if (!string) + return NULL; ++ ++ cstring = xmms_rcc_recode(XMMS_RCC_ID3, XMMS_RCC_CTYPE, string); ++ if (cstring) return cstring; + + if (!strcmp(to, "UTF-8")) + return xmms_charset_convert(string, strlen(string), "ISO-8859-1", to); +@@ -271,9 +277,14 @@ + + char* xmms_charset_from_latin1(const char *string) + { ++ char *cstring; ++ + if (!string) + return NULL; + ++ cstring = xmms_rcc_recode(XMMS_RCC_ID3, XMMS_RCC_CTYPE, string); ++ if (cstring) return cstring; ++ + return g_strdup(string); + } + +diff -dPNur xmms-1.2.10/libxmms/charset.h xmms-1.2.10-new/libxmms/charset.h +--- xmms-1.2.10/libxmms/charset.h 2005-08-10 03:20:03.000000000 +0200 ++++ xmms-1.2.10-new/libxmms/charset.h 2005-08-10 01:41:01.000000000 +0200 +@@ -16,5 +16,7 @@ + char* xmms_charset_from_utf16be(const unsigned char *string); + char* xmms_charset_from_latin1(const char *string); + ++size_t utf16_strlen(const char *string); ++ + #endif /* XMMS_CHARSET_H */ + diff --git a/patches/xmms/xmms-ds-rusxmms.patch b/patches/xmms/xmms-ds-rusxmms.patch new file mode 100644 index 0000000..6b9287f --- /dev/null +++ b/patches/xmms/xmms-ds-rusxmms.patch @@ -0,0 +1,172 @@ +diff -dPNur xmms-1.2.11/libxmms/configure.in xmms-1.2.11-new/libxmms/configure.in +--- xmms-1.2.11/libxmms/configure.in 2007-11-16 22:51:24.000000000 +0100 ++++ xmms-1.2.11-new/libxmms/configure.in 2007-11-25 17:38:56.000000000 +0100 +@@ -57,6 +57,16 @@ + AC_DEFINE([HAVE_CODESET],,[Define if nl_langinfo(CODESET) is available.]) + fi + ++AC_CHECK_LIB(rccgtk, rccUiInit,[ ++ AC_CHECK_HEADERS(librcc.h librccui.h,[ ++ LIBRCC_LIBS="-lrccgtk" ++ LIBRCC_INCLUDES="" ++ ],[ ++ LIBRCC_LIBS="" ++ LIBRCC_INCLUDES="" ++])]) ++AC_SUBST(LIBRCC_LIBS) ++AC_SUBST(LIBRCC_INCLUDES) + + AC_OUTPUT([ + Makefile +diff -dPNur xmms-1.2.11/libxmms/Makefile.am xmms-1.2.11-new/libxmms/Makefile.am +--- xmms-1.2.11/libxmms/Makefile.am 2004-04-04 10:51:20.000000000 +0200 ++++ xmms-1.2.11-new/libxmms/Makefile.am 2007-11-25 17:38:56.000000000 +0100 +@@ -4,10 +4,11 @@ + lib_LTLIBRARIES = libxmms.la + + libxmms_la_LDFLAGS = -export-dynamic -version-info $(LIBXMMS_MAJOR_VERSION):$(LIBXMMS_MINOR_VERSION):$(LIBXMMS_MICRO_VERSION) +-libxmms_la_LIBADD = @GTK_LIBS@ @POSIX_LIBS@ +-INCLUDES = @GTK_CFLAGS@ -I../intl -I.. ++libxmms_la_LIBADD = @LIBRCC_LIBS@ @GTK_LIBS@ @POSIX_LIBS@ ++INCLUDES = @LIBRCC_INCLUDES@ @GTK_CFLAGS@ -I../intl -I.. + + libxmms_la_SOURCES = \ ++rcc.c rcc.h rcc_langs.h \ + configfile.c configfile.h \ + xmmsctrl.c xmmsctrl.h \ + dirbrowser.c dirbrowser.h \ +diff -dPNur xmms-1.2.11/libxmms/titlestring.c xmms-1.2.11-new/libxmms/titlestring.c +--- xmms-1.2.11/libxmms/titlestring.c 2006-07-24 00:11:51.000000000 +0200 ++++ xmms-1.2.11-new/libxmms/titlestring.c 2007-11-25 17:39:21.000000000 +0100 +@@ -29,6 +29,7 @@ + #include <string.h> + #include <ctype.h> + ++#include "rcc.h" + #include "titlestring.h" + #include "../xmms/i18n.h" + +@@ -42,8 +43,9 @@ + PAD_SIDE_RIGHT, + }; + ++#define xmms_vputstr(out, pstr, pad) xmms_charset_vputstr(out, pstr, pad, from, pflag, c) + +-static int xmms_vputstr(GString *output, char *pstr, struct padding *pad) ++static int xmms_orig_vputstr(GString *output, char *pstr, struct padding *pad) + { + int i; + /* Lenght of the string that is actually printed */ +@@ -83,6 +85,22 @@ + return TRUE; + } + ++static int xmms_charset_vputstr(GString *output, char *pstr, struct padding *pad, int from, gint pflag, char c) { ++ int res; ++ gchar *cstring = NULL; ++ ++ if ((pflag&1)&&((c=='f')||(c=='F'))) { ++ cstring = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, pstr); ++ } ++ if ((pflag&2)&&((c=='a')||(c=='c')||(c=='g')||(c=='p')||(c=='t'))) { ++ cstring = xmms_rcc_recode((xmms_rcc_class)from, XMMS_RCC_CTYPE, pstr); ++ } ++ ++ res = xmms_orig_vputstr(output, cstring?cstring:pstr, pad); ++ if (cstring) g_free(cstring); ++ ++ return res; ++} + + static int xmms_vputnum(GString *output, int ival, struct padding *pad) + { +@@ -124,7 +142,7 @@ + return TRUE; + } + +-static int parse_variable(char **fmt, GString *string, TitleInput *input) ++static int parse_variable(char **fmt, GString *string, TitleInput *input, int from, gint pflag) + { + struct padding padding; + char *ptr = *fmt; +@@ -237,9 +255,33 @@ + return exp; + } + ++static int xmms_charset_analyze_fmt(gchar *fmt) { ++ int flag = 0; ++ ++ if (!fmt) return 0; ++ for (;*fmt;fmt++) { ++ while ((*fmt != '%')&&(*fmt != 0)) fmt++; ++ if (!*fmt) break; ++ while ((*fmt == '-')||(*fmt == ' ')||(*fmt == '0')) fmt++; ++ while (*fmt >= '0' && *fmt <= '9') fmt++; ++ if (*fmt == '.') { fmt++; while (*fmt >= '0' && *fmt <= '9') fmt++; } ++ if ((*fmt=='a')||(*fmt=='c')||(*fmt=='g')||(*fmt=='p')||(*fmt=='t')) flag|=1; ++ if ((*fmt=='f')||(*fmt=='F')) flag|=2; ++ } ++ ++ return flag; ++} ++ ++gchar *xmms_charset_get_titlestring(gchar *fmt, TitleInput *input, int from); + + char *xmms_get_titlestring(char *fmt, TitleInput *input) + { ++ return xmms_charset_get_titlestring(fmt, input, (xmms_rcc_class)-1); ++} ++ ++gchar *xmms_charset_get_titlestring(gchar *fmt, TitleInput *input, int from) { ++ gint pflag; ++ gchar *cstring = NULL; + int f_output = 0; + GString *string; + char *strptr; +@@ -249,12 +291,14 @@ + + string = g_string_new(""); + ++ pflag = (from == (xmms_rcc_class)-1)?0:xmms_charset_analyze_fmt(fmt); ++ + while (*fmt) + { + if (*fmt == '%') + { + fmt++; +- f_output += parse_variable(&fmt, string, input); ++ f_output += parse_variable(&fmt, string, input, from, pflag); + } + else + /* Normal character */ +@@ -271,6 +315,19 @@ + /* Return the result */ + strptr = string->str; + g_string_free(string, FALSE); ++ ++ if (pflag<3) { ++ if (pflag&2) ++ cstring = xmms_rcc_recode(XMMS_RCC_FS, XMMS_RCC_CTYPE, strptr); ++ else ++ cstring = xmms_rcc_recode((xmms_rcc_class)from, XMMS_RCC_CTYPE, strptr); ++ ++ if (cstring) { ++ g_free(strptr); ++ return cstring; ++ } ++ } ++ + return strptr; + } + +diff -dPNur xmms-1.2.11/libxmms/titlestring.h xmms-1.2.11-new/libxmms/titlestring.h +--- xmms-1.2.11/libxmms/titlestring.h 2005-05-15 02:01:20.000000000 +0200 ++++ xmms-1.2.11-new/libxmms/titlestring.h 2007-11-25 17:38:56.000000000 +0100 +@@ -77,6 +77,7 @@ + #endif + + gchar *xmms_get_titlestring(gchar *fmt, TitleInput *input); ++gchar *xmms_charset_get_titlestring(gchar *fmt, TitleInput *input, int from); + GtkWidget* xmms_titlestring_descriptions(char* tags, int rows); + + #ifdef __cplusplus diff --git a/patches/xmms/xmms-ds-shade.patch b/patches/xmms/xmms-ds-shade.patch new file mode 100644 index 0000000..41362df --- /dev/null +++ b/patches/xmms/xmms-ds-shade.patch @@ -0,0 +1,194 @@ +diff -dPNur xmms-1.2.11/xmms/main.c xmms-1.2.11-new/xmms/main.c +--- xmms-1.2.11/xmms/main.c 2007-11-25 01:10:52.000000000 +0100 ++++ xmms-1.2.11-new/xmms/main.c 2007-11-25 01:11:13.000000000 +0100 +@@ -382,6 +382,8 @@ + + cfg.gentitle_format = NULL; + ++ cfg.shade_font = NULL; ++ + filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); + cfgfile = xmms_cfg_open_file(filename); + if (cfgfile) +@@ -481,6 +483,8 @@ + } + xmms_cfg_read_string(cfgfile, "xmms", "generic_title_format", &cfg.gentitle_format); + ++ xmms_cfg_read_string(cfgfile, "xmms", "shade_font", &cfg.shade_font); ++ + xmms_cfg_free(cfgfile); + } + +@@ -519,6 +523,13 @@ + if (cfg.eqpreset_extension == NULL) + cfg.eqpreset_extension = g_strdup("preset"); + ++ if (cfg.shade_font && strlen(cfg.shade_font) == 0) { ++ g_free(cfg.shade_font); ++ cfg.shade_font = NULL; ++ } ++ if (!cfg.shade_font) ++ cfg.shade_font = g_strdup("-misc-fixed-medium-r-*-*-7-*"); ++ + g_free(filename); + } + +@@ -677,6 +688,8 @@ + } + xmms_cfg_write_string(cfgfile, "xmms", "generic_title_format", cfg.gentitle_format); + ++ xmms_cfg_write_string(cfgfile, "xmms", "shade_font", cfg.shade_font); ++ + xmms_cfg_write_file(cfgfile, filename); + xmms_cfg_free(cfgfile); + +diff -dPNur xmms-1.2.11/xmms/main.h xmms-1.2.11-new/xmms/main.h +--- xmms-1.2.11/xmms/main.h 2006-07-16 15:40:04.000000000 +0200 ++++ xmms-1.2.11-new/xmms/main.h 2007-11-25 01:12:55.000000000 +0100 +@@ -60,6 +60,7 @@ + gint mouse_change; + gboolean playlist_transparent; + gchar *gentitle_format; ++ gchar *shade_font; + } + Config; + +diff -dPNur xmms-1.2.11/xmms/playlistwin.c xmms-1.2.11-new/xmms/playlistwin.c +--- xmms-1.2.11/xmms/playlistwin.c 2007-11-16 22:51:30.000000000 +0100 ++++ xmms-1.2.11-new/xmms/playlistwin.c 2007-11-25 01:11:13.000000000 +0100 +@@ -39,7 +39,8 @@ + PButton *playlistwin_shade, *playlistwin_close; + static PlaylistSlider *playlistwin_slider = NULL; + static TextBox *playlistwin_time_min, *playlistwin_time_sec; +-static TextBox *playlistwin_info, *playlistwin_sinfo; ++static TextBox *playlistwin_info; ++TextBox *playlistwin_sinfo; + static SButton *playlistwin_srew, *playlistwin_splay; + static SButton *playlistwin_spause, *playlistwin_sstop; + static SButton *playlistwin_sfwd, *playlistwin_seject; +@@ -1882,6 +1883,7 @@ + static void playlistwin_create_widgets(void) + { + playlistwin_sinfo = create_textbox(&playlistwin_wlist, playlistwin_bg, playlistwin_gc, 4, 4, cfg.playlist_width - 35, FALSE, SKIN_TEXT); ++ textbox_set_xfont(playlistwin_sinfo, cfg.mainwin_use_xfont, cfg.shade_font); + if (!cfg.playlist_shaded) + hide_widget(playlistwin_sinfo); + if (cfg.playlist_shaded) +diff -dPNur xmms-1.2.11/xmms/prefswin.c xmms-1.2.11-new/xmms/prefswin.c +--- xmms-1.2.11/xmms/prefswin.c 2007-11-25 01:10:52.000000000 +0100 ++++ xmms-1.2.11-new/xmms/prefswin.c 2007-11-25 01:11:13.000000000 +0100 +@@ -35,6 +35,7 @@ + + static GtkWidget *prefswin_options_sd_entry, *prefswin_options_pbs_entry; + ++static GtkWidget *prefswin_shade_font_entry, *prefswin_shade_font_browse; + static GtkWidget *prefswin_options_font_entry, *prefswin_options_font_browse; + static GtkWidget *prefswin_options_fontset, *prefswin_mainwin_font_entry; + static GtkWidget *prefswin_mainwin_xfont, *prefswin_options_mouse_spin; +@@ -48,6 +49,7 @@ + extern PButton *playlistwin_shade, *playlistwin_close, *equalizerwin_close; + extern PButton *mainwin_menubtn, *mainwin_minimize, *mainwin_shade, *mainwin_close; + extern TextBox *mainwin_info; ++extern TextBox *playlistwin_sinfo; + extern gboolean mainwin_focus, equalizerwin_focus, playlistwin_focus; + + static gboolean is_opening = FALSE; +@@ -343,11 +345,13 @@ + gboolean show_wm_old = cfg.show_wm_decorations; + g_free(cfg.playlist_font); + g_free(cfg.mainwin_font); ++ g_free(cfg.shade_font); + g_free(cfg.gentitle_format); + prefswin_options_write_data(); + cfg.snap_distance = CLAMP(atoi(gtk_entry_get_text(GTK_ENTRY(prefswin_options_sd_entry))), 0, 1000); + cfg.playlist_font = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_options_font_entry))); + cfg.mainwin_font = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_mainwin_font_entry))); ++ cfg.shade_font = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_shade_font_entry))); + cfg.gentitle_format = g_strdup(gtk_entry_get_text(GTK_ENTRY(prefswin_title_entry))); + cfg.pause_between_songs_time = CLAMP(atoi(gtk_entry_get_text(GTK_ENTRY(prefswin_options_pbs_entry))), 0, 1000); + cfg.mouse_change = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(prefswin_options_mouse_spin)); +@@ -390,6 +394,7 @@ + prefswin_toggle_wm_decorations(); + + textbox_set_xfont(mainwin_info, cfg.mainwin_use_xfont, cfg.mainwin_font); ++ textbox_set_xfont(playlistwin_sinfo, cfg.mainwin_use_xfont, cfg.shade_font); + playlist_list_set_font(cfg.playlist_font); + playlistwin_update_list(); + mainwin_set_info_text(); +@@ -475,6 +480,34 @@ + } + } + ++void prefswin_shade_font_browse_ok(GtkWidget * w, gpointer data) ++{ ++ GtkFontSelectionDialog *fontsel = GTK_FONT_SELECTION_DIALOG(data); ++ gchar *fontname; ++ ++ fontname = gtk_font_selection_dialog_get_font_name(fontsel); ++ ++ if (fontname) ++ gtk_entry_set_text(GTK_ENTRY(prefswin_shade_font_entry), fontname); ++ ++ gtk_widget_destroy(GTK_WIDGET(fontsel)); ++} ++ ++void prefswin_shade_font_browse_cb(GtkWidget * w, gpointer data) ++{ ++ static GtkWidget *fontsel; ++ ++ if (fontsel != NULL) ++ return; ++ ++ fontsel = gtk_font_selection_dialog_new(_("Select playlist font:")); ++ gtk_font_selection_dialog_set_font_name(GTK_FONT_SELECTION_DIALOG(fontsel), gtk_entry_get_text(GTK_ENTRY(prefswin_shade_font_entry))); ++ gtk_signal_connect(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->ok_button), "clicked", GTK_SIGNAL_FUNC(prefswin_shade_font_browse_ok), fontsel); ++ gtk_signal_connect_object(GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(fontsel)); ++ gtk_signal_connect(GTK_OBJECT(fontsel), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &fontsel); ++ gtk_widget_show(fontsel); ++} ++ + void prefswin_gplugins_use_cb(GtkToggleButton * w, gpointer data) + { + gint sel; +@@ -693,7 +726,10 @@ + GtkWidget *prefswin_vplugins_box, *prefswin_vplugins_vbox; + GtkWidget *prefswin_vplugins_frame, *prefswin_vplugins_hbox; + GtkWidget *prefswin_vplugins_hbbox; +- ++ ++ GtkWidget *prefswin_fonts_shade_frame; ++ GtkWidget *options_font_shade_hbox, *options_font_shade_vbox; ++ + GtkWidget *prefswin_options_frame, *prefswin_options_vbox; + GtkWidget *prefswin_mainwin_frame, *prefswin_mainwin_vbox; + GtkWidget *prefswin_fonts_vbox, *prefswin_fonts_playlist_frame; +@@ -1105,6 +1141,21 @@ + gtk_widget_set_usize(prefswin_mainwin_font_browse, 85, 17); + gtk_box_pack_start(GTK_BOX(prefswin_mainwin_font_hbox), prefswin_mainwin_font_browse, FALSE, TRUE, 0); + ++ prefswin_fonts_shade_frame = gtk_frame_new(_("Shade")); ++ gtk_container_set_border_width(GTK_CONTAINER(prefswin_fonts_shade_frame), 5); ++ gtk_box_pack_start(GTK_BOX(prefswin_fonts_vbox), prefswin_fonts_shade_frame, FALSE, FALSE, 0); ++ options_font_shade_vbox = gtk_vbox_new(FALSE, 5); ++ gtk_container_border_width(GTK_CONTAINER(options_font_shade_vbox), 5); ++ gtk_container_add(GTK_CONTAINER(prefswin_fonts_shade_frame), options_font_shade_vbox); ++ options_font_shade_hbox = gtk_hbox_new(FALSE, 5); ++ gtk_box_pack_start_defaults(GTK_BOX(options_font_shade_vbox), options_font_shade_hbox); ++ prefswin_shade_font_entry = gtk_entry_new(); ++ gtk_box_pack_start(GTK_BOX(options_font_shade_hbox), prefswin_shade_font_entry, TRUE, TRUE, 0); ++ prefswin_shade_font_browse = gtk_button_new_with_label(_("Browse")); ++ gtk_signal_connect(GTK_OBJECT(prefswin_shade_font_browse), "clicked", GTK_SIGNAL_FUNC(prefswin_shade_font_browse_cb), NULL); ++ gtk_widget_set_usize(prefswin_shade_font_browse, 85, 17); ++ gtk_box_pack_start(GTK_BOX(options_font_shade_hbox), prefswin_shade_font_browse, FALSE, TRUE, 0); ++ + gtk_notebook_append_page(GTK_NOTEBOOK(prefswin_notebook), prefswin_fonts_vbox, gtk_label_new(_("Fonts"))); + + /* +@@ -1390,6 +1441,7 @@ + + gtk_entry_set_text(GTK_ENTRY(prefswin_options_font_entry), cfg.playlist_font); + gtk_entry_set_text(GTK_ENTRY(prefswin_mainwin_font_entry), cfg.mainwin_font); ++ gtk_entry_set_text(GTK_ENTRY(prefswin_shade_font_entry), cfg.shade_font); + gtk_entry_set_text(GTK_ENTRY(prefswin_title_entry), cfg.gentitle_format); + sprintf(temp, "%u", cfg.snap_distance); + gtk_entry_set_text(GTK_ENTRY(prefswin_options_sd_entry), temp); diff --git a/patches/xmms/xmms-ds-textbox.patch b/patches/xmms/xmms-ds-textbox.patch new file mode 100644 index 0000000..8442606 --- /dev/null +++ b/patches/xmms/xmms-ds-textbox.patch @@ -0,0 +1,31 @@ +diff -dPNur xmms-1.2.10/xmms/textbox.c xmms-1.2.10-patched/xmms/textbox.c +--- xmms-1.2.10/xmms/textbox.c 2001-12-01 18:00:51.000000000 +0100 ++++ xmms-1.2.10-patched/xmms/textbox.c 2005-06-02 22:43:42.000000000 +0200 +@@ -166,6 +166,8 @@ + GdkGC *gc, *maskgc; + GdkColor *c, pattern; + GdkBitmap *mask; ++ GdkWChar *wtext; ++ int len; + + length = strlen(pixmaptext); + +@@ -192,6 +194,18 @@ + tb->tb_pixmap_width, tb->tb_widget.height); + pattern.pixel = 1; + gdk_gc_set_foreground(maskgc, &pattern); ++ if (cfg.use_fontsets) { ++ wtext = g_malloc((length + 1) * sizeof(GdkWChar)); ++ len = gdk_mbstowcs(wtext, pixmaptext, length + 1); ++ if (len == -1) { ++ for (len = 0; pixmaptext[len] != '\0'; len++) ++ wtext[len] = pixmaptext[len]; ++ } ++ wtext[len] = L'\0'; ++ gdk_draw_text_wc(mask,tb->tb_font, maskgc, 0, tb->tb_font->ascent, wtext, len ); ++ g_free(wtext); ++ } ++ else + gdk_draw_text(mask, tb->tb_font, maskgc, 0, + tb->tb_font->ascent, pixmaptext, length); + gdk_gc_unref(maskgc); |