1 #include <locale.h>
2 #include <math.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <sys/ioctl.h>
7 #include <termios.h>
8 #include <unistd.h>
9 #include <wchar.h>
10
11 wchar_t *frame_buffer;
12 wchar_t *barstring[8];
13 wchar_t *spacestring;
14 int buf_length;
15 char *ttyframe_buffer;
16 char *ttybarstring[8];
17 char *ttyspacestring;
18 int ttybuf_length;
19
setecho(int fd,int onoff)20 int setecho(int fd, int onoff) {
21
22 struct termios t;
23
24 if (tcgetattr(fd, &t) == -1)
25 return -1;
26
27 if (onoff == 0)
28 t.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL | ICANON);
29 else
30 t.c_lflag |= (ECHO | ECHOE | ECHOK | ECHONL | ICANON);
31
32 if (tcsetattr(fd, TCSANOW, &t) == -1)
33 return -1;
34
35 return 0;
36 }
37
38 // general: cleanup
free_terminal_noncurses(void)39 void free_terminal_noncurses(void) {
40 free(frame_buffer);
41 free(ttyframe_buffer);
42 free(spacestring);
43 free(ttyspacestring);
44 for (int i = 0; i < 8; i++) {
45 free(barstring[i]);
46 free(ttybarstring[i]);
47 }
48 }
49
init_terminal_noncurses(int tty,int col,int bgcol,int width,int lines,int bar_width)50 int init_terminal_noncurses(int tty, int col, int bgcol, int width, int lines, int bar_width) {
51
52 free_terminal_noncurses();
53
54 if (tty) {
55
56 ttybuf_length = sizeof(char) * width * lines * 10;
57 ttyframe_buffer = (char *)malloc(ttybuf_length);
58 ttyspacestring = (char *)malloc(sizeof(char) * (bar_width + 1));
59
60 // clearing barstrings
61 for (int n = 0; n < 8; n++) {
62 ttybarstring[n] = (char *)malloc(sizeof(char) * (bar_width + 1));
63 ttybarstring[n][0] = '\0';
64 }
65 ttyspacestring[0] = '\0';
66 ttyframe_buffer[0] = '\0';
67
68 // creating barstrings for drawing
69 for (int n = 0; n < bar_width; n++) {
70 strcat(ttybarstring[0], "H");
71 strcat(ttybarstring[1], "A");
72 strcat(ttybarstring[2], "B");
73 strcat(ttybarstring[3], "C");
74 strcat(ttybarstring[4], "D");
75 strcat(ttybarstring[5], "E");
76 strcat(ttybarstring[6], "F");
77 strcat(ttybarstring[7], "G");
78 strcat(ttyspacestring, " ");
79 }
80 } else if (!tty) {
81
82 buf_length = sizeof(wchar_t) * width * lines * 10;
83 frame_buffer = (wchar_t *)malloc(buf_length);
84 spacestring = (wchar_t *)malloc(sizeof(wchar_t) * (bar_width + 1));
85
86 // clearing barstrings
87 for (int n = 0; n < 8; n++) {
88 barstring[n] = (wchar_t *)malloc(sizeof(wchar_t) * (bar_width + 1));
89 barstring[n][0] = '\0';
90 }
91 spacestring[0] = '\0';
92 frame_buffer[0] = '\0';
93
94 // creating barstrings for drawing
95 for (int n = 0; n < bar_width; n++) {
96 wcscat(barstring[0], L"\u2588");
97 wcscat(barstring[1], L"\u2581");
98 wcscat(barstring[2], L"\u2582");
99 wcscat(barstring[3], L"\u2583");
100 wcscat(barstring[4], L"\u2584");
101 wcscat(barstring[5], L"\u2585");
102 wcscat(barstring[6], L"\u2586");
103 wcscat(barstring[7], L"\u2587");
104 wcscat(spacestring, L" ");
105 }
106 }
107
108 col += 30;
109
110 system("setterm -cursor off");
111 system("setterm -blank 0");
112
113 // output: reset console
114 printf("\033[0m\n");
115 system("clear");
116
117 if (col)
118 printf("\033[%dm", col); // setting color
119
120 // printf("\033[1m"); // setting "bright" color mode, looks cooler... I think
121
122 if (bgcol != 0) {
123
124 bgcol += 40;
125 printf("\033[%dm", bgcol);
126
127 for (int n = lines; n >= 0; n--) {
128 for (int i = 0; i < width; i++) {
129
130 printf(" "); // setting backround color
131 }
132 if (n != 0)
133 printf("\n");
134 else
135 printf("\r");
136 }
137 printf("\033[%dA", lines); // moving cursor back up
138 }
139
140 setecho(STDIN_FILENO, 0);
141
142 return 0;
143 }
144
get_terminal_dim_noncurses(int * width,int * lines)145 void get_terminal_dim_noncurses(int *width, int *lines) {
146
147 struct winsize dim;
148
149 ioctl(STDOUT_FILENO, TIOCGWINSZ, &dim);
150
151 *lines = (int)dim.ws_row;
152 *width = (int)dim.ws_col;
153
154 system("clear"); // clearing in case of resieze
155 }
156
draw_terminal_noncurses(int tty,int lines,int width,int number_of_bars,int bar_width,int bar_spacing,int rest,int bars[256],int previous_frame[256],int x_axis_info)157 int draw_terminal_noncurses(int tty, int lines, int width, int number_of_bars, int bar_width,
158 int bar_spacing, int rest, int bars[256], int previous_frame[256],
159 int x_axis_info) {
160
161 int current_cell, prev_cell, same_line, new_line, cx;
162
163 struct winsize dim;
164
165 same_line = 0;
166 new_line = 0;
167 cx = 0;
168
169 if (!tty) {
170 // output: check if terminal has been resized
171 ioctl(STDOUT_FILENO, TIOCGWINSZ, &dim);
172 if (x_axis_info)
173 lines++;
174 if ((int)dim.ws_row != (lines) || (int)dim.ws_col != width)
175 return -1;
176 if (x_axis_info)
177 lines--;
178 }
179
180 if (tty)
181 ttyframe_buffer[0] = '\0';
182 else if (!tty)
183 frame_buffer[0] = '\0';
184
185 for (int current_line = lines - 1; current_line >= 0; current_line--) {
186
187 int same_bar = 0;
188 int center_adjusted = 0;
189
190 for (int i = 0; i < number_of_bars; i++) {
191
192 current_cell = bars[i] - current_line * 8;
193 prev_cell = previous_frame[i] - current_line * 8;
194
195 // same as last frame
196 if ((current_cell < 1 && prev_cell < 1) || (current_cell > 7 && prev_cell > 7) ||
197 (current_cell == prev_cell)) {
198 same_bar++;
199 } else {
200 if (tty) {
201 if (same_line > 0) {
202 cx += snprintf(ttyframe_buffer + cx, ttybuf_length - cx, "\033[%dB",
203 same_line); // move down
204 new_line += same_line;
205 same_line = 0;
206 }
207
208 if (same_bar > 0) {
209 cx += snprintf(ttyframe_buffer + cx, ttybuf_length - cx, "\033[%dC",
210 (bar_width + bar_spacing) * same_bar); // move forward
211 same_bar = 0;
212 }
213
214 if (!center_adjusted && rest) {
215 cx += snprintf(ttyframe_buffer + cx, ttybuf_length - cx, "\033[%dC", rest);
216 center_adjusted = 1;
217 }
218
219 if (current_cell < 1)
220 cx += snprintf(ttyframe_buffer + cx, ttybuf_length - cx, "%s",
221 ttyspacestring);
222 else if (current_cell > 7)
223 cx += snprintf(ttyframe_buffer + cx, ttybuf_length - cx, "%s",
224 ttybarstring[0]);
225 else
226 cx += snprintf(ttyframe_buffer + cx, ttybuf_length - cx, "%s",
227 ttybarstring[current_cell]);
228
229 if (bar_spacing)
230 cx += snprintf(ttyframe_buffer + cx, ttybuf_length - cx, "\033[%dC",
231 bar_spacing);
232 } else if (!tty) {
233 if (same_line > 0) {
234 cx += swprintf(frame_buffer + cx, buf_length - cx, L"\033[%dB",
235 same_line); // move down
236 new_line += same_line;
237 same_line = 0;
238 }
239
240 if (same_bar > 0) {
241 cx += swprintf(frame_buffer + cx, buf_length - cx, L"\033[%dC",
242 (bar_width + bar_spacing) * same_bar); // move forward
243 same_bar = 0;
244 }
245
246 if (!center_adjusted && rest) {
247 cx += swprintf(frame_buffer + cx, buf_length - cx, L"\033[%dC", rest);
248 center_adjusted = 1;
249 }
250
251 if (current_cell < 1)
252 cx += swprintf(frame_buffer + cx, buf_length - cx, spacestring);
253 else if (current_cell > 7)
254 cx += swprintf(frame_buffer + cx, buf_length - cx, barstring[0]);
255 else
256 cx += swprintf(frame_buffer + cx, buf_length - cx, barstring[current_cell]);
257
258 if (bar_spacing)
259 cx +=
260 swprintf(frame_buffer + cx, buf_length - cx, L"\033[%dC", bar_spacing);
261 }
262 }
263 }
264
265 if (same_bar != number_of_bars) {
266 if (current_line != 0) {
267 if (tty)
268 cx += snprintf(ttyframe_buffer + cx, ttybuf_length - cx, "\n");
269 else if (!tty)
270 cx += swprintf(frame_buffer + cx, buf_length - cx, L"\n");
271
272 new_line++;
273 }
274 } else {
275 same_line++;
276 }
277 }
278 if (same_line != lines) {
279 if (tty)
280 printf("%s\r\033[%dA", ttyframe_buffer, new_line);
281 else if (!tty)
282 printf("%ls\r\033[%dA", frame_buffer, new_line);
283
284 fflush(stdout);
285 }
286 return 0;
287 }
288
cleanup_terminal_noncurses(void)289 void cleanup_terminal_noncurses(void) {
290 setecho(STDIN_FILENO, 1);
291 printf("\033[0m\n");
292 system("setfont >/dev/null 2>&1");
293 system("setfont /usr/share/consolefonts/Lat2-Fixed16.psf.gz >/dev/null 2>&1");
294 system("setterm -cursor on");
295 system("setterm -blank 10");
296 system("clear");
297 }
298