12 * \brief gets the name of the system's terminal character set
13 * \return a malloced string indicating the system charset
15 * Be warned that this function on many systems is in no way thread-safe
16 * since it modifies global data
18 char* get_term_charset(void);
24 #define WIN32_LEAN_AND_MEAN
27 short stdoutAttrs
= 0;
28 HANDLE hConOut
= INVALID_HANDLE_VALUE
;
29 static const unsigned char ansi2win32
[10]=
34 FOREGROUND_GREEN
| FOREGROUND_RED
,
36 FOREGROUND_BLUE
| FOREGROUND_RED
,
37 FOREGROUND_BLUE
| FOREGROUND_GREEN
,
38 FOREGROUND_BLUE
| FOREGROUND_GREEN
| FOREGROUND_RED
,
39 FOREGROUND_BLUE
| FOREGROUND_GREEN
| FOREGROUND_RED
,
40 FOREGROUND_BLUE
| FOREGROUND_GREEN
| FOREGROUND_RED
44 /* maximum message length of mp_msg */
45 #define MSGSIZE_MAX 3072
47 int mp_msg_levels
[MSGT_MAX
]; // verbose level of this module. initialized to -2
48 int mp_msg_level_all
= MSGL_STATUS
;
51 int mp_msg_module
= 0;
53 char *mp_msg_charset
= NULL
;
54 static char *old_charset
= NULL
;
55 static iconv_t msgiconv
;
58 const char* filename_recode(const char* filename
)
60 #if !defined(CONFIG_ICONV) || !defined(MSG_CHARSET)
63 static iconv_t inv_msgiconv
= (iconv_t
)(-1);
64 static char recoded_filename
[MSGSIZE_MAX
];
65 size_t filename_len
, max_path
;
67 if (!mp_msg_charset
||
68 !strcasecmp(mp_msg_charset
, MSG_CHARSET
) ||
69 !strcasecmp(mp_msg_charset
, "noconv"))
71 if (inv_msgiconv
== (iconv_t
)(-1)) {
72 inv_msgiconv
= iconv_open(MSG_CHARSET
, mp_msg_charset
);
73 if (inv_msgiconv
== (iconv_t
)(-1))
76 filename_len
= strlen(filename
);
77 max_path
= MSGSIZE_MAX
- 4;
78 precoded
= recoded_filename
;
79 if (iconv(inv_msgiconv
, &filename
, &filename_len
,
80 &precoded
, &max_path
) == (size_t)(-1) && errno
== E2BIG
) {
81 precoded
[0] = precoded
[1] = precoded
[2] = '.';
85 return recoded_filename
;
89 void mp_msg_init(void){
91 char *env
= getenv("MPLAYER_VERBOSE");
94 for(i
=0;i
<MSGT_MAX
;i
++) mp_msg_levels
[i
] = -2;
95 mp_msg_levels
[MSGT_IDENTIFY
] = -1; // no -identify output by default
97 mp_msg_charset
= getenv("MPLAYER_CHARSET");
99 mp_msg_charset
= get_term_charset();
103 CONSOLE_SCREEN_BUFFER_INFO cinfo
;
106 hConOut
= GetStdHandle(STD_OUTPUT_HANDLE
);
107 if ((hConOut
== NULL
) || (hConOut
== INVALID_HANDLE_VALUE
))
110 fprintf(stderr
, "Cannot get Console handle of stdout\n");
114 GetConsoleMode(hConOut
, &cmode
);
115 cmode
|= (ENABLE_PROCESSED_OUTPUT
| ENABLE_WRAP_AT_EOL_OUTPUT
);
116 SetConsoleMode(hConOut
, cmode
);
118 GetConsoleScreenBufferInfo(hConOut
, &cinfo
);
119 stdoutAttrs
= cinfo
.wAttributes
;
124 int mp_msg_test(int mod
, int lev
)
126 return lev
<= (mp_msg_levels
[mod
] == -2 ? mp_msg_level_all
+ verbose
: mp_msg_levels
[mod
]);
129 static void set_msg_color(FILE* stream
, int lev
)
131 static const unsigned char v_colors
[10] = {9, 1, 3, 15, 7, 2, 2, 8, 8, 8};
132 int c
= v_colors
[lev
];
134 /* that's only a silly color test */
139 for(c
= 0; c
< 24; c
++)
140 printf("\033[%d;3%dm*** COLOR TEST %d ***\n", c
>7, c
&7, c
);
147 SetConsoleTextAttribute(hConOut
, ansi2win32
[c
] | FOREGROUND_INTENSITY
);
150 fprintf(stream
, "\033[%d;3%dm", c
>> 3, c
& 7);
154 static void print_msg_module(FILE* stream
, int mod
)
156 static const char *module_text
[MSGT_MAX
] = {
204 int c2
= (mod
+ 1) % 15 + 1;
209 SetConsoleTextAttribute(hConOut
, ansi2win32
[c2
&7] | FOREGROUND_INTENSITY
);
210 fprintf(stream
, "%9s", module_text
[mod
]);
212 SetConsoleTextAttribute(hConOut
, stdoutAttrs
);
215 fprintf(stream
, "\033[%d;3%dm", c2
>> 3, c2
& 7);
216 fprintf(stream
, "%9s", module_text
[mod
]);
218 fprintf(stream
, "\033[0;37m");
220 fprintf(stream
, ": ");
223 void mp_msg_va(int mod
, int lev
, const char *format
, va_list va
)
225 char tmp
[MSGSIZE_MAX
];
226 FILE *stream
= lev
<= MSGL_WARN
? stderr
: stdout
;
227 static int header
= 1;
229 if (!mp_msg_test(mod
, lev
)) return; // do not display
230 vsnprintf(tmp
, MSGSIZE_MAX
, format
, va
);
231 tmp
[MSGSIZE_MAX
-2] = '\n';
232 tmp
[MSGSIZE_MAX
-1] = 0;
234 #if defined(CONFIG_ICONV) && defined(MSG_CHARSET)
235 if (mp_msg_charset
&& strcasecmp(mp_msg_charset
, "noconv")) {
236 char tmp2
[MSGSIZE_MAX
];
237 size_t inlen
= strlen(tmp
), outlen
= MSGSIZE_MAX
;
238 char *in
= tmp
, *out
= tmp2
;
239 if (!old_charset
|| strcmp(old_charset
, mp_msg_charset
)) {
242 iconv_close(msgiconv
);
244 msgiconv
= iconv_open(mp_msg_charset
, MSG_CHARSET
);
245 old_charset
= strdup(mp_msg_charset
);
247 if (msgiconv
== (iconv_t
)(-1)) {
248 fprintf(stderr
,"iconv: conversion from %s to %s unsupported\n"
249 ,MSG_CHARSET
,mp_msg_charset
);
251 memset(tmp2
, 0, MSGSIZE_MAX
);
252 while (iconv(msgiconv
, &in
, &inlen
, &out
, &outlen
) == -1) {
253 if (!inlen
|| !outlen
)
258 strncpy(tmp
, tmp2
, MSGSIZE_MAX
);
259 tmp
[MSGSIZE_MAX
-1] = 0;
260 tmp
[MSGSIZE_MAX
-2] = '\n';
266 print_msg_module(stream
, mod
);
267 set_msg_color(stream
, lev
);
268 header
= tmp
[strlen(tmp
)-1] == '\n' || tmp
[strlen(tmp
)-1] == '\r';
270 fprintf(stream
, "%s", tmp
);
274 void mp_msg(int mod
, int lev
, const char *format
, ...)
277 va_start(va
, format
);
278 mp_msg_va(mod
, lev
, format
, va
);
283 char *mp_gtext(const char *string
)