terminal: abstract terminal color handling

Instead of making msg.c an ifdef hell for unix vs. windows code, move
the code to separate functions defined in terminal-unix.c/terminal-
win.c.

Drop the code that selects random colors for --msgmodule prefixes.
This commit is contained in:
wm4 2013-12-18 15:03:08 +01:00
parent a4fe95b0d8
commit 4d4b822171
5 changed files with 81 additions and 105 deletions

View File

@ -30,10 +30,6 @@
#include "osdep/terminal.h"
#include "osdep/io.h"
#ifndef __MINGW32__
#include <signal.h>
#endif
#include "common/msg.h"
bool mp_msg_stdout_in_use = 0;
@ -60,27 +56,6 @@ static struct mp_log *legacy_logs[MSGT_MAX];
/* maximum message length of mp_msg */
#define MSGSIZE_MAX 6144
#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;
@ -93,16 +68,6 @@ static int mp_msg_docolor(void) {
}
static void mp_msg_do_init(void){
#ifdef _WIN32
CONSOLE_SCREEN_BUFFER_INFO cinfo;
DWORD 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("MPV_VERBOSE");
if (env)
@ -114,13 +79,11 @@ static void mp_msg_do_init(void){
int mp_msg_test(int mod, int lev)
{
#ifndef __MINGW32__
if (lev == MSGL_STATUS) {
// skip status line output if stderr is a tty but in background
if (isatty(2) && tcgetpgrp(2) != getpgrp())
if (terminal_in_background())
return false;
}
#endif
return lev <= (mp_msg_levels[mod] == -2 ? mp_msg_level_all + verbose : mp_msg_levels[mod]);
}
@ -133,54 +96,8 @@ static void set_msg_color(FILE* stream, int lev)
{
static const int v_colors[10] = {9, 1, 3, 3, -1, -1, 2, 8, 8, 8};
int c = v_colors[lev];
#ifdef MP_ANNOY_ME
/* that's only a silly color test */
{
int c;
static int flag = 1;
if (flag)
for(c = 0; c < 24; c++)
printf("\033[%d;3%dm*** COLOR TEST %d ***\n", c>7, c&7, c);
flag = 0;
}
#endif
if (mp_msg_docolor())
{
#if defined(_WIN32) && !defined(__CYGWIN__)
HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT;
if (c == -1)
c = 7;
SetConsoleTextAttribute(wstream, ansi2win32[c] | FOREGROUND_INTENSITY);
#else
if (c == -1) {
fprintf(stream, "\033[0m");
} else {
fprintf(stream, "\033[%d;3%dm", c >> 3, c & 7);
}
#endif
}
}
static void print_msg_module(FILE* stream, struct mp_log *log)
{
int mod = log->legacy_mod;
int c2 = (mod + 1) % 15 + 1;
#ifdef _WIN32
HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT;
if (mp_msg_docolor())
SetConsoleTextAttribute(wstream, ansi2win32[c2&7] | FOREGROUND_INTENSITY);
fprintf(stream, "%9s", log->verbose_prefix);
if (mp_msg_docolor())
SetConsoleTextAttribute(wstream, stdoutAttrs);
#else
if (mp_msg_docolor())
fprintf(stream, "\033[%d;3%dm", c2 >> 3, c2 & 7);
fprintf(stream, "%9s", log->verbose_prefix);
if (mp_msg_docolor())
fprintf(stream, "\033[0;37m");
#endif
fprintf(stream, ": ");
terminal_set_foreground_color(stream, c);
}
static void mp_msg_log_va(struct mp_log *log, int lev, const char *format,
@ -208,8 +125,8 @@ static void mp_msg_log_va(struct mp_log *log, int lev, const char *format,
set_msg_color(stream, lev);
if (header) {
if (mp_msg_module) {
print_msg_module(stream, log);
set_msg_color(stream, lev);
fprintf(stream, "%9s", log->verbose_prefix);
fprintf(stream, ": ");
} else if (lev >= MSGL_V || verbose) {
fprintf(stream, "[%s] ", log->verbose_prefix);
} else if (log->prefix) {
@ -223,14 +140,7 @@ static void mp_msg_log_va(struct mp_log *log, int lev, const char *format,
fprintf(stream, "%s", tmp);
if (mp_msg_docolor())
{
#ifdef _WIN32
HANDLE *wstream = lev <= MSGL_WARN ? hSTDERR : hSTDOUT;
SetConsoleTextAttribute(wstream, stdoutAttrs);
#else
fprintf(stream, "\033[0m");
#endif
}
terminal_set_foreground_color(stream, -1);
fflush(stream);
}

View File

@ -227,7 +227,7 @@ static void termcap_add_extra_f_keys(void) {
#endif
int load_termcap(char *termtype){
static int load_termcap(char *termtype){
#if HAVE_TERMINFO || HAVE_TERMCAP
#if HAVE_TERMINFO
@ -578,3 +578,23 @@ void getch2_disable(void){
getch2_enabled = 0;
}
bool terminal_in_background(void)
{
return isatty(2) && tcgetpgrp(2) != getpgrp();
}
void terminal_set_foreground_color(FILE *stream, int c)
{
if (c == -1) {
fprintf(stream, "\033[0m");
} else {
fprintf(stream, "\033[%d;3%dm", c >> 3, c & 7);
}
}
int terminal_init(void)
{
load_termcap(NULL);
return 0;
}

View File

@ -28,10 +28,25 @@
#include <stdint.h>
#include <string.h>
#include <windows.h>
#include <io.h>
#include "input/keycodes.h"
#include "input/input.h"
#include "terminal.h"
#define hSTDOUT GetStdHandle(STD_OUTPUT_HANDLE)
#define hSTDERR GetStdHandle(STD_ERROR_HANDLE)
static short stdoutAttrs = 0;
static const unsigned char ansi2win32[8] = {
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,
};
int mp_input_slave_cmd_func(int fd, char *dest, int size)
{
DWORD retval;
@ -64,11 +79,6 @@ void get_screen_size(void)
}
}
int load_termcap(char *termtype)
{
return 0;
}
static HANDLE in;
static int getch2_status = 0;
@ -192,3 +202,31 @@ void getch2_disable(void)
return; // already disabled / never enabled
getch2_status = 0;
}
bool terminal_in_background(void)
{
return false;
}
void terminal_set_foreground_color(FILE *stream, int c)
{
HANDLE *wstream = stream == stderr ? hSTDERR : hSTDOUT;
if (c < 0 || c >= 8) { // reset or invalid
SetConsoleTextAttribute(wstream, stdoutAttrs);
} else {
SetConsoleTextAttribute(wstream, ansi2win32[c] | FOREGROUND_INTENSITY);
}
}
int terminal_init(void)
{
CONSOLE_SCREEN_BUFFER_INFO cinfo;
DWORD 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;
return 0;
}

View File

@ -25,6 +25,7 @@
#define MPLAYER_GETCH2_H
#include <stdbool.h>
#include <stdio.h>
/* Screen size. Initialized by load_termcap() and get_screen_size() */
extern int screen_width;
@ -33,12 +34,19 @@ extern int screen_height;
/* Termcap code to erase to end of line */
extern char * erase_to_end_of_line;
/* Global initialization for terminal output. */
int terminal_init(void);
/* Return whether the process has been backgrounded. */
bool terminal_in_background(void);
/* Set ANSI text foreground color. c is [-1, 7], where 0-7 are colors, and
* -1 means reset to default. stream is either stdout or stderr. */
void terminal_set_foreground_color(FILE *stream, int c);
/* Get screen-size using IOCTL call. */
void get_screen_size(void);
/* Load key definitions from the TERMCAP database. 'termtype' can be NULL */
int load_termcap(char *termtype);
/* Initialize getch2 */
void getch2_enable(void);
void getch2_disable(void);

View File

@ -264,7 +264,7 @@ static void osdep_preinit(int *p_argc, char ***p_argv)
SetErrorMode(0x8003);
#endif
load_termcap(NULL); // load key-codes
terminal_init();
mp_time_init();
}