1 /*
2  * Copyright (c) 2016-2021 Free Software Foundation, Inc.
3  *
4  * This file is part of libwget.
5  *
6  * Libwget is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Libwget is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with libwget.  If not, see <https://www.gnu.org/licenses/>.
18  *
19  *
20  * Console functions
21  *
22  */
23 
24 #include <config.h>
25 
26 #include <wget.h>
27 #include "private.h"
28 
29 #ifdef _WIN32
30 #include <windows.h>
31 CONSOLE_SCREEN_BUFFER_INFO g_console_info;
32 HANDLE                     g_stdout_hnd = INVALID_HANDLE_VALUE;
33 CRITICAL_SECTION           g_trace_crit;
34 #endif
35 
36 /**
37  * \file
38  * \brief Console functions
39  * \defgroup libwget-console Console functions
40  * @{
41  *
42  * Routines to address console controls like cursor positioning, fg+bg colors, ...
43  */
44 
reset_color(void)45 static void reset_color(void)
46 {
47 #ifdef _WIN32
48 	fflush(stdout);
49 
50 	if (g_stdout_hnd != INVALID_HANDLE_VALUE) {
51 		SetConsoleTextAttribute(g_stdout_hnd, g_console_info.wAttributes);
52 		g_stdout_hnd = INVALID_HANDLE_VALUE;
53 	}
54 #else
55 	if (isatty(fileno(stdout)))
56 		fputs("\033[m", stdout);
57 	fflush(stdout);
58 #endif
59 }
60 
61 /**
62  * \param[in] colorid Number of foreground/text color to set
63  *
64  * Sets the console foreground (text) color.
65  */
66 #ifdef _WIN32
wget_console_set_fg_color(wget_console_color colorid)67 void wget_console_set_fg_color(wget_console_color colorid)
68 {
69 	if (g_stdout_hnd != INVALID_HANDLE_VALUE) {
70 		static short color[] = {
71 			[WGET_CONSOLE_COLOR_WHITE] = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED,
72 			[WGET_CONSOLE_COLOR_BLUE] = FOREGROUND_BLUE,
73 			[WGET_CONSOLE_COLOR_GREEN] = FOREGROUND_GREEN,
74 			[WGET_CONSOLE_COLOR_RED] = FOREGROUND_RED,
75 			[WGET_CONSOLE_COLOR_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE
76 		};
77 
78 		fflush (stdout);
79 
80 		if (colorid == WGET_CONSOLE_COLOR_RESET)
81 			SetConsoleTextAttribute (g_stdout_hnd, g_console_info.wAttributes);
82 		else if (colorid < countof(color)) {
83 			WORD attr = (g_console_info.wAttributes & ~7) | color[colorid];
84 
85 			SetConsoleTextAttribute (g_stdout_hnd, attr | FOREGROUND_INTENSITY);
86 		}
87 	}
88 }
89 #else
wget_console_set_fg_color(WGET_GCC_UNUSED wget_console_color colorid)90 void wget_console_set_fg_color(WGET_GCC_UNUSED wget_console_color colorid)
91 {
92 }
93 #endif
94 
95 /**
96  * Resets the console foreground (text) color.
97  */
wget_console_reset_fg_color(void)98 void wget_console_reset_fg_color(void)
99 {
100 	wget_console_set_fg_color(WGET_CONSOLE_COLOR_RESET);
101 }
102 
103 /**
104  * \return 0 on success, or -1 on error
105  *
106  * Initializes the console.
107  */
wget_console_init(void)108 int wget_console_init(void)
109 {
110 #ifdef _WIN32
111 	static int win_init;
112 
113 	if (win_init)
114 		return 0;
115 
116 	g_stdout_hnd = GetStdHandle(STD_OUTPUT_HANDLE);
117 	if (g_stdout_hnd != INVALID_HANDLE_VALUE) {
118 		GetConsoleScreenBufferInfo(g_stdout_hnd, &g_console_info);
119 
120 		if (GetFileType(g_stdout_hnd) != FILE_TYPE_CHAR) /* The console is redirected */
121 			g_stdout_hnd = INVALID_HANDLE_VALUE;
122 	}
123 
124 	win_init = 1;
125 #endif
126 
127 	atexit(reset_color);
128 
129 	return 0;
130 }
131 
132 /**
133  * \return 0 on success, or -1 on error
134  *
135  * Deinitializes the console.
136  */
wget_console_deinit(void)137 int wget_console_deinit(void)
138 {
139 	reset_color();
140 
141 	return 0;
142 }
143 
144 /**@}*/
145