diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2010-03-08 22:48:50 +0200 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2010-03-08 22:53:12 +0200 |
commit | 81065d41b6d0844f138e0ad132d7861a03a4efc0 (patch) | |
tree | 8e1e8a7ec4919e35984a2863162b6b4f08050464 | |
parent | b34a88e4f44ee2a926c8c30f8fb3954fc7d71b90 (diff) | |
download | mpv-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.
-rwxr-xr-x | configure | 21 | ||||
-rw-r--r-- | mp_msg.c | 70 | ||||
-rw-r--r-- | mp_msg.h | 3 |
3 files changed, 92 insertions, 2 deletions
@@ -216,6 +216,7 @@ Installation directories: --mandir=DIR directory for installing man pages [PREFIX/share/man] --confdir=DIR directory for installing configuration files [PREFIX/etc/mplayer] + --localedir=DIR directory for locale tree [PREFIX/share/locale] --libdir=DIR directory for object code libraries [PREFIX/lib] --codecsdir=DIR directory for binary codecs [LIBDIR/codecs] --win32codecsdir=DIR directory for Windows DLLs [LIBDIR/codecs] @@ -398,6 +399,7 @@ Audio output: --disable-select disable using select() on the audio device [enable] Language options: + --enable-translation enable support for translated output [disable] --charset=charset convert the console messages to this character set --language-doc=lang language to use for the documentation [en] --language-man=lang language to use for the man pages [en] @@ -656,6 +658,7 @@ _largefiles=yes #language=en _shm=auto _linux_devfs=no +_translation=no _charset="UTF-8" _dynamic_plugins=no _crash_debug=no @@ -733,6 +736,9 @@ for ac_option do --realcodecsdir=*) _realcodecsdir=$(echo $ac_option | cut -d '=' -f 2) ;; + --localedir=*) + _localedir=$(echo $ac_option | cut -d '=' -f 2) + ;; --with-install=*) _install=$(echo $ac_option | cut -d '=' -f 2 ) @@ -843,6 +849,8 @@ for ac_option do --disable-debug) _debug= ;; + --enable-translation) _translation=yes ;; + --disable-translation) _translation=no ;; --enable-runtime-cpudetection) _runtime_cpudetection=yes ;; --disable-runtime-cpudetection) _runtime_cpudetection=no ;; --enable-cross-compile) _cross_compile=yes ;; @@ -1265,6 +1273,7 @@ test -z "$_datadir" && _datadir="$_prefix/share/mplayer" test -z "$_mandir" && _mandir="$_prefix/share/man" test -z "$_confdir" && _confdir="$_prefix/etc/mplayer" test -z "$_libdir" && _libdir="$_prefix/lib" +test -z "$_localedir" && _localedir="$_prefix/share/locale" # Determine our OS name and CPU architecture if test -z "$_target" ; then @@ -2825,6 +2834,14 @@ fi echores "$_langinfo" +echocheck "translation support" +if test "$_translation" = yes; then + def_translation="#define CONFIG_TRANSLATION 1" +else + def_translation="#undef CONFIG_TRANSLATION" +fi +echores "$_translation" + echocheck "language" # Set preferred languages, "all" uses English as main language. test -z "$language" && language=$LINGUAS @@ -7840,6 +7857,7 @@ DATADIR = \$(DESTDIR)$_datadir LIBDIR = \$(DESTDIR)$_libdir MANDIR = \$(DESTDIR)$_mandir CONFDIR = \$(DESTDIR)$_confdir +LOCALEDIR = \$(DESTDIR)$_localedir AR = $_ar AS = $_cc @@ -8137,6 +8155,9 @@ cat > $TMPH << EOF #define MPLAYER_DATADIR "$_datadir" #define MPLAYER_CONFDIR "$_confdir" #define MPLAYER_LIBDIR "$_libdir" +#define MPLAYER_LOCALEDIR "$_localedir" + +$def_translation /* definitions needed by included libraries */ #define HAVE_INTTYPES_H 1 @@ -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); +} @@ -118,12 +118,12 @@ int mp_msg_test(int mod, int lev); #include "config.h" char *mp_gtext(const char *string); -#define mp_tmsg mp_msg void mp_msg_va(int mod, int lev, const char *format, va_list va); #ifdef __GNUC__ void mp_msg(int mod, int lev, const char *format, ... ) __attribute__ ((format (printf, 3, 4))); +void mp_tmsg(int mod, int lev, const char *format, ... ) __attribute__ ((format (printf, 3, 4))); # ifdef MP_DEBUG # define mp_dbg(mod,lev, args... ) mp_msg(mod, lev, ## args ) # else @@ -131,6 +131,7 @@ void mp_msg(int mod, int lev, const char *format, ... ) __attribute__ ((format ( # endif #else // not GNU C void mp_msg(int mod, int lev, const char *format, ... ); +void mp_tmsg(int mod, int lev, const char *format, ...) # ifdef MP_DEBUG # define mp_dbg(mod,lev, ... ) mp_msg(mod, lev, __VA_ARGS__) # else |