summaryrefslogtreecommitdiffstats
path: root/mp_msg.c
diff options
context:
space:
mode:
authorUoti Urpala <uau@glyph.nonexistent.invalid>2010-03-08 22:48:50 +0200
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-03-08 22:53:12 +0200
commit81065d41b6d0844f138e0ad132d7861a03a4efc0 (patch)
tree8e1e8a7ec4919e35984a2863162b6b4f08050464 /mp_msg.c
parentb34a88e4f44ee2a926c8c30f8fb3954fc7d71b90 (diff)
downloadmpv-81065d41b6d0844f138e0ad132d7861a03a4efc0.tar.bz2
mpv-81065d41b6d0844f138e0ad132d7861a03a4efc0.tar.xz
Add runtime translation support
Add support for gettext-based runtime translations. Enabled with configure switch --enable-translation (no autodetection). Note that no translation files are installed yet.
Diffstat (limited to 'mp_msg.c')
-rw-r--r--mp_msg.c70
1 files changed, 69 insertions, 1 deletions
diff --git a/mp_msg.c b/mp_msg.c
index 7314dd25af..9da2c3095b 100644
--- a/mp_msg.c
+++ b/mp_msg.c
@@ -5,6 +5,11 @@
#include "config.h"
+#ifdef CONFIG_TRANSLATION
+#include <locale.h>
+#include <libintl.h>
+#endif
+
#ifdef CONFIG_ICONV
#include <iconv.h>
#include <errno.h>
@@ -77,6 +82,14 @@ void mp_msg_init(void){
if (!mp_msg_charset)
mp_msg_charset = get_term_charset();
#endif
+#ifdef CONFIG_TRANSLATION
+ textdomain("mplayer");
+ char *localedir = getenv("MPLAYER_LOCALEDIR");
+ if (localedir == NULL && strlen(MPLAYER_LOCALEDIR))
+ localedir = MPLAYER_LOCALEDIR;
+ bindtextdomain("mplayer", localedir);
+ bind_textdomain_codeset("mplayer", "UTF-8");
+#endif
}
int mp_msg_test(int mod, int lev)
@@ -224,8 +237,63 @@ void mp_msg(int mod, int lev, const char *format, ...)
va_end(va);
}
-
char *mp_gtext(const char *string)
{
+#ifdef CONFIG_TRANSLATION
+ /* gettext expects the global locale to be set with
+ * setlocale(LC_ALL, ""). However doing that would suck for a
+ * couple of reasons (locale stuff is badly designed and sucks in
+ * general).
+ *
+ * First setting the locale, especially LC_CTYPE, changes the
+ * behavior of various C functions and we don't want that - we
+ * want isalpha() for example to always behave like in the C
+ * locale.
+
+ * Second, there is no way to enforce a sane character set. All
+ * strings inside MPlayer must always be in utf-8, not in the
+ * character set specified by the system locale which could be
+ * something different and completely insane. The locale system
+ * lacks any way to say "set LC_CTYPE to utf-8, ignoring the
+ * default system locale if it specifies something different". We
+ * could try to work around that flaw by leaving LC_CTYPE to the C
+ * locale and only setting LC_MESSAGES (which is the variable that
+ * must be set to tell gettext which language to translate
+ * to). However if we leave LC_MESSAGES set then things like
+ * strerror() may produce completely garbled output when they try
+ * to translate their results but then try to convert some
+ * translated non-ASCII text to the character set specified by
+ * LC_CTYPE which would still be in the C locale (this doesn't
+ * affect gettext itself because it supports specifying the
+ * character set directly with bind_textdomain_codeset()).
+ *
+ * So the only solution (at leat short of trying to work around
+ * things possibly producing non-utf-8 output) is to leave all the
+ * locale variables unset. Note that this means it's not possible
+ * to get translated output from any libraries we call if they
+ * only rely on the broken locale system to specify the language
+ * to use; this is the case with libc for example.
+ *
+ * The locale changing below is rather ugly, but hard to avoid.
+ * gettext doesn't support specifying the translation target
+ * directly, only through locale.
+ * The main actual problem this could cause is interference with
+ * other threads; that could be avoided with thread-specific
+ * locale changes, but such functionality is less standard and I
+ * think it's not worth adding pre-emptively unless someone sees
+ * an actual problem case.
+ */
+ setlocale(LC_MESSAGES, "");
+ string = gettext(string);
+ setlocale(LC_MESSAGES, "C");
+#endif
return string;
}
+
+void mp_tmsg(int mod, int lev, const char *format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ mp_msg_va(mod, lev, mp_gtext(format), va);
+ va_end(va);
+}