static void ui_show_pane(struct ui_pane *pane) { int row, col; int lastBack = -1, lastFore = -1; for (row = 0; row < ui_bar_length; row++) { putp(tiparm(cursor_address, LINES - pane->start - row - 1, 0)); // What's the width of this row? Beyond this, we can // just clear the line. int endCol = 0; for (col = pane->barpos; col < pane->barpos + pane->width; col++) { if (UIXY(ui_back, col, row) != 0xff || UIXY(ui_display, col, row) != 0) endCol = col + 1; } for (col = pane->barpos; col < endCol; col++) { int cell = UIXY(ui_display, col, row); int back = UIXY(ui_back, col, row); int fore = UIXY(ui_fore, col, row); // If it's a space, we don't care what the // foreground color is. if (ui_chars[cell][0] == ' ' && lastFore != -1) fore = lastFore; // Set attributes if (lastBack != back || lastFore != fore) { if (back == 0xff || fore == 0xff) { putp(exit_attribute_mode); lastBack = lastFore = 0xff; } if (lastBack != back) { putp(tiparm(set_a_background, back)); lastBack = back; } if (lastFore != fore) { putp(tiparm(set_a_foreground, fore)); lastFore = fore; } } fputs(ui_chars[cell], stdout); } // Clear to the end of the line if (endCol < pane->barpos + pane->width) { if (lastBack != 0xff || lastFore != 0xff) { putp(exit_attribute_mode); lastBack = lastFore = 0xff; } putp(clr_eol); } } }
/* * __set_color -- * Set terminal foreground and background colours. */ void __set_color( /*ARGSUSED*/ WINDOW *win, attr_t attr) { (void)win; short pair; if ((curscr->wattr & __COLOR) == (attr & __COLOR)) return; pair = PAIR_NUMBER((u_int32_t)attr); switch (_cursesi_screen->color_type) { /* Set ANSI forground and background colours */ case COLOR_ANSI: if (_cursesi_screen->colour_pairs[pair].fore < 0 || _cursesi_screen->colour_pairs[pair].back < 0) __unset_color(curscr); if (_cursesi_screen->colour_pairs[pair].fore >= 0) tputs(tiparm(t_set_a_foreground(_cursesi_screen->term), (int)_cursesi_screen->colour_pairs[pair].fore), 0, __cputchar); if (_cursesi_screen->colour_pairs[pair].back >= 0) tputs(tiparm(t_set_a_background(_cursesi_screen->term), (int)_cursesi_screen->colour_pairs[pair].back), 0, __cputchar); break; case COLOR_HP: /* XXX: need to support HP style */ break; case COLOR_TEK: /* XXX: need to support Tek style */ break; case COLOR_OTHER: if (_cursesi_screen->colour_pairs[pair].fore < 0 || _cursesi_screen->colour_pairs[pair].back < 0) __unset_color(curscr); if (_cursesi_screen->colour_pairs[pair].fore >= 0) tputs(tiparm(t_set_foreground(_cursesi_screen->term), (int)_cursesi_screen->colour_pairs[pair].fore), 0, __cputchar); if (_cursesi_screen->colour_pairs[pair].back >= 0) tputs(tiparm(t_set_background(_cursesi_screen->term), (int)_cursesi_screen->colour_pairs[pair].back), 0, __cputchar); break; } curscr->wattr &= ~__COLOR; curscr->wattr |= attr & __COLOR; }
/* * Set the hardware tabs on the terminal, using the ct (clear all tabs), * st (set one tab) and ch (horizontal cursor addressing) capabilities. * This is done before if and is, so they can patch in case we blow this. * Return nonzero if we set any tab stops, zero if not. */ static int set_tabs(void) { int c; char *out; if (set_tab) { if (clear_all_tabs) { (void)putc('\r', stderr); /* Force to left margin. */ tputs(clear_all_tabs, 0, outc); } for (c = 8; c < ncolumns; c += 8) { if (column_address) out = tiparm(column_address, c); else out = NULL; if (out) tputs(out, 1, outc); else (void)fprintf(stderr, "%s", " "); /* Set the tab. */ tputs(set_tab, 0, outc); } putc('\r', stderr); return (1); } return (0); }
void ui_show_load(float load[3]) { char buf[1024]; int pos; snprintf(buf, sizeof buf, "%0.2f %0.2f %0.2f", load[0], load[1], load[2]); pos = COLS - strlen(buf) - 8; if (pos < 0) pos = 0; putp(tiparm(cursor_address, 0, pos)); putp(exit_attribute_mode); putp(tiparm(set_a_foreground, COLOR_WHITE)); fputs(" load: ", stdout); putp(exit_attribute_mode); fputs(buf, stdout); }
static void set_cursor_column (int column) { const char *capability; const char *terminal_string; capability = get_string_capability ("hpa"); terminal_string = tiparm (capability, column); fputs (terminal_string, stdout); }
static void set_fg_color (int color) { const char *capability; const char *terminal_string; capability = get_string_capability ("setaf"); terminal_string = tiparm (capability, color); fputs (terminal_string, stdout); }
char * tgoto(const char *cm, int destcol, int destline) { _DIAGASSERT(cm != NULL); return tiparm(cm, destline, destcol); }
void ui_layout(struct cpustats *cpus) { int i; putp(exit_attribute_mode); putp(clear_screen); // Draw key at the top const struct ui_stat *si; for (si = ui_stats; si->name; si++) { putp(tiparm(set_a_background, si->color)); printf(" "); putp(exit_attribute_mode); printf(" %s ", si->name); } // Create one pane by default ui_init_panes(1); ui_panes[0].barpos = 0; // Create bar info free(ui_bars); ui_num_bars = cpus->online + 1; ui_bars = malloc(ui_num_bars * sizeof *ui_bars); if (!ui_bars) epanic("allocating bars"); // Create average bar ui_bars[0].start = 0; ui_bars[0].width = 3; ui_bars[0].cpu = -1; // Lay out labels char buf[16]; snprintf(buf, sizeof buf, "%d", cpus->max); int length = strlen(buf); int label_len; int w = COLS - 4; if ((length + 1) * cpus->online < w) { // Lay out the labels horizontally ui_panes[0].start = 1; ui_bar_length = MAX(0, LINES - ui_panes[0].start - 2); label_len = 1; putp(tiparm(cursor_address, LINES, 0)); int bar = 1; for (i = 0; i <= cpus->max; ++i) { if (cpus->cpus[i].online) { ui_bars[bar].start = 4 + (bar-1)*(length+1); ui_bars[bar].width = length; ui_bars[bar].cpu = i; bar++; } } } else { // Lay out the labels vertically int pad = 0, count = cpus->online; ui_panes[0].start = length; ui_bar_length = MAX(0, LINES - ui_panes[0].start - 2); label_len = length; if (cpus->online * 2 < w) { // We have space for padding pad = 1; } else if (cpus->online >= w && COLS >= 2) { // We don't have space for all of them int totalw = 4 + cpus->online; ui_init_panes((totalw + COLS - 2) / (COLS - 1)); int plength = (LINES - 2) / ui_num_panes; for (i = 0; i < ui_num_panes; ++i) { ui_panes[i].start = (ui_num_panes-i-1) * plength + length; ui_panes[i].barpos = i * (COLS - 1); ui_panes[i].width = COLS - 1; } ui_bar_length = MAX(0, plength - length); } int bar = 1; for (i = 0; i <= cpus->max; ++i) { if (cpus->cpus[i].online) { ui_bars[bar].start = 4 + (bar-1)*(pad+1); ui_bars[bar].width = 1; ui_bars[bar].cpu = i; bar++; } } } // Allocate bar display buffers free(ui_display); free(ui_fore); free(ui_back); ui_bar_width = ui_bars[ui_num_bars-1].start + ui_bars[ui_num_bars-1].width; if (!(ui_display = malloc(ui_bar_length * ui_bar_width))) epanic("allocating display buffer"); if (!(ui_fore = malloc(ui_bar_length * ui_bar_width))) epanic("allocating foreground buffer"); if (!(ui_back = malloc(ui_bar_length * ui_bar_width))) epanic("allocating background buffer"); if (ui_ascii) { // ui_display and ui_fore don't change in ASCII mode memset(ui_display, 0, ui_bar_length * ui_bar_width); memset(ui_fore, 0xff, ui_bar_length * ui_bar_width); } // Trim down the last pane to the right width ui_panes[ui_num_panes - 1].width = ui_bar_width - ui_panes[ui_num_panes - 1].barpos; // Draw labels char *label_buf = malloc(ui_bar_width * label_len); if (!label_buf) epanic("allocating label buffer"); memset(label_buf, ' ', ui_bar_width * label_len); int bar; for (bar = 0; bar < ui_num_bars; ++bar) { char *out = &label_buf[ui_bars[bar].start]; int len; if (bar == 0) { strcpy(buf, "avg"); len = 3; } else len = snprintf(buf, sizeof buf, "%d", ui_bars[bar].cpu); if (label_len == 1 || bar == 0) memcpy(out, buf, len); else for (i = 0; i < len; i++) out[i * ui_bar_width] = buf[i]; } for (i = 0; i < ui_num_panes; ++i) { putp(tiparm(cursor_address, LINES - ui_panes[i].start, 0)); int row; for (row = 0; row < label_len; ++row) { if (row > 0) putchar('\n'); fwrite(&label_buf[row*ui_bar_width + ui_panes[i].barpos], 1, ui_panes[i].width, stdout); } } free(label_buf); }
// Init terminal and determine color command strings int terminal_init (void) { color_set_monochrome(); if (!isatty(STDOUT_FILENO)) return 1; if (setupterm (NULL, STDOUT_FILENO, NULL)) { log_error("Unable to configure terminal\n"); return 1; } char *boldstr = NULL; if(tigetstr("bold")) boldstr = strdup(tigetstr("bold")); if (tigetstr("setaf")) { log_debug("Using setaf color definitions\n"); red = strdup(tiparm(tigetstr("setaf"), 1)); green = strdup(tiparm(tigetstr("setaf"), 2)); yellow = strdup(tiparm(tigetstr("setaf"), 3)); if(boldstr) { blue = malloc(strlen(boldstr) + strlen(tiparm(tigetstr("setaf"), 4)) + 1); if(!blue) { log_error("malloc failed!\n"); exit(1); } strcpy(blue, boldstr); strcat(blue, tiparm(tigetstr("setaf"), 4)); } else blue = strdup(tiparm(tigetstr("setaf"), 4)); magenta = strdup(tiparm(tigetstr("setaf"), 5)); cyan = strdup(tiparm(tigetstr("setaf"), 6)); white = strdup(tiparm(tigetstr("setaf"), 7)); colors_available = 1; atexit(terminal_reset); } else if (tigetstr("setf")) { log_debug("Using setf color definitions\n"); red = strdup(tiparm(tigetstr("setf"), 4)); green = strdup(tiparm(tigetstr("setf"), 2)); yellow = strdup(tiparm(tigetstr("setf"), 6)); blue = strdup(tiparm(tigetstr("setf"), 1)); magenta = strdup(tiparm(tigetstr("setf"), 5)); cyan = strdup(tiparm(tigetstr("setf"), 3)); white = strdup(tiparm(tigetstr("setf"), 7)); colors_available = 1; atexit(terminal_reset); } else { log_warn("Unable to determine color commands for your terminal\n"); return 1; } char *r = tigetstr("sgr0"); if (r) default_color = strdup(r); else { color_set_monochrome(); log_error("Unable to get default color string\n"); return 1; } return 0; }
} void Terminal::setBackgroundColor(uint32_t color) { if(!m_valid) return; if(m_truecolor) { char buf[256]; snprintf(buf, sizeof(buf), "\033[48;2;%d;%d;%dm", color & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF); fputs(buf, stdout); } else { char* out = tiparm(m_bgColorStr.c_str(), ansiColor(color)); putp(out); } } void Terminal::setForegroundColor(uint32_t color) { if(!m_valid) return; if(m_truecolor) { char buf[256]; snprintf(buf, sizeof(buf), "\033[38;2;%d;%d;%dm", color & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF); fputs(buf, stdout); }