diff options
Diffstat (limited to 'lib/liblame/frontend/console.c')
-rw-r--r-- | lib/liblame/frontend/console.c | 322 |
1 files changed, 322 insertions, 0 deletions
diff --git a/lib/liblame/frontend/console.c b/lib/liblame/frontend/console.c new file mode 100644 index 0000000000..97938a3a0f --- /dev/null +++ b/lib/liblame/frontend/console.c @@ -0,0 +1,322 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <string.h> +#else +# ifndef HAVE_STRCHR +# define strchr index +# define strrchr rindex +# endif +char *strchr(), *strrchr(); +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# define memmove(d, s, n) bcopy ((s), (d), (n)) +# endif +#endif + +#if defined(HAVE_NCURSES_TERMCAP_H) +# include <ncurses/termcap.h> +#elif defined(HAVE_TERMCAP_H) +# include <termcap.h> +#elif defined(HAVE_TERMCAP) +# include <curses.h> +# if !defined(__bsdi__) +# include <term.h> +# endif +#endif + +#include <stdio.h> +#include <stdarg.h> +#include "console.h" + +#ifdef WITH_DMALLOC +#include <dmalloc.h> +#endif + +#define CLASS_ID 0x434F4E53 +#define REPORT_BUFF_SIZE 1024 + +#if defined(_WIN32) && !defined(__CYGWIN__) +# include <windows.h> +#endif + + + +static int +my_console_printing(FILE * fp, const char *format, va_list ap) +{ + if (fp != NULL) + return vfprintf(fp, format, ap); + return 0; +} + +static int +my_error_printing(FILE * fp, const char *format, va_list ap) +{ + if (fp != NULL) + return vfprintf(fp, format, ap); + return 0; +} + +static int +my_report_printing(FILE * fp, const char *format, va_list ap) +{ + if (fp != NULL) + return vfprintf(fp, format, ap); + return 0; +} + + +/* + * Taken from Termcap_Manual.html: + * + * With the Unix version of termcap, you must allocate space for the description yourself and pass + * the address of the space as the argument buffer. There is no way you can tell how much space is + * needed, so the convention is to allocate a buffer 2048 characters long and assume that is + * enough. (Formerly the convention was to allocate 1024 characters and assume that was enough. + * But one day, for one kind of terminal, that was not enough.) + */ + +#ifdef HAVE_TERMCAP +static void +apply_termcap_settings(Console_IO_t * const mfp) +{ + const char *term_name; + char term_buff[2048]; + char *tp; + char tc[10]; + int val; + + /* try to catch additional information about special console sequences */ + + if ((term_name = getenv("TERM")) == NULL) { + /* rh 061105: + silently ignore it and fallback to the behaviour as if + TERMCAP wasn't defined at all + */ + return; + /* + fprintf(mfp->Error_fp, "LAME: Can't get \"TERM\" environment string.\n"); + return -1; + */ + } + if (tgetent(term_buff, term_name) != 1) { + /* rh 061105: + silently ignore it and fallback to the behaviour as if + TERMCAP wasn't defined at all + */ + return; + /* + fprintf(mfp->Error_fp, "LAME: Can't find termcap entry for terminal \"%s\"\n", term_name); + return -1; + */ + } + + val = tgetnum("co"); + if (val >= 40 && val <= 512) + mfp->disp_width = val; + val = tgetnum("li"); + if (val >= 16 && val <= 256) + mfp->disp_height = val; + + *(tp = tc) = '\0'; + tp = tgetstr("up", &tp); + if (tp != NULL) + strcpy(mfp->str_up, tp); + + *(tp = tc) = '\0'; + tp = tgetstr("ce", &tp); + if (tp != NULL) + strcpy(mfp->str_clreoln, tp); + + *(tp = tc) = '\0'; + tp = tgetstr("md", &tp); + if (tp != NULL) + strcpy(mfp->str_emph, tp); + + *(tp = tc) = '\0'; + tp = tgetstr("me", &tp); + if (tp != NULL) + strcpy(mfp->str_norm, tp); +} +#endif /* TERMCAP_AVAILABLE */ + +static int +init_console(Console_IO_t * const mfp) +{ + /* setup basics of brhist I/O channels */ + mfp->disp_width = 80; + mfp->disp_height = 25; + mfp->Console_fp = stderr; + mfp->Error_fp = stderr; + mfp->Report_fp = NULL; + + /*mfp -> Console_buff = calloc ( 1, REPORT_BUFF_SIZE ); */ + setvbuf(mfp->Console_fp, mfp->Console_buff, _IOFBF, sizeof(mfp->Console_buff)); +/* setvbuf ( mfp -> Error_fp , NULL , _IONBF, 0 ); */ + +#if defined(_WIN32) && !defined(__CYGWIN__) + mfp->Console_Handle = GetStdHandle(STD_ERROR_HANDLE); +#endif + + strcpy(mfp->str_up, "\033[A"); + +#ifdef HAVE_TERMCAP + apply_termcap_settings(mfp); +#endif /* TERMCAP_AVAILABLE */ + + mfp->ClassID = CLASS_ID; + +#if defined(_WIN32) && !defined(__CYGWIN__) + mfp->Console_file_type = GetFileType(Console_IO.Console_Handle); +#else + mfp->Console_file_type = 0; +#endif + return 0; +} + +static void +deinit_console(Console_IO_t * const mfp) +{ + if (mfp->Report_fp != NULL) { + fclose(mfp->Report_fp); + mfp->Report_fp = NULL; + } + fflush(mfp->Console_fp); + setvbuf(mfp->Console_fp, NULL, _IONBF, (size_t) 0); + + memset(mfp->Console_buff, 0x55, REPORT_BUFF_SIZE); +} + + +/* LAME console + */ +Console_IO_t Console_IO; + +int +frontend_open_console(void) +{ + return init_console(&Console_IO); +} + +void +frontend_close_console(void) +{ + deinit_console(&Console_IO); +} + +void +frontend_debugf(const char *format, va_list ap) +{ + (void) my_report_printing(Console_IO.Report_fp, format, ap); +} + +void +frontend_msgf(const char *format, va_list ap) +{ + (void) my_console_printing(Console_IO.Console_fp, format, ap); +} + +void +frontend_errorf(const char *format, va_list ap) +{ + (void) my_error_printing(Console_IO.Error_fp, format, ap); +} + +int +console_printf(const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + ret = my_console_printing(Console_IO.Console_fp, format, args); + va_end(args); + + return ret; +} + +int +error_printf(const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + ret = my_console_printing(Console_IO.Error_fp, format, args); + va_end(args); + + return ret; +} + +int +report_printf(const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + ret = my_console_printing(Console_IO.Report_fp, format, args); + va_end(args); + + return ret; +} + +void +console_flush() +{ + fflush(Console_IO.Console_fp); +} + +void +error_flush() +{ + fflush(Console_IO.Error_fp); +} + +void +report_flush() +{ + fflush(Console_IO.Report_fp); +} + +void +console_up(int n_lines) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + if (Console_IO.Console_file_type != FILE_TYPE_PIPE) { + COORD Pos; + CONSOLE_SCREEN_BUFFER_INFO CSBI; + + console_flush(); + GetConsoleScreenBufferInfo(Console_IO.Console_Handle, &CSBI); + Pos.Y = CSBI.dwCursorPosition.Y - n_lines; + Pos.X = 0; + SetConsoleCursorPosition(Console_IO.Console_Handle, Pos); + } +#else + while (n_lines-- > 0) + fputs(Console_IO.str_up, Console_IO.Console_fp); + console_flush(); +#endif +} + + +void +set_debug_file(const char *fn) +{ + if (Console_IO.Report_fp == NULL) { + Console_IO.Report_fp = fopen(fn, "a"); + if (Console_IO.Report_fp != NULL) { + error_printf("writing debug info into: %s\n", fn); + } + else { + error_printf("Error: can't open for debug info: %s\n", fn); + } + } +} + +/* end of console.c */ |