diff options
-rw-r--r-- | mp_msg.c | 124 | ||||
-rw-r--r-- | osdep/getch2-win.c | 6 | ||||
-rw-r--r-- | osdep/io.c | 58 | ||||
-rw-r--r-- | osdep/io.h | 2 |
4 files changed, 163 insertions, 27 deletions
@@ -23,6 +23,7 @@ #include "config.h" #include "osdep/getch2.h" +#include "osdep/io.h" #ifdef CONFIG_TRANSLATION #include <locale.h> @@ -39,6 +40,27 @@ /* maximum message length of mp_msg */ #define MSGSIZE_MAX 3072 +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#include <io.h> +#define hSTDOUT GetStdHandle(STD_OUTPUT_HANDLE) +#define hSTDERR GetStdHandle(STD_ERROR_HANDLE) +static short stdoutAttrs = 0; +static const unsigned char ansi2win32[10] = { + 0, + FOREGROUND_RED, + FOREGROUND_GREEN, + FOREGROUND_GREEN | FOREGROUND_RED, + FOREGROUND_BLUE, + FOREGROUND_BLUE | FOREGROUND_RED, + FOREGROUND_BLUE | FOREGROUND_GREEN, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED, + FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED +}; +#endif + int mp_msg_levels[MSGT_MAX]; // verbose level of this module. initialized to -2 int mp_msg_level_all = MSGL_STATUS; int verbose = 0; @@ -82,6 +104,16 @@ const char* filename_recode(const char* filename) } void mp_msg_init(void){ +#ifdef _WIN32 + CONSOLE_SCREEN_BUFFER_INFO cinfo; + long cmode = 0; + GetConsoleMode(hSTDOUT, &cmode); + cmode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT); + SetConsoleMode(hSTDOUT, cmode); + SetConsoleMode(hSTDERR, cmode); + GetConsoleScreenBufferInfo(hSTDOUT, &cinfo); + stdoutAttrs = cinfo.wAttributes; +#endif int i; char *env = getenv("MPLAYER_VERBOSE"); if (env) @@ -91,7 +123,11 @@ void mp_msg_init(void){ #ifdef CONFIG_ICONV mp_msg_charset = getenv("MPLAYER_CHARSET"); if (!mp_msg_charset) - mp_msg_charset = get_term_charset(); +#ifdef _WIN32 + mp_msg_charset = "UTF-8"; +#else + mp_msg_charset = get_term_charset(); +#endif #endif #ifdef CONFIG_TRANSLATION textdomain("mplayer"); @@ -124,7 +160,14 @@ static void set_msg_color(FILE* stream, int lev) } #endif if (mp_msg_color) + { +#ifdef _WIN32 + HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT; + SetConsoleTextAttribute(wstream, ansi2win32[c] | FOREGROUND_INTENSITY); +#else fprintf(stream, "\033[%d;3%dm", c >> 3, c & 7); +#endif + } } static void print_msg_module(FILE* stream, int mod) @@ -181,11 +224,20 @@ static void print_msg_module(FILE* stream, int mod) if (!mp_msg_module) return; +#ifdef _WIN32 + HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT; + if (mp_msg_color) + SetConsoleTextAttribute(wstream, ansi2win32[c2&7] | FOREGROUND_INTENSITY); + fprintf(stream, "%9s", module_text[mod]); + if (mp_msg_color) + SetConsoleTextAttribute(wstream, stdoutAttrs); +#else if (mp_msg_color) fprintf(stream, "\033[%d;3%dm", c2 >> 3, c2 & 7); fprintf(stream, "%9s", module_text[mod]); if (mp_msg_color) fprintf(stream, "\033[0;37m"); +#endif fprintf(stream, ": "); } @@ -203,33 +255,43 @@ void mp_msg_va(int mod, int lev, const char *format, va_list va) tmp[MSGSIZE_MAX-1] = 0; #if defined(CONFIG_ICONV) && defined(MSG_CHARSET) - if (mp_msg_charset && strcasecmp(mp_msg_charset, "noconv")) { - char tmp2[MSGSIZE_MAX]; - size_t inlen = strlen(tmp), outlen = MSGSIZE_MAX; - char *in = tmp, *out = tmp2; - if (!old_charset || strcmp(old_charset, mp_msg_charset)) { - if (old_charset) { - free(old_charset); - iconv_close(msgiconv); + if (mp_msg_charset && strcasecmp(mp_msg_charset, "noconv")) + { + char tmp2[MSGSIZE_MAX]; + size_t inlen = strlen(tmp), outlen = MSGSIZE_MAX; + char *in = tmp, *out = tmp2; + if (!old_charset || strcmp(old_charset, mp_msg_charset)) + { + if (old_charset) + { + free(old_charset); + iconv_close(msgiconv); + } + msgiconv = iconv_open(mp_msg_charset, MSG_CHARSET); + old_charset = strdup(mp_msg_charset); + } + + if (msgiconv == (iconv_t)(-1)) + { + fprintf(stderr,"iconv: conversion from %s to %s unsupported\n" + ,MSG_CHARSET,mp_msg_charset); + } + else + { + memset(tmp2, 0, MSGSIZE_MAX); + + while (iconv(msgiconv, &in, &inlen, &out, &outlen) == -1) + { + if (!inlen || !outlen) + break; + *out++ = *in++; + outlen--; inlen--; + } + + strncpy(tmp, tmp2, MSGSIZE_MAX); + tmp[MSGSIZE_MAX-1] = 0; + tmp[MSGSIZE_MAX-2] = '\n'; } - msgiconv = iconv_open(mp_msg_charset, MSG_CHARSET); - old_charset = strdup(mp_msg_charset); - } - if (msgiconv == (iconv_t)(-1)) { - fprintf(stderr,"iconv: conversion from %s to %s unsupported\n" - ,MSG_CHARSET,mp_msg_charset); - }else{ - memset(tmp2, 0, MSGSIZE_MAX); - while (iconv(msgiconv, &in, &inlen, &out, &outlen) == -1) { - if (!inlen || !outlen) - break; - *out++ = *in++; - outlen--; inlen--; - } - strncpy(tmp, tmp2, MSGSIZE_MAX); - tmp[MSGSIZE_MAX-1] = 0; - tmp[MSGSIZE_MAX-2] = '\n'; - } } #endif @@ -248,8 +310,16 @@ void mp_msg_va(int mod, int lev, const char *format, va_list va) header = len && (tmp[len-1] == '\n' || tmp[len-1] == '\r'); fprintf(stream, "%s", tmp); + if (mp_msg_color) + { +#ifdef _WIN32 + HANDLE *wstream = lev <= MSGL_WARN ? hSTDERR : hSTDOUT; + SetConsoleTextAttribute(wstream, stdoutAttrs); +#else fprintf(stream, "\033[0m"); +#endif + } fflush(stream); } diff --git a/osdep/getch2-win.c b/osdep/getch2-win.c index 3e6eeff086..326cf1a7d0 100644 --- a/osdep/getch2-win.c +++ b/osdep/getch2-win.c @@ -55,6 +55,12 @@ int screen_height=24; char * erase_to_end_of_line = NULL; void get_screen_size(void){ + CONSOLE_SCREEN_BUFFER_INFO cinfo; + if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cinfo)) + { + screen_width = cinfo.dwMaximumWindowSize.X; + screen_height = cinfo.dwMaximumWindowSize.Y; + } } static HANDLE in; diff --git a/osdep/io.c b/osdep/io.c index 88433184f4..e3e750e30b 100644 --- a/osdep/io.c +++ b/osdep/io.c @@ -92,6 +92,64 @@ int mp_stat(const char *path, struct stat *buf) return res; } +int mp_fprintf(FILE *stream, const char *format, ...) +{ + va_list args; + int done = 0; + + va_start(args, format); + + if (stream == stdout || stream == stderr) + { + HANDLE *wstream = GetStdHandle(stream == stdout ? + STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); + if (wstream != INVALID_HANDLE_VALUE) + { + // figure out whether we're writing to a console + unsigned int filetype = GetFileType(wstream); + if (!((filetype == FILE_TYPE_UNKNOWN) && + (GetLastError() != ERROR_SUCCESS))) + { + int isConsole; + filetype &= ~(FILE_TYPE_REMOTE); + if (filetype == FILE_TYPE_CHAR) + { + DWORD ConsoleMode; + int ret = GetConsoleMode(wstream, &ConsoleMode); + if (!ret && (GetLastError() == ERROR_INVALID_HANDLE)) + isConsole = 0; + else + isConsole = 1; + } + else + isConsole = 0; + + if (isConsole) + { + int nchars = vsnprintf(NULL, 0, format, args) + 1; + char *buf = talloc_array(NULL, char, nchars); + if (buf) + { + vsnprintf(buf, nchars, format, args); + wchar_t *out = mp_from_utf8(NULL, buf); + size_t nchars = wcslen(out); + talloc_free(buf); + done = WriteConsoleW(wstream, out, nchars, NULL, NULL); + talloc_free(out); + } + } + else + done = vfprintf(stream, format, args); + } + } + } + else + done = vfprintf(stream, format, args); + + va_end(args); + + return done; +} int mp_open(const char *filename, int oflag, ...) { diff --git a/osdep/io.h b/osdep/io.h index 514030afca..462a84917b 100644 --- a/osdep/io.h +++ b/osdep/io.h @@ -46,6 +46,7 @@ char *mp_to_utf8(void *talloc_ctx, const wchar_t *s); void mp_get_converted_argv(int *argc, char ***argv); int mp_stat(const char *path, struct stat *buf); +int mp_fprintf(FILE *stream, const char *format, ...); int mp_open(const char *filename, int oflag, ...); int mp_creat(const char *filename, int mode); FILE *mp_fopen(const char *filename, const char *mode); @@ -57,6 +58,7 @@ int mp_mkdir(const char *path, int mode); // NOTE: Stat is not overridden with mp_stat, because MinGW-w64 defines it as // macro. +#define fprintf(...) mp_fprintf(__VA_ARGS__) #define open(...) mp_open(__VA_ARGS__) #define creat(...) mp_creat(__VA_ARGS__) #define fopen(...) mp_fopen(__VA_ARGS__) |