1159b3361Sopenharmony_ci#ifdef HAVE_CONFIG_H 2159b3361Sopenharmony_ci# include <config.h> 3159b3361Sopenharmony_ci#endif 4159b3361Sopenharmony_ci 5159b3361Sopenharmony_ci#ifdef STDC_HEADERS 6159b3361Sopenharmony_ci# include <stdlib.h> 7159b3361Sopenharmony_ci# include <string.h> 8159b3361Sopenharmony_ci#else 9159b3361Sopenharmony_ci# ifndef HAVE_STRCHR 10159b3361Sopenharmony_ci# define strchr index 11159b3361Sopenharmony_ci# define strrchr rindex 12159b3361Sopenharmony_ci# endif 13159b3361Sopenharmony_cichar *strchr(), *strrchr(); 14159b3361Sopenharmony_ci# ifndef HAVE_MEMCPY 15159b3361Sopenharmony_ci# define memcpy(d, s, n) bcopy ((s), (d), (n)) 16159b3361Sopenharmony_ci# define memmove(d, s, n) bcopy ((s), (d), (n)) 17159b3361Sopenharmony_ci# endif 18159b3361Sopenharmony_ci#endif 19159b3361Sopenharmony_ci 20159b3361Sopenharmony_ci#if defined(HAVE_NCURSES_TERMCAP_H) 21159b3361Sopenharmony_ci# include <ncurses/termcap.h> 22159b3361Sopenharmony_ci#elif defined(HAVE_TERMCAP_H) 23159b3361Sopenharmony_ci# include <termcap.h> 24159b3361Sopenharmony_ci#elif defined(HAVE_TERMCAP) 25159b3361Sopenharmony_ci# include <curses.h> 26159b3361Sopenharmony_ci# if !defined(__bsdi__) 27159b3361Sopenharmony_ci# include <term.h> 28159b3361Sopenharmony_ci# endif 29159b3361Sopenharmony_ci#endif 30159b3361Sopenharmony_ci 31159b3361Sopenharmony_ci#include <stdio.h> 32159b3361Sopenharmony_ci#include <stdarg.h> 33159b3361Sopenharmony_ci#include "console.h" 34159b3361Sopenharmony_ci#include "main.h" 35159b3361Sopenharmony_ci 36159b3361Sopenharmony_ci#ifdef WITH_DMALLOC 37159b3361Sopenharmony_ci#include <dmalloc.h> 38159b3361Sopenharmony_ci#endif 39159b3361Sopenharmony_ci 40159b3361Sopenharmony_ci#define CLASS_ID 0x434F4E53 41159b3361Sopenharmony_ci#define REPORT_BUFF_SIZE 1024 42159b3361Sopenharmony_ci 43159b3361Sopenharmony_ci#if defined(_WIN32) && !defined(__CYGWIN__) 44159b3361Sopenharmony_ci# include <windows.h> 45159b3361Sopenharmony_ci#endif 46159b3361Sopenharmony_ci 47159b3361Sopenharmony_ci 48159b3361Sopenharmony_ci/* 49159b3361Sopenharmony_ci * Taken from Termcap_Manual.html: 50159b3361Sopenharmony_ci * 51159b3361Sopenharmony_ci * With the Unix version of termcap, you must allocate space for the description yourself and pass 52159b3361Sopenharmony_ci * the address of the space as the argument buffer. There is no way you can tell how much space is 53159b3361Sopenharmony_ci * needed, so the convention is to allocate a buffer 2048 characters long and assume that is 54159b3361Sopenharmony_ci * enough. (Formerly the convention was to allocate 1024 characters and assume that was enough. 55159b3361Sopenharmony_ci * But one day, for one kind of terminal, that was not enough.) 56159b3361Sopenharmony_ci */ 57159b3361Sopenharmony_ci 58159b3361Sopenharmony_ci#ifdef HAVE_TERMCAP 59159b3361Sopenharmony_ci 60159b3361Sopenharmony_cistatic void 61159b3361Sopenharmony_ciget_termcap_string(char const* id, char* dest, size_t n) 62159b3361Sopenharmony_ci{ 63159b3361Sopenharmony_ci char tc[16]; 64159b3361Sopenharmony_ci char *tp = tc; 65159b3361Sopenharmony_ci tp[0] = '\0'; 66159b3361Sopenharmony_ci tp = tgetstr(id, &tp); 67159b3361Sopenharmony_ci if (tp != NULL && dest != NULL && n > 0) { 68159b3361Sopenharmony_ci strncpy(dest, tp, n); 69159b3361Sopenharmony_ci dest[n-1] = '\0'; 70159b3361Sopenharmony_ci } 71159b3361Sopenharmony_ci} 72159b3361Sopenharmony_ci 73159b3361Sopenharmony_cistatic void 74159b3361Sopenharmony_ciget_termcap_number(char const* id, int* dest, int low, int high) 75159b3361Sopenharmony_ci{ 76159b3361Sopenharmony_ci int const val = tgetnum(id); 77159b3361Sopenharmony_ci if (low <= val && val <= high) { 78159b3361Sopenharmony_ci *dest = val; 79159b3361Sopenharmony_ci } 80159b3361Sopenharmony_ci} 81159b3361Sopenharmony_ci 82159b3361Sopenharmony_cistatic void 83159b3361Sopenharmony_ciapply_termcap_settings(Console_IO_t * const mfp) 84159b3361Sopenharmony_ci{ 85159b3361Sopenharmony_ci /* try to catch additional information about special console sequences */ 86159b3361Sopenharmony_ci char const* term_name = getenv("TERM"); 87159b3361Sopenharmony_ci if (NULL != term_name) { 88159b3361Sopenharmony_ci char term_buff[4096]; 89159b3361Sopenharmony_ci int const ret = tgetent(term_buff, term_name); 90159b3361Sopenharmony_ci if (1 == ret) { 91159b3361Sopenharmony_ci get_termcap_number("co", &mfp->disp_width, 40, 512); 92159b3361Sopenharmony_ci get_termcap_number("li", &mfp->disp_height, 16, 256); 93159b3361Sopenharmony_ci get_termcap_string("up", mfp->str_up, sizeof(mfp->str_up)); 94159b3361Sopenharmony_ci get_termcap_string("md", mfp->str_emph, sizeof(mfp->str_emph)); 95159b3361Sopenharmony_ci get_termcap_string("me", mfp->str_norm, sizeof(mfp->str_norm)); 96159b3361Sopenharmony_ci get_termcap_string("ce", mfp->str_clreoln, sizeof(mfp->str_clreoln)); 97159b3361Sopenharmony_ci } 98159b3361Sopenharmony_ci } 99159b3361Sopenharmony_ci} 100159b3361Sopenharmony_ci#endif /* TERMCAP_AVAILABLE */ 101159b3361Sopenharmony_ci 102159b3361Sopenharmony_cistatic int 103159b3361Sopenharmony_ciis_console_initialized(Console_IO_t * const mfp) 104159b3361Sopenharmony_ci{ 105159b3361Sopenharmony_ci return mfp && mfp->ClassID == CLASS_ID ? 1 : 0; 106159b3361Sopenharmony_ci} 107159b3361Sopenharmony_ci 108159b3361Sopenharmony_cistatic int 109159b3361Sopenharmony_ciinit_console(Console_IO_t * const mfp) 110159b3361Sopenharmony_ci{ 111159b3361Sopenharmony_ci if (is_console_initialized(mfp)) { 112159b3361Sopenharmony_ci return 0; /* already initialized */ 113159b3361Sopenharmony_ci } 114159b3361Sopenharmony_ci /* setup basics of brhist I/O channels */ 115159b3361Sopenharmony_ci mfp->disp_width = 80; 116159b3361Sopenharmony_ci mfp->disp_height = 25; 117159b3361Sopenharmony_ci mfp->Console_fp = stderr; 118159b3361Sopenharmony_ci mfp->Error_fp = stderr; 119159b3361Sopenharmony_ci mfp->Report_fp = NULL; 120159b3361Sopenharmony_ci 121159b3361Sopenharmony_ci /*mfp -> Console_buff = calloc ( 1, REPORT_BUFF_SIZE ); */ 122159b3361Sopenharmony_ci setvbuf(mfp->Console_fp, mfp->Console_buff, _IOFBF, sizeof(mfp->Console_buff)); 123159b3361Sopenharmony_ci/* setvbuf ( mfp -> Error_fp , NULL , _IONBF, 0 ); */ 124159b3361Sopenharmony_ci 125159b3361Sopenharmony_ci#if defined(_WIN32) && !defined(__CYGWIN__) 126159b3361Sopenharmony_ci mfp->Console_Handle = GetStdHandle(STD_ERROR_HANDLE); 127159b3361Sopenharmony_ci#endif 128159b3361Sopenharmony_ci 129159b3361Sopenharmony_ci strcpy(mfp->str_up, "\033[A"); 130159b3361Sopenharmony_ci 131159b3361Sopenharmony_ci#ifdef HAVE_TERMCAP 132159b3361Sopenharmony_ci apply_termcap_settings(mfp); 133159b3361Sopenharmony_ci#endif /* TERMCAP_AVAILABLE */ 134159b3361Sopenharmony_ci 135159b3361Sopenharmony_ci mfp->ClassID = CLASS_ID; 136159b3361Sopenharmony_ci 137159b3361Sopenharmony_ci#if defined(_WIN32) && !defined(__CYGWIN__) 138159b3361Sopenharmony_ci mfp->Console_file_type = GetFileType(Console_IO.Console_Handle); 139159b3361Sopenharmony_ci#else 140159b3361Sopenharmony_ci mfp->Console_file_type = 0; 141159b3361Sopenharmony_ci#endif 142159b3361Sopenharmony_ci return 0; 143159b3361Sopenharmony_ci} 144159b3361Sopenharmony_ci 145159b3361Sopenharmony_cistatic void 146159b3361Sopenharmony_cideinit_console(Console_IO_t * const mfp) 147159b3361Sopenharmony_ci{ 148159b3361Sopenharmony_ci if (!is_console_initialized(mfp)) { 149159b3361Sopenharmony_ci return; /* not initialized or already de-initialized */ 150159b3361Sopenharmony_ci } 151159b3361Sopenharmony_ci if (mfp->Report_fp != NULL) { 152159b3361Sopenharmony_ci fclose(mfp->Report_fp); 153159b3361Sopenharmony_ci mfp->Report_fp = NULL; 154159b3361Sopenharmony_ci } 155159b3361Sopenharmony_ci fflush(mfp->Console_fp); 156159b3361Sopenharmony_ci setvbuf(mfp->Console_fp, NULL, _IONBF, (size_t) 0); 157159b3361Sopenharmony_ci 158159b3361Sopenharmony_ci memset(mfp->Console_buff, 0x55, REPORT_BUFF_SIZE); 159159b3361Sopenharmony_ci} 160159b3361Sopenharmony_ci 161159b3361Sopenharmony_ci/* LAME console 162159b3361Sopenharmony_ci */ 163159b3361Sopenharmony_ciConsole_IO_t Console_IO; 164159b3361Sopenharmony_ci 165159b3361Sopenharmony_cienum ConsoleEnum { ConsoleIoConsole, ConsoleIoError, ConsoleIoReport }; 166159b3361Sopenharmony_ci 167159b3361Sopenharmony_cistatic FILE* 168159b3361Sopenharmony_cifrontend_console_file_handle(enum ConsoleEnum e) 169159b3361Sopenharmony_ci{ 170159b3361Sopenharmony_ci if (is_console_initialized(&Console_IO)) { 171159b3361Sopenharmony_ci switch (e) { 172159b3361Sopenharmony_ci case ConsoleIoConsole: return Console_IO.Console_fp; 173159b3361Sopenharmony_ci case ConsoleIoError: return Console_IO.Error_fp; 174159b3361Sopenharmony_ci case ConsoleIoReport: return Console_IO.Report_fp; 175159b3361Sopenharmony_ci } 176159b3361Sopenharmony_ci } 177159b3361Sopenharmony_ci return 0; 178159b3361Sopenharmony_ci} 179159b3361Sopenharmony_ci 180159b3361Sopenharmony_cistatic int 181159b3361Sopenharmony_cifrontend_console_print(const char *format, va_list ap, enum ConsoleEnum e) 182159b3361Sopenharmony_ci{ 183159b3361Sopenharmony_ci FILE *fp = frontend_console_file_handle(e); 184159b3361Sopenharmony_ci 185159b3361Sopenharmony_ci if (fp != NULL) 186159b3361Sopenharmony_ci return vfprintf(fp, format, ap); 187159b3361Sopenharmony_ci return 0; 188159b3361Sopenharmony_ci} 189159b3361Sopenharmony_ci 190159b3361Sopenharmony_cistatic void 191159b3361Sopenharmony_cifrontend_console_flush(enum ConsoleEnum e) 192159b3361Sopenharmony_ci{ 193159b3361Sopenharmony_ci FILE *fp = frontend_console_file_handle(e); 194159b3361Sopenharmony_ci 195159b3361Sopenharmony_ci if (fp != NULL) 196159b3361Sopenharmony_ci fflush(fp); 197159b3361Sopenharmony_ci} 198159b3361Sopenharmony_ci 199159b3361Sopenharmony_ciint 200159b3361Sopenharmony_cifrontend_open_console(void) 201159b3361Sopenharmony_ci{ 202159b3361Sopenharmony_ci return init_console(&Console_IO); 203159b3361Sopenharmony_ci} 204159b3361Sopenharmony_ci 205159b3361Sopenharmony_civoid 206159b3361Sopenharmony_cifrontend_close_console(void) 207159b3361Sopenharmony_ci{ 208159b3361Sopenharmony_ci deinit_console(&Console_IO); 209159b3361Sopenharmony_ci} 210159b3361Sopenharmony_ci 211159b3361Sopenharmony_civoid 212159b3361Sopenharmony_cifrontend_debugf(const char *format, va_list ap) 213159b3361Sopenharmony_ci{ 214159b3361Sopenharmony_ci (void) frontend_console_print(format, ap, ConsoleIoReport); 215159b3361Sopenharmony_ci} 216159b3361Sopenharmony_ci 217159b3361Sopenharmony_civoid 218159b3361Sopenharmony_cifrontend_msgf(const char *format, va_list ap) 219159b3361Sopenharmony_ci{ 220159b3361Sopenharmony_ci (void) frontend_console_print(format, ap, ConsoleIoConsole); 221159b3361Sopenharmony_ci} 222159b3361Sopenharmony_ci 223159b3361Sopenharmony_civoid 224159b3361Sopenharmony_cifrontend_errorf(const char *format, va_list ap) 225159b3361Sopenharmony_ci{ 226159b3361Sopenharmony_ci (void) frontend_console_print(format, ap, ConsoleIoError); 227159b3361Sopenharmony_ci} 228159b3361Sopenharmony_ci 229159b3361Sopenharmony_civoid 230159b3361Sopenharmony_cifrontend_print_null(const char *format, va_list ap) 231159b3361Sopenharmony_ci{ 232159b3361Sopenharmony_ci (void) format; 233159b3361Sopenharmony_ci (void) ap; 234159b3361Sopenharmony_ci} 235159b3361Sopenharmony_ci 236159b3361Sopenharmony_ciint 237159b3361Sopenharmony_ciconsole_printf(const char *format, ...) 238159b3361Sopenharmony_ci{ 239159b3361Sopenharmony_ci va_list args; 240159b3361Sopenharmony_ci int ret; 241159b3361Sopenharmony_ci 242159b3361Sopenharmony_ci va_start(args, format); 243159b3361Sopenharmony_ci ret = frontend_console_print(format, args,ConsoleIoConsole); 244159b3361Sopenharmony_ci va_end(args); 245159b3361Sopenharmony_ci 246159b3361Sopenharmony_ci return ret; 247159b3361Sopenharmony_ci} 248159b3361Sopenharmony_ci 249159b3361Sopenharmony_ciint 250159b3361Sopenharmony_cierror_printf(const char *format, ...) 251159b3361Sopenharmony_ci{ 252159b3361Sopenharmony_ci va_list args; 253159b3361Sopenharmony_ci int ret; 254159b3361Sopenharmony_ci 255159b3361Sopenharmony_ci va_start(args, format); 256159b3361Sopenharmony_ci ret = frontend_console_print(format, args, ConsoleIoError); 257159b3361Sopenharmony_ci va_end(args); 258159b3361Sopenharmony_ci 259159b3361Sopenharmony_ci return ret; 260159b3361Sopenharmony_ci} 261159b3361Sopenharmony_ci 262159b3361Sopenharmony_ciint 263159b3361Sopenharmony_cireport_printf(const char *format, ...) 264159b3361Sopenharmony_ci{ 265159b3361Sopenharmony_ci va_list args; 266159b3361Sopenharmony_ci int ret; 267159b3361Sopenharmony_ci 268159b3361Sopenharmony_ci va_start(args, format); 269159b3361Sopenharmony_ci ret = frontend_console_print(format, args, ConsoleIoReport); 270159b3361Sopenharmony_ci va_end(args); 271159b3361Sopenharmony_ci 272159b3361Sopenharmony_ci return ret; 273159b3361Sopenharmony_ci} 274159b3361Sopenharmony_ci 275159b3361Sopenharmony_civoid 276159b3361Sopenharmony_ciconsole_flush() 277159b3361Sopenharmony_ci{ 278159b3361Sopenharmony_ci frontend_console_flush(ConsoleIoConsole); 279159b3361Sopenharmony_ci} 280159b3361Sopenharmony_ci 281159b3361Sopenharmony_civoid 282159b3361Sopenharmony_cierror_flush() 283159b3361Sopenharmony_ci{ 284159b3361Sopenharmony_ci frontend_console_flush(ConsoleIoError); 285159b3361Sopenharmony_ci} 286159b3361Sopenharmony_ci 287159b3361Sopenharmony_civoid 288159b3361Sopenharmony_cireport_flush() 289159b3361Sopenharmony_ci{ 290159b3361Sopenharmony_ci frontend_console_flush(ConsoleIoReport); 291159b3361Sopenharmony_ci} 292159b3361Sopenharmony_ci 293159b3361Sopenharmony_civoid 294159b3361Sopenharmony_ciconsole_up(int n_lines) 295159b3361Sopenharmony_ci{ 296159b3361Sopenharmony_ci if (!is_console_initialized(&Console_IO)) 297159b3361Sopenharmony_ci return; /* not initialized or already de-initialized */ 298159b3361Sopenharmony_ci#if defined(_WIN32) && !defined(__CYGWIN__) 299159b3361Sopenharmony_ci if (Console_IO.Console_file_type != FILE_TYPE_PIPE) { 300159b3361Sopenharmony_ci COORD Pos; 301159b3361Sopenharmony_ci CONSOLE_SCREEN_BUFFER_INFO CSBI; 302159b3361Sopenharmony_ci 303159b3361Sopenharmony_ci console_flush(); 304159b3361Sopenharmony_ci GetConsoleScreenBufferInfo(Console_IO.Console_Handle, &CSBI); 305159b3361Sopenharmony_ci Pos.Y = (SHORT)(CSBI.dwCursorPosition.Y - n_lines); 306159b3361Sopenharmony_ci Pos.X = 0; 307159b3361Sopenharmony_ci SetConsoleCursorPosition(Console_IO.Console_Handle, Pos); 308159b3361Sopenharmony_ci } 309159b3361Sopenharmony_ci#else 310159b3361Sopenharmony_ci while (n_lines-- > 0) 311159b3361Sopenharmony_ci fputs(Console_IO.str_up, Console_IO.Console_fp); 312159b3361Sopenharmony_ci console_flush(); 313159b3361Sopenharmony_ci#endif 314159b3361Sopenharmony_ci} 315159b3361Sopenharmony_ci 316159b3361Sopenharmony_ciint 317159b3361Sopenharmony_ciconsole_getwidth() 318159b3361Sopenharmony_ci{ 319159b3361Sopenharmony_ci if (is_console_initialized(&Console_IO)) 320159b3361Sopenharmony_ci return Console_IO.disp_width; 321159b3361Sopenharmony_ci return 80; /* default value */ 322159b3361Sopenharmony_ci} 323159b3361Sopenharmony_ci 324159b3361Sopenharmony_civoid 325159b3361Sopenharmony_ciset_debug_file(const char *fn) 326159b3361Sopenharmony_ci{ 327159b3361Sopenharmony_ci if (is_console_initialized(&Console_IO)) { 328159b3361Sopenharmony_ci if (Console_IO.Report_fp == NULL) { 329159b3361Sopenharmony_ci Console_IO.Report_fp = lame_fopen(fn, "a"); 330159b3361Sopenharmony_ci if (Console_IO.Report_fp != NULL) { 331159b3361Sopenharmony_ci error_printf("writing debug info into: %s\n", fn); 332159b3361Sopenharmony_ci } 333159b3361Sopenharmony_ci else { 334159b3361Sopenharmony_ci error_printf("Error: can't open for debug info: %s\n", fn); 335159b3361Sopenharmony_ci } 336159b3361Sopenharmony_ci } 337159b3361Sopenharmony_ci } 338159b3361Sopenharmony_ci} 339159b3361Sopenharmony_ci 340159b3361Sopenharmony_ci/* end of console.c */ 341