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