From ff9409b1737627857eb47f64f536a3f66b6a09a4 Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Mon, 11 Apr 2016 13:01:07 +0200 Subject: Imported Upstream version 2.0.0 --- Meter.c | 235 +++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 145 insertions(+), 90 deletions(-) (limited to 'Meter.c') diff --git a/Meter.c b/Meter.c index 3abd708..9a7868e 100644 --- a/Meter.c +++ b/Meter.c @@ -7,19 +7,10 @@ in the source distribution for its full text. #include "Meter.h" -#include "CPUMeter.h" -#include "MemoryMeter.h" -#include "SwapMeter.h" -#include "TasksMeter.h" -#include "LoadAverageMeter.h" -#include "UptimeMeter.h" -#include "BatteryMeter.h" -#include "ClockMeter.h" -#include "HostnameMeter.h" #include "RichString.h" #include "Object.h" #include "CRT.h" -#include "String.h" +#include "StringUtils.h" #include "ListItem.h" #include "Settings.h" @@ -30,11 +21,16 @@ in the source distribution for its full text. #include #include -#define METER_BUFFER_LEN 128 +#define METER_BUFFER_LEN 256 + +#define GRAPH_DELAY (DEFAULT_DELAY/2) + +#define GRAPH_HEIGHT 4 /* Unit: rows (lines) */ /*{ #include "ListItem.h" -#include "ProcessList.h" + +#include typedef struct Meter_ Meter; @@ -57,6 +53,7 @@ typedef struct MeterClass_ { const char* name; const char* uiName; const char* caption; + const char* description; const char maxItems; char curItems; } MeterClass; @@ -86,7 +83,7 @@ struct Meter_ { int param; void* drawData; int h; - ProcessList* pl; + struct ProcessList_* pl; double* values; double total; }; @@ -119,6 +116,9 @@ typedef struct GraphData_ { #ifndef MAX #define MAX(a,b) ((a)>(b)?(a):(b)) #endif +#ifndef CLAMP +#define CLAMP(x,low,high) (((x)>(high))?(high):(((x)<(low))?(low):(x))) +#endif MeterClass Meter_class = { .super = { @@ -126,29 +126,8 @@ MeterClass Meter_class = { } }; -MeterClass* Meter_types[] = { - &CPUMeter_class, - &ClockMeter_class, - &LoadAverageMeter_class, - &LoadMeter_class, - &MemoryMeter_class, - &SwapMeter_class, - &TasksMeter_class, - &UptimeMeter_class, - &BatteryMeter_class, - &HostnameMeter_class, - &AllCPUsMeter_class, - &AllCPUs2Meter_class, - &LeftCPUsMeter_class, - &RightCPUsMeter_class, - &LeftCPUs2Meter_class, - &RightCPUs2Meter_class, - &BlankMeter_class, - NULL -}; - -Meter* Meter_new(ProcessList* pl, int param, MeterClass* type) { - Meter* this = calloc(1, sizeof(Meter)); +Meter* Meter_new(struct ProcessList_* pl, int param, MeterClass* type) { + Meter* this = xCalloc(1, sizeof(Meter)); Object_setClass(this, type); this->h = 1; this->param = param; @@ -158,15 +137,46 @@ Meter* Meter_new(ProcessList* pl, int param, MeterClass* type) { maxItems = 1; } type->curItems = maxItems; - this->values = calloc(maxItems, sizeof(double)); + this->values = xCalloc(maxItems, sizeof(double)); this->total = type->total; - this->caption = strdup(type->caption); + this->caption = xStrdup(type->caption); 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"; + unsigned long int powi = 1; + unsigned int written, powj = 1, precision = 2; + + for(;;) { + if (value / 1024 < powi) + break; + + if (prefix[1] == 0) + break; + + powi *= 1024; + ++prefix; + } + + if (*prefix == 'K') + precision = 0; + + for (; precision > 0; precision--) { + powj *= 10; + if (value / powi < powj) + break; + } + + written = snprintf(buffer, size, "%.*f%c", + precision, (double) value / powi, *prefix); + + return written; +} + void Meter_delete(Object* cast) { if (!cast) return; @@ -183,7 +193,7 @@ void Meter_delete(Object* cast) { void Meter_setCaption(Meter* this, const char* caption) { free(this->caption); - this->caption = strdup(caption); + this->caption = xStrdup(caption); } static inline void Meter_displayBuffer(Meter* this, char* buffer, RichString* out) { @@ -217,7 +227,7 @@ void Meter_setMode(Meter* this, int modeIndex) { this->mode = modeIndex; } -ListItem* Meter_toListItem(Meter* this) { +ListItem* Meter_toListItem(Meter* this, bool moving) { char mode[21]; if (this->mode) snprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName); @@ -230,7 +240,9 @@ ListItem* Meter_toListItem(Meter* this) { number[0] = '\0'; char buffer[51]; snprintf(buffer, 50, "%s%s%s", Meter_uiName(this), number, mode); - return ListItem_new(buffer, 0); + ListItem* li = ListItem_new(buffer, 0); + li->moving = moving; + return li; } /* ---------- TextMeterMode ---------- */ @@ -244,7 +256,6 @@ static void TextMeterMode_draw(Meter* this, int x, int y, int w) { mvaddstr(y, x, this->caption); int captionLen = strlen(this->caption); x += captionLen; - mvhline(y, x, ' ', CRT_colors[DEFAULT_COLOR]); attrset(CRT_colors[RESET_COLOR]); RichString_begin(out); Meter_displayBuffer(this, buffer, &out); @@ -254,7 +265,7 @@ static void TextMeterMode_draw(Meter* this, int x, int y, int w) { /* ---------- BarMeterMode ---------- */ -static char BarMeterMode_characters[] = "|#*@$%&"; +static char BarMeterMode_characters[] = "|#*@$%&."; static void BarMeterMode_draw(Meter* this, int x, int y, int w) { char buffer[METER_BUFFER_LEN]; @@ -291,8 +302,7 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { int items = Meter_getItems(this); for (int i = 0; i < items; i++) { double value = this->values[i]; - value = MAX(value, 0); - value = MIN(value, this->total); + value = CLAMP(value, 0.0, this->total); if (value > 0) { blockSizes[i] = ceil((value/this->total) * w); } else { @@ -300,7 +310,7 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { } int nextOffset = offset + blockSizes[i]; // (Control against invalid values) - nextOffset = MIN(MAX(nextOffset, 0), w); + nextOffset = CLAMP(nextOffset, 0, w); for (int j = offset; j < nextOffset; j++) if (bar[j] == ' ') { if (CRT_colorScheme == COLORSCHEME_MONOCHROME) { @@ -318,8 +328,7 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { attrset(CRT_colors[Meter_attributes(this)[i]]); mvaddnstr(y, x + offset, bar + offset, blockSizes[i]); offset += blockSizes[i]; - offset = MAX(offset, 0); - offset = MIN(offset, w); + offset = CLAMP(offset, 0, w); } if (offset < w) { attrset(CRT_colors[BAR_SHADOW]); @@ -332,30 +341,56 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) { /* ---------- GraphMeterMode ---------- */ -#define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0) +#ifdef HAVE_LIBNCURSESW -static int GraphMeterMode_colors[21] = { - GRAPH_1, GRAPH_1, GRAPH_1, - GRAPH_2, GRAPH_2, GRAPH_2, - GRAPH_3, GRAPH_3, GRAPH_3, - GRAPH_4, GRAPH_4, GRAPH_4, - GRAPH_5, GRAPH_5, GRAPH_6, - GRAPH_7, GRAPH_7, GRAPH_7, - GRAPH_8, GRAPH_8, GRAPH_9 +#define PIXPERROW_UTF8 4 +static const char* GraphMeterMode_dotsUtf8[] = { + /*00*/" ", /*01*/"⢀", /*02*/"⢠", /*03*/"⢰", /*04*/ "⢸", + /*10*/"⡀", /*11*/"⣀", /*12*/"⣠", /*13*/"⣰", /*14*/ "⣸", + /*20*/"⡄", /*21*/"⣄", /*22*/"⣤", /*23*/"⣴", /*24*/ "⣼", + /*30*/"⡆", /*31*/"⣆", /*32*/"⣦", /*33*/"⣶", /*34*/ "⣾", + /*40*/"⡇", /*41*/"⣇", /*42*/"⣧", /*43*/"⣷", /*44*/ "⣿" }; -static const char* GraphMeterMode_characters = "^`'-.,_~'`-.,_~'`-.,_"; +#endif + +#define PIXPERROW_ASCII 2 +static const char* GraphMeterMode_dotsAscii[] = { + /*00*/" ", /*01*/".", /*02*/":", + /*10*/".", /*11*/".", /*12*/":", + /*20*/":", /*21*/":", /*22*/":" +}; + +static const char** GraphMeterMode_dots; +static int GraphMeterMode_pixPerRow; static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { - if (!this->drawData) this->drawData = calloc(1, sizeof(GraphData)); - GraphData* data = (GraphData*) this->drawData; + if (!this->drawData) this->drawData = xCalloc(1, sizeof(GraphData)); + GraphData* data = (GraphData*) this->drawData; const int nValues = METER_BUFFER_LEN; + +#ifdef HAVE_LIBNCURSESW + if (CRT_utf8) { + GraphMeterMode_dots = GraphMeterMode_dotsUtf8; + GraphMeterMode_pixPerRow = PIXPERROW_UTF8; + } else +#endif + { + GraphMeterMode_dots = GraphMeterMode_dotsAscii; + GraphMeterMode_pixPerRow = PIXPERROW_ASCII; + } + + attrset(CRT_colors[METER_TEXT]); + int captionLen = 3; + mvaddnstr(y, x, this->caption, captionLen); + x += captionLen; + w -= captionLen; struct timeval now; gettimeofday(&now, NULL); if (!timercmp(&now, &(data->time), <)) { - struct timeval delay = { .tv_sec = (int)(DEFAULT_DELAY/10), .tv_usec = (DEFAULT_DELAY-((int)(DEFAULT_DELAY/10)*10)) * 100000 }; + struct timeval delay = { .tv_sec = (int)(CRT_delay/10), .tv_usec = (CRT_delay-((int)(CRT_delay/10)*10)) * 100000 }; timeradd(&now, &delay, &(data->time)); for (int i = 0; i < nValues - 1; i++) @@ -372,55 +407,75 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { data->values[nValues - 1] = value; } - for (int i = nValues - w, k = 0; i < nValues; i++, k++) { - double value = data->values[i]; - DrawDot( CRT_colors[DEFAULT_COLOR], y, ' ' ); - DrawDot( CRT_colors[DEFAULT_COLOR], y+1, ' ' ); - DrawDot( CRT_colors[DEFAULT_COLOR], y+2, ' ' ); - - double threshold = 1.00; - for (int j = 0; j < 21; j++, threshold -= 0.05) - if (value >= threshold) { - DrawDot(CRT_colors[GraphMeterMode_colors[j]], y+(j/7.0), GraphMeterMode_characters[j]); - break; - } + int i = nValues - (w*2) + 2, k = 0; + if (i < 0) { + k = -i/2; + i = 0; + } + for (; i < nValues; i+=2, k++) { + int pix = GraphMeterMode_pixPerRow * GRAPH_HEIGHT; + int v1 = CLAMP(data->values[i] * pix, 1, pix); + int v2 = CLAMP(data->values[i+1] * pix, 1, pix); + + int colorIdx = GRAPH_1; + for (int line = 0; line < GRAPH_HEIGHT; line++) { + int line1 = CLAMP(v1 - (GraphMeterMode_pixPerRow * (GRAPH_HEIGHT - 1 - line)), 0, GraphMeterMode_pixPerRow); + 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]); + colorIdx = GRAPH_2; + } } attrset(CRT_colors[RESET_COLOR]); } /* ---------- LEDMeterMode ---------- */ -static const char* LEDMeterMode_digitsAscii[3][10] = { - { " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ "}, - { "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|"}, - { "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|"}, +static const char* LEDMeterMode_digitsAscii[] = { + " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ ", + "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|", + "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|" }; -static const char* LEDMeterMode_digitsUtf8[3][10] = { - { "┌──┐"," ┐ ","╶──┐","╶──┐","╷ ╷","┌──╴","┌──╴","╶──┐","┌──┐","┌──┐"}, - { "│ │"," │ ","┌──┘"," ──┤","└──┤","└──┐","├──┐"," │","├──┤","└──┤"}, - { "└──┘"," ╵ ","└──╴","╶──┘"," ╵","╶──┘","└──┘"," ╵","└──┘"," ──┘"}, +#ifdef HAVE_LIBNCURSESW + +static const char* LEDMeterMode_digitsUtf8[] = { + "┌──┐"," ┐ ","╶──┐","╶──┐","╷ ╷","┌──╴","┌──╴","╶──┐","┌──┐","┌──┐", + "│ │"," │ ","┌──┘"," ──┤","└──┤","└──┐","├──┐"," │","├──┤","└──┤", + "└──┘"," ╵ ","└──╴","╶──┘"," ╵","╶──┘","└──┘"," ╵","└──┘"," ──┘" }; +#endif + +static const char** LEDMeterMode_digits; + static void LEDMeterMode_drawDigit(int x, int y, int n) { - if (CRT_utf8) { - for (int i = 0; i < 3; i++) - mvaddstr(y+i, x, LEDMeterMode_digitsUtf8[i][n]); - } else { - for (int i = 0; i < 3; i++) - mvaddstr(y+i, x, LEDMeterMode_digitsAscii[i][n]); - } + for (int i = 0; i < 3; i++) + mvaddstr(y+i, x, LEDMeterMode_digits[i * 10 + n]); } static void LEDMeterMode_draw(Meter* this, int x, int y, int w) { (void) w; + +#ifdef HAVE_LIBNCURSESW + if (CRT_utf8) + LEDMeterMode_digits = LEDMeterMode_digitsUtf8; + else +#endif + LEDMeterMode_digits = LEDMeterMode_digitsAscii; + char buffer[METER_BUFFER_LEN]; Meter_setValues(this, buffer, METER_BUFFER_LEN - 1); RichString_begin(out); Meter_displayBuffer(this, buffer, &out); - int yText = CRT_utf8 ? y+1 : y+2; + int yText = +#ifdef HAVE_LIBNCURSESW + CRT_utf8 ? y+1 : +#endif + y+2; attrset(CRT_colors[LED_COLOR]); mvaddstr(yText, x, this->caption); int xx = x + strlen(this->caption); @@ -453,7 +508,7 @@ static MeterMode TextMeterMode = { static MeterMode GraphMeterMode = { .uiName = "Graph", - .h = 3, + .h = GRAPH_HEIGHT, .draw = GraphMeterMode_draw, }; -- cgit v1.2.3