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