summaryrefslogtreecommitdiffstats
path: root/mp_msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'mp_msg.c')
-rw-r--r--mp_msg.c100
1 files changed, 84 insertions, 16 deletions
diff --git a/mp_msg.c b/mp_msg.c
index 8d93c68c6e..ab7b969c84 100644
--- a/mp_msg.c
+++ b/mp_msg.c
@@ -24,18 +24,16 @@
#include "config.h"
#include "osdep/getch2.h"
+#ifdef CONFIG_TRANSLATION
+#include <locale.h>
+#include <libintl.h>
+#endif
+
#ifdef CONFIG_ICONV
#include <iconv.h>
#include <errno.h>
#endif
-#if defined(FOR_MENCODER)
-#undef CONFIG_GUI
-int use_gui;
-#else
-#include "gui/interface.h"
-#endif
-
#include "mp_msg.h"
/* maximum message length of mp_msg */
@@ -95,6 +93,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)
@@ -183,24 +189,17 @@ static void print_msg_module(FILE* stream, int mod)
fprintf(stream, ": ");
}
-void mp_msg(int mod, int lev, const char *format, ... ){
- va_list va;
+void mp_msg_va(int mod, int lev, const char *format, va_list va)
+{
char tmp[MSGSIZE_MAX];
FILE *stream = lev <= MSGL_WARN ? stderr : stdout;
static int header = 1;
if (!mp_msg_test(mod, lev)) return; // do not display
- va_start(va, format);
vsnprintf(tmp, MSGSIZE_MAX, format, va);
- va_end(va);
tmp[MSGSIZE_MAX-2] = '\n';
tmp[MSGSIZE_MAX-1] = 0;
-#ifdef CONFIG_GUI
- if(use_gui)
- guiMessageBox(lev, tmp);
-#endif
-
#if defined(CONFIG_ICONV) && defined(MSG_CHARSET)
if (mp_msg_charset && strcasecmp(mp_msg_charset, "noconv")) {
char tmp2[MSGSIZE_MAX];
@@ -242,3 +241,72 @@ void mp_msg(int mod, int lev, const char *format, ... ){
fprintf(stream, "\033[0m");
fflush(stream);
}
+
+void mp_msg(int mod, int lev, const char *format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ mp_msg_va(mod, lev, format, va);
+ 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);
+}