- Overhaul meters implementation;

- add AllCPUsMeter;
- because of that, the new .htoprc is incompatible with previous released versions.
This commit is contained in:
Hisham Muhammad 2006-04-10 20:40:38 +00:00
parent 34bcf8050e
commit 33113fe0d7
24 changed files with 775 additions and 702 deletions

View File

@ -35,19 +35,23 @@ AvailableMetersListBox* AvailableMetersListBox_new(Settings* settings, ListBox*
super->eventHandler = AvailableMetersListBox_EventHandler;
ListBox_setHeader(super, "Available meters");
ListBox_add(super, (Object*) ListItem_new("Swap", 0));
ListBox_add(super, (Object*) ListItem_new("Memory", 0));
ListBox_add(super, (Object*) ListItem_new("Clock", 0));
ListBox_add(super, (Object*) ListItem_new("Load", 0));
ListBox_add(super, (Object*) ListItem_new("LoadAverage", 0));
ListBox_add(super, (Object*) ListItem_new("Uptime", 0));
ListBox_add(super, (Object*) ListItem_new("Tasks", 0));
if (settings->pl->processorCount > 1)
ListBox_add(super, (Object*) ListItem_new("CPUAverage", 0));
for (int i = 1; i <= settings->pl->processorCount; i++) {
char buffer[50];
sprintf(buffer, "CPU(%d)", i);
ListBox_add(super, (Object*) ListItem_new(buffer, 0));
for (int i = 1; Meter_types[i]; i++) {
MeterType* type = Meter_types[i];
if (type != &CPUMeter && type != &AllCPUsMeter) {
ListBox_add(super, (Object*) ListItem_new(type->uiName, i << 16));
}
}
MeterType* type = &CPUMeter;
int processors = settings->pl->processorCount;
if (processors > 1) {
ListBox_add(super, (Object*) ListItem_new("CPU average", 0));
for (int i = 1; i <= processors; i++) {
char buffer[50];
sprintf(buffer, "%s %d", type->uiName, i);
ListBox_add(super, (Object*) ListItem_new(buffer, i));
}
} else {
ListBox_add(super, (Object*) ListItem_new("CPU", 1));
}
return this;
}
@ -60,10 +64,8 @@ void AvailableMetersListBox_delete(Object* object) {
}
/* private */
inline void AvailableMetersListBox_addHeader(Header* header, ListBox* lb, char* name, HeaderSide side) {
Header_createMeter(header, name, side);
int i = Header_size(header, side) - 1;
Meter* meter = (Meter*) Header_getMeter(header, i, side);
inline void AvailableMetersListBox_addHeader(Header* header, ListBox* lb, MeterType* type, int param, HeaderSide side) {
Meter* meter = (Meter*) Header_addMeter(header, type, param, side);
ListBox_add(lb, (Object*) Meter_toListItem(meter));
}
@ -72,7 +74,8 @@ HandlerResult AvailableMetersListBox_EventHandler(ListBox* super, int ch) {
Header* header = this->settings->header;
ListItem* selected = (ListItem*) ListBox_getSelected(super);
char* name = selected->value;
int param = selected->key & 0xff;
int type = selected->key >> 16;
HandlerResult result = IGNORED;
switch(ch) {
@ -80,7 +83,7 @@ HandlerResult AvailableMetersListBox_EventHandler(ListBox* super, int ch) {
case 'l':
case 'L':
{
AvailableMetersListBox_addHeader(header, this->leftBox, name, LEFT_HEADER);
AvailableMetersListBox_addHeader(header, this->leftBox, Meter_types[type], param, LEFT_HEADER);
result = HANDLED;
break;
}
@ -88,7 +91,7 @@ HandlerResult AvailableMetersListBox_EventHandler(ListBox* super, int ch) {
case 'r':
case 'R':
{
AvailableMetersListBox_addHeader(header, this->rightBox, name, RIGHT_HEADER);
AvailableMetersListBox_addHeader(header, this->rightBox, Meter_types[type], param, RIGHT_HEADER);
result = HANDLED;
break;
}

View File

@ -18,17 +18,36 @@ in the source distribution for its full text.
#include "debug.h"
#include <assert.h>
/*{
/* private property */
static int CPUMeter_attributes[] = { CPU_NICE, CPU_NORMAL, CPU_KERNEL };
typedef struct CPUMeter_ CPUMeter;
struct CPUMeter_ {
Meter super;
ProcessList* pl;
int processor;
/* private */
MeterType CPUMeter = {
.setValues = CPUMeter_setValues,
.display = CPUMeter_display,
.mode = BAR_METERMODE,
.items = 3,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "CPU",
.uiName = "CPU",
.caption = "CPU",
.init = CPUMeter_init
};
}*/
/* private */
MeterType AllCPUsMeter = {
.mode = 0,
.items = 1,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "AllCPUs",
.uiName = "All CPUs",
.caption = "CPU",
.draw = AllCPUsMeter_draw,
.init = AllCPUsMeter_init,
.done = AllCPUsMeter_done
};
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
@ -37,50 +56,66 @@ struct CPUMeter_ {
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
CPUMeter* CPUMeter_new(ProcessList* pl, int processor) {
CPUMeter* this = malloc(sizeof(CPUMeter));
char* caption;
if (pl->processorCount == 1 || processor == 0) {
caption = String_copy("CPU");
} else {
caption = (char*) malloc(4);
void CPUMeter_init(Meter* this) {
int processor = this->param;
if (this->pl->processorCount > 1) {
char caption[10];
sprintf(caption, "%-3d", processor);
Meter_setCaption(this, caption);
}
Meter_init((Meter*)this, NULL, caption, 3);
((Meter*)this)->name = malloc(20);
sprintf(((Meter*)this)->name, "CPU(%d)", processor);
((Meter*)this)->attributes[0] = CPU_NICE;
((Meter*)this)->attributes[1] = CPU_NORMAL;
((Meter*)this)->attributes[2] = CPU_KERNEL;
((Meter*)this)->setValues = CPUMeter_setValues;
((Object*)this)->display = CPUMeter_display;
((Meter*)this)->total = 1.0;
Meter_setMode((Meter*)this, BAR);
this->processor = processor;
this->pl = pl;
return this;
if (this->param == 0)
Meter_setCaption(this, "Avg");
}
void CPUMeter_setValues(Meter* cast) {
CPUMeter* this = (CPUMeter*)cast;
cast->values[0] = this->pl->nicePeriod[this->processor] / (double)this->pl->totalPeriod[this->processor];
cast->values[1] = this->pl->userPeriod[this->processor] / (double)this->pl->totalPeriod[this->processor];
cast->values[2] = this->pl->systemPeriod[this->processor] / (double)this->pl->totalPeriod[this->processor];
double cpu = MIN(100.0, MAX(0.0, (cast->values[0]+cast->values[1]+cast->values[2])*100.0 ));
snprintf(cast->displayBuffer.c, 7, "%5.1f%%", cpu );
void CPUMeter_setValues(Meter* this, char* buffer, int size) {
ProcessList* pl = this->pl;
int processor = this->param;
double total = (double) pl->totalPeriod[processor];
this->values[0] = pl->nicePeriod[processor] / total * 100.0;
this->values[1] = pl->userPeriod[processor] / total * 100.0;
this->values[2] = pl->systemPeriod[processor] / total * 100.0;
double cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2])));
snprintf(buffer, size, "%5.1f%%", cpu );
}
void CPUMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* this = (Meter*)cast;
RichString_prune(out);
sprintf(buffer, "%5.1f%% ", this->values[1] * 100.0);
sprintf(buffer, "%5.1f%% ", this->values[1]);
RichString_append(out, CRT_colors[METER_TEXT], ":");
RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[2] * 100.0);
sprintf(buffer, "%5.1f%% ", this->values[2]);
RichString_append(out, CRT_colors[METER_TEXT], "sys:");
RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[0] * 100.0);
sprintf(buffer, "%5.1f%% ", this->values[0]);
RichString_append(out, CRT_colors[METER_TEXT], "low:");
RichString_append(out, CRT_colors[CPU_NICE], buffer);
}
void AllCPUsMeter_init(Meter* this) {
int processors = this->pl->processorCount;
this->drawBuffer = malloc(sizeof(Meter*) * processors);
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++)
meters[i] = Meter_new(this->pl, i+1, &CPUMeter);
this->h = processors;
this->mode = BAR_METERMODE;
}
void AllCPUsMeter_done(Meter* this) {
int processors = this->pl->processorCount;
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++)
Meter_delete((Object*)meters[i]);
}
void AllCPUsMeter_draw(Meter* this, int x, int y, int w) {
int processors = this->pl->processorCount;
Meter** meters = (Meter**) this->drawBuffer;
this->h = Meter_modes[this->mode]->h * processors;
for (int i = 0; i < processors; i++) {
Meter_setMode(meters[i], this->mode);
meters[i]->draw(meters[i], x, y+i, w);
}
}

View File

@ -1,9 +1,9 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_CPUMeter
#define HEADER_CPUMeter
/*
htop
htop - CPUMeter.c
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -17,25 +17,30 @@ in the source distribution for its full text.
#include <curses.h>
#include <string.h>
#include <math.h>
#include <sys/param.h>
#include "debug.h"
#include <assert.h>
typedef struct CPUMeter_ CPUMeter;
struct CPUMeter_ {
Meter super;
ProcessList* pl;
int processor;
};
CPUMeter* CPUMeter_new(ProcessList* pl, int processor);
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
void CPUMeter_setValues(Meter* cast);
void CPUMeter_init(Meter* this);
void CPUMeter_setValues(Meter* this, char* buffer, int size);
void CPUMeter_display(Object* cast, RichString* out);
void AllCPUsMeter_init(Meter* this);
void AllCPUsMeter_done(Meter* this);
void AllCPUsMeter_draw(Meter* this, int x, int y, int w);
#endif

View File

@ -8,47 +8,29 @@ in the source distribution for its full text.
#include "ClockMeter.h"
#include "Meter.h"
#include "ProcessList.h"
#include <curses.h>
#include <time.h>
#include "debug.h"
/*{
/* private */
static int ClockMeter_attributes[] = { CLOCK };
typedef struct ClockMeter_ ClockMeter;
struct ClockMeter_ {
Meter super;
ProcessList* pl;
char clock[10];
/* private */
MeterType ClockMeter = {
.setValues = ClockMeter_setValues,
.display = NULL,
.mode = TEXT_METERMODE,
.total = 100.0,
.items = 1,
.attributes = ClockMeter_attributes,
.name = "Clock",
.uiName = "Clock",
.caption = "Time: ",
};
}*/
ClockMeter* ClockMeter_new() {
ClockMeter* this = malloc(sizeof(ClockMeter));
Meter_init((Meter*)this, String_copy("Clock"), String_copy("Time: "), 1);
((Meter*)this)->attributes[0] = CLOCK;
((Meter*)this)->setValues = ClockMeter_setValues;
((Object*)this)->display = ClockMeter_display;
((Meter*)this)->total = 24 * 60;
Meter_setMode((Meter*)this, TEXT);
return this;
}
void ClockMeter_setValues(Meter* cast) {
ClockMeter* this = (ClockMeter*) cast;
void ClockMeter_setValues(Meter* this, char* buffer, int size) {
time_t t = time(NULL);
struct tm *lt = localtime(&t);
cast->values[0] = lt->tm_hour * 60 + lt->tm_min;
strftime(this->clock, 9, "%H:%M:%S", lt);
snprintf(cast->displayBuffer.c, 9, "%s", this->clock);
}
void ClockMeter_display(Object* cast, RichString* out) {
Meter* super = (Meter*) cast;
ClockMeter* this = (ClockMeter*) cast;
RichString_write(out, CRT_colors[super->attributes[0]], this->clock);
this->values[0] = lt->tm_hour * 60 + lt->tm_min;
strftime(buffer, size, "%H:%M:%S", lt);
}

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_ClockMeter
#define HEADER_ClockMeter
@ -11,27 +11,11 @@ in the source distribution for its full text.
#include "Meter.h"
#include "ProcessList.h"
#include <curses.h>
#include <time.h>
#include "debug.h"
typedef struct ClockMeter_ ClockMeter;
struct ClockMeter_ {
Meter super;
ProcessList* pl;
char clock[10];
};
ClockMeter* ClockMeter_new();
void ClockMeter_setValues(Meter* cast);
void ClockMeter_display(Object* cast, RichString* out);
void ClockMeter_setValues(Meter* this, char* buffer, int size);
#endif

View File

@ -6,14 +6,7 @@ in the source distribution for its full text.
*/
#include "Header.h"
#include "CPUMeter.h"
#include "MemoryMeter.h"
#include "SwapMeter.h"
#include "LoadMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
#include "ClockMeter.h"
#include "TasksMeter.h"
#include "Meter.h"
#include "debug.h"
#include <assert.h>
@ -60,31 +53,22 @@ void Header_createMeter(Header* this, char* name, HeaderSide side) {
? this->leftMeters
: this->rightMeters;
if (String_eq(name, "Swap")) {
TypedVector_add(meters, SwapMeter_new(this->pl));
} else if (String_eq(name, "Memory")) {
TypedVector_add(meters, MemoryMeter_new(this->pl));
} else if (String_eq(name, "Clock")) {
TypedVector_add(meters, ClockMeter_new(this->pl));
} else if (String_eq(name, "Load")) {
TypedVector_add(meters, LoadMeter_new(this->pl));
} else if (String_eq(name, "LoadAverage")) {
TypedVector_add(meters, LoadAverageMeter_new(this->pl));
} else if (String_eq(name, "Uptime")) {
TypedVector_add(meters, UptimeMeter_new(this->pl));
} else if (String_eq(name, "Tasks")) {
TypedVector_add(meters, TasksMeter_new(this->pl));
} else if (String_startsWith(name, "CPUAverage")) {
TypedVector_add(meters, CPUMeter_new(this->pl, 0));
} else if (String_startsWith(name, "CPU")) {
int num;
int ok = sscanf(name, "CPU(%d)", &num);
if (ok)
TypedVector_add(meters, CPUMeter_new(this->pl, num));
char* paren = strchr(name, '(');
int param = 0;
if (paren) {
int ok = sscanf(paren, "(%d)", &param);
if (!ok) param = 0;
*paren = '\0';
}
for (MeterType** type = Meter_types; *type; type++) {
if (String_eq(name, (*type)->name)) {
TypedVector_add(meters, Meter_new(this->pl, param, *type));
break;
}
}
}
void Header_setMode(Header* this, int i, MeterMode mode, HeaderSide side) {
void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
@ -93,12 +77,14 @@ void Header_setMode(Header* this, int i, MeterMode mode, HeaderSide side) {
Meter_setMode(meter, mode);
}
Meter* Header_getMeter(Header* this, int i, HeaderSide side) {
Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
return (Meter*) TypedVector_get(meters, i);
Meter* meter = Meter_new(this->pl, param, type);
TypedVector_add(meters, meter);
return meter;
}
int Header_size(Header* this, HeaderSide side) {
@ -113,12 +99,20 @@ char* Header_readMeterName(Header* this, int i, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
Meter* meter = (Meter*) TypedVector_get(meters, i);
return meter->name;
int nameLen = strlen(meter->type->name);
int len = nameLen + 100;
char* name = malloc(len);
strncpy(name, meter->type->name, nameLen);
name[nameLen] = '\0';
if (meter->param)
snprintf(name + nameLen, len - nameLen, "(%d)", meter->param);
return name;
}
MeterMode Header_readMeterMode(Header* this, int i, HeaderSide side) {
MeterModeId Header_readMeterMode(Header* this, int i, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
@ -128,14 +122,13 @@ MeterMode Header_readMeterMode(Header* this, int i, HeaderSide side) {
}
void Header_defaultMeters(Header* this) {
for (int i = 1; i <= this->pl->processorCount; i++) {
TypedVector_add(this->leftMeters, CPUMeter_new(this->pl, i));
}
TypedVector_add(this->leftMeters, MemoryMeter_new(this->pl));
TypedVector_add(this->leftMeters, SwapMeter_new(this->pl));
TypedVector_add(this->rightMeters, TasksMeter_new(this->pl));
TypedVector_add(this->rightMeters, LoadAverageMeter_new(this->pl));
TypedVector_add(this->rightMeters, UptimeMeter_new(this->pl));
for (int i = 1; i <= this->pl->processorCount; i++)
TypedVector_add(this->leftMeters, Meter_new(this->pl, i, &CPUMeter));
TypedVector_add(this->leftMeters, Meter_new(this->pl, 0, &MemoryMeter));
TypedVector_add(this->leftMeters, Meter_new(this->pl, 0, &SwapMeter));
TypedVector_add(this->rightMeters, Meter_new(this->pl, 0, &TasksMeter));
TypedVector_add(this->rightMeters, Meter_new(this->pl, 0, &LoadAverageMeter));
TypedVector_add(this->rightMeters, Meter_new(this->pl, 0, &UptimeMeter));
}
void Header_draw(Header* this) {

View File

@ -1,22 +1,15 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Header
#define HEADER_Header
/*
htop
htop - Header.c
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "CPUMeter.h"
#include "MemoryMeter.h"
#include "SwapMeter.h"
#include "LoadMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
#include "ClockMeter.h"
#include "TasksMeter.h"
#include "Meter.h"
#include "debug.h"
#include <assert.h>
@ -37,21 +30,25 @@ typedef struct Header_ {
} Header;
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
Header* Header_new(ProcessList* pl);
void Header_delete(Header* this);
void Header_createMeter(Header* this, char* name, HeaderSide side);
void Header_setMode(Header* this, int i, MeterMode mode, HeaderSide side);
void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side);
Meter* Header_getMeter(Header* this, int i, HeaderSide side);
Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side);
int Header_size(Header* this, HeaderSide side);
char* Header_readMeterName(Header* this, int i, HeaderSide side);
MeterMode Header_readMeterMode(Header* this, int i, HeaderSide side);
MeterModeId Header_readMeterMode(Header* this, int i, HeaderSide side);
void Header_defaultMeters(Header* this);

View File

@ -8,42 +8,44 @@ in the source distribution for its full text.
#include "LoadAverageMeter.h"
#include "Meter.h"
#include "ProcessList.h"
#include <curses.h>
#include "debug.h"
/*{
typedef struct LoadAverageMeter_ LoadAverageMeter;
struct LoadAverageMeter_ {
Meter super;
ProcessList* pl;
};
}*/
/* private property */
void LoadAverageMeter_scan(double* one, double* five, double* fifteen);
LoadAverageMeter* LoadAverageMeter_new() {
LoadAverageMeter* this = malloc(sizeof(LoadAverageMeter));
Meter_init((Meter*)this, String_copy("LoadAverage"), String_copy("Load average: "), 3);
((Meter*)this)->attributes[0] = LOAD_AVERAGE_FIFTEEN;
((Meter*)this)->attributes[1] = LOAD_AVERAGE_FIVE;
((Meter*)this)->attributes[2] = LOAD_AVERAGE_ONE;
((Object*)this)->display = LoadAverageMeter_display;
((Meter*)this)->setValues = LoadAverageMeter_setValues;
Meter_setMode((Meter*)this, TEXT);
LoadAverageMeter_scan(&((Meter*)this)->values[0], &((Meter*)this)->values[1], &((Meter*)this)->values[2]);
((Meter*)this)->total = 100.0;
return this;
}
int LoadAverageMeter_attributes[] = { LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIVE, LOAD_AVERAGE_ONE };
/* private */
void LoadAverageMeter_scan(double* one, double* five, double* fifteen) {
MeterType LoadAverageMeter = {
.setValues = LoadAverageMeter_setValues,
.display = LoadAverageMeter_display,
.mode = TEXT_METERMODE,
.items = 3,
.total = 100.0,
.attributes = LoadAverageMeter_attributes,
.name = "LoadAverage",
.uiName = "Load average",
.caption = "Load average: "
};
/* private property */
int LoadMeter_attributes[] = { LOAD };
/* private */
MeterType LoadMeter = {
.setValues = LoadMeter_setValues,
.display = LoadMeter_display,
.mode = TEXT_METERMODE,
.items = 1,
.total = 100.0,
.attributes = LoadMeter_attributes,
.name = "Load",
.uiName = "Load",
.caption = "Load: "
};
/* private */
inline static void LoadAverageMeter_scan(double* one, double* five, double* fifteen) {
int activeProcs, totalProcs, lastProc;
FILE *fd = fopen(PROCDIR "/loadavg", "r");
int read = fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen,
@ -53,9 +55,9 @@ void LoadAverageMeter_scan(double* one, double* five, double* fifteen) {
fclose(fd);
}
void LoadAverageMeter_setValues(Meter* cast) {
LoadAverageMeter_scan(&cast->values[2], &cast->values[1], &cast->values[0]);
snprintf(cast->displayBuffer.c, 25, "%.2f/%.2f/%.2f", cast->values[2], cast->values[1], cast->values[0]);
void LoadAverageMeter_setValues(Meter* this, char* buffer, int size) {
LoadAverageMeter_scan(&this->values[2], &this->values[1], &this->values[0]);
snprintf(buffer, size, "%.2f/%.2f/%.2f", this->values[2], this->values[1], this->values[0]);
}
void LoadAverageMeter_display(Object* cast, RichString* out) {
@ -63,9 +65,26 @@ void LoadAverageMeter_display(Object* cast, RichString* out) {
char buffer[20];
RichString_prune(out);
sprintf(buffer, "%.2f ", this->values[2]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_ONE], buffer);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
sprintf(buffer, "%.2f ", this->values[1]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIVE], buffer);
sprintf(buffer, "%.2f ", this->values[0]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
RichString_append(out, CRT_colors[LOAD_AVERAGE_ONE], buffer);
}
void LoadMeter_setValues(Meter* this, char* buffer, int size) {
double five, fifteen;
LoadAverageMeter_scan(&this->values[0], &five, &fifteen);
if (this->values[0] > this->total) {
this->total = this->values[0];
}
snprintf(buffer, size, "%.2f", this->values[0]);
}
void LoadMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
char buffer[20];
RichString_prune(out);
sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
RichString_append(out, CRT_colors[LOAD], buffer);
}

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_LoadAverageMeter
#define HEADER_LoadAverageMeter
@ -11,27 +11,21 @@ in the source distribution for its full text.
#include "Meter.h"
#include "ProcessList.h"
#include <curses.h>
#include "debug.h"
typedef struct LoadAverageMeter_ LoadAverageMeter;
struct LoadAverageMeter_ {
Meter super;
ProcessList* pl;
};
LoadAverageMeter* LoadAverageMeter_new();
void LoadAverageMeter_setValues(Meter* cast);
void LoadAverageMeter_setValues(Meter* this, char* buffer, int size);
void LoadAverageMeter_display(Object* cast, RichString* out);
void LoadMeter_setValues(Meter* this, char* buffer, int size);
void LoadMeter_display(Object* cast, RichString* out);
#endif

View File

@ -13,13 +13,13 @@ AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
htop_SOURCES = AvailableMetersListBox.c CategoriesListBox.c ClockMeter.c \
CPUMeter.c CRT.c DebugMemory.c DisplayOptionsListBox.c FunctionBar.c \
Hashtable.c Header.c htop.c ListBox.c ListItem.c LoadAverageMeter.c \
LoadMeter.c MemoryMeter.c Meter.c MetersListBox.c Object.c Process.c \
MemoryMeter.c Meter.c MetersListBox.c Object.c Process.c \
ProcessList.c RichString.c ScreenManager.c Settings.c SignalItem.c \
SignalsListBox.c String.c SwapMeter.c TasksMeter.c TypedVector.c \
UptimeMeter.c UsersTable.c AvailableMetersListBox.h CategoriesListBox.h \
ClockMeter.h config.h CPUMeter.h CRT.h debug.h DebugMemory.h \
DisplayOptionsListBox.h FunctionBar.h Hashtable.h Header.h htop.h ListBox.h \
ListItem.h LoadAverageMeter.h LoadMeter.h MemoryMeter.h Meter.h \
ListItem.h LoadAverageMeter.h MemoryMeter.h Meter.h \
MetersListBox.h Object.h Process.h ProcessList.h RichString.h ScreenManager.h \
Settings.h SignalItem.h SignalsListBox.h String.h SwapMeter.h TasksMeter.h \
TypedVector.h UptimeMeter.h UsersTable.h CheckItem.c CheckItem.h \

View File

@ -19,61 +19,42 @@ in the source distribution for its full text.
#include "debug.h"
#include <assert.h>
/*{
/* private property */
static int MemoryMeter_attributes[] = { MEMORY_USED, MEMORY_BUFFERS, MEMORY_CACHE };
typedef struct MemoryMeter_ MemoryMeter;
struct MemoryMeter_ {
Meter super;
ProcessList* pl;
char* wideFormat;
int wideLimit;
/* private */
MeterType MemoryMeter = {
.setValues = MemoryMeter_setValues,
.display = MemoryMeter_display,
.mode = BAR_METERMODE,
.items = 3,
.total = 100.0,
.attributes = MemoryMeter_attributes,
"Memory",
"Memory",
"Mem"
};
}*/
MemoryMeter* MemoryMeter_new(ProcessList* pl) {
MemoryMeter* this = malloc(sizeof(MemoryMeter));
Meter_init((Meter*)this, String_copy("Memory"), String_copy("Mem"), 3);
((Meter*)this)->attributes[0] = MEMORY_USED;
((Meter*)this)->attributes[1] = MEMORY_BUFFERS;
((Meter*)this)->attributes[2] = MEMORY_CACHE;
((Meter*)this)->setValues = MemoryMeter_setValues;
((Object*)this)->display = MemoryMeter_display;
this->pl = pl;
Meter_setMode((Meter*)this, BAR);
this->wideFormat = "%6ldk ";
this->wideLimit = 22 + 8 * 4;
return this;
}
void MemoryMeter_setValues(Meter* cast) {
MemoryMeter* this = (MemoryMeter*)cast;
double totalMem = (double)this->pl->totalMem;
void MemoryMeter_setValues(Meter* this, char* buffer, int size) {
long int usedMem = this->pl->usedMem;
long int buffersMem = this->pl->buffersMem;
long int cachedMem = this->pl->cachedMem;
usedMem -= buffersMem + cachedMem;
cast->total = totalMem;
cast->values[0] = usedMem;
cast->values[1] = buffersMem;
cast->values[2] = cachedMem;
snprintf(cast->displayBuffer.c, 14, "%ld/%ldMB", usedMem / 1024, this->pl->totalMem / 1024);
this->total = this->pl->totalMem;
this->values[0] = usedMem;
this->values[1] = buffersMem;
this->values[2] = cachedMem;
snprintf(buffer, size, "%ld/%ldMB", (long int) usedMem / 1024, (long int) this->total / 1024);
}
void MemoryMeter_display(Object* cast, RichString* out) {
char buffer[50];
MemoryMeter* this = (MemoryMeter*)cast;
Meter* meter = (Meter*)cast;
Meter* this = (Meter*)cast;
int div = 1024; char* format = "%ldM ";
if (meter->w > this->wideLimit) {
div = 1; format = this->wideFormat;
}
long int totalMem = meter->total / div;
long int usedMem = meter->values[0] / div;
long int buffersMem = meter->values[1] / div;
long int cachedMem = meter->values[2] / div;
long int totalMem = this->total / div;
long int usedMem = this->values[0] / div;
long int buffersMem = this->values[1] / div;
long int cachedMem = this->values[2] / div;
RichString_prune(out);
RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, format, totalMem);

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_MemoryMeter
#define HEADER_MemoryMeter
@ -23,19 +23,8 @@ in the source distribution for its full text.
#include <assert.h>
typedef struct MemoryMeter_ MemoryMeter;
struct MemoryMeter_ {
Meter super;
ProcessList* pl;
char* wideFormat;
int wideLimit;
};
MemoryMeter* MemoryMeter_new(ProcessList* pl);
void MemoryMeter_setValues(Meter* cast);
void MemoryMeter_setValues(Meter* this, char* buffer, int size);
void MemoryMeter_display(Object* cast, RichString* out);

510
Meter.c
View File

@ -5,62 +5,101 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define _GNU_SOURCE
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <stdarg.h>
#include "Meter.h"
#include "Object.h"
#include "CRT.h"
#include "ListItem.h"
#include "String.h"
#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <math.h>
#include "ProcessList.h"
#include "debug.h"
#include <assert.h>
#define METER_BARBUFFER_LEN 128
#define METER_GRAPHBUFFER_LEN 128
#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(*Meter_SetValues)(Meter*);
typedef void(*MeterType_Init)(Meter*);
typedef void(*MeterType_Done)(Meter*);
typedef void(*Meter_SetValues)(Meter*, char*, int);
typedef void(*Meter_Draw)(Meter*, int, int, int);
typedef enum MeterMode_ {
UNSET,
BAR,
TEXT,
GRAPH,
LED,
LAST_METERMODE
} MeterMode;
struct MeterMode_ {
Meter_Draw draw;
char* uiName;
int h;
};
struct MeterType_ {
Meter_SetValues setValues;
Object_Display display;
int mode;
int items;
double total;
int* attributes;
char* name;
char* uiName;
char* caption;
MeterType_Init init;
MeterType_Done done;
Meter_Draw draw;
};
struct Meter_ {
Object super;
int h;
int w;
char* caption;
MeterType* type;
int mode;
int param;
Meter_Draw draw;
Meter_SetValues setValues;
int items;
int* attributes;
void* drawBuffer;
int h;
ProcessList* pl;
double* values;
double total;
char* caption;
char* name;
union {
RichString* rs;
char* c;
double* graph;
} displayBuffer;
MeterMode mode;
};
extern char* METER_CLASS;
extern MeterType CPUMeter;
extern MeterType ClockMeter;
extern MeterType LoadAverageMeter;
extern MeterType LoadMeter;
extern MeterType MemoryMeter;
extern MeterType SwapMeter;
extern MeterType TasksMeter;
extern MeterType UptimeMeter;
extern MeterType AllCPUsMeter;
typedef enum {
CUSTOM_METERMODE = 0,
BAR_METERMODE,
TEXT_METERMODE,
#ifdef USE_FUNKY_MODES
GRAPH_METERMODE,
LED_METERMODE,
#endif
LAST_METERMODE
} MeterModeId;
extern MeterType* Meter_types[];
extern MeterMode* Meter_modes[];
}*/
#ifndef MIN
@ -74,72 +113,178 @@ extern char* METER_CLASS;
char* METER_CLASS = "Meter";
/* private */
char* Meter_ledDigits[3][10] = {
{ " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ "},
{ "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|"},
{ "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|"},
MeterType* Meter_types[] = {
&CPUMeter,
&ClockMeter,
&LoadAverageMeter,
&MemoryMeter,
&SwapMeter,
&TasksMeter,
&UptimeMeter,
&AllCPUsMeter,
NULL
};
/* private property */
char Meter_barCharacters[] = "|#*@$%&";
/* private */
static MeterMode BarMeterMode = {
.uiName = "Bar",
.h = 1,
.draw = BarMeterMode_draw,
};
/* private */
static MeterMode TextMeterMode = {
.uiName = "Text",
.h = 1,
.draw = TextMeterMode_draw,
};
#ifdef USE_FUNKY_MODES
/* private */
static MeterMode GraphMeterMode = {
.uiName = "Graph",
.h = 3,
.draw = GraphMeterMode_draw,
};
/* private */
static MeterMode LEDMeterMode = {
.uiName = "LED",
.h = 3,
.draw = LEDMeterMode_draw,
};
#endif
/* private */
MeterMode* Meter_modes[] = {
NULL,
&BarMeterMode,
&TextMeterMode,
#ifdef USE_FUNKY_MODES
&GraphMeterMode,
&LEDMeterMode,
#endif
NULL
};
/* private property */
static RichString Meter_stringBuffer;
Meter* Meter_new(char* name, char* caption, int items) {
Meter* this = malloc(sizeof(Meter));
Meter_init(this, name, caption, items);
return this;
}
void Meter_init(Meter* this, char* name, char* caption, int items) {
Meter* Meter_new(ProcessList* pl, int param, MeterType* type) {
Meter* this = calloc(sizeof(Meter), 1);
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);
((Object*)this)->delete = Meter_delete;
((Object*)this)->class = METER_CLASS;
this->items = items;
this->name = name;
this->caption = caption;
this->attributes = malloc(sizeof(int) * items);
this->values = malloc(sizeof(double) * items);
this->displayBuffer.c = NULL;
this->mode = UNSET;
this->h = 0;
((Object*)this)->display = type->display;
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);
Meter_done(this);
if (this->type->done) {
this->type->done(this);
}
if (this->drawBuffer)
free(this->drawBuffer);
free(this->caption);
free(this->values);
free(this);
}
/* private */
void Meter_freeBuffer(Meter* this) {
switch (this->mode) {
case BAR: {
free(this->displayBuffer.c);
break;
}
case GRAPH: {
free(this->displayBuffer.graph);
break;
}
default: {
}
}
this->h = 0;
}
void Meter_done(Meter* this) {
void Meter_setCaption(Meter* this, char* caption) {
free(this->caption);
free(this->attributes);
free(this->values);
free(this->name);
Meter_freeBuffer(this);
this->caption = strdup(caption);
}
/* private */
void Meter_drawBar(Meter* this, int x, int y, int w) {
inline static void Meter_displayToStringBuffer(Meter* this, char* buffer) {
MeterType* type = this->type;
Object_Display display = ((Object*)this)->display;
if (display) {
display((Object*)this, &Meter_stringBuffer);
} else {
RichString_prune(&Meter_stringBuffer);
RichString_append(&Meter_stringBuffer, CRT_colors[type->attributes[0]], buffer);
}
}
void Meter_setMode(Meter* this, int modeIndex) {
if (modeIndex == this->mode)
return;
if (!modeIndex)
modeIndex = 1;
assert(modeIndex < LAST_METERMODE);
if (this->type->mode == 0) {
this->draw = this->type->draw;
} else {
if (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 ---------- */
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;
Meter_displayToStringBuffer(this, buffer);
mvhline(y, x, ' ', CRT_colors[DEFAULT_COLOR]);
attrset(CRT_colors[RESET_COLOR]);
mvaddchstr(y, x, Meter_stringBuffer.chstr);
}
/* ---------- BarMeterMode ---------- */
/* private property */
char BarMeterMode_characters[] = "|#*@$%&";
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]);
mvaddstr(y, x, this->caption);
@ -154,21 +299,19 @@ void Meter_drawBar(Meter* this, int x, int y, int w) {
x++;
char bar[w];
this->setValues(this);
int blockSizes[10];
for (int i = 0; i < w; i++)
bar[i] = ' ';
sprintf(bar + (w-strlen(this->displayBuffer.c)), "%s", this->displayBuffer.c);
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 < this->items; i++) {
this->values[i] = MAX(this->values[i], 0);
this->values[i] = MIN(this->values[i], this->total);
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 {
@ -176,12 +319,11 @@ void Meter_drawBar(Meter* this, int x, int y, int w) {
}
int nextOffset = offset + blockSizes[i];
// (Control against invalid values)
nextOffset = MAX(nextOffset, 0);
nextOffset = MIN(nextOffset, w);
nextOffset = MIN(MAX(nextOffset, 0), w);
for (int j = offset; j < nextOffset; j++)
if (bar[j] == ' ') {
if (CRT_colorScheme == COLORSCHEME_MONOCHROME) {
bar[j] = Meter_barCharacters[i];
bar[j] = BarMeterMode_characters[i];
} else {
bar[j] = '|';
}
@ -192,8 +334,8 @@ void Meter_drawBar(Meter* this, int x, int y, int w) {
// ...then print the buffer.
offset = 0;
for (int i = 0; i < this->items; i++) {
attrset(CRT_colors[this->attributes[i]]);
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);
@ -208,40 +350,86 @@ void Meter_drawBar(Meter* this, int x, int y, int w) {
attrset(CRT_colors[RESET_COLOR]);
}
/* private */
void Meter_drawText(Meter* this, int x, int y, int w) {
this->setValues(this);
this->w = w;
attrset(CRT_colors[METER_TEXT]);
mvaddstr(y, x, this->caption);
int captionLen = strlen(this->caption);
w -= captionLen;
x += captionLen;
((Object*)this)->display((Object*)this, this->displayBuffer.rs);
mvhline(y, x, ' ', CRT_colors[DEFAULT_COLOR]);
attrset(CRT_colors[RESET_COLOR]);
mvaddchstr(y, x, this->displayBuffer.rs->chstr);
}
#ifdef USE_FUNKY_MODES
/* ---------- GraphMeterMode ---------- */
#define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0)
/* private */
void Meter_drawDigit(int x, int y, int n) {
for (int i = 0; i < 3; i++) {
mvaddstr(y+i, x, Meter_ledDigits[i][n]);
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
};
/* private property */
static char* GraphMeterMode_characters = "^`'-.,_~'`-.,_~'`-.,_";
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;
mvprintw(0,0,"%f ",value);
for (int i = METER_BUFFER_LEN - w, k = 0; i < METER_BUFFER_LEN; i++, k++) {
double 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 i = 0; i < 21; i++, threshold -= 0.05)
if (value >= threshold) {
DrawDot(CRT_colors[GraphMeterMode_colors[i]], y+(i/7.0), GraphMeterMode_characters[i]);
break;
}
}
attrset(CRT_colors[RESET_COLOR]);
}
/* ---------- LEDMeterMode ---------- */
/* private */
void Meter_drawLed(Meter* this, int x, int y, int w) {
this->setValues(this);
((Object*)this)->display((Object*)this, this->displayBuffer.rs);
static char* LEDMeterMode_digits[3][10] = {
{ " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ "},
{ "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|"},
{ "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|"},
};
/* private */
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]);
}
void LEDMeterMode_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);
Meter_displayToStringBuffer(this, buffer);
attrset(CRT_colors[LED_COLOR]);
mvaddstr(y+2, x, this->caption);
int xx = x + strlen(this->caption);
for (int i = 0; i < this->displayBuffer.rs->len; i++) {
char c = this->displayBuffer.rs->chstr[i];
for (int i = 0; i < Meter_stringBuffer.len; i++) {
char c = Meter_stringBuffer.chstr[i];
if (c >= '0' && c <= '9') {
Meter_drawDigit(xx, y, c-48);
xx += 4;
LEDMeterMode_drawDigit(xx, y, c-48);
xx += 4;
} else {
mvaddch(y+2, xx, c);
xx += 1;
@ -250,104 +438,4 @@ void Meter_drawLed(Meter* this, int x, int y, int w) {
attrset(CRT_colors[RESET_COLOR]);
}
#define DrawDot(a,y,c) do { \
attrset(a); \
mvaddstr(y, x+k, c); \
} while(0)
/* private */
void Meter_drawGraph(Meter* this, int x, int y, int w) {
for (int i = 0; i < METER_GRAPHBUFFER_LEN - 1; i++) {
this->displayBuffer.graph[i] = this->displayBuffer.graph[i+1];
}
this->setValues(this);
double value = 0.0;
for (int i = 0; i < this->items; i++)
value += this->values[i] / this->total;
this->displayBuffer.graph[METER_GRAPHBUFFER_LEN - 1] = value;
for (int i = METER_GRAPHBUFFER_LEN - w, k = 0; i < METER_GRAPHBUFFER_LEN; i++, k++) {
double value = this->displayBuffer.graph[i];
DrawDot( CRT_colors[DEFAULT_COLOR], y, " " );
DrawDot( CRT_colors[DEFAULT_COLOR], y+1, " " );
DrawDot( CRT_colors[DEFAULT_COLOR], y+2, " " );
if (value >= 1.00) DrawDot( CRT_colors[GRAPH_1], y, "^" );
else if (value >= 0.95) DrawDot( CRT_colors[GRAPH_1], y, "`" );
else if (value >= 0.90) DrawDot( CRT_colors[GRAPH_1], y, "'" );
else if (value >= 0.85) DrawDot( CRT_colors[GRAPH_2], y, "-" );
else if (value >= 0.80) DrawDot( CRT_colors[GRAPH_2], y, "." );
else if (value >= 0.75) DrawDot( CRT_colors[GRAPH_2], y, "," );
else if (value >= 0.70) DrawDot( CRT_colors[GRAPH_3], y, "_" );
else if (value >= 0.65) DrawDot( CRT_colors[GRAPH_3], y+1, "~" );
else if (value >= 0.60) DrawDot( CRT_colors[GRAPH_3], y+1, "`" );
else if (value >= 0.55) DrawDot( CRT_colors[GRAPH_4], y+1, "'" );
else if (value >= 0.50) DrawDot( CRT_colors[GRAPH_4], y+1, "-" );
else if (value >= 0.45) DrawDot( CRT_colors[GRAPH_4], y+1, "." );
else if (value >= 0.40) DrawDot( CRT_colors[GRAPH_5], y+1, "," );
else if (value >= 0.35) DrawDot( CRT_colors[GRAPH_5], y+1, "_" );
else if (value >= 0.30) DrawDot( CRT_colors[GRAPH_6], y+2, "~" );
else if (value >= 0.25) DrawDot( CRT_colors[GRAPH_7], y+2, "`" );
else if (value >= 0.20) DrawDot( CRT_colors[GRAPH_7], y+2, "'" );
else if (value >= 0.15) DrawDot( CRT_colors[GRAPH_7], y+2, "-" );
else if (value >= 0.10) DrawDot( CRT_colors[GRAPH_8], y+2, "." );
else if (value >= 0.05) DrawDot( CRT_colors[GRAPH_8], y+2, "," );
else DrawDot( CRT_colors[GRAPH_9], y+2, "_" );
}
attrset(CRT_colors[RESET_COLOR]);
}
void Meter_setMode(Meter* this, MeterMode mode) {
Meter_freeBuffer(this);
switch (mode) {
case UNSET: {
// fallthrough to a sane default.
mode = TEXT;
}
case TEXT: {
this->draw = Meter_drawText;
this->displayBuffer.rs = & Meter_stringBuffer;
this->h = 1;
break;
}
case LED: {
this->draw = Meter_drawLed;
this->displayBuffer.rs = & Meter_stringBuffer;
this->h = 3;
break;
}
case BAR: {
this->draw = Meter_drawBar;
this->displayBuffer.c = malloc(METER_BARBUFFER_LEN);
this->h = 1;
break;
}
case GRAPH: {
this->draw = Meter_drawGraph;
this->displayBuffer.c = calloc(METER_GRAPHBUFFER_LEN, sizeof(double));
this->h = 3;
break;
}
default: {
assert(false);
}
}
this->mode = mode;
}
ListItem* Meter_toListItem(Meter* this) {
char buffer[50]; char* mode = NULL;
switch (this->mode) {
case BAR: mode = "Bar"; break;
case LED: mode = "LED"; break;
case TEXT: mode = "Text"; break;
case GRAPH: mode = "Graph"; break;
default: {
assert(false);
}
}
sprintf(buffer, "%s [%s]", this->name, mode);
return ListItem_new(buffer, 0);
}
#endif

161
Meter.h
View File

@ -1,94 +1,161 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Meter
#define HEADER_Meter
/*
htop
htop - Meter.c
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define _GNU_SOURCE
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <stdarg.h>
#include "Object.h"
#include "CRT.h"
#include "ListItem.h"
#include "String.h"
#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <math.h>
#include <sys/param.h>
#include "ProcessList.h"
#include "debug.h"
#include <assert.h>
#define METER_BARBUFFER_LEN 128
#define METER_GRAPHBUFFER_LEN 128
#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(*Meter_SetValues)(Meter*);
typedef void(*MeterType_Init)(Meter*);
typedef void(*MeterType_Done)(Meter*);
typedef void(*Meter_SetValues)(Meter*, char*, int);
typedef void(*Meter_Draw)(Meter*, int, int, int);
typedef enum MeterMode_ {
UNSET,
BAR,
TEXT,
GRAPH,
LED,
LAST_METERMODE
} MeterMode;
struct MeterMode_ {
Meter_Draw draw;
char* uiName;
int h;
};
struct MeterType_ {
Meter_SetValues setValues;
Object_Display display;
int mode;
int items;
double total;
int* attributes;
char* name;
char* uiName;
char* caption;
MeterType_Init init;
MeterType_Done done;
Meter_Draw draw;
};
struct Meter_ {
Object super;
int h;
int w;
char* caption;
MeterType* type;
int mode;
int param;
Meter_Draw draw;
Meter_SetValues setValues;
int items;
int* attributes;
void* drawBuffer;
int h;
ProcessList* pl;
double* values;
double total;
char* caption;
char* name;
union {
RichString* rs;
char* c;
double* graph;
} displayBuffer;
MeterMode mode;
};
extern char* METER_CLASS;
extern MeterType CPUMeter;
extern MeterType ClockMeter;
extern MeterType LoadAverageMeter;
extern MeterType LoadMeter;
extern MeterType MemoryMeter;
extern MeterType SwapMeter;
extern MeterType TasksMeter;
extern MeterType UptimeMeter;
extern MeterType AllCPUsMeter;
typedef enum {
CUSTOM_METERMODE = 0,
BAR_METERMODE,
TEXT_METERMODE,
#ifdef USE_FUNKY_MODES
GRAPH_METERMODE,
LED_METERMODE,
#endif
LAST_METERMODE
} MeterModeId;
extern MeterType* Meter_types[9];
extern MeterMode* Meter_modes[];
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
Meter* Meter_new(char* name, char* caption, int items);
void Meter_init(Meter* this, char* name, char* caption, int items);
#ifdef USE_FUNKY_MODES
#endif
Meter* Meter_new(ProcessList* pl, int param, MeterType* type);
void Meter_delete(Object* cast);
void Meter_done(Meter* this);
void Meter_setCaption(Meter* this, char* caption);
#define DrawDot(a,y,c) do { \
attrset(a); \
mvaddstr(y, x+k, c); \
} while(0)
void Meter_setMode(Meter* this, MeterMode mode);
void Meter_setMode(Meter* this, int modeIndex);
ListItem* Meter_toListItem(Meter* this);
/* ---------- TextMeterMode ---------- */
void TextMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- BarMeterMode ---------- */
void BarMeterMode_draw(Meter* this, int x, int y, int w);
#ifdef USE_FUNKY_MODES
/* ---------- GraphMeterMode ---------- */
#define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0)
void GraphMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- LEDMeterMode ---------- */
void LEDMeterMode_draw(Meter* this, int x, int y, int w);
#endif
#endif

View File

@ -59,9 +59,8 @@ HandlerResult MetersListBox_EventHandler(ListBox* super, int ch) {
case 't':
{
Meter* meter = (Meter*) TypedVector_get(this->meters, selected);
MeterMode mode = meter->mode + 1;
if (mode == LAST_METERMODE)
mode = 1; // skip mode 0, "unset"
int mode = meter->mode + 1;
if (mode == LAST_METERMODE) mode = 1;
Meter_setMode(meter, mode);
ListBox_set(super, selected, (Object*) Meter_toListItem(meter));
result = HANDLED;

View File

@ -105,7 +105,7 @@ typedef struct ProcessList_ {
}*/
/* private property */
ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, LAST_PROCESSFIELD, 0 };
ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
#ifdef DEBUG

View File

@ -143,17 +143,17 @@ bool Settings_read(Settings* this, char* fileName) {
if (this->colorScheme < 0) this->colorScheme = 0;
if (this->colorScheme > 5) this->colorScheme = 5;
} else if (String_eq(option[0], "left_meters")) {
Settings_readMeters(this, option[1], LEFT_HEADER);
readMeters = true;
Settings_readMeters(this, option[1], LEFT_HEADER);
readMeters = true;
} else if (String_eq(option[0], "right_meters")) {
Settings_readMeters(this, option[1], RIGHT_HEADER);
readMeters = true;
Settings_readMeters(this, option[1], RIGHT_HEADER);
readMeters = true;
} else if (String_eq(option[0], "left_meter_modes")) {
Settings_readMeterModes(this, option[1], LEFT_HEADER);
readMeters = true;
Settings_readMeterModes(this, option[1], LEFT_HEADER);
readMeters = true;
} else if (String_eq(option[0], "right_meter_modes")) {
Settings_readMeterModes(this, option[1], RIGHT_HEADER);
readMeters = true;
Settings_readMeterModes(this, option[1], RIGHT_HEADER);
readMeters = true;
}
String_freeArray(option);
}
@ -196,7 +196,9 @@ bool Settings_write(Settings* this) {
fprintf(fd, "delay=%d\n", (int) this->delay);
fprintf(fd, "left_meters=");
for (int i = 0; i < Header_size(this->header, LEFT_HEADER); i++) {
fprintf(fd, "%s ", Header_readMeterName(this->header, i, LEFT_HEADER));
char* name = Header_readMeterName(this->header, i, LEFT_HEADER);
fprintf(fd, "%s ", name);
free(name);
}
fprintf(fd, "\n");
fprintf(fd, "left_meter_modes=");
@ -204,14 +206,15 @@ bool Settings_write(Settings* this) {
fprintf(fd, "%d ", Header_readMeterMode(this->header, i, LEFT_HEADER));
fprintf(fd, "\n");
fprintf(fd, "right_meters=");
for (int i = 0; i < Header_size(this->header, RIGHT_HEADER); i++)
fprintf(fd, "%s ", Header_readMeterName(this->header, i, RIGHT_HEADER));
for (int i = 0; i < Header_size(this->header, RIGHT_HEADER); i++) {
char* name = Header_readMeterName(this->header, i, RIGHT_HEADER);
fprintf(fd, "%s ", name);
free(name);
}
fprintf(fd, "\n");
fprintf(fd, "right_meter_modes=");
for (int i = 0; i < Header_size(this->header, RIGHT_HEADER); i++)
fprintf(fd, "%d ", Header_readMeterMode(this->header, i, RIGHT_HEADER));
fprintf(fd, "\n");
fclose(fd);
return true;
}

View File

@ -1,9 +1,9 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Settings
#define HEADER_Settings
/*
htop
htop - Settings.c
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -15,14 +15,16 @@ in the source distribution for its full text.
#include "debug.h"
#define DEFAULT_DELAY 15
typedef struct Settings_ {
char* userSettings;
ProcessList* pl;
Header* header;
int colorScheme;
int delay;
bool changed;
int delay;
} Settings;

View File

@ -19,45 +19,36 @@ in the source distribution for its full text.
#include "debug.h"
#include <assert.h>
/*{
/* private property */
static int SwapMeter_attributes[] = { SWAP };
typedef struct SwapMeter_ SwapMeter;
struct SwapMeter_ {
Meter super;
ProcessList* pl;
/* private */
MeterType SwapMeter = {
.setValues = SwapMeter_setValues,
.display = SwapMeter_display,
.mode = BAR_METERMODE,
.items = 1,
.total = 100.0,
.attributes = SwapMeter_attributes,
.name = "Swap",
.uiName = "Swap",
.caption = "Swp"
};
}*/
SwapMeter* SwapMeter_new(ProcessList* pl) {
SwapMeter* this = malloc(sizeof(SwapMeter));
Meter_init((Meter*)this, String_copy("Swap"), String_copy("Swp"), 1);
((Meter*)this)->attributes[0] = SWAP;
((Meter*)this)->setValues = SwapMeter_setValues;
((Object*)this)->display = SwapMeter_display;
this->pl = pl;
Meter_setMode((Meter*)this, BAR);
return this;
}
void SwapMeter_setValues(Meter* cast) {
SwapMeter* this = (SwapMeter*)cast;
double totalSwap = (double)this->pl->totalSwap;
void SwapMeter_setValues(Meter* this, char* buffer, int len) {
long int usedSwap = this->pl->usedSwap;
cast->total = totalSwap;
cast->values[0] = usedSwap;
snprintf(cast->displayBuffer.c, 14, "%ld/%ldMB", usedSwap / 1024, this->pl->totalSwap / 1024);
this->total = this->pl->totalSwap;
this->values[0] = usedSwap;
snprintf(buffer, len, "%ld/%ldMB", (long int) usedSwap / 1024, (long int) this->total / 1024);
}
void SwapMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* meter = (Meter*)cast;
long int swap = (long int) meter->values[0];
Meter* this = (Meter*)cast;
long int swap = (long int) this->values[0];
RichString_prune(out);
RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, "%ldM ", (long int) meter->total / 1024);
sprintf(buffer, "%ldM ", (long int) this->total / 1024);
RichString_append(out, CRT_colors[METER_VALUE], buffer);
sprintf(buffer, "%ldk", swap);
RichString_append(out, CRT_colors[METER_TEXT], "used:");

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_SwapMeter
#define HEADER_SwapMeter
@ -23,17 +23,8 @@ in the source distribution for its full text.
#include <assert.h>
typedef struct SwapMeter_ SwapMeter;
struct SwapMeter_ {
Meter super;
ProcessList* pl;
};
SwapMeter* SwapMeter_new(ProcessList* pl);
void SwapMeter_setValues(Meter* cast);
void SwapMeter_setValues(Meter* this, char* buffer, int len);
void SwapMeter_display(Object* cast, RichString* out);

View File

@ -14,33 +14,26 @@ in the source distribution for its full text.
#include "debug.h"
/*{
/* private property */
int TasksMeter_attributes[] = { TASKS_RUNNING };
typedef struct TasksMeter_ TasksMeter;
struct TasksMeter_ {
Meter super;
ProcessList* pl;
/* private */
MeterType TasksMeter = {
.setValues = TasksMeter_setValues,
.display = TasksMeter_display,
.mode = TEXT_METERMODE,
.items = 1,
.total = 100.0,
.attributes = TasksMeter_attributes,
.name = "Tasks",
.uiName = "Task counter",
.caption = "Tasks: "
};
}*/
TasksMeter* TasksMeter_new(ProcessList* pl) {
TasksMeter* this = malloc(sizeof(TasksMeter));
Meter_init((Meter*)this, String_copy("Tasks"), String_copy("Tasks: "), 1);
((Meter*)this)->attributes[0] = TASKS_RUNNING;
((Object*)this)->display = TasksMeter_display;
((Meter*)this)->setValues = TasksMeter_setValues;
this->pl = pl;
Meter_setMode((Meter*)this, TEXT);
return this;
}
void TasksMeter_setValues(Meter* cast) {
TasksMeter* this = (TasksMeter*)cast;
cast->total = this->pl->totalTasks;
cast->values[0] = this->pl->runningTasks;
snprintf(cast->displayBuffer.c, 20, "%d/%d", (int) cast->values[0], (int) cast->total);
void TasksMeter_setValues(Meter* this, char* buffer, int len) {
this->total = this->pl->totalTasks;
this->values[0] = this->pl->runningTasks;
snprintf(buffer, len, "%d/%d", (int) this->values[0], (int) this->total);
}
void TasksMeter_display(Object* cast, RichString* out) {

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_TasksMeter
#define HEADER_TasksMeter
@ -18,17 +18,8 @@ in the source distribution for its full text.
#include "debug.h"
typedef struct TasksMeter_ TasksMeter;
struct TasksMeter_ {
Meter super;
ProcessList* pl;
};
TasksMeter* TasksMeter_new(ProcessList* pl);
void TasksMeter_setValues(Meter* cast);
void TasksMeter_setValues(Meter* this, char* buffer, int len);
void TasksMeter_display(Object* cast, RichString* out);

View File

@ -14,64 +14,45 @@ in the source distribution for its full text.
#include "debug.h"
/*{
/* private property */
static int UptimeMeter_attributes[] = { UPTIME };
typedef struct UptimeMeter_ UptimeMeter;
struct UptimeMeter_ {
Meter super;
ProcessList* pl;
int seconds;
int minutes;
int hours;
int days;
/* private */
MeterType UptimeMeter = {
.setValues = UptimeMeter_setValues,
.display = NULL,
.mode = TEXT_METERMODE,
.items = 1,
.total = 100.0,
.attributes = UptimeMeter_attributes,
.name = "Uptime",
.uiName = "Uptime",
.caption = "Uptime: "
};
}*/
UptimeMeter* UptimeMeter_new() {
UptimeMeter* this = malloc(sizeof(UptimeMeter));
Meter_init((Meter*)this, String_copy("Uptime"), String_copy("Uptime: "), 1);
((Meter*)this)->attributes[0] = UPTIME;
((Object*)this)->display = UptimeMeter_display;
((Meter*)this)->setValues = UptimeMeter_setValues;
Meter_setMode((Meter*)this, TEXT);
((Meter*)this)->total = 100.0;
return this;
}
void UptimeMeter_setValues(Meter* cast) {
UptimeMeter* this = (UptimeMeter*)cast;
void UptimeMeter_setValues(Meter* this, char* buffer, int len) {
double uptime;
FILE* fd = fopen(PROCDIR "/uptime", "r");
fscanf(fd, "%lf", &uptime);
fclose(fd);
int totalseconds = (int) ceil(uptime);
this->seconds = totalseconds % 60;
this->minutes = (totalseconds-this->seconds) % 3600 / 60;
this->hours = (totalseconds-this->seconds-(this->minutes*60)) % 86400 / 3600;
this->days = (totalseconds-this->seconds-(this->minutes*60)-(this->hours*3600)) / 86400;
cast->values[0] = this->days;
if (this->days > cast->total) {
cast->total = this->days;
int seconds = totalseconds % 60;
int minutes = (totalseconds-seconds) % 3600 / 60;
int hours = (totalseconds-seconds-(minutes*60)) % 86400 / 3600;
int days = (totalseconds-seconds-(minutes*60)-(hours*3600)) / 86400;
this->values[0] = days;
if (days > this->total) {
this->total = days;
}
snprintf(cast->displayBuffer.c, 14, "%d", this->days);
}
void UptimeMeter_display(Object* cast, RichString* out) {
UptimeMeter* this = (UptimeMeter*)cast;
char buffer[20];
RichString_prune(out);
if (this->days > 100) {
sprintf(buffer, "%d days, ", this->days);
RichString_write(out, CRT_colors[LARGE_NUMBER], buffer);
} else if (this->days > 1) {
sprintf(buffer, "%d days, ", this->days);
RichString_write(out, CRT_colors[UPTIME], buffer);
} else if (this->days == 1) {
sprintf(buffer, "%d day, ", this->days);
RichString_write(out, CRT_colors[UPTIME], buffer);
char daysbuf[10];
if (days > 100) {
sprintf(daysbuf, "%d days(!), ", days);
} else if (days > 1) {
sprintf(daysbuf, "%d days, ", days);
} else if (days == 1) {
sprintf(daysbuf, "1 day, ");
} else {
daysbuf[0] = '\0';
}
sprintf(buffer, "%02d:%02d:%02d ", this->hours, this->minutes, this->seconds);
RichString_append(out, CRT_colors[UPTIME], buffer);
snprintf(buffer, len, "%s%02d:%02d:%02d", daysbuf, hours, minutes, seconds);
}

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_UptimeMeter
#define HEADER_UptimeMeter
@ -18,22 +18,7 @@ in the source distribution for its full text.
#include "debug.h"
typedef struct UptimeMeter_ UptimeMeter;
struct UptimeMeter_ {
Meter super;
ProcessList* pl;
int seconds;
int minutes;
int hours;
int days;
};
UptimeMeter* UptimeMeter_new();
void UptimeMeter_setValues(Meter* cast);
void UptimeMeter_display(Object* cast, RichString* out);
void UptimeMeter_setValues(Meter* cast, char* buffer, int len);
#endif