diff options
author | Amit Pundir <amit.pundir@linaro.org> | 2012-04-17 15:05:59 +0530 |
---|---|---|
committer | Amit Pundir <amit.pundir@linaro.org> | 2012-04-17 15:05:59 +0530 |
commit | 96a11754a6950bfe50784c0877cb64b1ed7d2b18 (patch) | |
tree | b977131bbbb4c3bd8ade370aab2e4fc913440c04 /Meter.c | |
download | android_external_htop-96a11754a6950bfe50784c0877cb64b1ed7d2b18.tar.gz android_external_htop-96a11754a6950bfe50784c0877cb64b1ed7d2b18.tar.bz2 android_external_htop-96a11754a6950bfe50784c0877cb64b1ed7d2b18.zip |
add original htop code
htop-0.9 downloaded from http://archive.ubuntu.com/ubuntu/pool/universe/h/htop/htop_0.9.orig.tar.gz
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
Diffstat (limited to 'Meter.c')
-rw-r--r-- | Meter.c | 441 |
1 files changed, 441 insertions, 0 deletions
@@ -0,0 +1,441 @@ +/* +htop - Meter.c +(C) 2004-2010 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#define _GNU_SOURCE +#include "RichString.h" +#include "Meter.h" +#include "Object.h" +#include "CRT.h" +#include "ListItem.h" +#include "String.h" +#include "ProcessList.h" + +#include <math.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> + +#include "debug.h" +#include <assert.h> + +#ifndef USE_FUNKY_MODES +#define USE_FUNKY_MODES 1 +#endif + +#define METER_BUFFER_LEN 128 + +/*{ + +typedef struct Meter_ Meter; +typedef struct MeterType_ MeterType; +typedef struct MeterMode_ MeterMode; + +typedef void(*MeterType_Init)(Meter*); +typedef void(*MeterType_Done)(Meter*); +typedef void(*MeterType_SetMode)(Meter*, int); +typedef void(*Meter_SetValues)(Meter*, char*, int); +typedef void(*Meter_Draw)(Meter*, int, int, int); + +struct MeterMode_ { + Meter_Draw draw; + const char* uiName; + int h; +}; + +struct MeterType_ { + Meter_SetValues setValues; + Object_Display display; + int mode; + int items; + double total; + int* attributes; + const char* name; + const char* uiName; + const char* caption; + MeterType_Init init; + MeterType_Done done; + MeterType_SetMode setMode; + Meter_Draw draw; +}; + +struct Meter_ { + Object super; + char* caption; + MeterType* type; + int mode; + int param; + Meter_Draw draw; + void* drawBuffer; + int h; + ProcessList* pl; + double* values; + double total; +}; + +typedef enum { + CUSTOM_METERMODE = 0, + BAR_METERMODE, + TEXT_METERMODE, +#ifdef USE_FUNKY_MODES + GRAPH_METERMODE, + LED_METERMODE, +#endif + LAST_METERMODE +} MeterModeId; + +}*/ + +#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" + + +#ifndef MIN +#define MIN(a,b) ((a)<(b)?(a):(b)) +#endif +#ifndef MAX +#define MAX(a,b) ((a)>(b)?(a):(b)) +#endif + +#ifdef DEBUG +char* METER_CLASS = "Meter"; +#else +#define METER_CLASS NULL +#endif + +MeterType* Meter_types[] = { + &CPUMeter, + &ClockMeter, + &LoadAverageMeter, + &LoadMeter, + &MemoryMeter, + &SwapMeter, + &TasksMeter, + &UptimeMeter, + &BatteryMeter, + &AllCPUsMeter, + &HostnameMeter, + NULL +}; + +Meter* Meter_new(ProcessList* pl, int param, MeterType* type) { + Meter* this = calloc(sizeof(Meter), 1); + Object_setClass(this, METER_CLASS); + ((Object*)this)->delete = Meter_delete; + ((Object*)this)->display = type->display; + this->h = 1; + this->type = type; + this->param = param; + this->pl = pl; + this->values = calloc(sizeof(double), type->items); + this->total = type->total; + this->caption = strdup(type->caption); + Meter_setMode(this, type->mode); + if (this->type->init) + this->type->init(this); + return this; +} + +void Meter_delete(Object* cast) { + Meter* this = (Meter*) cast; + assert (this != NULL); + if (this->type->done) { + this->type->done(this); + } + if (this->drawBuffer) + free(this->drawBuffer); + free(this->caption); + free(this->values); + free(this); +} + +void Meter_setCaption(Meter* this, const char* caption) { + free(this->caption); + this->caption = strdup(caption); +} + +static inline void Meter_displayBuffer(Meter* this, char* buffer, RichString* out) { + MeterType* type = this->type; + Object_Display display = ((Object*)this)->display; + if (display) { + display((Object*)this, out); + } else { + RichString_write(out, CRT_colors[type->attributes[0]], buffer); + } +} + +void Meter_setMode(Meter* this, int modeIndex) { + if (modeIndex > 0 && modeIndex == this->mode) + return; + if (!modeIndex) + modeIndex = 1; + assert(modeIndex < LAST_METERMODE); + if (this->type->mode == 0) { + this->draw = this->type->draw; + if (this->type->setMode) + this->type->setMode(this, modeIndex); + } else { + assert(modeIndex >= 1); + if (this->drawBuffer) + free(this->drawBuffer); + this->drawBuffer = NULL; + + MeterMode* mode = Meter_modes[modeIndex]; + this->draw = mode->draw; + this->h = mode->h; + } + this->mode = modeIndex; +} + +ListItem* Meter_toListItem(Meter* this) { + MeterType* type = this->type; + char mode[21]; + if (this->mode) + snprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName); + else + mode[0] = '\0'; + char number[11]; + if (this->param > 0) + snprintf(number, 10, " %d", this->param); + else + number[0] = '\0'; + char buffer[51]; + snprintf(buffer, 50, "%s%s%s", type->uiName, number, mode); + return ListItem_new(buffer, 0); +} + +/* ---------- TextMeterMode ---------- */ + +static void TextMeterMode_draw(Meter* this, int x, int y, int w) { + MeterType* type = this->type; + char buffer[METER_BUFFER_LEN]; + type->setValues(this, buffer, METER_BUFFER_LEN - 1); + + attrset(CRT_colors[METER_TEXT]); + mvaddstr(y, x, this->caption); + int captionLen = strlen(this->caption); + w -= captionLen; + x += captionLen; + mvhline(y, x, ' ', CRT_colors[DEFAULT_COLOR]); + attrset(CRT_colors[RESET_COLOR]); + RichString_begin(out); + Meter_displayBuffer(this, buffer, &out); + RichString_printVal(out, y, x); + RichString_end(out); +} + +/* ---------- BarMeterMode ---------- */ + +static char BarMeterMode_characters[] = "|#*@$%&"; + +static void BarMeterMode_draw(Meter* this, int x, int y, int w) { + MeterType* type = this->type; + char buffer[METER_BUFFER_LEN]; + type->setValues(this, buffer, METER_BUFFER_LEN - 1); + + w -= 2; + attrset(CRT_colors[METER_TEXT]); + int captionLen = 3; + mvaddnstr(y, x, this->caption, captionLen); + x += captionLen; + w -= captionLen; + attrset(CRT_colors[BAR_BORDER]); + mvaddch(y, x, '['); + mvaddch(y, x + w, ']'); + + w--; + x++; + char bar[w]; + + int blockSizes[10]; + for (int i = 0; i < w; i++) + bar[i] = ' '; + + sprintf(bar + (w-strlen(buffer)), "%s", buffer); + + // First draw in the bar[] buffer... + double total = 0.0; + int offset = 0; + for (int i = 0; i < type->items; i++) { + double value = this->values[i]; + value = MAX(value, 0); + value = MIN(value, this->total); + if (value > 0) { + blockSizes[i] = ceil((value/this->total) * w); + } else { + blockSizes[i] = 0; + } + int nextOffset = offset + blockSizes[i]; + // (Control against invalid values) + nextOffset = MIN(MAX(nextOffset, 0), w); + for (int j = offset; j < nextOffset; j++) + if (bar[j] == ' ') { + if (CRT_colorScheme == COLORSCHEME_MONOCHROME) { + bar[j] = BarMeterMode_characters[i]; + } else { + bar[j] = '|'; + } + } + offset = nextOffset; + total += this->values[i]; + } + + // ...then print the buffer. + offset = 0; + for (int i = 0; i < type->items; i++) { + attrset(CRT_colors[type->attributes[i]]); + mvaddnstr(y, x + offset, bar + offset, blockSizes[i]); + offset += blockSizes[i]; + offset = MAX(offset, 0); + offset = MIN(offset, w); + } + if (offset < w) { + attrset(CRT_colors[BAR_SHADOW]); + mvaddnstr(y, x + offset, bar + offset, w - offset); + } + + move(y, x + w + 1); + attrset(CRT_colors[RESET_COLOR]); +} + +#ifdef USE_FUNKY_MODES + +/* ---------- GraphMeterMode ---------- */ + +#define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0) + +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 +}; + +static const char* GraphMeterMode_characters = "^`'-.,_~'`-.,_~'`-.,_"; + +static void GraphMeterMode_draw(Meter* this, int x, int y, int w) { + + if (!this->drawBuffer) this->drawBuffer = calloc(sizeof(double), METER_BUFFER_LEN); + double* drawBuffer = (double*) this->drawBuffer; + + for (int i = 0; i < METER_BUFFER_LEN - 1; i++) + drawBuffer[i] = drawBuffer[i+1]; + + MeterType* type = this->type; + char buffer[METER_BUFFER_LEN]; + type->setValues(this, buffer, METER_BUFFER_LEN - 1); + + double value = 0.0; + for (int i = 0; i < type->items; i++) + value += this->values[i]; + value /= this->total; + drawBuffer[METER_BUFFER_LEN - 1] = value; + for (int i = METER_BUFFER_LEN - w, k = 0; i < METER_BUFFER_LEN; i++, k++) { + value = drawBuffer[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; + } + } + attrset(CRT_colors[RESET_COLOR]); +} + +/* ---------- LEDMeterMode ---------- */ + +static const char* LEDMeterMode_digits[3][10] = { + { " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ "}, + { "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|"}, + { "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|"}, +}; + +static void LEDMeterMode_drawDigit(int x, int y, int n) { + for (int i = 0; i < 3; i++) + mvaddstr(y+i, x, LEDMeterMode_digits[i][n]); +} + +static void LEDMeterMode_draw(Meter* this, int x, int y, int w) { + (void) w; + MeterType* type = this->type; + char buffer[METER_BUFFER_LEN]; + type->setValues(this, buffer, METER_BUFFER_LEN - 1); + + RichString_begin(out); + Meter_displayBuffer(this, buffer, &out); + + attrset(CRT_colors[LED_COLOR]); + mvaddstr(y+2, 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); + if (c >= '0' && c <= '9') { + LEDMeterMode_drawDigit(xx, y, c-48); + xx += 4; + } else { + mvaddch(y+2, xx, c); + xx += 1; + } + } + attrset(CRT_colors[RESET_COLOR]); + RichString_end(out); +} + +#endif + +static MeterMode BarMeterMode = { + .uiName = "Bar", + .h = 1, + .draw = BarMeterMode_draw, +}; + +static MeterMode TextMeterMode = { + .uiName = "Text", + .h = 1, + .draw = TextMeterMode_draw, +}; + +#ifdef USE_FUNKY_MODES + +static MeterMode GraphMeterMode = { + .uiName = "Graph", + .h = 3, + .draw = GraphMeterMode_draw, +}; + +static MeterMode LEDMeterMode = { + .uiName = "LED", + .h = 3, + .draw = LEDMeterMode_draw, +}; + +#endif + +MeterMode* Meter_modes[] = { + NULL, + &BarMeterMode, + &TextMeterMode, +#ifdef USE_FUNKY_MODES + &GraphMeterMode, + &LEDMeterMode, +#endif + NULL +}; |