From 65357c8c46154de4e4eca14075bfe5523bb5fc14 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Mon, 7 Dec 2020 10:26:01 +0100 Subject: New upstream version 3.0.3 --- Meter.c | 194 +++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 105 insertions(+), 89 deletions(-) (limited to 'Meter.c') diff --git a/Meter.c b/Meter.c index 00c49ce..945911c 100644 --- a/Meter.c +++ b/Meter.c @@ -1,56 +1,60 @@ /* htop - Meter.c (C) 2004-2011 Hisham H. Muhammad -Released under the GNU GPL, see the COPYING file +Released under the GNU GPLv2, see the COPYING file in the source distribution for its full text. */ -#include "Meter.h" +#include "config.h" // IWYU pragma: keep -#include "RichString.h" -#include "Object.h" -#include "CRT.h" -#include "StringUtils.h" -#include "Settings.h" +#include "Meter.h" +#include #include -#include #include -#include -#include +#include +#include + +#include "CRT.h" +#include "Macros.h" +#include "Object.h" +#include "ProvideCurses.h" +#include "RichString.h" +#include "Settings.h" +#include "XUtils.h" -#define GRAPH_DELAY (DEFAULT_DELAY/2) #define GRAPH_HEIGHT 4 /* Unit: rows (lines) */ -MeterClass Meter_class = { +const MeterClass Meter_class = { .super = { .extends = Class(Object) } }; -Meter* Meter_new(struct ProcessList_* pl, int param, MeterClass* type) { +Meter* Meter_new(const struct ProcessList_* pl, int param, const MeterClass* type) { Meter* this = xCalloc(1, sizeof(Meter)); Object_setClass(this, type); this->h = 1; this->param = param; this->pl = pl; - type->curItems = type->maxItems; - this->values = xCalloc(type->maxItems, sizeof(double)); + this->curItems = type->maxItems; + this->values = type->maxItems ? xCalloc(type->maxItems, sizeof(double)) : NULL; this->total = type->total; this->caption = xStrdup(type->caption); - if (Meter_initFn(this)) + if (Meter_initFn(this)) { Meter_init(this); + } Meter_setMode(this, type->defaultMode); return this; } -int Meter_humanUnit(char* buffer, unsigned long int value, int size) { - const char * prefix = "KMGTPEZY"; +int Meter_humanUnit(char* buffer, unsigned long int value, size_t size) { + const char* prefix = "KMGTPEZY"; unsigned long int powi = 1; - unsigned int written, powj = 1, precision = 2; + unsigned int powj = 1, precision = 2; - for(;;) { + for (;;) { if (value / 1024 < powi) break; @@ -70,15 +74,13 @@ int Meter_humanUnit(char* buffer, unsigned long int value, int size) { break; } - written = snprintf(buffer, size, "%.*f%c", - precision, (double) value / powi, *prefix); - - return written; + return snprintf(buffer, size, "%.*f%c", precision, (double) value / powi, *prefix); } void Meter_delete(Object* cast) { if (!cast) return; + Meter* this = (Meter*) cast; if (Meter_doneFn(this)) { Meter_done(this); @@ -94,7 +96,7 @@ void Meter_setCaption(Meter* this, const char* caption) { this->caption = xStrdup(caption); } -static inline void Meter_displayBuffer(Meter* this, char* buffer, RichString* out) { +static inline void Meter_displayBuffer(const Meter* this, const char* buffer, RichString* out) { if (Object_displayFn(this)) { Object_display(this, out); } else { @@ -103,21 +105,26 @@ static inline void Meter_displayBuffer(Meter* this, char* buffer, RichString* ou } void Meter_setMode(Meter* this, int modeIndex) { - if (modeIndex > 0 && modeIndex == this->mode) + if (modeIndex > 0 && modeIndex == this->mode) { return; - if (!modeIndex) + } + + if (!modeIndex) { modeIndex = 1; + } + assert(modeIndex < LAST_METERMODE); if (Meter_defaultMode(this) == CUSTOM_METERMODE) { this->draw = Meter_drawFn(this); - if (Meter_updateModeFn(this)) + if (Meter_updateModeFn(this)) { Meter_updateMode(this, modeIndex); + } } else { assert(modeIndex >= 1); free(this->drawData); this->drawData = NULL; - MeterMode* mode = Meter_modes[modeIndex]; + const MeterMode* mode = Meter_modes[modeIndex]; this->draw = mode->draw; this->h = mode->h; } @@ -125,18 +132,20 @@ void Meter_setMode(Meter* this, int modeIndex) { } ListItem* Meter_toListItem(Meter* this, bool moving) { - char mode[21]; - if (this->mode) - xSnprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName); - else + char mode[20]; + if (this->mode) { + xSnprintf(mode, sizeof(mode), " [%s]", Meter_modes[this->mode]->uiName); + } else { mode[0] = '\0'; - char number[11]; - if (this->param > 0) - xSnprintf(number, 10, " %d", this->param); - else + } + char number[10]; + if (this->param > 0) { + xSnprintf(number, sizeof(number), " %d", this->param); + } else { number[0] = '\0'; - char buffer[51]; - xSnprintf(buffer, 50, "%s%s%s", Meter_uiName(this), number, mode); + } + char buffer[50]; + xSnprintf(buffer, sizeof(buffer), "%s%s%s", Meter_uiName(this), number, mode); ListItem* li = ListItem_new(buffer, 0); li->moving = moving; return li; @@ -146,7 +155,7 @@ ListItem* Meter_toListItem(Meter* this, bool moving) { static void TextMeterMode_draw(Meter* this, int x, int y, int w) { char buffer[METER_BUFFER_LEN]; - Meter_updateValues(this, buffer, METER_BUFFER_LEN - 1); + Meter_updateValues(this, buffer, sizeof(buffer)); (void) w; attrset(CRT_colors[METER_TEXT]); @@ -166,7 +175,7 @@ static const char BarMeterMode_characters[] = "|#*@$%&."; static void BarMeterMode_draw(Meter* this, int x, int y, int w) { char buffer[METER_BUFFER_LEN]; - Meter_updateValues(this, buffer, METER_BUFFER_LEN - 1); + Meter_updateValues(this, buffer, sizeof(buffer)); w -= 2; attrset(CRT_colors[METER_TEXT]); @@ -177,28 +186,33 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { attrset(CRT_colors[BAR_BORDER]); mvaddch(y, x, '['); mvaddch(y, x + w, ']'); + attrset(CRT_colors[RESET_COLOR]); w--; x++; - if (w < 1) { - attrset(CRT_colors[RESET_COLOR]); + if (w < 1) return; - } - char bar[w + 1]; - int blockSizes[10]; + // The text in the bar is right aligned; + // calculate needed padding and generate leading spaces + const int textLen = mbstowcs(NULL, buffer, 0); + const int padding = CLAMP(w - textLen, 0, w); - xSnprintf(bar, w + 1, "%*.*s", w, w, buffer); + RichString_begin(bar); + RichString_appendChr(&bar, ' ', padding); + RichString_append(&bar, 0, buffer); + assert(RichString_sizeVal(bar) >= w); + + int blockSizes[10]; // First draw in the bar[] buffer... int offset = 0; - int items = Meter_getItems(this); - for (int i = 0; i < items; i++) { + for (uint8_t i = 0; i < this->curItems; i++) { double value = this->values[i]; value = CLAMP(value, 0.0, this->total); if (value > 0) { - blockSizes[i] = ceil((value/this->total) * w); + blockSizes[i] = ceil((value / this->total) * w); } else { blockSizes[i] = 0; } @@ -206,11 +220,11 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { // (Control against invalid values) nextOffset = CLAMP(nextOffset, 0, w); for (int j = offset; j < nextOffset; j++) - if (bar[j] == ' ') { + if (RichString_getCharVal(bar, j) == ' ') { if (CRT_colorScheme == COLORSCHEME_MONOCHROME) { - bar[j] = BarMeterMode_characters[i]; + RichString_setChar(&bar, j, BarMeterMode_characters[i]); } else { - bar[j] = '|'; + RichString_setChar(&bar, j, '|'); } } offset = nextOffset; @@ -218,17 +232,19 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { // ...then print the buffer. offset = 0; - for (int i = 0; i < items; i++) { - attrset(CRT_colors[Meter_attributes(this)[i]]); - mvaddnstr(y, x + offset, bar + offset, blockSizes[i]); + for (uint8_t i = 0; i < this->curItems; i++) { + RichString_setAttrn(&bar, CRT_colors[Meter_attributes(this)[i]], offset, offset + blockSizes[i] - 1); + RichString_printoffnVal(bar, y, x + offset, offset, blockSizes[i]); offset += blockSizes[i]; offset = CLAMP(offset, 0, w); } if (offset < w) { - attrset(CRT_colors[BAR_SHADOW]); - mvaddnstr(y, x + offset, bar + offset, w - offset); + RichString_setAttrn(&bar, CRT_colors[BAR_SHADOW], offset, w - 1); + RichString_printoffnVal(bar, y, x + offset, offset, w - offset); } + RichString_end(bar); + move(y, x + w + 1); attrset(CRT_colors[RESET_COLOR]); } @@ -260,8 +276,10 @@ static int GraphMeterMode_pixPerRow; static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { - if (!this->drawData) this->drawData = xCalloc(1, sizeof(GraphData)); - GraphData* data = (GraphData*) this->drawData; + if (!this->drawData) { + this->drawData = xCalloc(1, sizeof(GraphData)); + } + GraphData* data = this->drawData; const int nValues = METER_BUFFER_LEN; #ifdef HAVE_LIBNCURSESW @@ -284,32 +302,32 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { struct timeval now; gettimeofday(&now, NULL); if (!timercmp(&now, &(data->time), <)) { - struct timeval delay = { .tv_sec = (int)(CRT_delay/10), .tv_usec = (CRT_delay-((int)(CRT_delay/10)*10)) * 100000 }; + int globalDelay = this->pl->settings->delay; + struct timeval delay = { .tv_sec = globalDelay / 10, .tv_usec = (globalDelay - ((globalDelay / 10) * 10)) * 100000 }; timeradd(&now, &delay, &(data->time)); for (int i = 0; i < nValues - 1; i++) - data->values[i] = data->values[i+1]; + data->values[i] = data->values[i + 1]; - char buffer[nValues]; - Meter_updateValues(this, buffer, nValues - 1); + char buffer[METER_BUFFER_LEN]; + Meter_updateValues(this, buffer, sizeof(buffer)); double value = 0.0; - int items = Meter_getItems(this); - for (int i = 0; i < items; i++) + for (uint8_t i = 0; i < this->curItems; i++) value += this->values[i]; value /= this->total; data->values[nValues - 1] = value; } - int i = nValues - (w*2) + 2, k = 0; + int i = nValues - (w * 2) + 2, k = 0; if (i < 0) { - k = -i/2; + k = -i / 2; i = 0; } - for (; i < nValues - 1; i+=2, k++) { + for (; i < nValues - 1; i += 2, k++) { int pix = GraphMeterMode_pixPerRow * GRAPH_HEIGHT; int v1 = CLAMP((int) lround(data->values[i] * pix), 1, pix); - int v2 = CLAMP((int) lround(data->values[i+1] * pix), 1, pix); + int v2 = CLAMP((int) lround(data->values[i + 1] * pix), 1, pix); int colorIdx = GRAPH_1; for (int line = 0; line < GRAPH_HEIGHT; line++) { @@ -317,7 +335,7 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { int line2 = CLAMP(v2 - (GraphMeterMode_pixPerRow * (GRAPH_HEIGHT - 1 - line)), 0, GraphMeterMode_pixPerRow); attrset(CRT_colors[colorIdx]); - mvaddstr(y+line, x+k, GraphMeterMode_dots[line1 * (GraphMeterMode_pixPerRow + 1) + line2]); + mvaddstr(y + line, x + k, GraphMeterMode_dots[line1 * (GraphMeterMode_pixPerRow + 1) + line2]); colorIdx = GRAPH_2; } } @@ -327,17 +345,17 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { /* ---------- LEDMeterMode ---------- */ static const char* const LEDMeterMode_digitsAscii[] = { - " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ ", - "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|", - "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|" + " __ ", " ", " __ ", " __ ", " ", " __ ", " __ ", " __ ", " __ ", " __ ", + "| |", " |", " __|", " __|", "|__|", "|__ ", "|__ ", " |", "|__|", "|__|", + "|__|", " |", "|__ ", " __|", " |", " __|", "|__|", " |", "|__|", " __|" }; #ifdef HAVE_LIBNCURSESW static const char* const LEDMeterMode_digitsUtf8[] = { - "┌──┐"," ┐ ","╶──┐","╶──┐","╷ ╷","┌──╴","┌──╴","╶──┐","┌──┐","┌──┐", - "│ │"," │ ","┌──┘"," ──┤","└──┤","└──┐","├──┐"," │","├──┤","└──┤", - "└──┘"," ╵ ","└──╴","╶──┘"," ╵","╶──┘","└──┘"," ╵","└──┘"," ──┘" + "┌──┐", " ┐ ", "╶──┐", "╶──┐", "╷ ╷", "┌──╴", "┌──╴", "╶──┐", "┌──┐", "┌──┐", + "│ │", " │ ", "┌──┘", " ──┤", "└──┤", "└──┐", "├──┐", " │", "├──┤", "└──┤", + "└──┘", " ╵ ", "└──╴", "╶──┘", " ╵", "╶──┘", "└──┘", " ╵", "└──┘", " ──┘" }; #endif @@ -360,24 +378,24 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) { LEDMeterMode_digits = LEDMeterMode_digitsAscii; char buffer[METER_BUFFER_LEN]; - Meter_updateValues(this, buffer, METER_BUFFER_LEN - 1); + Meter_updateValues(this, buffer, sizeof(buffer)); RichString_begin(out); Meter_displayBuffer(this, buffer, &out); int yText = #ifdef HAVE_LIBNCURSESW - CRT_utf8 ? y+1 : + CRT_utf8 ? y + 1 : #endif - y+2; + y + 2; attrset(CRT_colors[LED_COLOR]); mvaddstr(yText, x, this->caption); int xx = x + strlen(this->caption); int len = RichString_sizeVal(out); for (int i = 0; i < len; i++) { - char c = RichString_getCharVal(out, i); + int c = RichString_getCharVal(out, i); if (c >= '0' && c <= '9') { - LEDMeterMode_drawDigit(xx, y, c-48); + LEDMeterMode_drawDigit(xx, y, c - 48); xx += 4; } else { mvaddch(yText, xx, c); @@ -412,7 +430,7 @@ static MeterMode LEDMeterMode = { .draw = LEDMeterMode_draw, }; -MeterMode* Meter_modes[] = { +const MeterMode* const Meter_modes[] = { NULL, &BarMeterMode, &TextMeterMode, @@ -423,23 +441,21 @@ MeterMode* Meter_modes[] = { /* Blank meter */ -static void BlankMeter_updateValues(Meter* this, char* buffer, int size) { - (void) this; (void) buffer; (void) size; +static void BlankMeter_updateValues(ATTR_UNUSED Meter* this, char* buffer, size_t size) { if (size > 0) { *buffer = 0; } } -static void BlankMeter_display(Object* cast, RichString* out) { - (void) cast; +static void BlankMeter_display(ATTR_UNUSED const Object* cast, RichString* out) { RichString_prune(out); } -int BlankMeter_attributes[] = { +static const int BlankMeter_attributes[] = { DEFAULT_COLOR }; -MeterClass BlankMeter_class = { +const MeterClass BlankMeter_class = { .super = { .extends = Class(Meter), .delete = Meter_delete, -- cgit v1.2.3