Changes in object model: separate class objects to store vtable. Also, nicer UTF-8 display of big numbers.

This commit is contained in:
Hisham Muhammad 2012-12-05 15:12:20 +00:00
parent 2a73405cd0
commit 00b324bfc1
64 changed files with 662 additions and 566 deletions

27
Affinity.h Normal file
View File

@ -0,0 +1,27 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Affinity
#define HEADER_Affinity
/*
htop - Affinity.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
typedef struct Affinity_ {
int size;
int used;
int* cpus;
} Affinity;
Affinity* Affinity_new();
void Affinity_delete(Affinity* this);
void Affinity_add(Affinity* this, int id);
#endif

View File

@ -34,9 +34,17 @@ static HandlerResult AffinityPanel_eventHandler(Panel* this, int ch) {
return IGNORED; return IGNORED;
} }
PanelClass AffinityPanel_class = {
.super = {
.extends = Class(Panel),
.delete = Panel_delete
},
.eventHandler = AffinityPanel_eventHandler
};
Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) { Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) {
Panel* this = Panel_new(1, 1, 1, 1, CHECKITEM_CLASS, true, ListItem_compare); Panel* this = Panel_new(1, 1, 1, 1, true, Class(CheckItem));
this->eventHandler = AffinityPanel_eventHandler; Object_setClass(this, Class(AffinityPanel));
Panel_setHeader(this, "Use CPUs:"); Panel_setHeader(this, "Use CPUs:");
int curCpu = 0; int curCpu = 0;

View File

@ -14,6 +14,8 @@ in the source distribution for its full text.
#include "ProcessList.h" #include "ProcessList.h"
#include "ListItem.h" #include "ListItem.h"
extern PanelClass AffinityPanel_class;
Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity); Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity);
Affinity* AffinityPanel_getAffinity(Panel* this); Affinity* AffinityPanel_getAffinity(Panel* this);

View File

@ -63,15 +63,21 @@ static HandlerResult AvailableColumnsPanel_eventHandler(Panel* super, int ch) {
return result; return result;
} }
PanelClass AvailableColumnsPanel_class = {
.super = {
.extends = Class(Panel),
.delete = AvailableColumnsPanel_delete
},
.eventHandler = AvailableColumnsPanel_eventHandler
};
AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr) { AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr) {
AvailableColumnsPanel* this = (AvailableColumnsPanel*) malloc(sizeof(AvailableColumnsPanel)); AvailableColumnsPanel* this = AllocThis(AvailableColumnsPanel);
Panel* super = (Panel*) this; Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true); Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
((Object*)this)->delete = AvailableColumnsPanel_delete;
this->settings = settings; this->settings = settings;
this->scr = scr; this->scr = scr;
super->eventHandler = AvailableColumnsPanel_eventHandler;
Panel_setHeader(super, "Available Columns"); Panel_setHeader(super, "Available Columns");

View File

@ -22,6 +22,8 @@ typedef struct AvailableColumnsPanel_ {
} AvailableColumnsPanel; } AvailableColumnsPanel;
extern PanelClass AvailableColumnsPanel_class;
AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr); AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr);
#endif #endif

View File

@ -37,7 +37,7 @@ static void AvailableMetersPanel_delete(Object* object) {
free(this); free(this);
} }
static inline void AvailableMetersPanel_addHeader(Header* header, Panel* panel, MeterType* type, int param, HeaderSide side) { static inline void AvailableMetersPanel_addHeader(Header* header, Panel* panel, MeterClass* type, int param, HeaderSide side) {
Meter* meter = (Meter*) Header_addMeter(header, type, param, side); Meter* meter = (Meter*) Header_addMeter(header, type, param, side);
Panel_add(panel, (Object*) Meter_toListItem(meter)); Panel_add(panel, (Object*) Meter_toListItem(meter));
} }
@ -78,26 +78,32 @@ static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) {
return result; return result;
} }
PanelClass AvailableMetersPanel_class = {
.super = {
.extends = Class(Panel),
.delete = AvailableMetersPanel_delete
},
.eventHandler = AvailableMetersPanel_eventHandler
};
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr) { AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr) {
AvailableMetersPanel* this = (AvailableMetersPanel*) malloc(sizeof(AvailableMetersPanel)); AvailableMetersPanel* this = AllocThis(AvailableMetersPanel);
Panel* super = (Panel*) this; Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true); Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
((Object*)this)->delete = AvailableMetersPanel_delete;
this->settings = settings; this->settings = settings;
this->leftPanel = leftMeters; this->leftPanel = leftMeters;
this->rightPanel = rightMeters; this->rightPanel = rightMeters;
this->scr = scr; this->scr = scr;
super->eventHandler = AvailableMetersPanel_eventHandler;
Panel_setHeader(super, "Available meters"); Panel_setHeader(super, "Available meters");
for (int i = 1; Meter_types[i]; i++) { for (int i = 1; Meter_types[i]; i++) {
MeterType* type = Meter_types[i]; MeterClass* type = Meter_types[i];
if (type != &CPUMeter) { if (type != &CPUMeter_class) {
Panel_add(super, (Object*) ListItem_new(type->uiName, i << 16)); Panel_add(super, (Object*) ListItem_new(type->uiName, i << 16));
} }
} }
MeterType* type = &CPUMeter; MeterClass* type = &CPUMeter_class;
int cpus = settings->pl->cpuCount; int cpus = settings->pl->cpuCount;
if (cpus > 1) { if (cpus > 1) {
Panel_add(super, (Object*) ListItem_new("CPU average", 0)); Panel_add(super, (Object*) ListItem_new("CPU average", 0));

View File

@ -23,6 +23,8 @@ typedef struct AvailableMetersPanel_ {
} AvailableMetersPanel; } AvailableMetersPanel;
extern PanelClass AvailableMetersPanel_class;
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr); AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr);
#endif #endif

View File

@ -328,10 +328,13 @@ static void BatteryMeter_setValues(Meter * this, char *buffer, int len) {
return; return;
} }
MeterType BatteryMeter = { MeterClass BatteryMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete
},
.setValues = BatteryMeter_setValues, .setValues = BatteryMeter_setValues,
.display = NULL, .defaultMode = TEXT_METERMODE,
.mode = TEXT_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = BatteryMeter_attributes, .attributes = BatteryMeter_attributes,

View File

@ -22,6 +22,6 @@ typedef enum ACPresence_ {
extern int BatteryMeter_attributes[]; extern int BatteryMeter_attributes[];
extern MeterType BatteryMeter; extern MeterClass BatteryMeter_class;
#endif #endif

View File

@ -61,13 +61,13 @@ static void CPUMeter_setValues(Meter* this, char* buffer, int size) {
this->values[5] = cpuData->ioWaitPeriod / total * 100.0; this->values[5] = cpuData->ioWaitPeriod / total * 100.0;
this->values[6] = cpuData->stealPeriod / total * 100.0; this->values[6] = cpuData->stealPeriod / total * 100.0;
this->values[7] = cpuData->guestPeriod / total * 100.0; this->values[7] = cpuData->guestPeriod / total * 100.0;
this->type->items = 8; Meter_setItems(this, 8);
percent = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+ percent = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+
this->values[3]+this->values[4]))); this->values[3]+this->values[4])));
} else { } else {
this->values[2] = cpuData->systemAllPeriod / total * 100.0; this->values[2] = cpuData->systemAllPeriod / total * 100.0;
this->values[3] = (cpuData->stealPeriod + cpuData->guestPeriod) / total * 100.0; this->values[3] = (cpuData->stealPeriod + cpuData->guestPeriod) / total * 100.0;
this->type->items = 4; Meter_setItems(this, 4);
percent = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+this->values[3]))); percent = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+this->values[3])));
} }
if (isnan(percent)) percent = 0.0; if (isnan(percent)) percent = 0.0;
@ -126,7 +126,7 @@ static void CPUMeter_display(Object* cast, RichString* out) {
static void AllCPUsMeter_getRange(Meter* this, int* start, int* count) { static void AllCPUsMeter_getRange(Meter* this, int* start, int* count) {
int cpus = this->pl->cpuCount; int cpus = this->pl->cpuCount;
switch(this->type->name[0]) { switch(Meter_name(this)[0]) {
default: default:
case 'A': // All case 'A': // All
*start = 0; *start = 0;
@ -152,13 +152,13 @@ static void AllCPUsMeter_init(Meter* this) {
AllCPUsMeter_getRange(this, &start, &count); AllCPUsMeter_getRange(this, &start, &count);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
if (!meters[i]) if (!meters[i])
meters[i] = Meter_new(this->pl, start+i+1, &CPUMeter); meters[i] = Meter_new(this->pl, start+i+1, (MeterClass*) Class(CPUMeter));
meters[i]->type->init(meters[i]); Meter_init(meters[i]);
} }
if (this->mode == 0) if (this->mode == 0)
this->mode = BAR_METERMODE; this->mode = BAR_METERMODE;
int h = Meter_modes[this->mode]->h; int h = Meter_modes[this->mode]->h;
if (strchr(this->type->name, '2')) if (strchr(Meter_name(this), '2'))
this->h = h * ((count+1) / 2); this->h = h * ((count+1) / 2);
else else
this->h = h * count; this->h = h * count;
@ -172,7 +172,7 @@ static void AllCPUsMeter_done(Meter* this) {
Meter_delete((Object*)meters[i]); Meter_delete((Object*)meters[i]);
} }
static void AllCPUsMeter_setMode(Meter* this, int mode) { static void AllCPUsMeter_updateMode(Meter* this, int mode) {
Meter** meters = (Meter**) this->drawData; Meter** meters = (Meter**) this->drawData;
this->mode = mode; this->mode = mode;
int h = Meter_modes[mode]->h; int h = Meter_modes[mode]->h;
@ -181,7 +181,7 @@ static void AllCPUsMeter_setMode(Meter* this, int mode) {
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
Meter_setMode(meters[i], mode); Meter_setMode(meters[i], mode);
} }
if (strchr(this->type->name, '2')) if (strchr(Meter_name(this), '2'))
this->h = h * ((count+1) / 2); this->h = h * ((count+1) / 2);
else else
this->h = h * count; this->h = h * count;
@ -214,10 +214,14 @@ static void SingleColCPUsMeter_draw(Meter* this, int x, int y, int w) {
} }
} }
MeterType CPUMeter = { MeterClass CPUMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.setValues = CPUMeter_setValues, .setValues = CPUMeter_setValues,
.display = CPUMeter_display, .defaultMode = BAR_METERMODE,
.mode = BAR_METERMODE,
.items = 8, .items = 8,
.total = 100.0, .total = 100.0,
.attributes = CPUMeter_attributes, .attributes = CPUMeter_attributes,
@ -227,8 +231,13 @@ MeterType CPUMeter = {
.init = CPUMeter_init .init = CPUMeter_init
}; };
MeterType AllCPUsMeter = { MeterClass AllCPUsMeter_class = {
.mode = 0, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = CPUMeter_attributes, .attributes = CPUMeter_attributes,
@ -237,12 +246,17 @@ MeterType AllCPUsMeter = {
.caption = "CPU", .caption = "CPU",
.draw = SingleColCPUsMeter_draw, .draw = SingleColCPUsMeter_draw,
.init = AllCPUsMeter_init, .init = AllCPUsMeter_init,
.setMode = AllCPUsMeter_setMode, .updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done .done = AllCPUsMeter_done
}; };
MeterType AllCPUs2Meter = { MeterClass AllCPUs2Meter_class = {
.mode = 0, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = CPUMeter_attributes, .attributes = CPUMeter_attributes,
@ -251,12 +265,17 @@ MeterType AllCPUs2Meter = {
.caption = "CPU", .caption = "CPU",
.draw = DualColCPUsMeter_draw, .draw = DualColCPUsMeter_draw,
.init = AllCPUsMeter_init, .init = AllCPUsMeter_init,
.setMode = AllCPUsMeter_setMode, .updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done .done = AllCPUsMeter_done
}; };
MeterType LeftCPUsMeter = { MeterClass LeftCPUsMeter_class = {
.mode = 0, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = CPUMeter_attributes, .attributes = CPUMeter_attributes,
@ -265,12 +284,17 @@ MeterType LeftCPUsMeter = {
.caption = "CPU", .caption = "CPU",
.draw = SingleColCPUsMeter_draw, .draw = SingleColCPUsMeter_draw,
.init = AllCPUsMeter_init, .init = AllCPUsMeter_init,
.setMode = AllCPUsMeter_setMode, .updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done .done = AllCPUsMeter_done
}; };
MeterType RightCPUsMeter = { MeterClass RightCPUsMeter_class = {
.mode = 0, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = CPUMeter_attributes, .attributes = CPUMeter_attributes,
@ -279,12 +303,17 @@ MeterType RightCPUsMeter = {
.caption = "CPU", .caption = "CPU",
.draw = SingleColCPUsMeter_draw, .draw = SingleColCPUsMeter_draw,
.init = AllCPUsMeter_init, .init = AllCPUsMeter_init,
.setMode = AllCPUsMeter_setMode, .updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done .done = AllCPUsMeter_done
}; };
MeterType LeftCPUs2Meter = { MeterClass LeftCPUs2Meter_class = {
.mode = 0, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = CPUMeter_attributes, .attributes = CPUMeter_attributes,
@ -293,12 +322,17 @@ MeterType LeftCPUs2Meter = {
.caption = "CPU", .caption = "CPU",
.draw = DualColCPUsMeter_draw, .draw = DualColCPUsMeter_draw,
.init = AllCPUsMeter_init, .init = AllCPUsMeter_init,
.setMode = AllCPUsMeter_setMode, .updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done .done = AllCPUsMeter_done
}; };
MeterType RightCPUs2Meter = { MeterClass RightCPUs2Meter_class = {
.mode = 0, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = CPUMeter_attributes, .attributes = CPUMeter_attributes,
@ -307,7 +341,7 @@ MeterType RightCPUs2Meter = {
.caption = "CPU", .caption = "CPU",
.draw = DualColCPUsMeter_draw, .draw = DualColCPUsMeter_draw,
.init = AllCPUsMeter_init, .init = AllCPUsMeter_init,
.setMode = AllCPUsMeter_setMode, .updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done .done = AllCPUsMeter_done
}; };

View File

@ -20,19 +20,19 @@ extern int CPUMeter_attributes[];
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
extern MeterType CPUMeter; extern MeterClass CPUMeter_class;
extern MeterType AllCPUsMeter; extern MeterClass AllCPUsMeter_class;
extern MeterType AllCPUs2Meter; extern MeterClass AllCPUs2Meter_class;
extern MeterType LeftCPUsMeter; extern MeterClass LeftCPUsMeter_class;
extern MeterType RightCPUsMeter; extern MeterClass RightCPUsMeter_class;
extern MeterType LeftCPUs2Meter; extern MeterClass LeftCPUs2Meter_class;
extern MeterType RightCPUs2Meter; extern MeterClass RightCPUs2Meter_class;
#endif #endif

10
CRT.c
View File

@ -112,10 +112,12 @@ typedef enum ColorElements_ {
static bool CRT_hasColors; static bool CRT_hasColors;
int CRT_delay = 0; static int CRT_delay = 0;
int CRT_colorScheme = 0; int CRT_colorScheme = 0;
bool CRT_utf8 = false;
int CRT_colors[LAST_COLORELEMENT] = { 0 }; int CRT_colors[LAST_COLORELEMENT] = { 0 };
int CRT_cursorX = 0; int CRT_cursorX = 0;
@ -158,7 +160,7 @@ void CRT_init(int delay, int colorScheme) {
noecho(); noecho();
CRT_delay = delay; CRT_delay = delay;
CRT_colorScheme = colorScheme; CRT_colorScheme = colorScheme;
halfdelay(CRT_delay); halfdelay(CRT_delay/2);
nonl(); nonl();
intrflush(stdscr, false); intrflush(stdscr, false);
keypad(stdscr, true); keypad(stdscr, true);
@ -212,7 +214,7 @@ int CRT_readKey() {
cbreak(); cbreak();
nodelay(stdscr, FALSE); nodelay(stdscr, FALSE);
int ret = getch(); int ret = getch();
halfdelay(CRT_delay); halfdelay(CRT_delay/2);
return ret; return ret;
} }
@ -223,7 +225,7 @@ void CRT_disableDelay() {
} }
void CRT_enableDelay() { void CRT_enableDelay() {
halfdelay(CRT_delay); halfdelay(CRT_delay/2);
} }
void CRT_setColors(int colorScheme) { void CRT_setColors(int colorScheme) {

4
CRT.h
View File

@ -101,10 +101,10 @@ typedef enum ColorElements_ {
// TODO: centralize these in Settings. // TODO: centralize these in Settings.
extern int CRT_delay;
extern int CRT_colorScheme; extern int CRT_colorScheme;
extern bool CRT_utf8;
extern int CRT_colors[LAST_COLORELEMENT]; extern int CRT_colors[LAST_COLORELEMENT];
extern int CRT_cursorX; extern int CRT_cursorX;

View File

@ -132,15 +132,21 @@ static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
return result; return result;
} }
PanelClass CategoriesPanel_class = {
.super = {
.extends = Class(Panel),
.delete = CategoriesPanel_delete
},
.eventHandler = CategoriesPanel_eventHandler
};
CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr) { CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr) {
CategoriesPanel* this = (CategoriesPanel*) malloc(sizeof(CategoriesPanel)); CategoriesPanel* this = AllocThis(CategoriesPanel);
Panel* super = (Panel*) this; Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true); Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
((Object*)this)->delete = CategoriesPanel_delete;
this->settings = settings; this->settings = settings;
this->scr = scr; this->scr = scr;
super->eventHandler = CategoriesPanel_eventHandler;
Panel_setHeader(super, "Setup"); Panel_setHeader(super, "Setup");
Panel_add(super, (Object*) ListItem_new("Meters", 0)); Panel_add(super, (Object*) ListItem_new("Meters", 0));
Panel_add(super, (Object*) ListItem_new("Display options", 0)); Panel_add(super, (Object*) ListItem_new("Display options", 0));

View File

@ -23,6 +23,8 @@ typedef struct CategoriesPanel_ {
void CategoriesPanel_makeMetersPage(CategoriesPanel* this); void CategoriesPanel_makeMetersPage(CategoriesPanel* this);
extern PanelClass CategoriesPanel_class;
CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr); CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr);
#endif #endif

View File

@ -24,12 +24,6 @@ typedef struct CheckItem_ {
}*/ }*/
#ifdef DEBUG
char* CHECKITEM_CLASS = "CheckItem";
#else
#define CHECKITEM_CLASS NULL
#endif
static void CheckItem_delete(Object* cast) { static void CheckItem_delete(Object* cast) {
CheckItem* this = (CheckItem*)cast; CheckItem* this = (CheckItem*)cast;
assert (this != NULL); assert (this != NULL);
@ -50,11 +44,13 @@ static void CheckItem_display(Object* cast, RichString* out) {
RichString_append(out, CRT_colors[CHECK_TEXT], this->text); RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
} }
ObjectClass CheckItem_class = {
.display = CheckItem_display,
.delete = CheckItem_delete
};
CheckItem* CheckItem_new(char* text, bool* ref, bool value) { CheckItem* CheckItem_new(char* text, bool* ref, bool value) {
CheckItem* this = malloc(sizeof(CheckItem)); CheckItem* this = AllocThis(CheckItem);
Object_setClass(this, CHECKITEM_CLASS);
((Object*)this)->display = CheckItem_display;
((Object*)this)->delete = CheckItem_delete;
this->text = text; this->text = text;
this->value = value; this->value = value;
this->ref = ref; this->ref = ref;

View File

@ -19,11 +19,7 @@ typedef struct CheckItem_ {
} CheckItem; } CheckItem;
#ifdef DEBUG extern ObjectClass CheckItem_class;
extern char* CHECKITEM_CLASS;
#else
#define CHECKITEM_CLASS NULL
#endif
CheckItem* CheckItem_new(char* text, bool* ref, bool value); CheckItem* CheckItem_new(char* text, bool* ref, bool value);

View File

@ -26,10 +26,13 @@ static void ClockMeter_setValues(Meter* this, char* buffer, int size) {
strftime(buffer, size, "%H:%M:%S", lt); strftime(buffer, size, "%H:%M:%S", lt);
} }
MeterType ClockMeter = { MeterClass ClockMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete
},
.setValues = ClockMeter_setValues, .setValues = ClockMeter_setValues,
.display = NULL, .defaultMode = TEXT_METERMODE,
.mode = TEXT_METERMODE,
.total = 100.0, .total = 100.0,
.items = 1, .items = 1,
.attributes = ClockMeter_attributes, .attributes = ClockMeter_attributes,

View File

@ -13,6 +13,6 @@ in the source distribution for its full text.
extern int ClockMeter_attributes[]; extern int ClockMeter_attributes[];
extern MeterType ClockMeter; extern MeterClass ClockMeter_class;
#endif #endif

View File

@ -51,7 +51,7 @@ static void ColorsPanel_delete(Object* object) {
free(this); free(this);
} }
static HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) { static HandlerResult ColorsPanel_eventHandler(Panel* super, int ch) {
ColorsPanel* this = (ColorsPanel*) super; ColorsPanel* this = (ColorsPanel*) super;
HandlerResult result = IGNORED; HandlerResult result = IGNORED;
@ -83,15 +83,21 @@ static HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
return result; return result;
} }
PanelClass ColorsPanel_class = {
.super = {
.extends = Class(Panel),
.delete = ColorsPanel_delete
},
.eventHandler = ColorsPanel_eventHandler
};
ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr) { ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr) {
ColorsPanel* this = (ColorsPanel*) malloc(sizeof(ColorsPanel)); ColorsPanel* this = AllocThis(ColorsPanel);
Panel* super = (Panel*) this; Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true); Panel_init(super, 1, 1, 1, 1, Class(CheckItem), true);
((Object*)this)->delete = ColorsPanel_delete;
this->settings = settings; this->settings = settings;
this->scr = scr; this->scr = scr;
super->eventHandler = ColorsPanel_EventHandler;
Panel_setHeader(super, "Colors"); Panel_setHeader(super, "Colors");
for (int i = 0; ColorSchemes[i] != NULL; i++) { for (int i = 0; ColorSchemes[i] != NULL; i++) {

View File

@ -27,6 +27,8 @@ typedef struct ColorsPanel_ {
} ColorsPanel; } ColorsPanel;
extern PanelClass ColorsPanel_class;
ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr); ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr);
#endif #endif

View File

@ -82,15 +82,21 @@ static HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch) {
return result; return result;
} }
PanelClass ColumnsPanel_class = {
.super = {
.extends = Class(Panel),
.delete = ColumnsPanel_delete
},
.eventHandler = ColumnsPanel_eventHandler
};
ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr) { ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr) {
ColumnsPanel* this = (ColumnsPanel*) malloc(sizeof(ColumnsPanel)); ColumnsPanel* this = AllocThis(ColumnsPanel);
Panel* super = (Panel*) this; Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true); Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
((Object*)this)->delete = ColumnsPanel_delete;
this->settings = settings; this->settings = settings;
this->scr = scr; this->scr = scr;
super->eventHandler = ColumnsPanel_eventHandler;
Panel_setHeader(super, "Active Columns"); Panel_setHeader(super, "Active Columns");
ProcessField* fields = this->settings->pl->fields; ProcessField* fields = this->settings->pl->fields;

View File

@ -21,6 +21,8 @@ typedef struct ColumnsPanel_ {
} ColumnsPanel; } ColumnsPanel;
extern PanelClass ColumnsPanel_class;
ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr); ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr);
int ColumnsPanel_fieldNameToIndex(const char* name); int ColumnsPanel_fieldNameToIndex(const char* name);

View File

@ -61,15 +61,21 @@ static HandlerResult DisplayOptionsPanel_eventHandler(Panel* super, int ch) {
return result; return result;
} }
PanelClass DisplayOptionsPanel_class = {
.super = {
.extends = Class(Panel),
.delete = DisplayOptionsPanel_delete
},
.eventHandler = DisplayOptionsPanel_eventHandler
};
DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr) { DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr) {
DisplayOptionsPanel* this = (DisplayOptionsPanel*) malloc(sizeof(DisplayOptionsPanel)); DisplayOptionsPanel* this = AllocThis(DisplayOptionsPanel);
Panel* super = (Panel*) this; Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true); Panel_init(super, 1, 1, 1, 1, Class(CheckItem), true);
((Object*)this)->delete = DisplayOptionsPanel_delete;
this->settings = settings; this->settings = settings;
this->scr = scr; this->scr = scr;
super->eventHandler = DisplayOptionsPanel_eventHandler;
Panel_setHeader(super, "Display options"); Panel_setHeader(super, "Display options");
Panel_add(super, (Object*) CheckItem_new(strdup("Tree view"), &(settings->pl->treeView), false)); Panel_add(super, (Object*) CheckItem_new(strdup("Tree view"), &(settings->pl->treeView), false));

View File

@ -21,6 +21,8 @@ typedef struct DisplayOptionsPanel_ {
} DisplayOptionsPanel; } DisplayOptionsPanel;
extern PanelClass DisplayOptionsPanel_class;
DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr); DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr);
#endif #endif

View File

@ -29,22 +29,18 @@ typedef struct FunctionBar_ {
}*/ }*/
#ifdef DEBUG
char* FUNCTIONBAR_CLASS = "FunctionBar";
#else
#define FUNCTIONBAR_CLASS NULL
#endif
static const char* FunctionBar_FKeys[] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", NULL}; static const char* FunctionBar_FKeys[] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", NULL};
static const char* FunctionBar_FLabels[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", NULL}; static const char* FunctionBar_FLabels[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", NULL};
static int FunctionBar_FEvents[] = {KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10)}; static int FunctionBar_FEvents[] = {KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10)};
ObjectClass FunctionBar_class = {
.delete = FunctionBar_delete
};
FunctionBar* FunctionBar_new(const char** functions, const char** keys, int* events) { FunctionBar* FunctionBar_new(const char** functions, const char** keys, int* events) {
FunctionBar* this = malloc(sizeof(FunctionBar)); FunctionBar* this = AllocThis(FunctionBar);
Object_setClass(this, FUNCTIONBAR_CLASS);
((Object*) this)->delete = FunctionBar_delete;
this->functions = (char**) functions; this->functions = (char**) functions;
if (keys && events) { if (keys && events) {
this->staticData = false; this->staticData = false;

View File

@ -21,11 +21,7 @@ typedef struct FunctionBar_ {
} FunctionBar; } FunctionBar;
#ifdef DEBUG extern ObjectClass FunctionBar_class;
extern char* FUNCTIONBAR_CLASS;
#else
#define FUNCTIONBAR_CLASS NULL
#endif
FunctionBar* FunctionBar_new(const char** functions, const char** keys, int* events); FunctionBar* FunctionBar_new(const char** functions, const char** keys, int* events);

View File

@ -50,8 +50,8 @@ typedef struct Header_ {
Header* Header_new(ProcessList* pl) { Header* Header_new(ProcessList* pl) {
Header* this = calloc(sizeof(Header), 1); Header* this = calloc(sizeof(Header), 1);
this->leftMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE, NULL); this->leftMeters = Vector_new(Class(Meter), true, DEFAULT_SIZE);
this->rightMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE, NULL); this->rightMeters = Vector_new(Class(Meter), true, DEFAULT_SIZE);
this->margin = true; this->margin = true;
this->pl = pl; this->pl = pl;
return this; return this;
@ -75,7 +75,7 @@ void Header_createMeter(Header* this, char* name, HeaderSide side) {
if (!ok) param = 0; if (!ok) param = 0;
*paren = '\0'; *paren = '\0';
} }
for (MeterType** type = Meter_types; *type; type++) { for (MeterClass** type = Meter_types; *type; type++) {
if (String_eq(name, (*type)->name)) { if (String_eq(name, (*type)->name)) {
Vector_add(meters, Meter_new(this->pl, param, *type)); Vector_add(meters, Meter_new(this->pl, param, *type));
break; break;
@ -94,7 +94,7 @@ void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side) {
Meter_setMode(meter, mode); Meter_setMode(meter, mode);
} }
Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side) { Meter* Header_addMeter(Header* this, MeterClass* type, int param, HeaderSide side) {
Vector* meters = side == LEFT_HEADER Vector* meters = side == LEFT_HEADER
? this->leftMeters ? this->leftMeters
: this->rightMeters; : this->rightMeters;
@ -118,10 +118,10 @@ char* Header_readMeterName(Header* this, int i, HeaderSide side) {
: this->rightMeters; : this->rightMeters;
Meter* meter = (Meter*) Vector_get(meters, i); Meter* meter = (Meter*) Vector_get(meters, i);
int nameLen = strlen(meter->type->name); int nameLen = strlen(Meter_name(meter));
int len = nameLen + 100; int len = nameLen + 100;
char* name = malloc(len); char* name = malloc(len);
strncpy(name, meter->type->name, nameLen); strncpy(name, Meter_name(meter), nameLen);
name[nameLen] = '\0'; name[nameLen] = '\0';
if (meter->param) if (meter->param)
snprintf(name + nameLen, len - nameLen, "(%d)", meter->param); snprintf(name + nameLen, len - nameLen, "(%d)", meter->param);
@ -140,38 +140,37 @@ MeterModeId Header_readMeterMode(Header* this, int i, HeaderSide side) {
void Header_defaultMeters(Header* this, int cpuCount) { void Header_defaultMeters(Header* this, int cpuCount) {
if (cpuCount > 8) { if (cpuCount > 8) {
Vector_add(this->leftMeters, Meter_new(this->pl, 0, &LeftCPUs2Meter)); Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(LeftCPUs2Meter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, &RightCPUs2Meter)); Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(RightCPUs2Meter)));
} else if (cpuCount > 4) { } else if (cpuCount > 4) {
Vector_add(this->leftMeters, Meter_new(this->pl, 0, &LeftCPUsMeter)); Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(LeftCPUsMeter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, &RightCPUsMeter)); Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(RightCPUsMeter)));
} else { } else {
Vector_add(this->leftMeters, Meter_new(this->pl, 0, &AllCPUsMeter)); Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(AllCPUsMeter)));
} }
Vector_add(this->leftMeters, Meter_new(this->pl, 0, &MemoryMeter)); Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(MemoryMeter)));
Vector_add(this->leftMeters, Meter_new(this->pl, 0, &SwapMeter)); Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(SwapMeter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, &TasksMeter)); Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(TasksMeter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, &LoadAverageMeter)); Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(LoadAverageMeter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, &UptimeMeter)); Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(UptimeMeter)));
} }
void Header_reinit(Header* this) { void Header_reinit(Header* this) {
for (int i = 0; i < Vector_size(this->leftMeters); i++) { for (int i = 0; i < Vector_size(this->leftMeters); i++) {
Meter* meter = (Meter*) Vector_get(this->leftMeters, i); Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
if (meter->type->init) if (Meter_initFn(meter))
meter->type->init(meter); Meter_init(meter);
} }
for (int i = 0; i < Vector_size(this->rightMeters); i++) { for (int i = 0; i < Vector_size(this->rightMeters); i++) {
Meter* meter = (Meter*) Vector_get(this->rightMeters, i); Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
if (meter->type->init) if (Meter_initFn(meter))
meter->type->init(meter); Meter_init(meter);
} }
} }
void Header_draw(const Header* this) { void Header_draw(const Header* this) {
int height = this->height; int height = this->height;
int pad = this->pad; int pad = this->pad;
attrset(CRT_colors[RESET_COLOR]); attrset(CRT_colors[RESET_COLOR]);
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
mvhline(y, 0, ' ', COLS); mvhline(y, 0, ' ', COLS);

View File

@ -39,7 +39,7 @@ void Header_createMeter(Header* this, char* name, HeaderSide side);
void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side); void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side);
Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side); Meter* Header_addMeter(Header* this, MeterClass* type, int param, HeaderSide side);
int Header_size(Header* this, HeaderSide side); int Header_size(Header* this, HeaderSide side);

View File

@ -24,10 +24,13 @@ static void HostnameMeter_setValues(Meter* this, char* buffer, int size) {
gethostname(buffer, size-1); gethostname(buffer, size-1);
} }
MeterType HostnameMeter = { MeterClass HostnameMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete
},
.setValues = HostnameMeter_setValues, .setValues = HostnameMeter_setValues,
.display = NULL, .defaultMode = TEXT_METERMODE,
.mode = TEXT_METERMODE,
.total = 100.0, .total = 100.0,
.items = 1, .items = 1,
.attributes = HostnameMeter_attributes, .attributes = HostnameMeter_attributes,

View File

@ -13,6 +13,6 @@ in the source distribution for its full text.
extern int HostnameMeter_attributes[]; extern int HostnameMeter_attributes[];
extern MeterType HostnameMeter; extern MeterClass HostnameMeter_class;
#endif #endif

View File

@ -14,7 +14,7 @@ in the source distribution for its full text.
}*/ }*/
Panel* IOPriorityPanel_new(IOPriority currPrio) { Panel* IOPriorityPanel_new(IOPriority currPrio) {
Panel* this = Panel_new(1, 1, 1, 1, LISTITEM_CLASS, true, ListItem_compare); Panel* this = Panel_new(1, 1, 1, 1, true, Class(ListItem));
Panel_setHeader(this, "IO Priority:"); Panel_setHeader(this, "IO Priority:");
Panel_add(this, (Object*) ListItem_new("None (based on nice)", IOPriority_None)); Panel_add(this, (Object*) ListItem_new("None (based on nice)", IOPriority_None));

View File

@ -26,12 +26,6 @@ typedef struct ListItem_ {
}*/ }*/
#ifdef DEBUG
char* LISTITEM_CLASS = "ListItem";
#else
#define LISTITEM_CLASS NULL
#endif
static void ListItem_delete(Object* cast) { static void ListItem_delete(Object* cast) {
ListItem* this = (ListItem*)cast; ListItem* this = (ListItem*)cast;
free(this->value); free(this->value);
@ -49,11 +43,13 @@ static void ListItem_display(Object* cast, RichString* out) {
RichString_write(out, CRT_colors[DEFAULT_COLOR], this->value/*buffer*/); RichString_write(out, CRT_colors[DEFAULT_COLOR], this->value/*buffer*/);
} }
ObjectClass ListItem_class = {
.display = ListItem_display,
.delete = ListItem_delete
};
ListItem* ListItem_new(const char* value, int key) { ListItem* ListItem_new(const char* value, int key) {
ListItem* this = malloc(sizeof(ListItem)); ListItem* this = AllocThis(ListItem);
Object_setClass(this, LISTITEM_CLASS);
((Object*)this)->display = ListItem_display;
((Object*)this)->delete = ListItem_delete;
this->value = strdup(value); this->value = strdup(value);
this->key = key; this->key = key;
return this; return this;

View File

@ -18,11 +18,7 @@ typedef struct ListItem_ {
} ListItem; } ListItem;
#ifdef DEBUG extern ObjectClass ListItem_class;
extern char* LISTITEM_CLASS;
#else
#define LISTITEM_CLASS NULL
#endif
ListItem* ListItem_new(const char* value, int key); ListItem* ListItem_new(const char* value, int key);

View File

@ -67,10 +67,14 @@ static void LoadMeter_display(Object* cast, RichString* out) {
RichString_write(out, CRT_colors[LOAD], buffer); RichString_write(out, CRT_colors[LOAD], buffer);
} }
MeterType LoadAverageMeter = { MeterClass LoadAverageMeter_class = {
.setValues = LoadAverageMeter_setValues, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = LoadAverageMeter_display, .display = LoadAverageMeter_display,
.mode = TEXT_METERMODE, },
.setValues = LoadAverageMeter_setValues,
.defaultMode = TEXT_METERMODE,
.items = 3, .items = 3,
.total = 100.0, .total = 100.0,
.attributes = LoadAverageMeter_attributes, .attributes = LoadAverageMeter_attributes,
@ -79,10 +83,14 @@ MeterType LoadAverageMeter = {
.caption = "Load average: " .caption = "Load average: "
}; };
MeterType LoadMeter = { MeterClass LoadMeter_class = {
.setValues = LoadMeter_setValues, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = LoadMeter_display, .display = LoadMeter_display,
.mode = TEXT_METERMODE, },
.setValues = LoadMeter_setValues,
.defaultMode = TEXT_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = LoadMeter_attributes, .attributes = LoadMeter_attributes,

View File

@ -15,8 +15,8 @@ extern int LoadAverageMeter_attributes[];
extern int LoadMeter_attributes[]; extern int LoadMeter_attributes[];
extern MeterType LoadAverageMeter; extern MeterClass LoadAverageMeter_class;
extern MeterType LoadMeter; extern MeterClass LoadMeter_class;
#endif #endif

View File

@ -59,10 +59,14 @@ static void MemoryMeter_display(Object* cast, RichString* out) {
RichString_append(out, CRT_colors[MEMORY_CACHE], buffer); RichString_append(out, CRT_colors[MEMORY_CACHE], buffer);
} }
MeterType MemoryMeter = { MeterClass MemoryMeter_class = {
.setValues = MemoryMeter_setValues, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = MemoryMeter_display, .display = MemoryMeter_display,
.mode = BAR_METERMODE, },
.setValues = MemoryMeter_setValues,
.defaultMode = BAR_METERMODE,
.items = 3, .items = 3,
.total = 100.0, .total = 100.0,
.attributes = MemoryMeter_attributes, .attributes = MemoryMeter_attributes,

View File

@ -13,6 +13,6 @@ in the source distribution for its full text.
extern int MemoryMeter_attributes[]; extern int MemoryMeter_attributes[];
extern MeterType MemoryMeter; extern MeterClass MemoryMeter_class;
#endif #endif

221
Meter.c
View File

@ -21,17 +21,14 @@ in the source distribution for its full text.
#include "CRT.h" #include "CRT.h"
#include "String.h" #include "String.h"
#include "ListItem.h" #include "ListItem.h"
#include "Settings.h"
#include <math.h> #include <math.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <assert.h> #include <assert.h>
#include <time.h> #include <sys/time.h>
#ifndef USE_FUNKY_MODES
#define USE_FUNKY_MODES 1
#endif
#define METER_BUFFER_LEN 128 #define METER_BUFFER_LEN 128
@ -40,44 +37,52 @@ in the source distribution for its full text.
#include "ProcessList.h" #include "ProcessList.h"
typedef struct Meter_ Meter; typedef struct Meter_ Meter;
typedef struct MeterType_ MeterType;
typedef struct MeterMode_ MeterMode;
typedef void(*MeterType_Init)(Meter*); typedef void(*Meter_Init)(Meter*);
typedef void(*MeterType_Done)(Meter*); typedef void(*Meter_Done)(Meter*);
typedef void(*MeterType_SetMode)(Meter*, int); typedef void(*Meter_UpdateMode)(Meter*, int);
typedef void(*Meter_SetValues)(Meter*, char*, int); typedef void(*Meter_SetValues)(Meter*, char*, int);
typedef void(*Meter_Draw)(Meter*, int, int, int); typedef void(*Meter_Draw)(Meter*, int, int, int);
struct MeterMode_ { typedef struct MeterClass_ {
Meter_Draw draw; ObjectClass super;
const char* uiName; const Meter_Init init;
int h; const Meter_Done done;
}; const Meter_UpdateMode updateMode;
const Meter_Draw draw;
struct MeterType_ { const Meter_SetValues setValues;
Meter_SetValues setValues; const int defaultMode;
Object_Display display;
int mode;
int items; int items;
double total; const double total;
int* attributes; const int* attributes;
const char* name; const char* name;
const char* uiName; const char* uiName;
const char* caption; const char* caption;
MeterType_Init init; } MeterClass;
MeterType_Done done;
MeterType_SetMode setMode; #define As_Meter(this_) ((MeterClass*)((this_)->super.klass))
Meter_Draw draw; #define Meter_initFn(this_) As_Meter(this_)->init
}; #define Meter_init(this_) As_Meter(this_)->init((Meter*)(this_))
#define Meter_done(this_) As_Meter(this_)->done((Meter*)(this_))
#define Meter_updateModeFn(this_) As_Meter(this_)->updateMode
#define Meter_updateMode(this_, m_) As_Meter(this_)->updateMode((Meter*)(this_), m_)
#define Meter_drawFn(this_) As_Meter(this_)->draw
#define Meter_doneFn(this_) As_Meter(this_)->done
#define Meter_setValues(this_, c_, i_) As_Meter(this_)->setValues((Meter*)(this_), c_, i_)
#define Meter_defaultMode(this_) As_Meter(this_)->defaultMode
#define Meter_getItems(this_) As_Meter(this_)->items
#define Meter_setItems(this_, n_) As_Meter(this_)->items = (n_)
#define Meter_attributes(this_) As_Meter(this_)->attributes
#define Meter_name(this_) As_Meter(this_)->name
#define Meter_uiName(this_) As_Meter(this_)->uiName
struct Meter_ { struct Meter_ {
Object super; Object super;
Meter_Draw draw;
char* caption; char* caption;
MeterType* type;
int mode; int mode;
int param; int param;
Meter_Draw draw;
void* drawData; void* drawData;
int h; int h;
ProcessList* pl; ProcessList* pl;
@ -85,24 +90,26 @@ struct Meter_ {
double total; double total;
}; };
#ifdef USE_FUNKY_MODES typedef struct MeterMode_ {
typedef struct GraphData_ { Meter_Draw draw;
time_t time; const char* uiName;
double values[METER_BUFFER_LEN]; int h;
} GraphData; } MeterMode;
#endif
typedef enum { typedef enum {
CUSTOM_METERMODE = 0, CUSTOM_METERMODE = 0,
BAR_METERMODE, BAR_METERMODE,
TEXT_METERMODE, TEXT_METERMODE,
#ifdef USE_FUNKY_MODES
GRAPH_METERMODE, GRAPH_METERMODE,
LED_METERMODE, LED_METERMODE,
#endif
LAST_METERMODE LAST_METERMODE
} MeterModeId; } MeterModeId;
typedef struct GraphData_ {
struct timeval time;
double values[METER_BUFFER_LEN];
} GraphData;
}*/ }*/
#ifndef MIN #ifndef MIN
@ -112,47 +119,44 @@ typedef enum {
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
#ifdef DEBUG MeterClass Meter_class = {
char* METER_CLASS = "Meter"; .super = {
#else .extends = Class(Object)
#define METER_CLASS NULL }
#endif };
MeterType* Meter_types[] = { MeterClass* Meter_types[] = {
&CPUMeter, &CPUMeter_class,
&ClockMeter, &ClockMeter_class,
&LoadAverageMeter, &LoadAverageMeter_class,
&LoadMeter, &LoadMeter_class,
&MemoryMeter, &MemoryMeter_class,
&SwapMeter, &SwapMeter_class,
&TasksMeter, &TasksMeter_class,
&UptimeMeter, &UptimeMeter_class,
&BatteryMeter, &BatteryMeter_class,
&HostnameMeter, &HostnameMeter_class,
&AllCPUsMeter, &AllCPUsMeter_class,
&AllCPUs2Meter, &AllCPUs2Meter_class,
&LeftCPUsMeter, &LeftCPUsMeter_class,
&RightCPUsMeter, &RightCPUsMeter_class,
&LeftCPUs2Meter, &LeftCPUs2Meter_class,
&RightCPUs2Meter, &RightCPUs2Meter_class,
NULL NULL
}; };
Meter* Meter_new(ProcessList* pl, int param, MeterType* type) { Meter* Meter_new(ProcessList* pl, int param, MeterClass* type) {
Meter* this = calloc(sizeof(Meter), 1); Meter* this = calloc(sizeof(Meter), 1);
Object_setClass(this, METER_CLASS); Object_setClass(this, type);
((Object*)this)->delete = Meter_delete;
((Object*)this)->display = type->display;
this->h = 1; this->h = 1;
this->type = type;
this->param = param; this->param = param;
this->pl = pl; this->pl = pl;
this->values = calloc(sizeof(double), type->items); this->values = calloc(sizeof(double), type->items);
this->total = type->total; this->total = type->total;
this->caption = strdup(type->caption); this->caption = strdup(type->caption);
if (this->type->init) if (Meter_initFn(this))
this->type->init(this); Meter_init(this);
Meter_setMode(this, type->mode); Meter_setMode(this, type->defaultMode);
return this; return this;
} }
@ -160,8 +164,8 @@ void Meter_delete(Object* cast) {
if (!cast) if (!cast)
return; return;
Meter* this = (Meter*) cast; Meter* this = (Meter*) cast;
if (this->type->done) { if (Meter_doneFn(this)) {
this->type->done(this); Meter_done(this);
} }
if (this->drawData) if (this->drawData)
free(this->drawData); free(this->drawData);
@ -176,12 +180,10 @@ void Meter_setCaption(Meter* this, const char* caption) {
} }
static inline void Meter_displayBuffer(Meter* this, char* buffer, RichString* out) { static inline void Meter_displayBuffer(Meter* this, char* buffer, RichString* out) {
MeterType* type = this->type; if (Object_displayFn(this)) {
Object_Display display = ((Object*)this)->display; Object_display(this, out);
if (display) {
display((Object*)this, out);
} else { } else {
RichString_write(out, CRT_colors[type->attributes[0]], buffer); RichString_write(out, CRT_colors[Meter_attributes(this)[0]], buffer);
} }
} }
@ -191,10 +193,10 @@ void Meter_setMode(Meter* this, int modeIndex) {
if (!modeIndex) if (!modeIndex)
modeIndex = 1; modeIndex = 1;
assert(modeIndex < LAST_METERMODE); assert(modeIndex < LAST_METERMODE);
if (this->type->mode == 0) { if (Meter_defaultMode(this) == CUSTOM_METERMODE) {
this->draw = this->type->draw; this->draw = Meter_drawFn(this);
if (this->type->setMode) if (Meter_updateModeFn(this))
this->type->setMode(this, modeIndex); Meter_updateMode(this, modeIndex);
} else { } else {
assert(modeIndex >= 1); assert(modeIndex >= 1);
if (this->drawData) if (this->drawData)
@ -209,7 +211,6 @@ void Meter_setMode(Meter* this, int modeIndex) {
} }
ListItem* Meter_toListItem(Meter* this) { ListItem* Meter_toListItem(Meter* this) {
MeterType* type = this->type;
char mode[21]; char mode[21];
if (this->mode) if (this->mode)
snprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName); snprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName);
@ -221,16 +222,15 @@ ListItem* Meter_toListItem(Meter* this) {
else else
number[0] = '\0'; number[0] = '\0';
char buffer[51]; char buffer[51];
snprintf(buffer, 50, "%s%s%s", type->uiName, number, mode); snprintf(buffer, 50, "%s%s%s", Meter_uiName(this), number, mode);
return ListItem_new(buffer, 0); return ListItem_new(buffer, 0);
} }
/* ---------- TextMeterMode ---------- */ /* ---------- TextMeterMode ---------- */
static void TextMeterMode_draw(Meter* this, int x, int y, int w) { static void TextMeterMode_draw(Meter* this, int x, int y, int w) {
MeterType* type = this->type;
char buffer[METER_BUFFER_LEN]; char buffer[METER_BUFFER_LEN];
type->setValues(this, buffer, METER_BUFFER_LEN - 1); Meter_setValues(this, buffer, METER_BUFFER_LEN - 1);
attrset(CRT_colors[METER_TEXT]); attrset(CRT_colors[METER_TEXT]);
mvaddstr(y, x, this->caption); mvaddstr(y, x, this->caption);
@ -250,9 +250,8 @@ static void TextMeterMode_draw(Meter* this, int x, int y, int w) {
static char BarMeterMode_characters[] = "|#*@$%&"; static char BarMeterMode_characters[] = "|#*@$%&";
static void BarMeterMode_draw(Meter* this, int x, int y, int w) { static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
MeterType* type = this->type;
char buffer[METER_BUFFER_LEN]; char buffer[METER_BUFFER_LEN];
type->setValues(this, buffer, METER_BUFFER_LEN - 1); Meter_setValues(this, buffer, METER_BUFFER_LEN - 1);
w -= 2; w -= 2;
attrset(CRT_colors[METER_TEXT]); attrset(CRT_colors[METER_TEXT]);
@ -282,7 +281,8 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
// First draw in the bar[] buffer... // First draw in the bar[] buffer...
int offset = 0; int offset = 0;
for (int i = 0; i < type->items; i++) { int items = Meter_getItems(this);
for (int i = 0; i < items; i++) {
double value = this->values[i]; double value = this->values[i];
value = MAX(value, 0); value = MAX(value, 0);
value = MIN(value, this->total); value = MIN(value, this->total);
@ -307,8 +307,8 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
// ...then print the buffer. // ...then print the buffer.
offset = 0; offset = 0;
for (int i = 0; i < type->items; i++) { for (int i = 0; i < items; i++) {
attrset(CRT_colors[type->attributes[i]]); attrset(CRT_colors[Meter_attributes(this)[i]]);
mvaddnstr(y, x + offset, bar + offset, blockSizes[i]); mvaddnstr(y, x + offset, bar + offset, blockSizes[i]);
offset += blockSizes[i]; offset += blockSizes[i];
offset = MAX(offset, 0); offset = MAX(offset, 0);
@ -323,8 +323,6 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
attrset(CRT_colors[RESET_COLOR]); attrset(CRT_colors[RESET_COLOR]);
} }
#ifdef USE_FUNKY_MODES
/* ---------- GraphMeterMode ---------- */ /* ---------- GraphMeterMode ---------- */
#define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0) #define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0)
@ -347,19 +345,21 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
GraphData* data = (GraphData*) this->drawData; GraphData* data = (GraphData*) this->drawData;
const int nValues = METER_BUFFER_LEN; const int nValues = METER_BUFFER_LEN;
time_t now = time(NULL); struct timeval now;
if (now > data->time) { gettimeofday(&now, NULL);
data->time = now; if (!timercmp(&now, &(data->time), <)) {
struct timeval delay = { .tv_sec = (int)(DEFAULT_DELAY/10), .tv_usec = (DEFAULT_DELAY-((int)(DEFAULT_DELAY/10)*10)) * 100000 };
timeradd(&now, &delay, &(data->time));
for (int i = 0; i < nValues - 1; i++) for (int i = 0; i < nValues - 1; i++)
data->values[i] = data->values[i+1]; data->values[i] = data->values[i+1];
MeterType* type = this->type;
char buffer[nValues]; char buffer[nValues];
type->setValues(this, buffer, nValues - 1); Meter_setValues(this, buffer, nValues - 1);
double value = 0.0; double value = 0.0;
for (int i = 0; i < type->items; i++) int items = Meter_getItems(this);
for (int i = 0; i < items; i++)
value += this->values[i]; value += this->values[i];
value /= this->total; value /= this->total;
data->values[nValues - 1] = value; data->values[nValues - 1] = value;
@ -383,28 +383,39 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
/* ---------- LEDMeterMode ---------- */ /* ---------- LEDMeterMode ---------- */
static const char* LEDMeterMode_digits[3][10] = { static const char* LEDMeterMode_digitsAscii[3][10] = {
{ " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ "}, { " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ "},
{ "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|"}, { "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|"},
{ "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|"}, { "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|"},
}; };
static const char* LEDMeterMode_digitsUtf8[3][10] = {
{ "┌──┐","","╶──┐","╶──┐","╷ ╷","┌──╴","┌──╴","╶──┐","┌──┐","┌──┐"},
{ "│ │","","┌──┘"," ──┤","└──┤","└──┐","├──┐","","├──┤","└──┤"},
{ "└──┘","","└──╴","╶──┘","","╶──┘","└──┘","","└──┘"," ──┘"},
};
static void LEDMeterMode_drawDigit(int x, int y, int n) { static void LEDMeterMode_drawDigit(int x, int y, int n) {
if (CRT_utf8) {
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
mvaddstr(y+i, x, LEDMeterMode_digits[i][n]); mvaddstr(y+i, x, LEDMeterMode_digitsUtf8[i][n]);
} else {
for (int i = 0; i < 3; i++)
mvaddstr(y+i, x, LEDMeterMode_digitsAscii[i][n]);
}
} }
static void LEDMeterMode_draw(Meter* this, int x, int y, int w) { static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
(void) w; (void) w;
MeterType* type = this->type;
char buffer[METER_BUFFER_LEN]; char buffer[METER_BUFFER_LEN];
type->setValues(this, buffer, METER_BUFFER_LEN - 1); Meter_setValues(this, buffer, METER_BUFFER_LEN - 1);
RichString_begin(out); RichString_begin(out);
Meter_displayBuffer(this, buffer, &out); Meter_displayBuffer(this, buffer, &out);
int yText = CRT_utf8 ? y+1 : y+2;
attrset(CRT_colors[LED_COLOR]); attrset(CRT_colors[LED_COLOR]);
mvaddstr(y+2, x, this->caption); mvaddstr(yText, x, this->caption);
int xx = x + strlen(this->caption); int xx = x + strlen(this->caption);
int len = RichString_sizeVal(out); int len = RichString_sizeVal(out);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
@ -413,7 +424,7 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
LEDMeterMode_drawDigit(xx, y, c-48); LEDMeterMode_drawDigit(xx, y, c-48);
xx += 4; xx += 4;
} else { } else {
mvaddch(y+2, xx, c); mvaddch(yText, xx, c);
xx += 1; xx += 1;
} }
} }
@ -421,8 +432,6 @@ static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
RichString_end(out); RichString_end(out);
} }
#endif
static MeterMode BarMeterMode = { static MeterMode BarMeterMode = {
.uiName = "Bar", .uiName = "Bar",
.h = 1, .h = 1,
@ -435,8 +444,6 @@ static MeterMode TextMeterMode = {
.draw = TextMeterMode_draw, .draw = TextMeterMode_draw,
}; };
#ifdef USE_FUNKY_MODES
static MeterMode GraphMeterMode = { static MeterMode GraphMeterMode = {
.uiName = "Graph", .uiName = "Graph",
.h = 3, .h = 3,
@ -449,15 +456,11 @@ static MeterMode LEDMeterMode = {
.draw = LEDMeterMode_draw, .draw = LEDMeterMode_draw,
}; };
#endif
MeterMode* Meter_modes[] = { MeterMode* Meter_modes[] = {
NULL, NULL,
&BarMeterMode, &BarMeterMode,
&TextMeterMode, &TextMeterMode,
#ifdef USE_FUNKY_MODES
&GraphMeterMode, &GraphMeterMode,
&LEDMeterMode, &LEDMeterMode,
#endif
NULL NULL
}; };

96
Meter.h
View File

@ -9,54 +9,58 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#ifndef USE_FUNKY_MODES
#define USE_FUNKY_MODES 1
#endif
#define METER_BUFFER_LEN 128 #define METER_BUFFER_LEN 128
#include "ListItem.h" #include "ListItem.h"
#include "ProcessList.h" #include "ProcessList.h"
typedef struct Meter_ Meter; typedef struct Meter_ Meter;
typedef struct MeterType_ MeterType;
typedef struct MeterMode_ MeterMode;
typedef void(*MeterType_Init)(Meter*); typedef void(*Meter_Init)(Meter*);
typedef void(*MeterType_Done)(Meter*); typedef void(*Meter_Done)(Meter*);
typedef void(*MeterType_SetMode)(Meter*, int); typedef void(*Meter_UpdateMode)(Meter*, int);
typedef void(*Meter_SetValues)(Meter*, char*, int); typedef void(*Meter_SetValues)(Meter*, char*, int);
typedef void(*Meter_Draw)(Meter*, int, int, int); typedef void(*Meter_Draw)(Meter*, int, int, int);
struct MeterMode_ { typedef struct MeterClass_ {
Meter_Draw draw; ObjectClass super;
const char* uiName; const Meter_Init init;
int h; const Meter_Done done;
}; const Meter_UpdateMode updateMode;
const Meter_Draw draw;
struct MeterType_ { const Meter_SetValues setValues;
Meter_SetValues setValues; const int defaultMode;
Object_Display display;
int mode;
int items; int items;
double total; const double total;
int* attributes; const int* attributes;
const char* name; const char* name;
const char* uiName; const char* uiName;
const char* caption; const char* caption;
MeterType_Init init; } MeterClass;
MeterType_Done done;
MeterType_SetMode setMode; #define As_Meter(this_) ((MeterClass*)((this_)->super.klass))
Meter_Draw draw; #define Meter_initFn(this_) As_Meter(this_)->init
}; #define Meter_init(this_) As_Meter(this_)->init((Meter*)(this_))
#define Meter_done(this_) As_Meter(this_)->done((Meter*)(this_))
#define Meter_updateModeFn(this_) As_Meter(this_)->updateMode
#define Meter_updateMode(this_, m_) As_Meter(this_)->updateMode((Meter*)(this_), m_)
#define Meter_drawFn(this_) As_Meter(this_)->draw
#define Meter_doneFn(this_) As_Meter(this_)->done
#define Meter_setValues(this_, c_, i_) As_Meter(this_)->setValues((Meter*)(this_), c_, i_)
#define Meter_defaultMode(this_) As_Meter(this_)->defaultMode
#define Meter_getItems(this_) As_Meter(this_)->items
#define Meter_setItems(this_, n_) As_Meter(this_)->items = (n_)
#define Meter_attributes(this_) As_Meter(this_)->attributes
#define Meter_name(this_) As_Meter(this_)->name
#define Meter_uiName(this_) As_Meter(this_)->uiName
struct Meter_ { struct Meter_ {
Object super; Object super;
Meter_Draw draw;
char* caption; char* caption;
MeterType* type;
int mode; int mode;
int param; int param;
Meter_Draw draw;
void* drawData; void* drawData;
int h; int h;
ProcessList* pl; ProcessList* pl;
@ -64,24 +68,26 @@ struct Meter_ {
double total; double total;
}; };
#ifdef USE_FUNKY_MODES typedef struct MeterMode_ {
typedef struct GraphData_ { Meter_Draw draw;
time_t time; const char* uiName;
double values[METER_BUFFER_LEN]; int h;
} GraphData; } MeterMode;
#endif
typedef enum { typedef enum {
CUSTOM_METERMODE = 0, CUSTOM_METERMODE = 0,
BAR_METERMODE, BAR_METERMODE,
TEXT_METERMODE, TEXT_METERMODE,
#ifdef USE_FUNKY_MODES
GRAPH_METERMODE, GRAPH_METERMODE,
LED_METERMODE, LED_METERMODE,
#endif
LAST_METERMODE LAST_METERMODE
} MeterModeId; } MeterModeId;
typedef struct GraphData_ {
struct timeval time;
double values[METER_BUFFER_LEN];
} GraphData;
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
@ -90,15 +96,11 @@ typedef enum {
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
#ifdef DEBUG extern MeterClass Meter_class;
extern char* METER_CLASS;
#else
#define METER_CLASS NULL
#endif
extern MeterType* Meter_types[]; extern MeterClass* Meter_types[];
Meter* Meter_new(ProcessList* pl, int param, MeterType* type); Meter* Meter_new(ProcessList* pl, int param, MeterClass* type);
void Meter_delete(Object* cast); void Meter_delete(Object* cast);
@ -112,20 +114,12 @@ ListItem* Meter_toListItem(Meter* this);
/* ---------- BarMeterMode ---------- */ /* ---------- BarMeterMode ---------- */
#ifdef USE_FUNKY_MODES
/* ---------- GraphMeterMode ---------- */ /* ---------- GraphMeterMode ---------- */
#define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0) #define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0)
/* ---------- LEDMeterMode ---------- */ /* ---------- LEDMeterMode ---------- */
#endif
#ifdef USE_FUNKY_MODES
#endif
extern MeterMode* Meter_modes[]; extern MeterMode* Meter_modes[];
#endif #endif

View File

@ -92,16 +92,22 @@ static HandlerResult MetersPanel_eventHandler(Panel* super, int ch) {
return result; return result;
} }
PanelClass MetersPanel_class = {
.super = {
.extends = Class(Panel),
.delete = MetersPanel_delete
},
.eventHandler = MetersPanel_eventHandler
};
MetersPanel* MetersPanel_new(Settings* settings, const char* header, Vector* meters, ScreenManager* scr) { MetersPanel* MetersPanel_new(Settings* settings, const char* header, Vector* meters, ScreenManager* scr) {
MetersPanel* this = (MetersPanel*) malloc(sizeof(MetersPanel)); MetersPanel* this = AllocThis(MetersPanel);
Panel* super = (Panel*) this; Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true); Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
((Object*)this)->delete = MetersPanel_delete;
this->settings = settings; this->settings = settings;
this->meters = meters; this->meters = meters;
this->scr = scr; this->scr = scr;
super->eventHandler = MetersPanel_eventHandler;
Panel_setHeader(super, header); Panel_setHeader(super, header);
for (int i = 0; i < Vector_size(meters); i++) { for (int i = 0; i < Vector_size(meters); i++) {
Meter* meter = (Meter*) Vector_get(meters, i); Meter* meter = (Meter*) Vector_get(meters, i);

View File

@ -22,6 +22,8 @@ typedef struct MetersPanel_ {
} MetersPanel; } MetersPanel;
extern PanelClass MetersPanel_class;
MetersPanel* MetersPanel_new(Settings* settings, const char* header, Vector* meters, ScreenManager* scr); MetersPanel* MetersPanel_new(Settings* settings, const char* header, Vector* meters, ScreenManager* scr);
#endif #endif

View File

@ -1,51 +1,62 @@
/* /*
htop - Object.c htop - Object.c
(C) 2004-2011 Hisham H. Muhammad (C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file Released under the GNU GPL, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#include "Object.h" #include "Object.h"
#include "CRT.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
/*{ /*{
#include "RichString.h" #include "RichString.h"
#ifndef DEBUG
#define Object_setClass(obj, class)
#endif
typedef struct Object_ Object; typedef struct Object_ Object;
typedef void(*Object_Display)(Object*, RichString*); typedef void(*Object_Display)(Object*, RichString*);
typedef int(*Object_Compare)(const void*, const void*); typedef int(*Object_Compare)(const void*, const void*);
typedef void(*Object_Delete)(Object*); typedef void(*Object_Delete)(Object*);
#define Object_getClass(obj_) ((Object*)(obj_))->klass
#define Object_setClass(obj_, class_) Object_getClass(obj_) = (ObjectClass*) class_
#define Object_delete(obj_) Object_getClass(obj_)->delete((Object*)(obj_))
#define Object_displayFn(obj_) Object_getClass(obj_)->display
#define Object_display(obj_, str_) Object_getClass(obj_)->display((Object*)(obj_), str_)
#define Object_compare(obj_, other_) Object_getClass(obj_)->compare((const void*)(obj_), other_)
#define Class(class_) ((ObjectClass*)(&(class_ ## _class)))
#define AllocThis(class_) (class_*) malloc(sizeof(class_)); Object_setClass(this, Class(class_));
typedef struct ObjectClass_ {
const void* extends;
const Object_Display display;
const Object_Delete delete;
const Object_Compare compare;
} ObjectClass;
struct Object_ { struct Object_ {
#ifdef DEBUG ObjectClass* klass;
char* class;
#endif
Object_Display display;
Object_Delete delete;
}; };
}*/ }*/
#ifdef DEBUG ObjectClass Object_class = {
char* OBJECT_CLASS = "Object"; .extends = NULL
};
#else
#define OBJECT_CLASS NULL
#endif
#ifdef DEBUG #ifdef DEBUG
void Object_setClass(void* this, char* class) { bool Object_isA(Object* o, const ObjectClass* klass) {
((Object*)this)->class = class; if (!o)
return false;
const ObjectClass* type = o->klass;
while (type) {
if (type == klass)
return true;
type = type->extends;
}
return false;
} }
#endif #endif

View File

@ -4,41 +4,48 @@
#define HEADER_Object #define HEADER_Object
/* /*
htop - Object.h htop - Object.h
(C) 2004-2011 Hisham H. Muhammad (C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file Released under the GNU GPL, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#include "RichString.h" #include "RichString.h"
#ifndef DEBUG
#define Object_setClass(obj, class)
#endif
typedef struct Object_ Object; typedef struct Object_ Object;
typedef void(*Object_Display)(Object*, RichString*); typedef void(*Object_Display)(Object*, RichString*);
typedef int(*Object_Compare)(const void*, const void*); typedef int(*Object_Compare)(const void*, const void*);
typedef void(*Object_Delete)(Object*); typedef void(*Object_Delete)(Object*);
#define Object_getClass(obj_) ((Object*)(obj_))->klass
#define Object_setClass(obj_, class_) Object_getClass(obj_) = (ObjectClass*) class_
#define Object_delete(obj_) Object_getClass(obj_)->delete((Object*)(obj_))
#define Object_displayFn(obj_) Object_getClass(obj_)->display
#define Object_display(obj_, str_) Object_getClass(obj_)->display((Object*)(obj_), str_)
#define Object_compare(obj_, other_) Object_getClass(obj_)->compare((const void*)(obj_), other_)
#define Class(class_) ((ObjectClass*)(&(class_ ## _class)))
#define AllocThis(class_) (class_*) malloc(sizeof(class_)); Object_setClass(this, Class(class_));
typedef struct ObjectClass_ {
const void* extends;
const Object_Display display;
const Object_Delete delete;
const Object_Compare compare;
} ObjectClass;
struct Object_ { struct Object_ {
#ifdef DEBUG ObjectClass* klass;
char* class;
#endif
Object_Display display;
Object_Delete delete;
}; };
#ifdef DEBUG
extern char* OBJECT_CLASS;
#else extern ObjectClass Object_class;
#define OBJECT_CLASS NULL
#endif
#ifdef DEBUG #ifdef DEBUG
void Object_setClass(void* this, char* class); bool Object_isA(Object* o, const ObjectClass* klass);
#endif #endif

View File

@ -57,7 +57,7 @@ static int ofsEvents[] = {KEY_F(3), KEY_F(4), KEY_F(5), 27};
OpenFilesScreen* OpenFilesScreen_new(Process* process) { OpenFilesScreen* OpenFilesScreen_new(Process* process) {
OpenFilesScreen* this = (OpenFilesScreen*) malloc(sizeof(OpenFilesScreen)); OpenFilesScreen* this = (OpenFilesScreen*) malloc(sizeof(OpenFilesScreen));
this->process = process; this->process = process;
this->display = Panel_new(0, 1, COLS, LINES-3, LISTITEM_CLASS, false, ListItem_compare); this->display = Panel_new(0, 1, COLS, LINES-3, false, Class(ListItem));
if (Process_isThread(process)) if (Process_isThread(process))
this->pid = process->tgid; this->pid = process->tgid;
else else
@ -170,7 +170,7 @@ void OpenFilesScreen_run(OpenFilesScreen* this) {
FunctionBar* bar = FunctionBar_new(ofsFunctions, ofsKeys, ofsEvents); FunctionBar* bar = FunctionBar_new(ofsFunctions, ofsKeys, ofsEvents);
IncSet* inc = IncSet_new(bar); IncSet* inc = IncSet_new(bar);
Vector* lines = Vector_new(panel->items->type, true, DEFAULT_SIZE, ListItem_compare); Vector* lines = Vector_new(panel->items->type, true, DEFAULT_SIZE);
OpenFilesScreen_scan(this, lines, inc); OpenFilesScreen_scan(this, lines, inc);
OpenFilesScreen_draw(this, inc); OpenFilesScreen_draw(this, inc);
@ -234,6 +234,7 @@ void OpenFilesScreen_run(OpenFilesScreen* this) {
} }
} }
Vector_delete(lines);
FunctionBar_delete((Object*)bar); FunctionBar_delete((Object*)bar);
IncSet_delete(inc); IncSet_delete(inc);
} }

51
Panel.c
View File

@ -38,8 +38,18 @@ typedef enum HandlerResult_ {
typedef HandlerResult(*Panel_EventHandler)(Panel*, int); typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
typedef struct PanelClass_ {
const ObjectClass super;
const Panel_EventHandler eventHandler;
} PanelClass;
#define As_Panel(this_) ((PanelClass*)((this_)->super.klass))
#define Panel_eventHandlerFn(this_) As_Panel(this_)->eventHandler
#define Panel_eventHandler(this_, ev_) As_Panel(this_)->eventHandler((Panel*)(this_), ev_)
struct Panel_ { struct Panel_ {
Object super; Object super;
PanelClass* class;
int x, y, w, h; int x, y, w, h;
WINDOW* window; WINDOW* window;
Vector* items; Vector* items;
@ -49,7 +59,6 @@ struct Panel_ {
int oldSelected; int oldSelected;
bool needsRedraw; bool needsRedraw;
RichString header; RichString header;
Panel_EventHandler eventHandler;
char* eventHandlerBuffer; char* eventHandlerBuffer;
}; };
@ -62,22 +71,24 @@ struct Panel_ {
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
#ifdef DEBUG
char* PANEL_CLASS = "Panel";
#else
#define PANEL_CLASS NULL
#endif
#define KEY_CTRLN 0016 /* control-n key */ #define KEY_CTRLN 0016 /* control-n key */
#define KEY_CTRLP 0020 /* control-p key */ #define KEY_CTRLP 0020 /* control-p key */
#define KEY_CTRLF 0006 /* control-f key */ #define KEY_CTRLF 0006 /* control-f key */
#define KEY_CTRLB 0002 /* control-b key */ #define KEY_CTRLB 0002 /* control-b key */
Panel* Panel_new(int x, int y, int w, int h, char* type, bool owner, Object_Compare compare) { PanelClass Panel_class = {
.super = {
.extends = Class(Object),
.delete = Panel_delete
},
.eventHandler = Panel_selectByTyping
};
Panel* Panel_new(int x, int y, int w, int h, bool owner, ObjectClass* type) {
Panel* this; Panel* this;
this = malloc(sizeof(Panel)); this = malloc(sizeof(Panel));
Object_setClass(this, Class(Panel));
Panel_init(this, x, y, w, h, type, owner); Panel_init(this, x, y, w, h, type, owner);
this->items->compare = compare;
return this; return this;
} }
@ -87,17 +98,13 @@ void Panel_delete(Object* cast) {
free(this); free(this);
} }
void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner) { void Panel_init(Panel* this, int x, int y, int w, int h, ObjectClass* type, bool owner) {
Object* super = (Object*) this;
Object_setClass(this, PANEL_CLASS);
super->delete = Panel_delete;
this->x = x; this->x = x;
this->y = y; this->y = y;
this->w = w; this->w = w;
this->h = h; this->h = h;
this->eventHandler = NULL;
this->eventHandlerBuffer = NULL; this->eventHandlerBuffer = NULL;
this->items = Vector_new(type, owner, DEFAULT_SIZE, ListItem_compare); this->items = Vector_new(type, owner, DEFAULT_SIZE);
this->scrollV = 0; this->scrollV = 0;
this->scrollH = 0; this->scrollH = 0;
this->selected = 0; this->selected = 0;
@ -129,10 +136,6 @@ inline void Panel_setHeader(Panel* this, const char* header) {
this->needsRedraw = true; this->needsRedraw = true;
} }
void Panel_setEventHandler(Panel* this, Panel_EventHandler eh) {
this->eventHandler = eh;
}
void Panel_move(Panel* this, int x, int y) { void Panel_move(Panel* this, int x, int y) {
assert (this != NULL); assert (this != NULL);
@ -238,8 +241,8 @@ void Panel_setSelected(Panel* this, int selected) {
selected = MAX(0, MIN(Vector_size(this->items) - 1, selected)); selected = MAX(0, MIN(Vector_size(this->items) - 1, selected));
this->selected = selected; this->selected = selected;
if (this->eventHandler) { if (Panel_eventHandlerFn(this)) {
this->eventHandler(this, EVENT_SETSELECTED); Panel_eventHandler(this, EVENT_SETSELECTED);
} }
} }
@ -293,7 +296,7 @@ void Panel_draw(Panel* this, bool focus) {
for(int i = first, j = 0; j < this->h && i < last; i++, j++) { for(int i = first, j = 0; j < this->h && i < last; i++, j++) {
Object* itemObj = Vector_get(this->items, i); Object* itemObj = Vector_get(this->items, i);
RichString_begin(item); RichString_begin(item);
itemObj->display(itemObj, &item); Object_display(itemObj, &item);
int itemLen = RichString_sizeVal(item); int itemLen = RichString_sizeVal(item);
int amt = MIN(itemLen - scrollH, this->w); int amt = MIN(itemLen - scrollH, this->w);
if (i == this->selected) { if (i == this->selected) {
@ -317,11 +320,11 @@ void Panel_draw(Panel* this, bool focus) {
} else { } else {
Object* oldObj = Vector_get(this->items, this->oldSelected); Object* oldObj = Vector_get(this->items, this->oldSelected);
RichString_begin(old); RichString_begin(old);
oldObj->display(oldObj, &old); Object_display(oldObj, &old);
int oldLen = RichString_sizeVal(old); int oldLen = RichString_sizeVal(old);
Object* newObj = Vector_get(this->items, this->selected); Object* newObj = Vector_get(this->items, this->selected);
RichString_begin(new); RichString_begin(new);
newObj->display(newObj, &new); Object_display(newObj, &new);
int newLen = RichString_sizeVal(new); int newLen = RichString_sizeVal(new);
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w); mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
if (scrollH < oldLen) if (scrollH < oldLen)

25
Panel.h
View File

@ -26,8 +26,18 @@ typedef enum HandlerResult_ {
typedef HandlerResult(*Panel_EventHandler)(Panel*, int); typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
typedef struct PanelClass_ {
const ObjectClass super;
const Panel_EventHandler eventHandler;
} PanelClass;
#define As_Panel(this_) ((PanelClass*)((this_)->super.klass))
#define Panel_eventHandlerFn(this_) As_Panel(this_)->eventHandler
#define Panel_eventHandler(this_, ev_) As_Panel(this_)->eventHandler((Panel*)(this_), ev_)
struct Panel_ { struct Panel_ {
Object super; Object super;
PanelClass* class;
int x, y, w, h; int x, y, w, h;
WINDOW* window; WINDOW* window;
Vector* items; Vector* items;
@ -37,7 +47,6 @@ struct Panel_ {
int oldSelected; int oldSelected;
bool needsRedraw; bool needsRedraw;
RichString header; RichString header;
Panel_EventHandler eventHandler;
char* eventHandlerBuffer; char* eventHandlerBuffer;
}; };
@ -49,22 +58,18 @@ struct Panel_ {
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
#ifdef DEBUG
extern char* PANEL_CLASS;
#else
#define PANEL_CLASS NULL
#endif
#define KEY_CTRLN 0016 /* control-n key */ #define KEY_CTRLN 0016 /* control-n key */
#define KEY_CTRLP 0020 /* control-p key */ #define KEY_CTRLP 0020 /* control-p key */
#define KEY_CTRLF 0006 /* control-f key */ #define KEY_CTRLF 0006 /* control-f key */
#define KEY_CTRLB 0002 /* control-b key */ #define KEY_CTRLB 0002 /* control-b key */
Panel* Panel_new(int x, int y, int w, int h, char* type, bool owner, Object_Compare compare); extern PanelClass Panel_class;
Panel* Panel_new(int x, int y, int w, int h, bool owner, ObjectClass* type);
void Panel_delete(Object* cast); void Panel_delete(Object* cast);
void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner); void Panel_init(Panel* this, int x, int y, int w, int h, ObjectClass* type, bool owner);
void Panel_done(Panel* this); void Panel_done(Panel* this);
@ -72,8 +77,6 @@ RichString* Panel_getHeader(Panel* this);
extern void Panel_setHeader(Panel* this, const char* header); extern void Panel_setHeader(Panel* this, const char* header);
void Panel_setEventHandler(Panel* this, Panel_EventHandler eh);
void Panel_move(Panel* this, int x, int y); void Panel_move(Panel* this, int x, int y);
void Panel_resize(Panel* this, int w, int h); void Panel_resize(Panel* this, int w, int h);

View File

@ -175,12 +175,6 @@ typedef struct Process_ {
}*/ }*/
#ifdef DEBUG
char* PROCESS_CLASS = "Process";
#else
#define PROCESS_CLASS NULL
#endif
const char *Process_fieldNames[] = { const char *Process_fieldNames[] = {
"", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION", "", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION",
"TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT", "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT",
@ -564,11 +558,16 @@ void Process_delete(Object* cast) {
free(this); free(this);
} }
ObjectClass Process_class = {
.extends = Class(Object),
.display = Process_display,
.delete = Process_delete,
.compare = Process_compare
};
Process* Process_new(struct ProcessList_ *pl) { Process* Process_new(struct ProcessList_ *pl) {
Process* this = calloc(sizeof(Process), 1); Process* this = calloc(sizeof(Process), 1);
Object_setClass(this, PROCESS_CLASS); Object_setClass(this, Class(Process));
((Object*)this)->display = Process_display;
((Object*)this)->delete = Process_delete;
this->pid = 0; this->pid = 0;
this->pl = pl; this->pl = pl;
this->tag = false; this->tag = false;

View File

@ -153,12 +153,6 @@ typedef struct Process_ {
} Process; } Process;
#ifdef DEBUG
extern char* PROCESS_CLASS;
#else
#define PROCESS_CLASS NULL
#endif
extern const char *Process_fieldNames[]; extern const char *Process_fieldNames[];
extern const char *Process_fieldTitles[]; extern const char *Process_fieldTitles[];
@ -172,6 +166,8 @@ void Process_getMaxPid();
void Process_delete(Object* cast); void Process_delete(Object* cast);
extern ObjectClass Process_class;
Process* Process_new(struct ProcessList_ *pl); Process* Process_new(struct ProcessList_ *pl);
void Process_toggleTag(Process* this); void Process_toggleTag(Process* this);

View File

@ -68,12 +68,6 @@ typedef enum TreeStr_ {
TREE_STR_COUNT TREE_STR_COUNT
} TreeStr; } TreeStr;
typedef enum TreeType_ {
TREE_TYPE_AUTO,
TREE_TYPE_ASCII,
TREE_TYPE_UTF8,
} TreeType;
typedef struct CPUData_ { typedef struct CPUData_ {
unsigned long long int totalTime; unsigned long long int totalTime;
unsigned long long int userTime; unsigned long long int userTime;
@ -184,13 +178,13 @@ const char *ProcessList_treeStrUtf8[TREE_STR_COUNT] = {
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) { ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) {
ProcessList* this; ProcessList* this;
this = calloc(sizeof(ProcessList), 1); this = calloc(sizeof(ProcessList), 1);
this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare); this->processes = Vector_new(Class(Process), true, DEFAULT_SIZE);
this->processTable = Hashtable_new(140, false); this->processTable = Hashtable_new(140, false);
this->usersTable = usersTable; this->usersTable = usersTable;
this->pidWhiteList = pidWhiteList; this->pidWhiteList = pidWhiteList;
/* tree-view auxiliary buffers */ /* tree-view auxiliary buffers */
this->processes2 = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare); this->processes2 = Vector_new(Class(Process), true, DEFAULT_SIZE);
FILE* file = fopen(PROCSTATFILE, "r"); FILE* file = fopen(PROCSTATFILE, "r");
if (file == NULL) { if (file == NULL) {
@ -243,6 +237,9 @@ ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList) {
this->treeStr = NULL; this->treeStr = NULL;
this->following = -1; this->following = -1;
if (CRT_utf8)
this->treeStr = CRT_utf8 ? ProcessList_treeStrUtf8 : ProcessList_treeStrAscii;
return this; return this;
} }
@ -312,7 +309,7 @@ int ProcessList_size(ProcessList* this) {
} }
static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int indent, int direction, bool show) { static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int indent, int direction, bool show) {
Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare); Vector* children = Vector_new(Class(Process), false, DEFAULT_SIZE);
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) { for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
Process* process = (Process*) (Vector_get(this->processes, i)); Process* process = (Process*) (Vector_get(this->processes, i));

View File

@ -51,12 +51,6 @@ typedef enum TreeStr_ {
TREE_STR_COUNT TREE_STR_COUNT
} TreeStr; } TreeStr;
typedef enum TreeType_ {
TREE_TYPE_AUTO,
TREE_TYPE_ASCII,
TREE_TYPE_UTF8,
} TreeType;
typedef struct CPUData_ { typedef struct CPUData_ {
unsigned long long int totalTime; unsigned long long int totalTime;
unsigned long long int userTime; unsigned long long int userTime;

View File

@ -52,8 +52,8 @@ ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation ori
this->y2 = y2; this->y2 = y2;
this->fuBar = NULL; this->fuBar = NULL;
this->orientation = orientation; this->orientation = orientation;
this->panels = Vector_new(PANEL_CLASS, owner, DEFAULT_SIZE, NULL); this->panels = Vector_new(Class(Panel), owner, DEFAULT_SIZE);
this->fuBars = Vector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE, NULL); this->fuBars = Vector_new(Class(FunctionBar), true, DEFAULT_SIZE);
this->panelCount = 0; this->panelCount = 0;
this->header = header; this->header = header;
this->owner = owner; this->owner = owner;
@ -184,8 +184,8 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
} }
} }
if (panelFocus->eventHandler) { if (Panel_eventHandlerFn(panelFocus)) {
HandlerResult result = panelFocus->eventHandler(panelFocus, ch); HandlerResult result = Panel_eventHandler(panelFocus, ch);
if (result == HANDLED) { if (result == HANDLED) {
continue; continue;
} else if (result == BREAK_LOOP) { } else if (result == BREAK_LOOP) {

View File

@ -5,6 +5,7 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#include "Panel.h"
#include "SignalsPanel.h" #include "SignalsPanel.h"
#include "ListItem.h" #include "ListItem.h"
@ -16,26 +17,14 @@ in the source distribution for its full text.
#include <ctype.h> #include <ctype.h>
/*{ /*{
#include "Panel.h"
typedef struct SignalItem_ { typedef struct SignalItem_ {
const char* name; const char* name;
int number; int number;
} SignalItem; } SignalItem;
typedef struct SignalsPanel_ {
Panel super;
} SignalsPanel;
}*/ }*/
static void SignalsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
SignalsPanel* this = (SignalsPanel*) object;
Panel_done(super);
free(this);
}
static SignalItem signals[] = { static SignalItem signals[] = {
{ .name = " 0 Cancel", .number = 0 }, { .name = " 0 Cancel", .number = 0 },
{ .name = " 1 SIGHUP", .number = 1 }, { .name = " 1 SIGHUP", .number = 1 },
@ -73,21 +62,11 @@ static SignalItem signals[] = {
{ .name = "31 SIGSYS", .number = 31 }, { .name = "31 SIGSYS", .number = 31 },
}; };
SignalsPanel* SignalsPanel_new(int x, int y, int w, int h) { Panel* SignalsPanel_new() {
SignalsPanel* this = (SignalsPanel*) malloc(sizeof(SignalsPanel)); Panel* this = Panel_new(1, 1, 1, 1, true, Class(ListItem));
Panel* super = (Panel*) this;
Panel_init(super, x, y, w, h, LISTITEM_CLASS, true);
((Object*)this)->delete = SignalsPanel_delete;
for(unsigned int i = 0; i < sizeof(signals)/sizeof(SignalItem); i++) for(unsigned int i = 0; i < sizeof(signals)/sizeof(SignalItem); i++)
Panel_set(super, i, (Object*) ListItem_new(signals[i].name, signals[i].number)); Panel_set(this, i, (Object*) ListItem_new(signals[i].name, signals[i].number));
SignalsPanel_reset(this); Panel_setHeader(this, "Send signal:");
Panel_setSelected(this, 16); // 16th item is SIGTERM
return this; return this;
} }
void SignalsPanel_reset(SignalsPanel* this) {
Panel* super = (Panel*) this;
Panel_setHeader(super, "Send signal:");
Panel_setSelected(super, 16); // 16th item is SIGTERM
}

View File

@ -9,20 +9,13 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text. in the source distribution for its full text.
*/ */
#include "Panel.h"
typedef struct SignalItem_ { typedef struct SignalItem_ {
const char* name; const char* name;
int number; int number;
} SignalItem; } SignalItem;
typedef struct SignalsPanel_ {
Panel super;
} SignalsPanel;
Panel* SignalsPanel_new();
SignalsPanel* SignalsPanel_new(int x, int y, int w, int h);
void SignalsPanel_reset(SignalsPanel* this);
#endif #endif

View File

@ -59,10 +59,14 @@ static void SwapMeter_display(Object* cast, RichString* out) {
RichString_append(out, CRT_colors[METER_VALUE], buffer); RichString_append(out, CRT_colors[METER_VALUE], buffer);
} }
MeterType SwapMeter = { MeterClass SwapMeter_class = {
.setValues = SwapMeter_setValues, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = SwapMeter_display, .display = SwapMeter_display,
.mode = BAR_METERMODE, },
.setValues = SwapMeter_setValues,
.defaultMode = BAR_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = SwapMeter_attributes, .attributes = SwapMeter_attributes,

View File

@ -18,6 +18,6 @@ in the source distribution for its full text.
extern int SwapMeter_attributes[]; extern int SwapMeter_attributes[];
/* NOTE: Value is in kilobytes */ /* NOTE: Value is in kilobytes */
extern MeterType SwapMeter; extern MeterClass SwapMeter_class;
#endif #endif

View File

@ -55,10 +55,14 @@ static void TasksMeter_display(Object* cast, RichString* out) {
RichString_append(out, CRT_colors[METER_TEXT], " running"); RichString_append(out, CRT_colors[METER_TEXT], " running");
} }
MeterType TasksMeter = { MeterClass TasksMeter_class = {
.setValues = TasksMeter_setValues, .super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = TasksMeter_display, .display = TasksMeter_display,
.mode = TEXT_METERMODE, },
.setValues = TasksMeter_setValues,
.defaultMode = TEXT_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = TasksMeter_attributes, .attributes = TasksMeter_attributes,

View File

@ -13,6 +13,6 @@ in the source distribution for its full text.
extern int TasksMeter_attributes[]; extern int TasksMeter_attributes[];
extern MeterType TasksMeter; extern MeterClass TasksMeter_class;
#endif #endif

View File

@ -46,7 +46,7 @@ static int tsEvents[] = {KEY_F(3), KEY_F(4), KEY_F(8), KEY_F(9), 27};
TraceScreen* TraceScreen_new(Process* process) { TraceScreen* TraceScreen_new(Process* process) {
TraceScreen* this = (TraceScreen*) malloc(sizeof(TraceScreen)); TraceScreen* this = (TraceScreen*) malloc(sizeof(TraceScreen));
this->process = process; this->process = process;
this->display = Panel_new(0, 1, COLS, LINES-2, LISTITEM_CLASS, false, ListItem_compare); this->display = Panel_new(0, 1, COLS, LINES-2, false, Class(ListItem));
this->tracing = true; this->tracing = true;
return this; return this;
} }
@ -106,7 +106,7 @@ void TraceScreen_run(TraceScreen* this) {
FunctionBar* bar = FunctionBar_new(tsFunctions, tsKeys, tsEvents); FunctionBar* bar = FunctionBar_new(tsFunctions, tsKeys, tsEvents);
IncSet* inc = IncSet_new(bar); IncSet* inc = IncSet_new(bar);
Vector* lines = Vector_new(panel->items->type, true, DEFAULT_SIZE, ListItem_compare); Vector* lines = Vector_new(panel->items->type, true, DEFAULT_SIZE);
TraceScreen_draw(this, inc); TraceScreen_draw(this, inc);
@ -122,11 +122,11 @@ void TraceScreen_run(TraceScreen* this) {
if (ch == ERR) { if (ch == ERR) {
fd_set fds; fd_set fds;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); // FD_SET(STDIN_FILENO, &fds);
FD_SET(fd_strace, &fds); FD_SET(fd_strace, &fds);
//struct timeval tv; struct timeval tv;
//tv.tv_sec = 0; tv.tv_usec = 500; tv.tv_sec = 0; tv.tv_usec = 500;
int ready = select(fd_strace+1, &fds, NULL, NULL, NULL/*&tv*/); int ready = select(fd_strace+1, &fds, NULL, NULL, &tv);
int nread = 0; int nread = 0;
if (ready > 0 && FD_ISSET(fd_strace, &fds)) if (ready > 0 && FD_ISSET(fd_strace, &fds))
nread = fread(buffer, 1, 1000, strace); nread = fread(buffer, 1, 1000, strace);
@ -218,6 +218,7 @@ void TraceScreen_run(TraceScreen* this) {
IncSet_delete(inc); IncSet_delete(inc);
FunctionBar_delete((Object*)bar); FunctionBar_delete((Object*)bar);
Vector_delete(lines);
kill(child, SIGTERM); kill(child, SIGTERM);
waitpid(child, NULL, 0); waitpid(child, NULL, 0);

View File

@ -49,10 +49,13 @@ static void UptimeMeter_setValues(Meter* this, char* buffer, int len) {
snprintf(buffer, len, "%s%02d:%02d:%02d", daysbuf, hours, minutes, seconds); snprintf(buffer, len, "%s%02d:%02d:%02d", daysbuf, hours, minutes, seconds);
} }
MeterType UptimeMeter = { MeterClass UptimeMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete
},
.setValues = UptimeMeter_setValues, .setValues = UptimeMeter_setValues,
.display = NULL, .defaultMode = TEXT_METERMODE,
.mode = TEXT_METERMODE,
.items = 1, .items = 1,
.total = 100.0, .total = 100.0,
.attributes = UptimeMeter_attributes, .attributes = UptimeMeter_attributes,

View File

@ -13,6 +13,6 @@ in the source distribution for its full text.
extern int UptimeMeter_attributes[]; extern int UptimeMeter_attributes[];
extern MeterType UptimeMeter; extern MeterClass UptimeMeter_class;
#endif #endif

View File

@ -23,17 +23,16 @@ in the source distribution for its full text.
typedef struct Vector_ { typedef struct Vector_ {
Object **array; Object **array;
Object_Compare compare; ObjectClass* type;
int arraySize; int arraySize;
int growthRate; int growthRate;
int items; int items;
char* type;
bool owner; bool owner;
} Vector; } Vector;
}*/ }*/
Vector* Vector_new(char* type, bool owner, int size, Object_Compare compare) { Vector* Vector_new(ObjectClass* type, bool owner, int size) {
Vector* this; Vector* this;
if (size == DEFAULT_SIZE) if (size == DEFAULT_SIZE)
@ -45,7 +44,6 @@ Vector* Vector_new(char* type, bool owner, int size, Object_Compare compare) {
this->items = 0; this->items = 0;
this->type = type; this->type = type;
this->owner = owner; this->owner = owner;
this->compare = compare;
return this; return this;
} }
@ -53,7 +51,7 @@ void Vector_delete(Vector* this) {
if (this->owner) { if (this->owner) {
for (int i = 0; i < this->items; i++) for (int i = 0; i < this->items; i++)
if (this->array[i]) if (this->array[i])
(this->array[i])->delete(this->array[i]); Object_delete(this->array[i]);
} }
free(this->array); free(this->array);
free(this); free(this);
@ -65,7 +63,7 @@ static inline bool Vector_isConsistent(Vector* this) {
assert(this->items <= this->arraySize); assert(this->items <= this->arraySize);
if (this->owner) { if (this->owner) {
for (int i = 0; i < this->items; i++) for (int i = 0; i < this->items; i++)
if (this->array[i] && this->array[i]->class != this->type) if (this->array[i] && !Object_isA(this->array[i], this->type))
return false; return false;
return true; return true;
} else { } else {
@ -92,7 +90,7 @@ void Vector_prune(Vector* this) {
if (this->owner) { if (this->owner) {
for (i = 0; i < this->items; i++) for (i = 0; i < this->items; i++)
if (this->array[i]) { if (this->array[i]) {
(this->array[i])->delete(this->array[i]); Object_delete(this->array[i]);
//this->array[i] = NULL; //this->array[i] = NULL;
} }
} }
@ -164,18 +162,16 @@ static void insertionSort(Object** array, int left, int right, Object_Compare co
} }
void Vector_quickSort(Vector* this) { void Vector_quickSort(Vector* this) {
assert(this->compare); assert(this->type->compare);
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
Object_Compare compare = this->compare; quickSort(this->array, 0, this->items - 1, this->type->compare);
quickSort(this->array, 0, this->items - 1, compare);
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
void Vector_insertionSort(Vector* this) { void Vector_insertionSort(Vector* this) {
assert(this->compare); assert(this->type->compare);
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
Object_Compare compare = this->compare; insertionSort(this->array, 0, this->items - 1, this->type->compare);
insertionSort(this->array, 0, this->items - 1, compare);
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
@ -196,8 +192,7 @@ void Vector_insert(Vector* this, int idx, void* data_) {
Object* data = data_; Object* data = data_;
assert(idx >= 0); assert(idx >= 0);
assert(idx <= this->items); assert(idx <= this->items);
assert(data_); assert(Object_isA(data, this->type));
assert(data->class == this->type);
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
Vector_checkArraySize(this); Vector_checkArraySize(this);
@ -226,7 +221,7 @@ Object* Vector_take(Vector* this, int idx) {
Object* Vector_remove(Vector* this, int idx) { Object* Vector_remove(Vector* this, int idx) {
Object* removed = Vector_take(this, idx); Object* removed = Vector_take(this, idx);
if (this->owner) { if (this->owner) {
removed->delete(removed); Object_delete(removed);
return NULL; return NULL;
} else } else
return removed; return removed;
@ -253,9 +248,9 @@ void Vector_moveDown(Vector* this, int idx) {
} }
void Vector_set(Vector* this, int idx, void* data_) { void Vector_set(Vector* this, int idx, void* data_) {
assert(idx >= 0);
assert(((Object*)data_)->class == this->type);
Object* data = data_; Object* data = data_;
assert(idx >= 0);
assert(Object_isA((Object*)data, this->type));
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
Vector_checkArraySize(this); Vector_checkArraySize(this);
@ -266,7 +261,7 @@ void Vector_set(Vector* this, int idx, void* data_) {
Object* removed = this->array[idx]; Object* removed = this->array[idx];
assert (removed != NULL); assert (removed != NULL);
if (this->owner) { if (this->owner) {
removed->delete(removed); Object_delete(removed);
} }
} }
} }
@ -309,8 +304,8 @@ static void Vector_merge(Vector* this, Vector* v2) {
*/ */
void Vector_add(Vector* this, void* data_) { void Vector_add(Vector* this, void* data_) {
assert(data_ && ((Object*)data_)->class == this->type);
Object* data = data_; Object* data = data_;
assert(Object_isA((Object*)data, this->type));
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
int i = this->items; int i = this->items;
Vector_set(this, this->items, data); Vector_set(this, this->items, data);
@ -319,9 +314,9 @@ void Vector_add(Vector* this, void* data_) {
} }
inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) { inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) {
assert(((Object*)search_)->class == this->type);
assert(this->compare);
Object* search = search_; Object* search = search_;
assert(Object_isA((Object*)search, this->type));
assert(compare);
assert(Vector_isConsistent(this)); assert(Vector_isConsistent(this));
for (int i = 0; i < this->items; i++) { for (int i = 0; i < this->items; i++) {
Object* o = (Object*)this->array[i]; Object* o = (Object*)this->array[i];

View File

@ -19,16 +19,15 @@ in the source distribution for its full text.
typedef struct Vector_ { typedef struct Vector_ {
Object **array; Object **array;
Object_Compare compare; ObjectClass* type;
int arraySize; int arraySize;
int growthRate; int growthRate;
int items; int items;
char* type;
bool owner; bool owner;
} Vector; } Vector;
Vector* Vector_new(char* type, bool owner, int size, Object_Compare compare); Vector* Vector_new(ObjectClass* type, bool owner, int size);
void Vector_delete(Vector* this); void Vector_delete(Vector* this);

79
htop.c
View File

@ -210,8 +210,6 @@ static bool changePriority(Panel* panel, int delta) {
static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, const char** keyLabels, FunctionBar* prevBar, Header* header) { static Object* pickFromVector(Panel* panel, Panel* list, int x, int y, const char** keyLabels, FunctionBar* prevBar, Header* header) {
const char* fuKeys[] = {"Enter", "Esc", NULL}; const char* fuKeys[] = {"Enter", "Esc", NULL};
int fuEvents[] = {13, 27}; int fuEvents[] = {13, 27};
if (!list->eventHandler)
Panel_setEventHandler(list, Panel_selectByTyping);
ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, header, false); ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, header, false);
scr->allowFocusChange = false; scr->allowFocusChange = false;
ScreenManager_add(scr, list, FunctionBar_new(keyLabels, fuKeys, fuEvents), x - 1); ScreenManager_add(scr, list, FunctionBar_new(keyLabels, fuKeys, fuEvents), x - 1);
@ -275,7 +273,6 @@ int main(int argc, char** argv) {
bool userOnly = false; bool userOnly = false;
uid_t userId = 0; uid_t userId = 0;
int usecolors = 1; int usecolors = 1;
TreeType treeType = TREE_TYPE_AUTO;
char *argCopy; char *argCopy;
char *pid; char *pid;
Hashtable *pidWhiteList = NULL; Hashtable *pidWhiteList = NULL;
@ -378,11 +375,23 @@ int main(int argc, char** argv) {
bool doRecalculate = false; bool doRecalculate = false;
Settings* settings; Settings* settings;
Panel* killPanel = NULL;
ProcessList* pl = NULL; ProcessList* pl = NULL;
UsersTable* ut = UsersTable_new(); UsersTable* ut = UsersTable_new();
#ifdef HAVE_LIBNCURSESW
char *locale = setlocale(LC_ALL, NULL);
if (locale == NULL || locale[0] == '\0')
locale = setlocale(LC_CTYPE, NULL);
if (locale != NULL &&
(strstr(locale, "UTF-8") ||
strstr(locale, "utf-8") ||
strstr(locale, "UTF8") ||
strstr(locale, "utf8")))
CRT_utf8 = true;
else
CRT_utf8 = false;
#endif
pl = ProcessList_new(ut, pidWhiteList); pl = ProcessList_new(ut, pidWhiteList);
Process_getMaxPid(); Process_getMaxPid();
@ -396,36 +405,9 @@ int main(int argc, char** argv) {
if (!usecolors) if (!usecolors)
settings->colorScheme = COLORSCHEME_MONOCHROME; settings->colorScheme = COLORSCHEME_MONOCHROME;
if (treeType == TREE_TYPE_AUTO) {
#ifdef HAVE_LIBNCURSESW
char *locale = setlocale(LC_ALL, NULL);
if (locale == NULL || locale[0] == '\0')
locale = setlocale(LC_CTYPE, NULL);
if (locale != NULL &&
(strstr(locale, "UTF-8") ||
strstr(locale, "utf-8") ||
strstr(locale, "UTF8") ||
strstr(locale, "utf8")))
treeType = TREE_TYPE_UTF8;
else
treeType = TREE_TYPE_ASCII;
#else
treeType = TREE_TYPE_ASCII;
#endif
}
switch (treeType) {
default:
case TREE_TYPE_ASCII:
pl->treeStr = ProcessList_treeStrAscii;
break;
case TREE_TYPE_UTF8:
pl->treeStr = ProcessList_treeStrUtf8;
break;
}
CRT_init(settings->delay, settings->colorScheme); CRT_init(settings->delay, settings->colorScheme);
Panel* panel = Panel_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false, NULL); Panel* panel = Panel_new(0, headerHeight, COLS, LINES - headerHeight - 2, false, &Process_class);
ProcessList_setPanel(pl, panel); ProcessList_setPanel(pl, panel);
if (sortKey > 0) { if (sortKey > 0) {
@ -457,14 +439,18 @@ int main(int argc, char** argv) {
int ch = ERR; int ch = ERR;
int closeTimeout = 0; int closeTimeout = 0;
bool idle = false;
while (!quit) { while (!quit) {
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000); newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000);
recalculate = (newTime - oldTime > CRT_delay); recalculate = (newTime - oldTime > settings->delay);
Process* p = (Process*)Panel_getSelected(panel); Process* p = (Process*)Panel_getSelected(panel);
int following = (follow && p) ? p->pid : -1; int following = (follow && p) ? p->pid : -1;
if (recalculate) if (recalculate) {
Header_draw(header);
oldTime = newTime; oldTime = newTime;
}
if (doRefresh) { if (doRefresh) {
if (recalculate || doRecalculate) { if (recalculate || doRecalculate) {
ProcessList_scan(pl); ProcessList_scan(pl);
@ -475,12 +461,13 @@ int main(int argc, char** argv) {
refreshTimeout = 1; refreshTimeout = 1;
} }
ProcessList_rebuildPanel(pl, true, following, userOnly, userId, IncSet_filter(inc)); ProcessList_rebuildPanel(pl, true, following, userOnly, userId, IncSet_filter(inc));
idle = false;
} }
doRefresh = true; doRefresh = true;
Header_draw(header); if (!idle)
Panel_draw(panel, true); Panel_draw(panel, true);
int prev = ch; int prev = ch;
if (inc->active) if (inc->active)
move(LINES-1, CRT_cursorX); move(LINES-1, CRT_cursorX);
@ -496,8 +483,10 @@ int main(int argc, char** argv) {
} }
} else } else
closeTimeout = 0; closeTimeout = 0;
idle = true;
continue; continue;
} }
idle = false;
if (ch == KEY_MOUSE) { if (ch == KEY_MOUSE) {
MEVENT mevent; MEVENT mevent;
@ -655,7 +644,7 @@ int main(int argc, char** argv) {
} }
case 'u': case 'u':
{ {
Panel* usersPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare); Panel* usersPanel = Panel_new(0, 0, 0, 0, true, Class(ListItem));
Panel_setHeader(usersPanel, "Show processes of:"); Panel_setHeader(usersPanel, "Show processes of:");
UsersTable_foreach(ut, addUserToVector, usersPanel); UsersTable_foreach(ut, addUserToVector, usersPanel);
Vector_insertionSort(usersPanel->items); Vector_insertionSort(usersPanel->items);
@ -687,12 +676,9 @@ int main(int argc, char** argv) {
case KEY_F(9): case KEY_F(9):
case 'k': case 'k':
{ {
if (!killPanel) { Panel* signalsPanel = (Panel*) SignalsPanel_new();
killPanel = (Panel*) SignalsPanel_new(0, 0, 0, 0);
}
SignalsPanel_reset((SignalsPanel*) killPanel);
const char* fuFunctions[] = {"Send ", "Cancel ", NULL}; const char* fuFunctions[] = {"Send ", "Cancel ", NULL};
ListItem* sgn = (ListItem*) pickFromVector(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar, header); ListItem* sgn = (ListItem*) pickFromVector(panel, signalsPanel, 15, headerHeight, fuFunctions, defaultBar, header);
if (sgn) { if (sgn) {
if (sgn->key != 0) { if (sgn->key != 0) {
Panel_setHeader(panel, "Sending..."); Panel_setHeader(panel, "Sending...");
@ -703,6 +689,7 @@ int main(int argc, char** argv) {
} }
} }
ProcessList_printHeader(pl, Panel_getHeader(panel)); ProcessList_printHeader(pl, Panel_getHeader(panel));
Panel_delete((Object*)signalsPanel);
refreshTimeout = 0; refreshTimeout = 0;
break; break;
} }
@ -744,7 +731,7 @@ int main(int argc, char** argv) {
case '.': case '.':
case KEY_F(6): case KEY_F(6):
{ {
Panel* sortPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare); Panel* sortPanel = Panel_new(0, 0, 0, 0, true, Class(ListItem));
Panel_setHeader(sortPanel, "Sort by"); Panel_setHeader(sortPanel, "Sort by");
const char* fuFunctions[] = {"Sort ", "Cancel ", NULL}; const char* fuFunctions[] = {"Sort ", "Cancel ", NULL};
ProcessField* fields = pl->fields; ProcessField* fields = pl->fields;
@ -762,7 +749,7 @@ int main(int argc, char** argv) {
} else { } else {
ProcessList_printHeader(pl, Panel_getHeader(panel)); ProcessList_printHeader(pl, Panel_getHeader(panel));
} }
((Object*)sortPanel)->delete((Object*)sortPanel); Object_delete(sortPanel);
refreshTimeout = 0; refreshTimeout = 0;
break; break;
} }
@ -858,8 +845,6 @@ int main(int argc, char** argv) {
IncSet_delete(inc); IncSet_delete(inc);
FunctionBar_delete((Object*)defaultBar); FunctionBar_delete((Object*)defaultBar);
Panel_delete((Object*)panel); Panel_delete((Object*)panel);
if (killPanel)
((Object*)killPanel)->delete((Object*)killPanel);
UsersTable_delete(ut); UsersTable_delete(ut);
Settings_delete(settings); Settings_delete(settings);
if(pidWhiteList) { if(pidWhiteList) {