33 Commits
0.6.2 ... 0.6.4

Author SHA1 Message Date
0384613450 Tag release 0.6.4 in revision history 2006-10-06 23:07:46 +00:00
649419abe5 Prepare for next release 2006-10-04 16:42:15 +00:00
2c4d730403 Allocate per-processor values in a contiguous chunk of memory 2006-10-04 16:25:41 +00:00
538d29b3f6 Add changelog entry for Philipp Richter's contribution 2006-10-04 14:48:03 +00:00
3e4f06d101 Contribution by Philipp Richter: Display IO-Wait, IRQ and Soft-IRQ values in status bar
(minor modifications: default to false, add help)
2006-10-04 14:21:27 +00:00
4a93a7e962 changelog entry for Marc's bugfix 2006-08-30 04:38:53 +00:00
ef5b27f33a A fix for long uptimes, sent my Marc Cahalan 2006-08-30 04:37:20 +00:00
cc5af25e11 Fix bug 1538463. 2006-08-24 21:28:29 +00:00
b10821aae9 --sort-key flag in the command-line, overriding the
saved setting in .htoprc for the session.
(thanks to Rodolfo Borges)
2006-08-04 20:54:37 +00:00
bf44e233e6 No longer untag processes after sending a signal
(useful for when SIGTERM fails and one wants to try again
with SIGKILL).
2006-07-23 22:57:25 +00:00
2ecf199cf7 Horizontally scroll in larger increments when on the
Linux console because of slow update of unaccelerated fb
2006-07-23 22:45:24 +00:00
eb2803ce79 Share name strings from UsersList 2006-07-12 01:35:59 +00:00
dbe2670b69 Perform RichString operations by hand.
Avoid unnecessary operations when processing entries on ProcessList.
2006-07-12 01:16:03 +00:00
e46f1426b9 Make checks for headers and libraries actually halt configure. 2006-07-12 01:15:14 +00:00
3bf904b7ce Bringing extra files up-to-date 2006-07-12 01:14:48 +00:00
07030b4518 Minor update to the README file. 2006-07-11 06:20:33 +00:00
5d48ab8c28 Performance improvement hackathon: improve process comparison routines,
disable useless code in release builds such as runtime type-checking on
dynamic data structures and process fields that are not being computed,
faster(?) method for verifying the process owner (still need to ensure
correctness), don't destroy and create process objects for hidden kernel
threads over and over. Phew. I shouldn't be doing all this today, but I
could not resist.
2006-07-11 06:13:32 +00:00
4c41e78bbf Standardize on sourceforge address for htop information. 2006-07-11 00:34:39 +00:00
646f174d26 Bring TODO file back from the dead 2006-07-01 22:52:39 +00:00
2f1f82ee87 Updates for new version of the MakeHeader.py script. 2006-06-06 20:41:01 +00:00
b95993fa22 More information in debug output. 2006-06-06 20:40:29 +00:00
f6e0b7d0c0 Regenerated all headers. 2006-06-06 20:28:42 +00:00
35afc13ebf New version of MakeHeader. Does not use 'private' comment annotation,
using the 'static' storage class instead. Automatically generates
'extern' declarations in headers for non-static data.
2006-06-06 20:28:09 +00:00
5d07013e83 These were merged into LoadAverageMeter.[ch] 2006-06-06 20:14:34 +00:00
8c643f5f89 Use long long types to avoid overflow 2006-06-05 21:28:54 +00:00
d0325cfec5 Disable old hack that's interfering with real debugging. 2006-06-05 15:53:16 +00:00
8bc180b7d1 Display error message when strace is not available.
Mark autogen.sh executable in svn.
2006-06-03 23:14:09 +00:00
57bd892b37 Add "debuglite" mode. 2006-05-30 14:26:30 +00:00
9da282d748 Remove references to ListBox 2006-05-30 14:02:43 +00:00
ea855aef73 Remove references to ListBox 2006-05-30 14:00:18 +00:00
73de9f1ed4 Rename ListBox'es to Panel's, matching dit. 2006-05-30 13:52:12 +00:00
c2cdcd0c1d Rename ListBox to Panel, matching dit. 2006-05-30 13:47:28 +00:00
a853faaa2d Rename TypedVector to Vector, matching dit. 2006-05-30 13:45:40 +00:00
100 changed files with 2451 additions and 2205 deletions

View File

@ -1,72 +0,0 @@
#include "AvailableColumnsListBox.h"
#include "Settings.h"
#include "Header.h"
#include "ScreenManager.h"
#include "ColumnsListBox.h"
#include "ListBox.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct AvailableColumnsListBox_ {
ListBox super;
ListBox* columns;
Settings* settings;
ScreenManager* scr;
} AvailableColumnsListBox;
}*/
AvailableColumnsListBox* AvailableColumnsListBox_new(Settings* settings, ListBox* columns, ScreenManager* scr) {
AvailableColumnsListBox* this = (AvailableColumnsListBox*) malloc(sizeof(AvailableColumnsListBox));
ListBox* super = (ListBox*) this;
ListBox_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = AvailableColumnsListBox_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = AvailableColumnsListBox_eventHandler;
ListBox_setHeader(super, "Available Columns");
for (int i = 1; i < LAST_PROCESSFIELD; i++) {
if (i != COMM)
ListBox_add(super, (Object*) ListItem_new(Process_fieldNames[i], 0));
}
this->columns = columns;
return this;
}
void AvailableColumnsListBox_delete(Object* object) {
ListBox* super = (ListBox*) object;
AvailableColumnsListBox* this = (AvailableColumnsListBox*) object;
ListBox_done(super);
free(this);
}
HandlerResult AvailableColumnsListBox_eventHandler(ListBox* super, int ch) {
AvailableColumnsListBox* this = (AvailableColumnsListBox*) super;
char* text = ((ListItem*) ListBox_getSelected(super))->value;
HandlerResult result = IGNORED;
switch(ch) {
case 13:
case KEY_ENTER:
case KEY_F(5):
{
int at = ListBox_getSelectedIndex(this->columns) + 1;
if (at == ListBox_getSize(this->columns))
at--;
ListBox_insert(this->columns, at, (Object*) ListItem_new(text, 0));
ColumnsListBox_update(this->columns);
result = HANDLED;
break;
}
}
return result;
}

View File

@ -1,31 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_AvailableColumnsListBox
#define HEADER_AvailableColumnsListBox
#include "Settings.h"
#include "Header.h"
#include "ScreenManager.h"
#include "ListBox.h"
#include "debug.h"
#include <assert.h>
typedef struct AvailableColumnsListBox_ {
ListBox super;
Settings* settings;
ScreenManager* scr;
ListBox* columns;
} AvailableColumnsListBox;
AvailableColumnsListBox* AvailableColumnsListBox_new(Settings* settings, ListBox* columns, ScreenManager* scr);
void AvailableColumnsListBox_delete(Object* object);
HandlerResult AvailableColumnsListBox_eventHandler(ListBox* super, int ch);
#endif

72
AvailableColumnsPanel.c Normal file
View File

@ -0,0 +1,72 @@
#include "AvailableColumnsPanel.h"
#include "Settings.h"
#include "Header.h"
#include "ScreenManager.h"
#include "ColumnsPanel.h"
#include "Panel.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct AvailableColumnsPanel_ {
Panel super;
Panel* columns;
Settings* settings;
ScreenManager* scr;
} AvailableColumnsPanel;
}*/
AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr) {
AvailableColumnsPanel* this = (AvailableColumnsPanel*) malloc(sizeof(AvailableColumnsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = AvailableColumnsPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = AvailableColumnsPanel_eventHandler;
Panel_setHeader(super, "Available Columns");
for (int i = 1; i < LAST_PROCESSFIELD; i++) {
if (i != COMM)
Panel_add(super, (Object*) ListItem_new(Process_fieldNames[i], 0));
}
this->columns = columns;
return this;
}
void AvailableColumnsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
AvailableColumnsPanel* this = (AvailableColumnsPanel*) object;
Panel_done(super);
free(this);
}
HandlerResult AvailableColumnsPanel_eventHandler(Panel* super, int ch) {
AvailableColumnsPanel* this = (AvailableColumnsPanel*) super;
char* text = ((ListItem*) Panel_getSelected(super))->value;
HandlerResult result = IGNORED;
switch(ch) {
case 13:
case KEY_ENTER:
case KEY_F(5):
{
int at = Panel_getSelectedIndex(this->columns) + 1;
if (at == Panel_getSize(this->columns))
at--;
Panel_insert(this->columns, at, (Object*) ListItem_new(text, 0));
ColumnsPanel_update(this->columns);
result = HANDLED;
break;
}
}
return result;
}

32
AvailableColumnsPanel.h Normal file
View File

@ -0,0 +1,32 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_AvailableColumnsPanel
#define HEADER_AvailableColumnsPanel
#include "Settings.h"
#include "Header.h"
#include "ScreenManager.h"
#include "ColumnsPanel.h"
#include "Panel.h"
#include "debug.h"
#include <assert.h>
typedef struct AvailableColumnsPanel_ {
Panel super;
Panel* columns;
Settings* settings;
ScreenManager* scr;
} AvailableColumnsPanel;
AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr);
void AvailableColumnsPanel_delete(Object* object);
HandlerResult AvailableColumnsPanel_eventHandler(Panel* super, int ch);
#endif

View File

@ -1,106 +0,0 @@
#include "AvailableMetersListBox.h"
#include "Settings.h"
#include "Header.h"
#include "ScreenManager.h"
#include "ListBox.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct AvailableMetersListBox_ {
ListBox super;
Settings* settings;
ListBox* leftBox;
ListBox* rightBox;
ScreenManager* scr;
} AvailableMetersListBox;
}*/
AvailableMetersListBox* AvailableMetersListBox_new(Settings* settings, ListBox* leftMeters, ListBox* rightMeters, ScreenManager* scr) {
AvailableMetersListBox* this = (AvailableMetersListBox*) malloc(sizeof(AvailableMetersListBox));
ListBox* super = (ListBox*) this;
ListBox_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = AvailableMetersListBox_delete;
this->settings = settings;
this->leftBox = leftMeters;
this->rightBox = rightMeters;
this->scr = scr;
super->eventHandler = AvailableMetersListBox_EventHandler;
ListBox_setHeader(super, "Available meters");
for (int i = 1; Meter_types[i]; i++) {
MeterType* type = Meter_types[i];
if (type != &CPUMeter) {
ListBox_add(super, (Object*) ListItem_new(type->uiName, i << 16));
}
}
MeterType* type = &CPUMeter;
int processors = settings->pl->processorCount;
if (processors > 1) {
ListBox_add(super, (Object*) ListItem_new("CPU average", 0));
for (int i = 1; i <= processors; i++) {
char buffer[50];
sprintf(buffer, "%s %d", type->uiName, i);
ListBox_add(super, (Object*) ListItem_new(buffer, i));
}
} else {
ListBox_add(super, (Object*) ListItem_new("CPU", 1));
}
return this;
}
void AvailableMetersListBox_delete(Object* object) {
ListBox* super = (ListBox*) object;
AvailableMetersListBox* this = (AvailableMetersListBox*) object;
ListBox_done(super);
free(this);
}
/* private */
inline void AvailableMetersListBox_addHeader(Header* header, ListBox* lb, MeterType* type, int param, HeaderSide side) {
Meter* meter = (Meter*) Header_addMeter(header, type, param, side);
ListBox_add(lb, (Object*) Meter_toListItem(meter));
}
HandlerResult AvailableMetersListBox_EventHandler(ListBox* super, int ch) {
AvailableMetersListBox* this = (AvailableMetersListBox*) super;
Header* header = this->settings->header;
ListItem* selected = (ListItem*) ListBox_getSelected(super);
int param = selected->key & 0xff;
int type = selected->key >> 16;
HandlerResult result = IGNORED;
switch(ch) {
case KEY_F(5):
case 'l':
case 'L':
{
AvailableMetersListBox_addHeader(header, this->leftBox, Meter_types[type], param, LEFT_HEADER);
result = HANDLED;
break;
}
case KEY_F(6):
case 'r':
case 'R':
{
AvailableMetersListBox_addHeader(header, this->rightBox, Meter_types[type], param, RIGHT_HEADER);
result = HANDLED;
break;
}
}
if (result == HANDLED) {
this->settings->changed = true;
Header_calculateHeight(header);
Header_draw(header);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
}
return result;
}

View File

@ -1,33 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_AvailableMetersListBox
#define HEADER_AvailableMetersListBox
#include "Settings.h"
#include "Header.h"
#include "ScreenManager.h"
#include "ListBox.h"
#include "debug.h"
#include <assert.h>
typedef struct AvailableMetersListBox_ {
ListBox super;
Settings* settings;
ListBox* leftBox;
ListBox* rightBox;
ScreenManager* scr;
} AvailableMetersListBox;
AvailableMetersListBox* AvailableMetersListBox_new(Settings* settings, ListBox* leftMeters, ListBox* rightMeters, ScreenManager* scr);
void AvailableMetersListBox_delete(Object* object);
HandlerResult AvailableMetersListBox_EventHandler(ListBox* super, int ch);
#endif

106
AvailableMetersPanel.c Normal file
View File

@ -0,0 +1,106 @@
#include "AvailableMetersPanel.h"
#include "Settings.h"
#include "Header.h"
#include "ScreenManager.h"
#include "CPUMeter.h"
#include "Panel.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct AvailableMetersPanel_ {
Panel super;
Settings* settings;
Panel* leftPanel;
Panel* rightPanel;
ScreenManager* scr;
} AvailableMetersPanel;
}*/
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr) {
AvailableMetersPanel* this = (AvailableMetersPanel*) malloc(sizeof(AvailableMetersPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = AvailableMetersPanel_delete;
this->settings = settings;
this->leftPanel = leftMeters;
this->rightPanel = rightMeters;
this->scr = scr;
super->eventHandler = AvailableMetersPanel_EventHandler;
Panel_setHeader(super, "Available meters");
for (int i = 1; Meter_types[i]; i++) {
MeterType* type = Meter_types[i];
if (type != &CPUMeter) {
Panel_add(super, (Object*) ListItem_new(type->uiName, i << 16));
}
}
MeterType* type = &CPUMeter;
int processors = settings->pl->processorCount;
if (processors > 1) {
Panel_add(super, (Object*) ListItem_new("CPU average", 0));
for (int i = 1; i <= processors; i++) {
char buffer[50];
sprintf(buffer, "%s %d", type->uiName, i);
Panel_add(super, (Object*) ListItem_new(buffer, i));
}
} else {
Panel_add(super, (Object*) ListItem_new("CPU", 1));
}
return this;
}
void AvailableMetersPanel_delete(Object* object) {
Panel* super = (Panel*) object;
AvailableMetersPanel* this = (AvailableMetersPanel*) object;
Panel_done(super);
free(this);
}
static inline void AvailableMetersPanel_addHeader(Header* header, Panel* panel, MeterType* type, int param, HeaderSide side) {
Meter* meter = (Meter*) Header_addMeter(header, type, param, side);
Panel_add(panel, (Object*) Meter_toListItem(meter));
}
HandlerResult AvailableMetersPanel_EventHandler(Panel* super, int ch) {
AvailableMetersPanel* this = (AvailableMetersPanel*) super;
Header* header = this->settings->header;
ListItem* selected = (ListItem*) Panel_getSelected(super);
int param = selected->key & 0xff;
int type = selected->key >> 16;
HandlerResult result = IGNORED;
switch(ch) {
case KEY_F(5):
case 'l':
case 'L':
{
AvailableMetersPanel_addHeader(header, this->leftPanel, Meter_types[type], param, LEFT_HEADER);
result = HANDLED;
break;
}
case KEY_F(6):
case 'r':
case 'R':
{
AvailableMetersPanel_addHeader(header, this->rightPanel, Meter_types[type], param, RIGHT_HEADER);
result = HANDLED;
break;
}
}
if (result == HANDLED) {
this->settings->changed = true;
Header_calculateHeight(header);
Header_draw(header);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
}
return result;
}

33
AvailableMetersPanel.h Normal file
View File

@ -0,0 +1,33 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_AvailableMetersPanel
#define HEADER_AvailableMetersPanel
#include "Settings.h"
#include "Header.h"
#include "ScreenManager.h"
#include "CPUMeter.h"
#include "Panel.h"
#include "debug.h"
#include <assert.h>
typedef struct AvailableMetersPanel_ {
Panel super;
Settings* settings;
Panel* leftPanel;
Panel* rightPanel;
ScreenManager* scr;
} AvailableMetersPanel;
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr);
void AvailableMetersPanel_delete(Object* object);
HandlerResult AvailableMetersPanel_EventHandler(Panel* super, int ch);
#endif

View File

@ -18,15 +18,15 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
/* private property */ int CPUMeter_attributes[] = {
static int CPUMeter_attributes[] = { CPU_NICE, CPU_NORMAL, CPU_KERNEL }; CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IOWAIT, CPU_IRQ, CPU_SOFTIRQ
};
/* private */
MeterType CPUMeter = { MeterType CPUMeter = {
.setValues = CPUMeter_setValues, .setValues = CPUMeter_setValues,
.display = CPUMeter_display, .display = CPUMeter_display,
.mode = BAR_METERMODE, .mode = BAR_METERMODE,
.items = 3, .items = 6,
.total = 100.0, .total = 100.0,
.attributes = CPUMeter_attributes, .attributes = CPUMeter_attributes,
.name = "CPU", .name = "CPU",
@ -35,7 +35,6 @@ MeterType CPUMeter = {
.init = CPUMeter_init .init = CPUMeter_init
}; };
/* private */
MeterType AllCPUsMeter = { MeterType AllCPUsMeter = {
.mode = 0, .mode = 0,
.items = 1, .items = 1,
@ -72,26 +71,56 @@ void CPUMeter_setValues(Meter* this, char* buffer, int size) {
ProcessList* pl = this->pl; ProcessList* pl = this->pl;
int processor = this->param; int processor = this->param;
double total = (double) pl->totalPeriod[processor]; double total = (double) pl->totalPeriod[processor];
double cpu;
this->values[0] = pl->nicePeriod[processor] / total * 100.0; this->values[0] = pl->nicePeriod[processor] / total * 100.0;
this->values[1] = pl->userPeriod[processor] / total * 100.0; this->values[1] = pl->userPeriod[processor] / total * 100.0;
if (pl->expandSystemTime) {
this->values[2] = pl->systemPeriod[processor] / total * 100.0; this->values[2] = pl->systemPeriod[processor] / total * 100.0;
double cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]))); this->values[3] = pl->ioWaitPeriod[processor] / total * 100.0;
this->values[4] = pl->irqPeriod[processor] / total * 100.0;
this->values[5] = pl->softIrqPeriod[processor] / total * 100.0;
this->type->items = 6;
cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2]+
this->values[3]+this->values[4]+this->values[5])));
} else {
this->values[2] = pl->systemAllPeriod[processor] / total * 100.0;
this->type->items = 3;
cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2])));
}
snprintf(buffer, size, "%5.1f%%", cpu ); snprintf(buffer, size, "%5.1f%%", cpu );
} }
void CPUMeter_display(Object* cast, RichString* out) { void CPUMeter_display(Object* cast, RichString* out) {
char buffer[50]; char buffer[50];
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
RichString_prune(out); RichString_init(out);
sprintf(buffer, "%5.1f%% ", this->values[1]); sprintf(buffer, "%5.1f%% ", this->values[1]);
RichString_append(out, CRT_colors[METER_TEXT], ":"); RichString_append(out, CRT_colors[METER_TEXT], ":");
RichString_append(out, CRT_colors[CPU_NORMAL], buffer); RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
if (this->pl->expandSystemTime) {
sprintf(buffer, "%5.1f%% ", this->values[2]);
RichString_append(out, CRT_colors[METER_TEXT], "sy:");
RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[0]);
RichString_append(out, CRT_colors[METER_TEXT], "ni:");
RichString_append(out, CRT_colors[CPU_NICE], buffer);
sprintf(buffer, "%5.1f%% ", this->values[3]);
RichString_append(out, CRT_colors[METER_TEXT], "wa:");
RichString_append(out, CRT_colors[CPU_IOWAIT], buffer);
sprintf(buffer, "%5.1f%% ", this->values[4]);
RichString_append(out, CRT_colors[METER_TEXT], "hi:");
RichString_append(out, CRT_colors[CPU_IRQ], buffer);
sprintf(buffer, "%5.1f%% ", this->values[4]);
RichString_append(out, CRT_colors[METER_TEXT], "si:");
RichString_append(out, CRT_colors[CPU_SOFTIRQ], buffer);
} else {
sprintf(buffer, "%5.1f%% ", this->values[2]); sprintf(buffer, "%5.1f%% ", this->values[2]);
RichString_append(out, CRT_colors[METER_TEXT], "sys:"); RichString_append(out, CRT_colors[METER_TEXT], "sys:");
RichString_append(out, CRT_colors[CPU_KERNEL], buffer); RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[0]); sprintf(buffer, "%5.1f%% ", this->values[0]);
RichString_append(out, CRT_colors[METER_TEXT], "low:"); RichString_append(out, CRT_colors[METER_TEXT], "low:");
RichString_append(out, CRT_colors[CPU_NICE], buffer); RichString_append(out, CRT_colors[CPU_NICE], buffer);
}
} }
void AllCPUsMeter_init(Meter* this) { void AllCPUsMeter_init(Meter* this) {

View File

@ -3,7 +3,7 @@
#ifndef HEADER_CPUMeter #ifndef HEADER_CPUMeter
#define HEADER_CPUMeter #define HEADER_CPUMeter
/* /*
htop - CPUMeter.c htop - CPUMeter.h
(C) 2004-2006 Hisham H. Muhammad (C) 2004-2006 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.
@ -21,8 +21,11 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
extern int CPUMeter_attributes[];
extern MeterType CPUMeter;
extern MeterType AllCPUsMeter;
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))

43
CRT.c
View File

@ -93,27 +93,23 @@ typedef enum ColorElements_ {
CPU_NORMAL, CPU_NORMAL,
CPU_KERNEL, CPU_KERNEL,
HELP_BOLD, HELP_BOLD,
CPU_IOWAIT,
CPU_IRQ,
CPU_SOFTIRQ,
LAST_COLORELEMENT LAST_COLORELEMENT
} ColorElements; } ColorElements;
extern int CRT_delay;
extern int CRT_colors[LAST_COLORELEMENT];
extern int CRT_colorScheme;
}*/ }*/
// TODO: centralize these in Settings. // TODO: centralize these in Settings.
/* private property */ int CRT_delay = 0;
int CRT_delay;
/* private property */ int CRT_colorScheme = 0;
int CRT_colorScheme;
/* private property */ int CRT_colors[LAST_COLORELEMENT] = { 0 };
int CRT_colors[LAST_COLORELEMENT];
char* CRT_termType;
// TODO: pass an instance of Settings instead. // TODO: pass an instance of Settings instead.
@ -133,8 +129,8 @@ void CRT_init(int delay, int colorScheme) {
} else { } else {
CRT_hasColors = false; CRT_hasColors = false;
} }
char* termType = getenv("TERM"); CRT_termType = getenv("TERM");
if (String_eq(termType, "xterm") || String_eq(termType, "xterm-color") || String_eq(termType, "vt220")) { if (String_eq(CRT_termType, "xterm") || String_eq(CRT_termType, "xterm-color") || String_eq(CRT_termType, "vt220")) {
define_key("\033[H", KEY_HOME); define_key("\033[H", KEY_HOME);
define_key("\033[F", KEY_END); define_key("\033[F", KEY_END);
define_key("\033OP", KEY_F(1)); define_key("\033OP", KEY_F(1));
@ -167,6 +163,7 @@ void CRT_done() {
int CRT_readKey() { int CRT_readKey() {
nocbreak(); nocbreak();
cbreak(); cbreak();
nodelay(stdscr, FALSE);
int ret = getch(); int ret = getch();
halfdelay(CRT_delay); halfdelay(CRT_delay);
return ret; return ret;
@ -257,6 +254,9 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = A_BOLD; CRT_colors[CHECK_BOX] = A_BOLD;
CRT_colors[CHECK_MARK] = A_NORMAL; CRT_colors[CHECK_MARK] = A_NORMAL;
CRT_colors[CHECK_TEXT] = A_NORMAL; CRT_colors[CHECK_TEXT] = A_NORMAL;
CRT_colors[CPU_IOWAIT] = A_BOLD;
CRT_colors[CPU_IRQ] = A_BOLD;
CRT_colors[CPU_SOFTIRQ] = A_BOLD;
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE) { } else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE) {
CRT_colors[RESET_COLOR] = ColorPair(Black,White); CRT_colors[RESET_COLOR] = ColorPair(Black,White);
CRT_colors[DEFAULT_COLOR] = ColorPair(Black,White); CRT_colors[DEFAULT_COLOR] = ColorPair(Black,White);
@ -309,6 +309,9 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = ColorPair(Blue,White); CRT_colors[CHECK_BOX] = ColorPair(Blue,White);
CRT_colors[CHECK_MARK] = ColorPair(Black,White); CRT_colors[CHECK_MARK] = ColorPair(Black,White);
CRT_colors[CHECK_TEXT] = ColorPair(Black,White); CRT_colors[CHECK_TEXT] = ColorPair(Black,White);
CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,White);
CRT_colors[CPU_IRQ] = ColorPair(Blue,White);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,White);
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE2) { } else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE2) {
CRT_colors[RESET_COLOR] = ColorPair(Black,Black); CRT_colors[RESET_COLOR] = ColorPair(Black,Black);
CRT_colors[DEFAULT_COLOR] = ColorPair(Black,Black); CRT_colors[DEFAULT_COLOR] = ColorPair(Black,Black);
@ -361,6 +364,9 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = ColorPair(Blue,Black); CRT_colors[CHECK_BOX] = ColorPair(Blue,Black);
CRT_colors[CHECK_MARK] = ColorPair(Black,Black); CRT_colors[CHECK_MARK] = ColorPair(Black,Black);
CRT_colors[CHECK_TEXT] = ColorPair(Black,Black); CRT_colors[CHECK_TEXT] = ColorPair(Black,Black);
CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black);
} else if (CRT_colorScheme == COLORSCHEME_MIDNIGHT) { } else if (CRT_colorScheme == COLORSCHEME_MIDNIGHT) {
CRT_colors[RESET_COLOR] = ColorPair(White,Blue); CRT_colors[RESET_COLOR] = ColorPair(White,Blue);
CRT_colors[DEFAULT_COLOR] = ColorPair(White,Blue); CRT_colors[DEFAULT_COLOR] = ColorPair(White,Blue);
@ -413,6 +419,9 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = ColorPair(Cyan,Blue); CRT_colors[CHECK_BOX] = ColorPair(Cyan,Blue);
CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(White,Blue); CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(White,Blue);
CRT_colors[CHECK_TEXT] = A_NORMAL | ColorPair(White,Blue); CRT_colors[CHECK_TEXT] = A_NORMAL | ColorPair(White,Blue);
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Black,Blue);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Black,Blue);
} else if (CRT_colorScheme == COLORSCHEME_BLACKNIGHT) { } else if (CRT_colorScheme == COLORSCHEME_BLACKNIGHT) {
CRT_colors[RESET_COLOR] = ColorPair(Cyan,Black); CRT_colors[RESET_COLOR] = ColorPair(Cyan,Black);
CRT_colors[DEFAULT_COLOR] = ColorPair(Cyan,Black); CRT_colors[DEFAULT_COLOR] = ColorPair(Cyan,Black);
@ -465,6 +474,9 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = ColorPair(Green,Black); CRT_colors[CHECK_BOX] = ColorPair(Green,Black);
CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(Green,Black); CRT_colors[CHECK_MARK] = A_BOLD | ColorPair(Green,Black);
CRT_colors[CHECK_TEXT] = ColorPair(Cyan,Black); CRT_colors[CHECK_TEXT] = ColorPair(Cyan,Black);
CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black);
} else { } else {
/* Default */ /* Default */
CRT_colors[RESET_COLOR] = ColorPair(White,Black); CRT_colors[RESET_COLOR] = ColorPair(White,Black);
@ -518,5 +530,8 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = ColorPair(Cyan,Black); CRT_colors[CHECK_BOX] = ColorPair(Cyan,Black);
CRT_colors[CHECK_MARK] = A_BOLD; CRT_colors[CHECK_MARK] = A_BOLD;
CRT_colors[CHECK_TEXT] = A_NORMAL; CRT_colors[CHECK_TEXT] = A_NORMAL;
CRT_colors[CPU_IOWAIT] = ColorPair(Cyan,Black);
CRT_colors[CPU_IRQ] = ColorPair(Yellow,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Magenta,Black);
} }
} }

37
CRT.h
View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_CRT #ifndef HEADER_CRT
#define HEADER_CRT #define HEADER_CRT
@ -19,6 +19,8 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
#define COLORSCHEME_DEFAULT 0 #define COLORSCHEME_DEFAULT 0
#define COLORSCHEME_MONOCHROME 1 #define COLORSCHEME_MONOCHROME 1
#define COLORSCHEME_BLACKONWHITE 2 #define COLORSCHEME_BLACKONWHITE 2
@ -26,6 +28,15 @@ in the source distribution for its full text.
#define COLORSCHEME_MIDNIGHT 4 #define COLORSCHEME_MIDNIGHT 4
#define COLORSCHEME_BLACKNIGHT 5 #define COLORSCHEME_BLACKNIGHT 5
#define Black COLOR_BLACK
#define Red COLOR_RED
#define Green COLOR_GREEN
#define Yellow COLOR_YELLOW
#define Blue COLOR_BLUE
#define Magenta COLOR_MAGENTA
#define Cyan COLOR_CYAN
#define White COLOR_WHITE
//#link curses //#link curses
bool CRT_hasColors; bool CRT_hasColors;
@ -84,29 +95,39 @@ typedef enum ColorElements_ {
CPU_NORMAL, CPU_NORMAL,
CPU_KERNEL, CPU_KERNEL,
HELP_BOLD, HELP_BOLD,
CPU_IOWAIT,
CPU_IRQ,
CPU_SOFTIRQ,
LAST_COLORELEMENT LAST_COLORELEMENT
} ColorElements; } ColorElements;
extern int CRT_colors[LAST_COLORELEMENT];
extern int CRT_colorScheme; // TODO: centralize these in Settings.
extern int CRT_delay; extern int CRT_delay;
void CRT_init(); extern int CRT_colorScheme;
extern int CRT_colors[LAST_COLORELEMENT];
char* CRT_termType;
// TODO: pass an instance of Settings instead.
void CRT_init(int delay, int colorScheme);
void CRT_done(); void CRT_done();
int CRT_readKey(); int CRT_readKey();
void CRT_disableDelay();
void CRT_enableDelay();
void CRT_handleSIGSEGV(int signal); void CRT_handleSIGSEGV(int signal);
void CRT_handleSIGTERM(int signal); void CRT_handleSIGTERM(int signal);
void CRT_setColors(int colorScheme); void CRT_setColors(int colorScheme);
void CRT_enableDelay();
void CRT_disableDelay();
#endif #endif

View File

@ -1,134 +0,0 @@
#include "CategoriesListBox.h"
#include "AvailableMetersListBox.h"
#include "MetersListBox.h"
#include "DisplayOptionsListBox.h"
#include "ColumnsListBox.h"
#include "ColorsListBox.h"
#include "AvailableColumnsListBox.h"
#include "ListBox.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct CategoriesListBox_ {
ListBox super;
Settings* settings;
ScreenManager* scr;
} CategoriesListBox;
}*/
/* private property */
char* MetersFunctions[10] = {" ", " ", " ", "Type ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done "};
/* private property */
char* AvailableMetersFunctions[10] = {" ", " ", " ", " ", "Add L ", "Add R ", " ", " ", " ", "Done "};
/* private property */
char* DisplayOptionsFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
/* private property */
char* ColumnsFunctions[10] = {" ", " ", " ", " ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done "};
/* private property */
char* ColorsFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
/* private property */
char* AvailableColumnsFunctions[10] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done "};
CategoriesListBox* CategoriesListBox_new(Settings* settings, ScreenManager* scr) {
CategoriesListBox* this = (CategoriesListBox*) malloc(sizeof(CategoriesListBox));
ListBox* super = (ListBox*) this;
ListBox_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = CategoriesListBox_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = CategoriesListBox_eventHandler;
ListBox_setHeader(super, "Setup");
ListBox_add(super, (Object*) ListItem_new("Meters", 0));
ListBox_add(super, (Object*) ListItem_new("Display options", 0));
ListBox_add(super, (Object*) ListItem_new("Colors", 0));
ListBox_add(super, (Object*) ListItem_new("Columns", 0));
return this;
}
void CategoriesListBox_delete(Object* object) {
ListBox* super = (ListBox*) object;
CategoriesListBox* this = (CategoriesListBox*) object;
ListBox_done(super);
free(this);
}
HandlerResult CategoriesListBox_eventHandler(ListBox* super, int ch) {
CategoriesListBox* this = (CategoriesListBox*) super;
HandlerResult result = IGNORED;
int previous = ListBox_getSelectedIndex(super);
switch (ch) {
case KEY_UP:
case KEY_DOWN:
case KEY_NPAGE:
case KEY_PPAGE:
case KEY_HOME:
case KEY_END: {
ListBox_onKey(super, ch);
int selected = ListBox_getSelectedIndex(super);
if (previous != selected) {
int size = ScreenManager_size(this->scr);
for (int i = 1; i < size; i++)
ScreenManager_remove(this->scr, 1);
switch (selected) {
case 0:
CategoriesListBox_makeMetersPage(this);
break;
case 1:
CategoriesListBox_makeDisplayOptionsPage(this);
break;
case 2:
CategoriesListBox_makeColorsPage(this);
break;
case 3:
CategoriesListBox_makeColumnsPage(this);
break;
}
}
result = HANDLED;
}
}
return result;
}
void CategoriesListBox_makeMetersPage(CategoriesListBox* this) {
ListBox* lbLeftMeters = (ListBox*) MetersListBox_new(this->settings, "Left column", this->settings->header->leftMeters, this->scr);
ListBox* lbRightMeters = (ListBox*) MetersListBox_new(this->settings, "Right column", this->settings->header->rightMeters, this->scr);
ListBox* lbAvailableMeters = (ListBox*) AvailableMetersListBox_new(this->settings, lbLeftMeters, lbRightMeters, this->scr);
ScreenManager_add(this->scr, lbLeftMeters, FunctionBar_new(10, MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, lbRightMeters, FunctionBar_new(10, MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, lbAvailableMeters, FunctionBar_new(10, AvailableMetersFunctions, NULL, NULL), -1);
}
void CategoriesListBox_makeDisplayOptionsPage(CategoriesListBox* this) {
ListBox* lbDisplayOptions = (ListBox*) DisplayOptionsListBox_new(this->settings, this->scr);
ScreenManager_add(this->scr, lbDisplayOptions, FunctionBar_new(10, DisplayOptionsFunctions, NULL, NULL), -1);
}
void CategoriesListBox_makeColorsPage(CategoriesListBox* this) {
ListBox* lbColors = (ListBox*) ColorsListBox_new(this->settings, this->scr);
ScreenManager_add(this->scr, lbColors, FunctionBar_new(10, ColorsFunctions, NULL, NULL), -1);
}
void CategoriesListBox_makeColumnsPage(CategoriesListBox* this) {
ListBox* lbColumns = (ListBox*) ColumnsListBox_new(this->settings, this->scr);
ListBox* lbAvailableColumns = (ListBox*) AvailableColumnsListBox_new(this->settings, lbColumns, this->scr);
ScreenManager_add(this->scr, lbColumns, FunctionBar_new(10, ColumnsFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, lbAvailableColumns, FunctionBar_new(10, AvailableColumnsFunctions, NULL, NULL), -1);
}

View File

@ -1,40 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_CategoriesListBox
#define HEADER_CategoriesListBox
#include "AvailableMetersListBox.h"
#include "MetersListBox.h"
#include "DisplayOptionsListBox.h"
#include "ListBox.h"
#include "debug.h"
#include <assert.h>
typedef struct CategoriesListBox_ {
ListBox super;
Settings* settings;
ScreenManager* scr;
} CategoriesListBox;
CategoriesListBox* CategoriesListBox_new(Settings* settings, ScreenManager* scr);
void CategoriesListBox_delete(Object* object);
HandlerResult CategoriesListBox_eventHandler(ListBox* super, int ch);
void CategoriesListBox_makeMetersPage(CategoriesListBox* this);
void CategoriesListBox_makeDisplayOptionsPage(CategoriesListBox* this);
void CategoriesListBox_makeColorsPage(CategoriesListBox* this);
void CategoriesListBox_makeColumnsPage(CategoriesListBox* this);
#endif

128
CategoriesPanel.c Normal file
View File

@ -0,0 +1,128 @@
#include "CategoriesPanel.h"
#include "AvailableMetersPanel.h"
#include "MetersPanel.h"
#include "DisplayOptionsPanel.h"
#include "ColumnsPanel.h"
#include "ColorsPanel.h"
#include "AvailableColumnsPanel.h"
#include "Panel.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct CategoriesPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} CategoriesPanel;
}*/
static char* MetersFunctions[10] = {" ", " ", " ", "Type ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done "};
static char* AvailableMetersFunctions[10] = {" ", " ", " ", " ", "Add L ", "Add R ", " ", " ", " ", "Done "};
static char* DisplayOptionsFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
static char* ColumnsFunctions[10] = {" ", " ", " ", " ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done "};
static char* ColorsFunctions[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done "};
static char* AvailableColumnsFunctions[10] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done "};
CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr) {
CategoriesPanel* this = (CategoriesPanel*) malloc(sizeof(CategoriesPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = CategoriesPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = CategoriesPanel_eventHandler;
Panel_setHeader(super, "Setup");
Panel_add(super, (Object*) ListItem_new("Meters", 0));
Panel_add(super, (Object*) ListItem_new("Display options", 0));
Panel_add(super, (Object*) ListItem_new("Colors", 0));
Panel_add(super, (Object*) ListItem_new("Columns", 0));
return this;
}
void CategoriesPanel_delete(Object* object) {
Panel* super = (Panel*) object;
CategoriesPanel* this = (CategoriesPanel*) object;
Panel_done(super);
free(this);
}
HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
CategoriesPanel* this = (CategoriesPanel*) super;
HandlerResult result = IGNORED;
int previous = Panel_getSelectedIndex(super);
switch (ch) {
case KEY_UP:
case KEY_DOWN:
case KEY_NPAGE:
case KEY_PPAGE:
case KEY_HOME:
case KEY_END: {
Panel_onKey(super, ch);
int selected = Panel_getSelectedIndex(super);
if (previous != selected) {
int size = ScreenManager_size(this->scr);
for (int i = 1; i < size; i++)
ScreenManager_remove(this->scr, 1);
switch (selected) {
case 0:
CategoriesPanel_makeMetersPage(this);
break;
case 1:
CategoriesPanel_makeDisplayOptionsPage(this);
break;
case 2:
CategoriesPanel_makeColorsPage(this);
break;
case 3:
CategoriesPanel_makeColumnsPage(this);
break;
}
}
result = HANDLED;
}
}
return result;
}
void CategoriesPanel_makeMetersPage(CategoriesPanel* this) {
Panel* leftMeters = (Panel*) MetersPanel_new(this->settings, "Left column", this->settings->header->leftMeters, this->scr);
Panel* rightMeters = (Panel*) MetersPanel_new(this->settings, "Right column", this->settings->header->rightMeters, this->scr);
Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->settings, leftMeters, rightMeters, this->scr);
ScreenManager_add(this->scr, leftMeters, FunctionBar_new(10, MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, rightMeters, FunctionBar_new(10, MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableMeters, FunctionBar_new(10, AvailableMetersFunctions, NULL, NULL), -1);
}
void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this) {
Panel* displayOptions = (Panel*) DisplayOptionsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, displayOptions, FunctionBar_new(10, DisplayOptionsFunctions, NULL, NULL), -1);
}
void CategoriesPanel_makeColorsPage(CategoriesPanel* this) {
Panel* colors = (Panel*) ColorsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, colors, FunctionBar_new(10, ColorsFunctions, NULL, NULL), -1);
}
void CategoriesPanel_makeColumnsPage(CategoriesPanel* this) {
Panel* columns = (Panel*) ColumnsPanel_new(this->settings, this->scr);
Panel* availableColumns = (Panel*) AvailableColumnsPanel_new(this->settings, columns, this->scr);
ScreenManager_add(this->scr, columns, FunctionBar_new(10, ColumnsFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableColumns, FunctionBar_new(10, AvailableColumnsFunctions, NULL, NULL), -1);
}

41
CategoriesPanel.h Normal file
View File

@ -0,0 +1,41 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_CategoriesPanel
#define HEADER_CategoriesPanel
#include "AvailableMetersPanel.h"
#include "MetersPanel.h"
#include "DisplayOptionsPanel.h"
#include "ColumnsPanel.h"
#include "ColorsPanel.h"
#include "AvailableColumnsPanel.h"
#include "Panel.h"
#include "debug.h"
#include <assert.h>
typedef struct CategoriesPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} CategoriesPanel;
CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr);
void CategoriesPanel_delete(Object* object);
HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch);
void CategoriesPanel_makeMetersPage(CategoriesPanel* this);
void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this);
void CategoriesPanel_makeColorsPage(CategoriesPanel* this);
void CategoriesPanel_makeColumnsPage(CategoriesPanel* this);
#endif

View File

@ -1,4 +1,34 @@
What's new in version 0.6.4
* Add an option to split the display of kernel time
in the CPU meter into system, IO-wait, IRQ and soft-IRQ.
(thanks to Philipp Richter)
* --sort-key flag in the command-line, overriding the
saved setting in .htoprc for the session.
(thanks to Rodolfo Borges)
* BUGFIX: Fixed string overflow on uptime display.
(thanks to Marc Cahalan)
What's new in version 0.6.3
* Performance improvements: uses much less CPU than the
previous release with the default setup.
* Use 64-bit values when storing processor times to
avoid overflow.
* Memory consumption improvements, compensating storage
of 64-bit values.
* Internal change: rename TypedVector to Vector and
ListBox (and related classes) to Panel.
* Have configure actually fail when needed libraries or
headers are not found.
* Horizontally scroll in larger increments when on the
Linux console because of slow update of unaccelerated fb
* No longer untag processes after sending a signal
(useful for when SIGTERM fails and one wants to try again
with SIGKILL). All processes can be untagged at once with 'U'.
(thanks to A. Costa for the suggestion)
What's new in version 0.6.2 What's new in version 0.6.2
* BUGFIX: Fixed crash when using some .htoprc files from 0.6 * BUGFIX: Fixed crash when using some .htoprc files from 0.6
@ -137,7 +167,7 @@ What's new in version 0.4
* Clock and load average meters * Clock and load average meters
(thanks to Marc Calahan) (thanks to Marc Calahan)
* BUGFIX: numeric swap indicator was printing bogus value * BUGFIX: numeric swap indicator was printing bogus value
* BUGFIX: internal fixes on ListBox widget * BUGFIX: internal fixes on Panel widget
* Clear the bottom line when exiting * Clear the bottom line when exiting
* Press "F3" during search to walk through the results * Press "F3" during search to walk through the results
* Improved navigation on column configuration screen * Improved navigation on column configuration screen

View File

@ -19,15 +19,17 @@ typedef struct CheckItem_ {
bool* value; bool* value;
} CheckItem; } CheckItem;
extern char* CHECKITEM_CLASS;
}*/ }*/
/* private property */ #ifdef DEBUG
char* CHECKITEM_CLASS = "CheckItem"; char* CHECKITEM_CLASS = "CheckItem";
#else
#define CHECKITEM_CLASS NULL
#endif
CheckItem* CheckItem_new(char* text, bool* value) { CheckItem* CheckItem_new(char* text, bool* value) {
CheckItem* this = malloc(sizeof(CheckItem)); CheckItem* this = malloc(sizeof(CheckItem));
((Object*)this)->class = CHECKITEM_CLASS; Object_setClass(this, CHECKITEM_CLASS);
((Object*)this)->display = CheckItem_display; ((Object*)this)->display = CheckItem_display;
((Object*)this)->delete = CheckItem_delete; ((Object*)this)->delete = CheckItem_delete;
this->text = text; this->text = text;

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_CheckItem #ifndef HEADER_CheckItem
#define HEADER_CheckItem #define HEADER_CheckItem
@ -21,8 +21,12 @@ typedef struct CheckItem_ {
bool* value; bool* value;
} CheckItem; } CheckItem;
extern char* CHECKITEM_CLASS;
#ifdef DEBUG
extern char* CHECKITEM_CLASS;
#else
#define CHECKITEM_CLASS NULL
#endif
CheckItem* CheckItem_new(char* text, bool* value); CheckItem* CheckItem_new(char* text, bool* value);

View File

@ -12,10 +12,10 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
/* private */ int ClockMeter_attributes[] = {
static int ClockMeter_attributes[] = { CLOCK }; CLOCK
};
/* private */
MeterType ClockMeter = { MeterType ClockMeter = {
.setValues = ClockMeter_setValues, .setValues = ClockMeter_setValues,
.display = NULL, .display = NULL,

View File

@ -15,6 +15,9 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
extern int ClockMeter_attributes[];
extern MeterType ClockMeter;
void ClockMeter_setValues(Meter* this, char* buffer, int size); void ClockMeter_setValues(Meter* this, char* buffer, int size);

View File

@ -1,32 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_ColorsListBox
#define HEADER_ColorsListBox
#include "ListBox.h"
#include "CheckItem.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
typedef struct ColorsListBox_ {
ListBox super;
Settings* settings;
ScreenManager* scr;
bool check[5];
} ColorsListBox;
ColorsListBox* ColorsListBox_new(Settings* settings, ScreenManager* scr);
void ColorsListBox_delete(Object* object);
HandlerResult ColorsListBox_EventHandler(ListBox* super, int ch);
#endif

View File

@ -1,8 +1,8 @@
#include "CRT.h" #include "CRT.h"
#include "ColorsListBox.h" #include "ColorsPanel.h"
#include "ListBox.h" #include "Panel.h"
#include "CheckItem.h" #include "CheckItem.h"
#include "Settings.h" #include "Settings.h"
#include "ScreenManager.h" #include "ScreenManager.h"
@ -11,24 +11,23 @@
#include <assert.h> #include <assert.h>
// TO ADD A NEW SCHEME: // TO ADD A NEW SCHEME:
// * Increment the size of bool check in ColorsListBox.h // * Increment the size of bool check in ColorsPanel.h
// * Add the entry in the ColorSchemes array below in the file // * Add the entry in the ColorSchemes array below in the file
// * Add a define in CRT.h that matches the order of the array // * Add a define in CRT.h that matches the order of the array
// * Add the colors in CRT_setColors // * Add the colors in CRT_setColors
/*{ /*{
typedef struct ColorsListBox_ { typedef struct ColorsPanel_ {
ListBox super; Panel super;
Settings* settings; Settings* settings;
ScreenManager* scr; ScreenManager* scr;
bool check[5]; bool check[5];
} ColorsListBox; } ColorsPanel;
}*/ }*/
/* private */
static char* ColorSchemes[] = { static char* ColorSchemes[] = {
"Default", "Default",
"Monochromatic", "Monochromatic",
@ -39,37 +38,37 @@ static char* ColorSchemes[] = {
NULL NULL
}; };
ColorsListBox* ColorsListBox_new(Settings* settings, ScreenManager* scr) { ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr) {
ColorsListBox* this = (ColorsListBox*) malloc(sizeof(ColorsListBox)); ColorsPanel* this = (ColorsPanel*) malloc(sizeof(ColorsPanel));
ListBox* super = (ListBox*) this; Panel* super = (Panel*) this;
ListBox_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true); Panel_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true);
((Object*)this)->delete = ColorsListBox_delete; ((Object*)this)->delete = ColorsPanel_delete;
this->settings = settings; this->settings = settings;
this->scr = scr; this->scr = scr;
super->eventHandler = ColorsListBox_EventHandler; super->eventHandler = ColorsPanel_EventHandler;
ListBox_setHeader(super, "Colors"); Panel_setHeader(super, "Colors");
for (int i = 0; ColorSchemes[i] != NULL; i++) { for (int i = 0; ColorSchemes[i] != NULL; i++) {
ListBox_add(super, (Object*) CheckItem_new(String_copy(ColorSchemes[i]), &(this->check[i]))); Panel_add(super, (Object*) CheckItem_new(String_copy(ColorSchemes[i]), &(this->check[i])));
this->check[i] = false; this->check[i] = false;
} }
this->check[settings->colorScheme] = true; this->check[settings->colorScheme] = true;
return this; return this;
} }
void ColorsListBox_delete(Object* object) { void ColorsPanel_delete(Object* object) {
ListBox* super = (ListBox*) object; Panel* super = (Panel*) object;
ColorsListBox* this = (ColorsListBox*) object; ColorsPanel* this = (ColorsPanel*) object;
ListBox_done(super); Panel_done(super);
free(this); free(this);
} }
HandlerResult ColorsListBox_EventHandler(ListBox* super, int ch) { HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
ColorsListBox* this = (ColorsListBox*) super; ColorsPanel* this = (ColorsPanel*) super;
HandlerResult result = IGNORED; HandlerResult result = IGNORED;
int mark = ListBox_getSelectedIndex(super); int mark = Panel_getSelectedIndex(super);
switch(ch) { switch(ch) {
case 0x0a: case 0x0a:
@ -88,10 +87,10 @@ HandlerResult ColorsListBox_EventHandler(ListBox* super, int ch) {
this->settings->changed = true; this->settings->changed = true;
Header* header = this->settings->header; Header* header = this->settings->header;
CRT_setColors(mark); CRT_setColors(mark);
ListBox* lbMenu = (ListBox*) TypedVector_get(this->scr->items, 0); Panel* menu = (Panel*) Vector_get(this->scr->items, 0);
Header_draw(header); Header_draw(header);
RichString_setAttr(&(super->header), CRT_colors[PANEL_HEADER_FOCUS]); RichString_setAttr(&(super->header), CRT_colors[PANEL_HEADER_FOCUS]);
RichString_setAttr(&(lbMenu->header), CRT_colors[PANEL_HEADER_UNFOCUS]); RichString_setAttr(&(menu->header), CRT_colors[PANEL_HEADER_UNFOCUS]);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2); ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
} }
return result; return result;

39
ColorsPanel.h Normal file
View File

@ -0,0 +1,39 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_ColorsPanel
#define HEADER_ColorsPanel
#include "CRT.h"
#include "Panel.h"
#include "CheckItem.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
// TO ADD A NEW SCHEME:
// * Increment the size of bool check in ColorsPanel.h
// * Add the entry in the ColorSchemes array below in the file
// * Add a define in CRT.h that matches the order of the array
// * Add the colors in CRT_setColors
typedef struct ColorsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
bool check[5];
} ColorsPanel;
ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr);
void ColorsPanel_delete(Object* object);
HandlerResult ColorsPanel_EventHandler(Panel* super, int ch);
#endif

View File

@ -1,104 +0,0 @@
#include "ColumnsListBox.h"
#include "ListBox.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct ColumnsListBox_ {
ListBox super;
Settings* settings;
ScreenManager* scr;
} ColumnsListBox;
}*/
ColumnsListBox* ColumnsListBox_new(Settings* settings, ScreenManager* scr) {
ColumnsListBox* this = (ColumnsListBox*) malloc(sizeof(ColumnsListBox));
ListBox* super = (ListBox*) this;
ListBox_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = ColumnsListBox_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = ColumnsListBox_eventHandler;
ListBox_setHeader(super, "Active Columns");
ProcessField* fields = this->settings->pl->fields;
for (; *fields; fields++) {
ListBox_add(super, (Object*) ListItem_new(Process_fieldNames[*fields], 0));
}
return this;
}
void ColumnsListBox_delete(Object* object) {
ListBox* super = (ListBox*) object;
ColumnsListBox* this = (ColumnsListBox*) object;
ListBox_done(super);
free(this);
}
void ColumnsListBox_update(ListBox* super) {
ColumnsListBox* this = (ColumnsListBox*) super;
int size = ListBox_getSize(super);
this->settings->changed = true;
// FIXME: this is crappily inefficient
free(this->settings->pl->fields);
this->settings->pl->fields = (ProcessField*) malloc(sizeof(ProcessField) * (size+1));
for (int i = 0; i < size; i++) {
char* text = ((ListItem*) ListBox_get(super, i))->value;
for (int j = 1; j <= LAST_PROCESSFIELD; j++) {
if (String_eq(text, Process_fieldNames[j])) {
this->settings->pl->fields[i] = j;
break;
}
}
}
this->settings->pl->fields[size] = 0;
}
HandlerResult ColumnsListBox_eventHandler(ListBox* super, int ch) {
int selected = ListBox_getSelectedIndex(super);
HandlerResult result = IGNORED;
int size = ListBox_getSize(super);
switch(ch) {
case KEY_F(7):
case '[':
case '-':
{
if (selected < size - 1)
ListBox_moveSelectedUp(super);
result = HANDLED;
break;
}
case KEY_F(8):
case ']':
case '+':
{
if (selected < size - 2)
ListBox_moveSelectedDown(super);
result = HANDLED;
break;
}
case KEY_F(9):
case KEY_DC:
{
if (selected < size - 1) {
ListBox_remove(super, selected);
}
result = HANDLED;
break;
}
}
if (result == HANDLED)
ColumnsListBox_update(super);
return result;
}

View File

@ -1,32 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_ColumnsListBox
#define HEADER_ColumnsListBox
#include "ListBox.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
typedef struct ColumnsListBox_ {
ListBox super;
Settings* settings;
TypedVector* columns;
ScreenManager* scr;
} ColumnsListBox;
ColumnsListBox* ColumnsListBox_new(Settings* settings, ScreenManager* scr);
void ColumnsListBox_delete(Object* object);
void ColumnsListBox_update(ListBox* super);
HandlerResult ColumnsListBox_eventHandler(ListBox* super, int ch);
#endif

110
ColumnsPanel.c Normal file
View File

@ -0,0 +1,110 @@
#include "ColumnsPanel.h"
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct ColumnsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} ColumnsPanel;
}*/
ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr) {
ColumnsPanel* this = (ColumnsPanel*) malloc(sizeof(ColumnsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = ColumnsPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = ColumnsPanel_eventHandler;
Panel_setHeader(super, "Active Columns");
ProcessField* fields = this->settings->pl->fields;
for (; *fields; fields++) {
Panel_add(super, (Object*) ListItem_new(Process_fieldNames[*fields], 0));
}
return this;
}
void ColumnsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
ColumnsPanel* this = (ColumnsPanel*) object;
Panel_done(super);
free(this);
}
int ColumnsPanel_fieldNameToIndex(const char* name) {
for (int j = 1; j <= LAST_PROCESSFIELD; j++) {
if (String_eq(name, Process_fieldNames[j])) {
return j;
}
}
return 0;
}
void ColumnsPanel_update(Panel* super) {
ColumnsPanel* this = (ColumnsPanel*) super;
int size = Panel_getSize(super);
this->settings->changed = true;
// FIXME: this is crappily inefficient
free(this->settings->pl->fields);
this->settings->pl->fields = (ProcessField*) malloc(sizeof(ProcessField) * (size+1));
for (int i = 0; i < size; i++) {
char* text = ((ListItem*) Panel_get(super, i))->value;
int j = ColumnsPanel_fieldNameToIndex(text);
if (j > 0)
this->settings->pl->fields[i] = j;
}
this->settings->pl->fields[size] = 0;
}
HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch) {
int selected = Panel_getSelectedIndex(super);
HandlerResult result = IGNORED;
int size = Panel_getSize(super);
switch(ch) {
case KEY_F(7):
case '[':
case '-':
{
if (selected < size - 1)
Panel_moveSelectedUp(super);
result = HANDLED;
break;
}
case KEY_F(8):
case ']':
case '+':
{
if (selected < size - 2)
Panel_moveSelectedDown(super);
result = HANDLED;
break;
}
case KEY_F(9):
case KEY_DC:
{
if (selected < size - 1) {
Panel_remove(super, selected);
}
result = HANDLED;
break;
}
}
if (result == HANDLED)
ColumnsPanel_update(super);
return result;
}

33
ColumnsPanel.h Normal file
View File

@ -0,0 +1,33 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_ColumnsPanel
#define HEADER_ColumnsPanel
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
typedef struct ColumnsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} ColumnsPanel;
ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr);
void ColumnsPanel_delete(Object* object);
int ColumnsPanel_fieldNameToIndex(const char* name);
void ColumnsPanel_update(Panel* super);
HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch);
#endif

View File

@ -1,25 +1,25 @@
#define _GNU_SOURCE #define _GNU_SOURCE
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <assert.h> #include <assert.h>
#include "DebugMemory.h"
#undef strdup #undef strdup
#undef malloc #undef malloc
#undef realloc #undef realloc
#undef calloc #undef calloc
#undef free #undef free
#include "DebugMemory.h"
/*{ /*{
typedef struct DebugMemoryItem_ DebugMemoryItem; typedef struct DebugMemoryItem_ DebugMemoryItem;
struct DebugMemoryItem_ { struct DebugMemoryItem_ {
int magic;
void* data; void* data;
char* file; char* file;
int line; int line;
@ -31,12 +31,15 @@ typedef struct DebugMemory_ {
int allocations; int allocations;
int deallocations; int deallocations;
int size; int size;
bool totals;
FILE* file; FILE* file;
} DebugMemory; } DebugMemory;
}*/ }*/
/* private property */ #if defined(DEBUG)
DebugMemory* singleton = NULL;
static DebugMemory* singleton = NULL;
void DebugMemory_new() { void DebugMemory_new() {
if (singleton) if (singleton)
@ -47,40 +50,60 @@ void DebugMemory_new() {
singleton->deallocations = 0; singleton->deallocations = 0;
singleton->size = 0; singleton->size = 0;
singleton->file = fopen("/tmp/htop-debug-alloc.txt", "w"); singleton->file = fopen("/tmp/htop-debug-alloc.txt", "w");
singleton->totals = true;
//singleton->file = NULL;
} }
void* DebugMemory_malloc(int size, char* file, int line) { void* DebugMemory_malloc(int size, char* file, int line, char* str) {
void* data = malloc(size); void* data = malloc(size);
DebugMemory_registerAllocation(data, file, line); DebugMemory_registerAllocation(data, file, line);
fprintf(singleton->file, "%d\t%s:%d\n", size, file, line); if (singleton->file) {
if (singleton->totals) fprintf(singleton->file, "%d\t", singleton->size);
fprintf(singleton->file, "%d\t%s:%d (%s)\n", size, file, line, str);
}
return data; return data;
} }
void* DebugMemory_calloc(int a, int b, char* file, int line) { void* DebugMemory_calloc(int a, int b, char* file, int line) {
void* data = calloc(a, b); void* data = calloc(a, b);
DebugMemory_registerAllocation(data, file, line); DebugMemory_registerAllocation(data, file, line);
if (singleton->file) {
if (singleton->totals) fprintf(singleton->file, "%d\t", singleton->size);
fprintf(singleton->file, "%d\t%s:%d\n", a*b, file, line); fprintf(singleton->file, "%d\t%s:%d\n", a*b, file, line);
}
return data; return data;
} }
void* DebugMemory_realloc(void* ptr, int size, char* file, int line) { void* DebugMemory_realloc(void* ptr, int size, char* file, int line, char* str) {
if (ptr != NULL) if (ptr != NULL)
DebugMemory_registerDeallocation(ptr, file, line); DebugMemory_registerDeallocation(ptr, file, line);
void* data = realloc(ptr, size); void* data = realloc(ptr, size);
DebugMemory_registerAllocation(data, file, line); DebugMemory_registerAllocation(data, file, line);
fprintf(singleton->file, "%d\t%s:%d\n", size, file, line); if (singleton->file) {
if (singleton->totals) fprintf(singleton->file, "%d\t", singleton->size);
fprintf(singleton->file, "%d\t%s:%d (%s)\n", size, file, line, str);
}
return data; return data;
} }
void* DebugMemory_strdup(char* str, char* file, int line) { void* DebugMemory_strdup(char* str, char* file, int line) {
assert(str);
char* data = strdup(str); char* data = strdup(str);
DebugMemory_registerAllocation(data, file, line); DebugMemory_registerAllocation(data, file, line);
if (singleton->file) {
if (singleton->totals) fprintf(singleton->file, "%d\t", singleton->size);
fprintf(singleton->file, "%d\t%s:%d\n", (int) strlen(str), file, line); fprintf(singleton->file, "%d\t%s:%d\n", (int) strlen(str), file, line);
}
return data; return data;
} }
void DebugMemory_free(void* data, char* file, int line) { void DebugMemory_free(void* data, char* file, int line) {
assert(data);
DebugMemory_registerDeallocation(data, file, line); DebugMemory_registerDeallocation(data, file, line);
if (singleton->file) {
if (singleton->totals) fprintf(singleton->file, "%d\t", singleton->size);
fprintf(singleton->file, "free\t%s:%d\n", file, line);
}
free(data); free(data);
} }
@ -91,6 +114,7 @@ void DebugMemory_assertSize() {
DebugMemoryItem* walk = singleton->first; DebugMemoryItem* walk = singleton->first;
int i = 0; int i = 0;
while (walk != NULL) { while (walk != NULL) {
assert(walk->magic == 11061980);
i++; i++;
walk = walk->next; walk = walk->next;
} }
@ -104,6 +128,7 @@ int DebugMemory_getBlockCount() {
DebugMemoryItem* walk = singleton->first; DebugMemoryItem* walk = singleton->first;
int i = 0; int i = 0;
while (walk != NULL) { while (walk != NULL) {
assert(walk->magic == 11061980);
i++; i++;
walk = walk->next; walk = walk->next;
} }
@ -115,6 +140,7 @@ void DebugMemory_registerAllocation(void* data, char* file, int line) {
DebugMemory_new(); DebugMemory_new();
DebugMemory_assertSize(); DebugMemory_assertSize();
DebugMemoryItem* item = (DebugMemoryItem*) malloc(sizeof(DebugMemoryItem)); DebugMemoryItem* item = (DebugMemoryItem*) malloc(sizeof(DebugMemoryItem));
item->magic = 11061980;
item->data = data; item->data = data;
item->file = file; item->file = file;
item->line = line; item->line = line;
@ -130,6 +156,7 @@ void DebugMemory_registerAllocation(void* data, char* file, int line) {
walk->next = item; walk->next = item;
break; break;
} }
assert(walk->magic == 11061980);
walk = walk->next; walk = walk->next;
} }
} }
@ -141,14 +168,13 @@ void DebugMemory_registerAllocation(void* data, char* file, int line) {
} }
void DebugMemory_registerDeallocation(void* data, char* file, int line) { void DebugMemory_registerDeallocation(void* data, char* file, int line) {
if (!data)
return;
assert(singleton); assert(singleton);
assert(singleton->first); assert(singleton->first);
DebugMemoryItem* walk = singleton->first; DebugMemoryItem* walk = singleton->first;
DebugMemoryItem* prev = NULL; DebugMemoryItem* prev = NULL;
int val = DebugMemory_getBlockCount(); int val = DebugMemory_getBlockCount();
while (walk != NULL) { while (walk != NULL) {
assert(walk->magic == 11061980);
if (walk->data == data) { if (walk->data == data) {
if (prev == NULL) { if (prev == NULL) {
singleton->first = walk->next; singleton->first = walk->next;
@ -176,6 +202,7 @@ void DebugMemory_report() {
DebugMemoryItem* walk = singleton->first; DebugMemoryItem* walk = singleton->first;
int i = 0; int i = 0;
while (walk != NULL) { while (walk != NULL) {
assert(walk->magic == 11061980);
i++; i++;
fprintf(stderr, "%p %s:%d\n", walk->data, walk->file, walk->line); fprintf(stderr, "%p %s:%d\n", walk->data, walk->file, walk->line);
walk = walk->next; walk = walk->next;
@ -185,5 +212,12 @@ void DebugMemory_report() {
fprintf(stderr, "%d deallocations\n", singleton->deallocations); fprintf(stderr, "%d deallocations\n", singleton->deallocations);
fprintf(stderr, "%d size\n", singleton->size); fprintf(stderr, "%d size\n", singleton->size);
fprintf(stderr, "%d non-freed blocks\n", i); fprintf(stderr, "%d non-freed blocks\n", i);
if (singleton->file)
fclose(singleton->file); fclose(singleton->file);
} }
#elif defined(DEBUGLITE)
//#include "efence.h"
#endif

View File

@ -1,27 +1,27 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_DebugMemory #ifndef HEADER_DebugMemory
#define HEADER_DebugMemory #define HEADER_DebugMemory
#define _GNU_SOURCE #define _GNU_SOURCE
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <assert.h> #include <assert.h>
#undef strdup #undef strdup
#undef malloc #undef malloc
#undef realloc #undef realloc
#undef calloc #undef calloc
#undef free #undef free
typedef struct DebugMemoryItem_ DebugMemoryItem; typedef struct DebugMemoryItem_ DebugMemoryItem;
struct DebugMemoryItem_ { struct DebugMemoryItem_ {
int magic;
void* data; void* data;
char* file; char* file;
int line; int line;
@ -33,17 +33,20 @@ typedef struct DebugMemory_ {
int allocations; int allocations;
int deallocations; int deallocations;
int size; int size;
bool totals;
FILE* file; FILE* file;
} DebugMemory; } DebugMemory;
#if defined(DEBUG)
void DebugMemory_new(); void DebugMemory_new();
void* DebugMemory_malloc(int size, char* file, int line); void* DebugMemory_malloc(int size, char* file, int line, char* str);
void* DebugMemory_calloc(int a, int b, char* file, int line); void* DebugMemory_calloc(int a, int b, char* file, int line);
void* DebugMemory_realloc(void* ptr, int size, char* file, int line); void* DebugMemory_realloc(void* ptr, int size, char* file, int line, char* str);
void* DebugMemory_strdup(char* str, char* file, int line); void* DebugMemory_strdup(char* str, char* file, int line);
@ -59,4 +62,10 @@ void DebugMemory_registerDeallocation(void* data, char* file, int line);
void DebugMemory_report(); void DebugMemory_report();
#elif defined(DEBUGLITE)
//#include "efence.h"
#endif
#endif #endif

View File

@ -1,75 +0,0 @@
#include "DisplayOptionsListBox.h"
#include "ListBox.h"
#include "CheckItem.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct DisplayOptionsListBox_ {
ListBox super;
Settings* settings;
ScreenManager* scr;
} DisplayOptionsListBox;
}*/
DisplayOptionsListBox* DisplayOptionsListBox_new(Settings* settings, ScreenManager* scr) {
DisplayOptionsListBox* this = (DisplayOptionsListBox*) malloc(sizeof(DisplayOptionsListBox));
ListBox* super = (ListBox*) this;
ListBox_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true);
((Object*)this)->delete = DisplayOptionsListBox_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = DisplayOptionsListBox_EventHandler;
ListBox_setHeader(super, "Display options");
ListBox_add(super, (Object*) CheckItem_new(String_copy("Tree view"), &(settings->pl->treeView)));
ListBox_add(super, (Object*) CheckItem_new(String_copy("Shadow other users' processes"), &(settings->pl->shadowOtherUsers)));
ListBox_add(super, (Object*) CheckItem_new(String_copy("Hide kernel threads"), &(settings->pl->hideKernelThreads)));
ListBox_add(super, (Object*) CheckItem_new(String_copy("Hide userland threads"), &(settings->pl->hideUserlandThreads)));
ListBox_add(super, (Object*) CheckItem_new(String_copy("Highlight program \"basename\""), &(settings->pl->highlightBaseName)));
ListBox_add(super, (Object*) CheckItem_new(String_copy("Highlight megabytes in memory counters"), &(settings->pl->highlightMegabytes)));
ListBox_add(super, (Object*) CheckItem_new(String_copy("Leave a margin around header"), &(settings->header->margin)));
return this;
}
void DisplayOptionsListBox_delete(Object* object) {
ListBox* super = (ListBox*) object;
DisplayOptionsListBox* this = (DisplayOptionsListBox*) object;
ListBox_done(super);
free(this);
}
HandlerResult DisplayOptionsListBox_EventHandler(ListBox* super, int ch) {
DisplayOptionsListBox* this = (DisplayOptionsListBox*) super;
HandlerResult result = IGNORED;
CheckItem* selected = (CheckItem*) ListBox_getSelected(super);
switch(ch) {
case 0x0a:
case 0x0d:
case KEY_ENTER:
case ' ':
*(selected->value) = ! *(selected->value);
result = HANDLED;
}
if (result == HANDLED) {
this->settings->changed = true;
Header* header = this->settings->header;
Header_calculateHeight(header);
Header_draw(header);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
}
return result;
}

View File

@ -1,31 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_DisplayOptionsListBox
#define HEADER_DisplayOptionsListBox
#include "ListBox.h"
#include "CheckItem.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
typedef struct DisplayOptionsListBox_ {
ListBox super;
Settings* settings;
ScreenManager* scr;
} DisplayOptionsListBox;
DisplayOptionsListBox* DisplayOptionsListBox_new(Settings* settings, ScreenManager* scr);
void DisplayOptionsListBox_delete(Object* object);
HandlerResult DisplayOptionsListBox_EventHandler(ListBox* super, int ch);
#endif

76
DisplayOptionsPanel.c Normal file
View File

@ -0,0 +1,76 @@
#include "DisplayOptionsPanel.h"
#include "Panel.h"
#include "CheckItem.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct DisplayOptionsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} DisplayOptionsPanel;
}*/
DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr) {
DisplayOptionsPanel* this = (DisplayOptionsPanel*) malloc(sizeof(DisplayOptionsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true);
((Object*)this)->delete = DisplayOptionsPanel_delete;
this->settings = settings;
this->scr = scr;
super->eventHandler = DisplayOptionsPanel_EventHandler;
Panel_setHeader(super, "Display options");
Panel_add(super, (Object*) CheckItem_new(String_copy("Tree view"), &(settings->pl->treeView)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Shadow other users' processes"), &(settings->pl->shadowOtherUsers)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide kernel threads"), &(settings->pl->hideKernelThreads)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Hide userland threads"), &(settings->pl->hideUserlandThreads)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight program \"basename\""), &(settings->pl->highlightBaseName)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Highlight megabytes in memory counters"), &(settings->pl->highlightMegabytes)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Leave a margin around header"), &(settings->header->margin)));
Panel_add(super, (Object*) CheckItem_new(String_copy("Split System Time into System/IO-Wait/Hard-IRQ/Soft-IRQ"), &(settings->pl->expandSystemTime)));
return this;
}
void DisplayOptionsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
DisplayOptionsPanel* this = (DisplayOptionsPanel*) object;
Panel_done(super);
free(this);
}
HandlerResult DisplayOptionsPanel_EventHandler(Panel* super, int ch) {
DisplayOptionsPanel* this = (DisplayOptionsPanel*) super;
HandlerResult result = IGNORED;
CheckItem* selected = (CheckItem*) Panel_getSelected(super);
switch(ch) {
case 0x0a:
case 0x0d:
case KEY_ENTER:
case ' ':
*(selected->value) = ! *(selected->value);
result = HANDLED;
}
if (result == HANDLED) {
this->settings->changed = true;
Header* header = this->settings->header;
Header_calculateHeight(header);
Header_draw(header);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
}
return result;
}

31
DisplayOptionsPanel.h Normal file
View File

@ -0,0 +1,31 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_DisplayOptionsPanel
#define HEADER_DisplayOptionsPanel
#include "Panel.h"
#include "CheckItem.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
typedef struct DisplayOptionsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} DisplayOptionsPanel;
DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr);
void DisplayOptionsPanel_delete(Object* object);
HandlerResult DisplayOptionsPanel_EventHandler(Panel* super, int ch);
#endif

View File

@ -28,25 +28,23 @@ typedef struct FunctionBar_ {
bool staticData; bool staticData;
} FunctionBar; } FunctionBar;
extern char* FUNCTIONBAR_CLASS;
}*/ }*/
/* private property */ #ifdef DEBUG
char* FUNCTIONBAR_CLASS = "FunctionBar"; char* FUNCTIONBAR_CLASS = "FunctionBar";
#else
#define FUNCTIONBAR_CLASS NULL
#endif
/* private property */
static char* FunctionBar_FKeys[10] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"}; static char* FunctionBar_FKeys[10] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"};
/* private property */
static char* FunctionBar_FLabels[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " "}; static char* FunctionBar_FLabels[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
/* private property */
static int FunctionBar_FEvents[10] = {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[10] = {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)};
FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events) { FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events) {
FunctionBar* this = malloc(sizeof(FunctionBar)); FunctionBar* this = malloc(sizeof(FunctionBar));
((Object*) this)->class = FUNCTIONBAR_CLASS; Object_setClass(this, FUNCTIONBAR_CLASS);
((Object*) this)->delete = FunctionBar_delete; ((Object*) this)->delete = FunctionBar_delete;
this->functions = functions; this->functions = functions;
this->size = size; this->size = size;

View File

@ -1,9 +1,9 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_FunctionBar #ifndef HEADER_FunctionBar
#define HEADER_FunctionBar #define HEADER_FunctionBar
/* /*
htop htop - FunctionBar.h
(C) 2004-2006 Hisham H. Muhammad (C) 2004-2006 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.
@ -30,16 +30,21 @@ typedef struct FunctionBar_ {
bool staticData; bool staticData;
} FunctionBar; } FunctionBar;
#ifdef DEBUG
extern char* FUNCTIONBAR_CLASS; extern char* FUNCTIONBAR_CLASS;
#else
#define FUNCTIONBAR_CLASS NULL
#endif
FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events); FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events);
void FunctionBar_delete(Object* this); void FunctionBar_delete(Object* cast);
void FunctionBar_draw(FunctionBar* this, char* buffer);
void FunctionBar_setLabel(FunctionBar* this, int event, char* text); void FunctionBar_setLabel(FunctionBar* this, int event, char* text);
void FunctionBar_draw(FunctionBar* this, char* buffer);
void FunctionBar_drawAttr(FunctionBar* this, char* buffer, int attr); void FunctionBar_drawAttr(FunctionBar* this, char* buffer, int attr);
int FunctionBar_synthesizeEvent(FunctionBar* this, int pos); int FunctionBar_synthesizeEvent(FunctionBar* this, int pos);

View File

@ -16,7 +16,6 @@ in the source distribution for its full text.
typedef struct Hashtable_ Hashtable; typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*); typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem { typedef struct HashtableItem {
int key; int key;
@ -28,7 +27,6 @@ struct Hashtable_ {
int size; int size;
HashtableItem** buckets; HashtableItem** buckets;
int items; int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner; bool owner;
}; };
}*/ }*/
@ -49,15 +47,10 @@ Hashtable* Hashtable_new(int size, bool owner) {
this = (Hashtable*) malloc(sizeof(Hashtable)); this = (Hashtable*) malloc(sizeof(Hashtable));
this->size = size; this->size = size;
this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size); this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size);
this->hashAlgorithm = Hashtable_hashAlgorithm;
this->owner = owner; this->owner = owner;
return this; return this;
} }
int Hashtable_hashAlgorithm(Hashtable* this, int key) {
return (key % this->size);
}
void Hashtable_delete(Hashtable* this) { void Hashtable_delete(Hashtable* this) {
for (int i = 0; i < this->size; i++) { for (int i = 0; i < this->size; i++) {
HashtableItem* walk = this->buckets[i]; HashtableItem* walk = this->buckets[i];
@ -78,7 +71,7 @@ inline int Hashtable_size(Hashtable* this) {
} }
void Hashtable_put(Hashtable* this, int key, void* value) { void Hashtable_put(Hashtable* this, int key, void* value) {
int index = this->hashAlgorithm(this, key); int index = key % this->size;
HashtableItem** bucketPtr = &(this->buckets[index]); HashtableItem** bucketPtr = &(this->buckets[index]);
while (true) while (true)
if (*bucketPtr == NULL) { if (*bucketPtr == NULL) {
@ -95,7 +88,7 @@ void Hashtable_put(Hashtable* this, int key, void* value) {
} }
void* Hashtable_remove(Hashtable* this, int key) { void* Hashtable_remove(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key); int index = key % this->size;
HashtableItem** bucketPtr = &(this->buckets[index]); HashtableItem** bucketPtr = &(this->buckets[index]);
while (true) while (true)
if (*bucketPtr == NULL) { if (*bucketPtr == NULL) {
@ -116,17 +109,20 @@ void* Hashtable_remove(Hashtable* this, int key) {
} else } else
bucketPtr = &((*bucketPtr)->next); bucketPtr = &((*bucketPtr)->next);
} }
//#include <stdio.h>
inline void* Hashtable_get(Hashtable* this, int key) { inline void* Hashtable_get(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key); int index = key % this->size;
HashtableItem* bucketPtr = this->buckets[index]; HashtableItem* bucketPtr = this->buckets[index];
while (true) // fprintf(stderr, "%d -> %d\n", key, index);
while (true) {
if (bucketPtr == NULL) { if (bucketPtr == NULL) {
return NULL; return NULL;
} else if (bucketPtr->key == key) { } else if (bucketPtr->key == key) {
return bucketPtr->value; return bucketPtr->value;
} else } else
bucketPtr = bucketPtr->next; bucketPtr = bucketPtr->next;
// fprintf(stderr, "*\n");
}
} }
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) { void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) {

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Hashtable #ifndef HEADER_Hashtable
#define HEADER_Hashtable #define HEADER_Hashtable
@ -18,7 +18,6 @@ in the source distribution for its full text.
typedef struct Hashtable_ Hashtable; typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*); typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem { typedef struct HashtableItem {
int key; int key;
@ -30,7 +29,6 @@ struct Hashtable_ {
int size; int size;
HashtableItem** buckets; HashtableItem** buckets;
int items; int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner; bool owner;
}; };
@ -38,8 +36,6 @@ HashtableItem* HashtableItem_new(int key, void* value);
Hashtable* Hashtable_new(int size, bool owner); Hashtable* Hashtable_new(int size, bool owner);
int Hashtable_hashAlgorithm(Hashtable* this, int key);
void Hashtable_delete(Hashtable* this); void Hashtable_delete(Hashtable* this);
inline int Hashtable_size(Hashtable* this); inline int Hashtable_size(Hashtable* this);
@ -47,7 +43,7 @@ inline int Hashtable_size(Hashtable* this);
void Hashtable_put(Hashtable* this, int key, void* value); void Hashtable_put(Hashtable* this, int key, void* value);
void* Hashtable_remove(Hashtable* this, int key); void* Hashtable_remove(Hashtable* this, int key);
//#include <stdio.h>
inline void* Hashtable_get(Hashtable* this, int key); inline void* Hashtable_get(Hashtable* this, int key);
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData); void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData);

View File

@ -19,8 +19,8 @@ typedef enum HeaderSide_ {
} HeaderSide; } HeaderSide;
typedef struct Header_ { typedef struct Header_ {
TypedVector* leftMeters; Vector* leftMeters;
TypedVector* rightMeters; Vector* rightMeters;
ProcessList* pl; ProcessList* pl;
bool margin; bool margin;
int height; int height;
@ -35,21 +35,21 @@ typedef struct Header_ {
Header* Header_new(ProcessList* pl) { Header* Header_new(ProcessList* pl) {
Header* this = malloc(sizeof(Header)); Header* this = malloc(sizeof(Header));
this->leftMeters = TypedVector_new(METER_CLASS, true, DEFAULT_SIZE); this->leftMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE, NULL);
this->rightMeters = TypedVector_new(METER_CLASS, true, DEFAULT_SIZE); this->rightMeters = Vector_new(METER_CLASS, true, DEFAULT_SIZE, NULL);
this->margin = true; this->margin = true;
this->pl = pl; this->pl = pl;
return this; return this;
} }
void Header_delete(Header* this) { void Header_delete(Header* this) {
TypedVector_delete(this->leftMeters); Vector_delete(this->leftMeters);
TypedVector_delete(this->rightMeters); Vector_delete(this->rightMeters);
free(this); free(this);
} }
void Header_createMeter(Header* this, char* name, HeaderSide side) { void Header_createMeter(Header* this, char* name, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER Vector* meters = side == LEFT_HEADER
? this->leftMeters ? this->leftMeters
: this->rightMeters; : this->rightMeters;
@ -62,44 +62,44 @@ void Header_createMeter(Header* this, char* name, HeaderSide side) {
} }
for (MeterType** type = Meter_types; *type; type++) { for (MeterType** type = Meter_types; *type; type++) {
if (String_eq(name, (*type)->name)) { if (String_eq(name, (*type)->name)) {
TypedVector_add(meters, Meter_new(this->pl, param, *type)); Vector_add(meters, Meter_new(this->pl, param, *type));
break; break;
} }
} }
} }
void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side) { void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER Vector* meters = side == LEFT_HEADER
? this->leftMeters ? this->leftMeters
: this->rightMeters; : this->rightMeters;
Meter* meter = (Meter*) TypedVector_get(meters, i); Meter* meter = (Meter*) Vector_get(meters, i);
Meter_setMode(meter, mode); Meter_setMode(meter, mode);
} }
Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side) { Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER Vector* meters = side == LEFT_HEADER
? this->leftMeters ? this->leftMeters
: this->rightMeters; : this->rightMeters;
Meter* meter = Meter_new(this->pl, param, type); Meter* meter = Meter_new(this->pl, param, type);
TypedVector_add(meters, meter); Vector_add(meters, meter);
return meter; return meter;
} }
int Header_size(Header* this, HeaderSide side) { int Header_size(Header* this, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER Vector* meters = side == LEFT_HEADER
? this->leftMeters ? this->leftMeters
: this->rightMeters; : this->rightMeters;
return TypedVector_size(meters); return Vector_size(meters);
} }
char* Header_readMeterName(Header* this, int i, HeaderSide side) { char* Header_readMeterName(Header* this, int i, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER Vector* meters = side == LEFT_HEADER
? this->leftMeters ? this->leftMeters
: this->rightMeters; : this->rightMeters;
Meter* meter = (Meter*) TypedVector_get(meters, i); Meter* meter = (Meter*) Vector_get(meters, i);
int nameLen = strlen(meter->type->name); int nameLen = strlen(meter->type->name);
int len = nameLen + 100; int len = nameLen + 100;
@ -113,21 +113,21 @@ char* Header_readMeterName(Header* this, int i, HeaderSide side) {
} }
MeterModeId Header_readMeterMode(Header* this, int i, HeaderSide side) { MeterModeId Header_readMeterMode(Header* this, int i, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER Vector* meters = side == LEFT_HEADER
? this->leftMeters ? this->leftMeters
: this->rightMeters; : this->rightMeters;
Meter* meter = (Meter*) TypedVector_get(meters, i); Meter* meter = (Meter*) Vector_get(meters, i);
return meter->mode; return meter->mode;
} }
void Header_defaultMeters(Header* this) { void Header_defaultMeters(Header* this) {
TypedVector_add(this->leftMeters, Meter_new(this->pl, 0, &AllCPUsMeter)); Vector_add(this->leftMeters, Meter_new(this->pl, 0, &AllCPUsMeter));
TypedVector_add(this->leftMeters, Meter_new(this->pl, 0, &MemoryMeter)); Vector_add(this->leftMeters, Meter_new(this->pl, 0, &MemoryMeter));
TypedVector_add(this->leftMeters, Meter_new(this->pl, 0, &SwapMeter)); Vector_add(this->leftMeters, Meter_new(this->pl, 0, &SwapMeter));
TypedVector_add(this->rightMeters, Meter_new(this->pl, 0, &TasksMeter)); Vector_add(this->rightMeters, Meter_new(this->pl, 0, &TasksMeter));
TypedVector_add(this->rightMeters, Meter_new(this->pl, 0, &LoadAverageMeter)); Vector_add(this->rightMeters, Meter_new(this->pl, 0, &LoadAverageMeter));
TypedVector_add(this->rightMeters, Meter_new(this->pl, 0, &UptimeMeter)); Vector_add(this->rightMeters, Meter_new(this->pl, 0, &UptimeMeter));
} }
void Header_draw(Header* this) { void Header_draw(Header* this) {
@ -138,13 +138,13 @@ void Header_draw(Header* this) {
for (int y = 0; y < height; y++) { for (int y = 0; y < height; y++) {
mvhline(y, 0, ' ', COLS); mvhline(y, 0, ' ', COLS);
} }
for (int y = (pad / 2), i = 0; i < TypedVector_size(this->leftMeters); i++) { for (int y = (pad / 2), i = 0; i < Vector_size(this->leftMeters); i++) {
Meter* meter = (Meter*) TypedVector_get(this->leftMeters, i); Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
meter->draw(meter, pad, y, COLS / 2 - (pad * 2 - 1) - 1); meter->draw(meter, pad, y, COLS / 2 - (pad * 2 - 1) - 1);
y += meter->h; y += meter->h;
} }
for (int y = (pad / 2), i = 0; i < TypedVector_size(this->rightMeters); i++) { for (int y = (pad / 2), i = 0; i < Vector_size(this->rightMeters); i++) {
Meter* meter = (Meter*) TypedVector_get(this->rightMeters, i); Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
meter->draw(meter, COLS / 2 + pad, y, COLS / 2 - (pad * 2 - 1) - 1); meter->draw(meter, COLS / 2 + pad, y, COLS / 2 - (pad * 2 - 1) - 1);
y += meter->h; y += meter->h;
} }
@ -155,12 +155,12 @@ int Header_calculateHeight(Header* this) {
int leftHeight = pad; int leftHeight = pad;
int rightHeight = pad; int rightHeight = pad;
for (int i = 0; i < TypedVector_size(this->leftMeters); i++) { for (int i = 0; i < Vector_size(this->leftMeters); i++) {
Meter* meter = (Meter*) TypedVector_get(this->leftMeters, i); Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
leftHeight += meter->h; leftHeight += meter->h;
} }
for (int i = 0; i < TypedVector_size(this->rightMeters); i++) { for (int i = 0; i < Vector_size(this->rightMeters); i++) {
Meter* meter = (Meter*) TypedVector_get(this->rightMeters, i); Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
rightHeight += meter->h; rightHeight += meter->h;
} }
this->pad = pad; this->pad = pad;

View File

@ -3,7 +3,7 @@
#ifndef HEADER_Header #ifndef HEADER_Header
#define HEADER_Header #define HEADER_Header
/* /*
htop - Header.c htop - Header.h
(C) 2004-2006 Hisham H. Muhammad (C) 2004-2006 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.
@ -21,8 +21,8 @@ typedef enum HeaderSide_ {
} HeaderSide; } HeaderSide;
typedef struct Header_ { typedef struct Header_ {
TypedVector* leftMeters; Vector* leftMeters;
TypedVector* rightMeters; Vector* rightMeters;
ProcessList* pl; ProcessList* pl;
bool margin; bool margin;
int height; int height;

101
ListBox.h
View File

@ -1,101 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_ListBox
#define HEADER_ListBox
/*
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Object.h"
#include "TypedVector.h"
#include "CRT.h"
#include "RichString.h"
#include <math.h>
#include <sys/param.h>
#include <stdbool.h>
#include "debug.h"
#include <assert.h>
#include <curses.h>
//#link curses
typedef struct ListBox_ ListBox;
typedef enum HandlerResult_ {
HANDLED,
IGNORED,
BREAK_LOOP
} HandlerResult;
typedef HandlerResult(*ListBox_EventHandler)(ListBox*, int);
struct ListBox_ {
Object super;
int x, y, w, h;
WINDOW* window;
TypedVector* items;
int selected;
int scrollV, scrollH;
int oldSelected;
bool needsRedraw;
RichString header;
ListBox_EventHandler eventHandler;
};
extern char* LISTBOX_CLASS;
ListBox* ListBox_new(int x, int y, int w, int h, char* type, bool owner);
void ListBox_delete(Object* cast);
void ListBox_init(ListBox* this, int x, int y, int w, int h, char* type, bool owner);
void ListBox_done(ListBox* this);
void ListBox_setEventHandler(ListBox* this, ListBox_EventHandler eh);
void ListBox_setRichHeader(ListBox* this, RichString header);
void ListBox_setHeader(ListBox* this, char* header);
void ListBox_move(ListBox* this, int x, int y);
void ListBox_resize(ListBox* this, int w, int h);
void ListBox_prune(ListBox* this);
void ListBox_add(ListBox* this, Object* o);
void ListBox_insert(ListBox* this, int i, Object* o);
void ListBox_set(ListBox* this, int i, Object* o);
Object* ListBox_get(ListBox* this, int i);
Object* ListBox_remove(ListBox* this, int i);
Object* ListBox_getSelected(ListBox* this);
void ListBox_moveSelectedUp(ListBox* this);
void ListBox_moveSelectedDown(ListBox* this);
int ListBox_getSelectedIndex(ListBox* this);
int ListBox_getSize(ListBox* this);
void ListBox_setSelected(ListBox* this, int selected);
void ListBox_draw(ListBox* this, bool focus);
void ListBox_onKey(ListBox* this, int key);
#endif

View File

@ -21,18 +21,19 @@ typedef struct ListItem_ {
int key; int key;
} ListItem; } ListItem;
extern char* LISTITEM_CLASS;
}*/ }*/
/* private property */ #ifdef DEBUG
char* LISTITEM_CLASS = "ListItem"; char* LISTITEM_CLASS = "ListItem";
#else
#define LISTITEM_CLASS NULL
#endif
ListItem* ListItem_new(char* value, int key) { ListItem* ListItem_new(char* value, int key) {
ListItem* this = malloc(sizeof(ListItem)); ListItem* this = malloc(sizeof(ListItem));
((Object*)this)->class = LISTITEM_CLASS; Object_setClass(this, LISTITEM_CLASS);
((Object*)this)->display = ListItem_display; ((Object*)this)->display = ListItem_display;
((Object*)this)->delete = ListItem_delete; ((Object*)this)->delete = ListItem_delete;
((Object*)this)->compare = ListItem_compare;
this->value = String_copy(value); this->value = String_copy(value);
this->key = key; this->key = key;
return this; return this;
@ -64,7 +65,7 @@ const char* ListItem_getRef(ListItem* this) {
return this->value; return this->value;
} }
int ListItem_compare(const Object* cast1, const Object* cast2) { int ListItem_compare(const void* cast1, const void* cast2) {
ListItem* obj1 = (ListItem*) cast1; ListItem* obj1 = (ListItem*) cast1;
ListItem* obj2 = (ListItem*) cast2; ListItem* obj2 = (ListItem*) cast2;
return strcmp(obj1->value, obj2->value); return strcmp(obj1->value, obj2->value);

View File

@ -1,9 +1,9 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_ListItem #ifndef HEADER_ListItem
#define HEADER_ListItem #define HEADER_ListItem
/* /*
htop htop - ListItem.h
(C) 2004-2006 Hisham H. Muhammad (C) 2004-2006 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.
@ -16,24 +16,31 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
typedef struct ListItem_ { typedef struct ListItem_ {
Object super; Object super;
char* value; char* value;
int key; int key;
} ListItem; } ListItem;
#ifdef DEBUG
extern char* LISTITEM_CLASS; extern char* LISTITEM_CLASS;
#else
#define LISTITEM_CLASS NULL
#endif
ListItem* ListItem_new(char* value, int key); ListItem* ListItem_new(char* value, int key);
void ListItem_append(ListItem* this, char* text);
void ListItem_delete(Object* cast); void ListItem_delete(Object* cast);
void ListItem_display(Object* cast, RichString* out); void ListItem_display(Object* cast, RichString* out);
void ListItem_append(ListItem* this, char* text);
const char* ListItem_getRef(ListItem* this); const char* ListItem_getRef(ListItem* this);
int ListItem_compare(const Object*, const Object*); int ListItem_compare(const void* cast1, const void* cast2);
#endif #endif

View File

@ -12,10 +12,10 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
/* private property */ int LoadAverageMeter_attributes[] = {
int LoadAverageMeter_attributes[] = { LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIVE, LOAD_AVERAGE_ONE }; LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIVE, LOAD_AVERAGE_ONE
};
/* private */
MeterType LoadAverageMeter = { MeterType LoadAverageMeter = {
.setValues = LoadAverageMeter_setValues, .setValues = LoadAverageMeter_setValues,
.display = LoadAverageMeter_display, .display = LoadAverageMeter_display,
@ -28,10 +28,8 @@ MeterType LoadAverageMeter = {
.caption = "Load average: " .caption = "Load average: "
}; };
/* private property */
int LoadMeter_attributes[] = { LOAD }; int LoadMeter_attributes[] = { LOAD };
/* private */
MeterType LoadMeter = { MeterType LoadMeter = {
.setValues = LoadMeter_setValues, .setValues = LoadMeter_setValues,
.display = LoadMeter_display, .display = LoadMeter_display,
@ -44,8 +42,7 @@ MeterType LoadMeter = {
.caption = "Load: " .caption = "Load: "
}; };
/* private */ static inline void LoadAverageMeter_scan(double* one, double* five, double* fifteen) {
inline static void LoadAverageMeter_scan(double* one, double* five, double* fifteen) {
int activeProcs, totalProcs, lastProc; int activeProcs, totalProcs, lastProc;
FILE *fd = fopen(PROCDIR "/loadavg", "r"); FILE *fd = fopen(PROCDIR "/loadavg", "r");
int read = fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen, int read = fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen,
@ -63,7 +60,7 @@ void LoadAverageMeter_setValues(Meter* this, char* buffer, int size) {
void LoadAverageMeter_display(Object* cast, RichString* out) { void LoadAverageMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
char buffer[20]; char buffer[20];
RichString_prune(out); RichString_init(out);
sprintf(buffer, "%.2f ", this->values[2]); sprintf(buffer, "%.2f ", this->values[2]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer); RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
sprintf(buffer, "%.2f ", this->values[1]); sprintf(buffer, "%.2f ", this->values[1]);
@ -84,7 +81,7 @@ void LoadMeter_setValues(Meter* this, char* buffer, int size) {
void LoadMeter_display(Object* cast, RichString* out) { void LoadMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
char buffer[20]; char buffer[20];
RichString_prune(out); RichString_init(out);
sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]); sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
RichString_append(out, CRT_colors[LOAD], buffer); RichString_append(out, CRT_colors[LOAD], buffer);
} }

View File

@ -15,10 +15,13 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
extern int LoadAverageMeter_attributes[];
extern MeterType LoadAverageMeter;
extern int LoadMeter_attributes[];
extern MeterType LoadMeter;
void LoadAverageMeter_setValues(Meter* this, char* buffer, int size); void LoadAverageMeter_setValues(Meter* this, char* buffer, int size);

View File

@ -1,63 +0,0 @@
/*
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "LoadMeter.h"
#include "Meter.h"
#include "ProcessList.h"
#include "debug.h"
/*{
typedef struct LoadMeter_ LoadMeter;
struct LoadMeter_ {
Meter super;
ProcessList* pl;
};
}*/
LoadMeter* LoadMeter_new() {
LoadMeter* this = malloc(sizeof(LoadMeter));
Meter_init((Meter*)this, String_copy("Load"), String_copy("Load: "), 1);
((Meter*)this)->attributes[0] = LOAD;
((Meter*)this)->setValues = LoadMeter_setValues;
((Object*)this)->display = LoadMeter_display;
Meter_setMode((Meter*)this, GRAPH);
((Meter*)this)->total = 1.0;
return this;
}
/* private */
void LoadMeter_scan(double* one, double* five, double* fifteen) {
int activeProcs, totalProcs, lastProc;
FILE *fd = fopen(PROCDIR "/loadavg", "r");
int read = fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen,
&activeProcs, &totalProcs, &lastProc);
(void) read;
assert(read == 6);
fclose(fd);
}
void LoadMeter_setValues(Meter* cast) {
double five, fifteen;
LoadMeter_scan(&cast->values[0], &five, &fifteen);
if (cast->values[0] > cast->total) {
cast->total = cast->values[0];
}
snprintf(cast->displayBuffer.c, 7, "%.2f", cast->values[0]);
}
void LoadMeter_display(Object* cast, RichString* out) {
LoadMeter* this = (LoadMeter*)cast;
char buffer[20];
RichString_prune(out);
sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
RichString_append(out, CRT_colors[LOAD], buffer);
}

View File

@ -1,34 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_LoadMeter
#define HEADER_LoadMeter
/*
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Meter.h"
#include "ProcessList.h"
#include "debug.h"
typedef struct LoadMeter_ LoadMeter;
struct LoadMeter_ {
Meter super;
ProcessList* pl;
};
LoadMeter* LoadMeter_new();
void LoadMeter_setValues(Meter* cast);
void LoadMeter_display(Object* cast, RichString* out);
#endif

View File

@ -1,7 +1,8 @@
bin_PROGRAMS = htop bin_PROGRAMS = htop
dist_man_MANS = htop.1 dist_man_MANS = htop.1
EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png scripts/MakeHeader.py EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png scripts/MakeHeader.py \
install-sh autogen.sh missing
applicationsdir = $(datadir)/applications applicationsdir = $(datadir)/applications
applications_DATA = htop.desktop applications_DATA = htop.desktop
pixmapdir = $(datadir)/pixmaps pixmapdir = $(datadir)/pixmaps
@ -10,22 +11,28 @@ pixmap_DATA = htop.png
AM_CFLAGS = -pedantic -Wall -std=c99 AM_CFLAGS = -pedantic -Wall -std=c99
AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\" AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
htop_SOURCES = AvailableMetersListBox.c CategoriesListBox.c ClockMeter.c \ htop_SOURCES = AvailableMetersPanel.c CategoriesPanel.c ClockMeter.c \
CPUMeter.c CRT.c DebugMemory.c DisplayOptionsListBox.c FunctionBar.c \ CPUMeter.c CRT.c DebugMemory.c DisplayOptionsPanel.c FunctionBar.c \
Hashtable.c Header.c htop.c ListBox.c ListItem.c LoadAverageMeter.c \ Hashtable.c Header.c htop.c Panel.c ListItem.c LoadAverageMeter.c \
MemoryMeter.c Meter.c MetersListBox.c Object.c Process.c \ MemoryMeter.c Meter.c MetersPanel.c Object.c Process.c \
ProcessList.c RichString.c ScreenManager.c Settings.c SignalItem.c \ ProcessList.c RichString.c ScreenManager.c Settings.c SignalItem.c \
SignalsListBox.c String.c SwapMeter.c TasksMeter.c TypedVector.c \ SignalsPanel.c String.c SwapMeter.c TasksMeter.c Vector.c \
UptimeMeter.c UsersTable.c AvailableMetersListBox.h CategoriesListBox.h \ UptimeMeter.c UsersTable.c AvailableMetersPanel.h CategoriesPanel.h \
ClockMeter.h config.h CPUMeter.h CRT.h debug.h DebugMemory.h \ ClockMeter.h config.h CPUMeter.h CRT.h debug.h DebugMemory.h \
DisplayOptionsListBox.h FunctionBar.h Hashtable.h Header.h htop.h ListBox.h \ DisplayOptionsPanel.h FunctionBar.h Hashtable.h Header.h htop.h Panel.h \
ListItem.h LoadAverageMeter.h MemoryMeter.h Meter.h \ ListItem.h LoadAverageMeter.h MemoryMeter.h Meter.h \
MetersListBox.h Object.h Process.h ProcessList.h RichString.h ScreenManager.h \ MetersPanel.h Object.h Process.h ProcessList.h RichString.h ScreenManager.h \
Settings.h SignalItem.h SignalsListBox.h String.h SwapMeter.h TasksMeter.h \ Settings.h SignalItem.h SignalsPanel.h String.h SwapMeter.h TasksMeter.h \
TypedVector.h UptimeMeter.h UsersTable.h CheckItem.c CheckItem.h \ Vector.h UptimeMeter.h UsersTable.h CheckItem.c CheckItem.h \
ColorsListBox.c ColorsListBox.h TraceScreen.c TraceScreen.h \ ColorsPanel.c ColorsPanel.h TraceScreen.c TraceScreen.h \
AvailableColumnsListBox.c AvailableColumnsListBox.h ColumnsListBox.c \ AvailableColumnsPanel.c AvailableColumnsPanel.h ColumnsPanel.c \
ColumnsListBox.h ColumnsPanel.h
profile:
$(MAKE) all CFLAGS="-pg -O2"
debug: debug:
$(MAKE) all CFLAGS="-g -DDEBUG" $(MAKE) all CFLAGS="-g -DDEBUG"
debuglite:
$(MAKE) all CFLAGS="-g -DDEBUGLITE"

View File

@ -19,10 +19,10 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
/* private property */ int MemoryMeter_attributes[] = {
static int MemoryMeter_attributes[] = { MEMORY_USED, MEMORY_BUFFERS, MEMORY_CACHE }; MEMORY_USED, MEMORY_BUFFERS, MEMORY_CACHE
};
/* private */
MeterType MemoryMeter = { MeterType MemoryMeter = {
.setValues = MemoryMeter_setValues, .setValues = MemoryMeter_setValues,
.display = MemoryMeter_display, .display = MemoryMeter_display,
@ -55,7 +55,7 @@ void MemoryMeter_display(Object* cast, RichString* out) {
long int usedMem = this->values[0] / div; long int usedMem = this->values[0] / div;
long int buffersMem = this->values[1] / div; long int buffersMem = this->values[1] / div;
long int cachedMem = this->values[2] / div; long int cachedMem = this->values[2] / div;
RichString_prune(out); RichString_init(out);
RichString_append(out, CRT_colors[METER_TEXT], ":"); RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, format, totalMem); sprintf(buffer, format, totalMem);
RichString_append(out, CRT_colors[METER_VALUE], buffer); RichString_append(out, CRT_colors[METER_VALUE], buffer);

View File

@ -22,7 +22,9 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
extern int MemoryMeter_attributes[];
extern MeterType MemoryMeter;
void MemoryMeter_setValues(Meter* this, char* buffer, int size); void MemoryMeter_setValues(Meter* this, char* buffer, int size);

67
Meter.c
View File

@ -76,18 +76,6 @@ struct Meter_ {
double total; double total;
}; };
extern char* METER_CLASS;
extern MeterType CPUMeter;
extern MeterType ClockMeter;
extern MeterType LoadAverageMeter;
extern MeterType LoadMeter;
extern MeterType MemoryMeter;
extern MeterType SwapMeter;
extern MeterType TasksMeter;
extern MeterType UptimeMeter;
extern MeterType AllCPUsMeter;
typedef enum { typedef enum {
CUSTOM_METERMODE = 0, CUSTOM_METERMODE = 0,
BAR_METERMODE, BAR_METERMODE,
@ -99,11 +87,16 @@ typedef enum {
LAST_METERMODE LAST_METERMODE
} MeterModeId; } MeterModeId;
extern MeterType* Meter_types[];
extern MeterMode* Meter_modes[];
}*/ }*/
#include "CPUMeter.h"
#include "MemoryMeter.h"
#include "SwapMeter.h"
#include "TasksMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
#include "ClockMeter.h"
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
#endif #endif
@ -111,10 +104,12 @@ extern MeterMode* Meter_modes[];
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
/* private property */ #ifdef DEBUG
char* METER_CLASS = "Meter"; char* METER_CLASS = "Meter";
#else
#define METER_CLASS NULL
#endif
/* private */
MeterType* Meter_types[] = { MeterType* Meter_types[] = {
&CPUMeter, &CPUMeter,
&ClockMeter, &ClockMeter,
@ -128,14 +123,12 @@ MeterType* Meter_types[] = {
NULL NULL
}; };
/* private */
static MeterMode BarMeterMode = { static MeterMode BarMeterMode = {
.uiName = "Bar", .uiName = "Bar",
.h = 1, .h = 1,
.draw = BarMeterMode_draw, .draw = BarMeterMode_draw,
}; };
/* private */
static MeterMode TextMeterMode = { static MeterMode TextMeterMode = {
.uiName = "Text", .uiName = "Text",
.h = 1, .h = 1,
@ -143,22 +136,21 @@ static MeterMode TextMeterMode = {
}; };
#ifdef USE_FUNKY_MODES #ifdef USE_FUNKY_MODES
/* private */
static MeterMode GraphMeterMode = { static MeterMode GraphMeterMode = {
.uiName = "Graph", .uiName = "Graph",
.h = 3, .h = 3,
.draw = GraphMeterMode_draw, .draw = GraphMeterMode_draw,
}; };
/* private */
static MeterMode LEDMeterMode = { static MeterMode LEDMeterMode = {
.uiName = "LED", .uiName = "LED",
.h = 3, .h = 3,
.draw = LEDMeterMode_draw, .draw = LEDMeterMode_draw,
}; };
#endif #endif
/* private */
MeterMode* Meter_modes[] = { MeterMode* Meter_modes[] = {
NULL, NULL,
&BarMeterMode, &BarMeterMode,
@ -170,11 +162,13 @@ MeterMode* Meter_modes[] = {
NULL NULL
}; };
/* private property */
static RichString Meter_stringBuffer; static RichString Meter_stringBuffer;
Meter* Meter_new(ProcessList* pl, int param, MeterType* type) { Meter* Meter_new(ProcessList* pl, int param, MeterType* type) {
Meter* this = calloc(sizeof(Meter), 1); Meter* this = calloc(sizeof(Meter), 1);
Object_setClass(this, METER_CLASS);
((Object*)this)->delete = Meter_delete;
((Object*)this)->display = type->display;
this->h = 1; this->h = 1;
this->type = type; this->type = type;
this->param = param; this->param = param;
@ -182,9 +176,6 @@ Meter* Meter_new(ProcessList* pl, int param, MeterType* type) {
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);
((Object*)this)->delete = Meter_delete;
((Object*)this)->class = METER_CLASS;
((Object*)this)->display = type->display;
Meter_setMode(this, type->mode); Meter_setMode(this, type->mode);
if (this->type->init) if (this->type->init)
this->type->init(this); this->type->init(this);
@ -209,14 +200,13 @@ void Meter_setCaption(Meter* this, char* caption) {
this->caption = strdup(caption); this->caption = strdup(caption);
} }
/* private */ static inline void Meter_displayToStringBuffer(Meter* this, char* buffer) {
inline static void Meter_displayToStringBuffer(Meter* this, char* buffer) {
MeterType* type = this->type; MeterType* type = this->type;
Object_Display display = ((Object*)this)->display; Object_Display display = ((Object*)this)->display;
if (display) { if (display) {
display((Object*)this, &Meter_stringBuffer); display((Object*)this, &Meter_stringBuffer);
} else { } else {
RichString_prune(&Meter_stringBuffer); RichString_initVal(Meter_stringBuffer);
RichString_append(&Meter_stringBuffer, CRT_colors[type->attributes[0]], buffer); RichString_append(&Meter_stringBuffer, CRT_colors[type->attributes[0]], buffer);
} }
} }
@ -281,8 +271,7 @@ void TextMeterMode_draw(Meter* this, int x, int y, int w) {
/* ---------- BarMeterMode ---------- */ /* ---------- BarMeterMode ---------- */
/* private property */ static char BarMeterMode_characters[] = "|#*@$%&";
char BarMeterMode_characters[] = "|#*@$%&";
void BarMeterMode_draw(Meter* this, int x, int y, int w) { void BarMeterMode_draw(Meter* this, int x, int y, int w) {
MeterType* type = this->type; MeterType* type = this->type;
@ -360,14 +349,16 @@ void BarMeterMode_draw(Meter* this, int x, int y, int w) {
#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)
/* private */ static int GraphMeterMode_colors[21] = {
static int GraphMeterMode_colors[21] = {GRAPH_1, GRAPH_1, GRAPH_1, GRAPH_1, GRAPH_1, GRAPH_1,
GRAPH_2, GRAPH_2, GRAPH_2, GRAPH_3, GRAPH_3, GRAPH_3, GRAPH_2, GRAPH_2, GRAPH_2,
GRAPH_4, GRAPH_4, GRAPH_4, GRAPH_5, GRAPH_5, GRAPH_6, GRAPH_3, GRAPH_3, GRAPH_3,
GRAPH_7, GRAPH_7, GRAPH_7, GRAPH_8, GRAPH_8, GRAPH_9 GRAPH_4, GRAPH_4, GRAPH_4,
GRAPH_5, GRAPH_5, GRAPH_6,
GRAPH_7, GRAPH_7, GRAPH_7,
GRAPH_8, GRAPH_8, GRAPH_9
}; };
/* private property */
static char* GraphMeterMode_characters = "^`'-.,_~'`-.,_~'`-.,_"; static char* GraphMeterMode_characters = "^`'-.,_~'`-.,_~'`-.,_";
void GraphMeterMode_draw(Meter* this, int x, int y, int w) { void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
@ -405,14 +396,12 @@ void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
/* ---------- LEDMeterMode ---------- */ /* ---------- LEDMeterMode ---------- */
/* private */
static char* LEDMeterMode_digits[3][10] = { static char* LEDMeterMode_digits[3][10] = {
{ " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ "}, { " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ "},
{ "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|"}, { "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|"},
{ "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|"}, { "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|"},
}; };
/* private */
static void LEDMeterMode_drawDigit(int x, int y, int n) { static void LEDMeterMode_drawDigit(int x, int y, int n) {
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_digits[i][n]);

39
Meter.h
View File

@ -3,7 +3,7 @@
#ifndef HEADER_Meter #ifndef HEADER_Meter
#define HEADER_Meter #define HEADER_Meter
/* /*
htop - Meter.c htop - Meter.h
(C) 2004-2006 Hisham H. Muhammad (C) 2004-2006 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.
@ -78,18 +78,6 @@ struct Meter_ {
double total; double total;
}; };
extern char* METER_CLASS;
extern MeterType CPUMeter;
extern MeterType ClockMeter;
extern MeterType LoadAverageMeter;
extern MeterType LoadMeter;
extern MeterType MemoryMeter;
extern MeterType SwapMeter;
extern MeterType TasksMeter;
extern MeterType UptimeMeter;
extern MeterType AllCPUsMeter;
typedef enum { typedef enum {
CUSTOM_METERMODE = 0, CUSTOM_METERMODE = 0,
BAR_METERMODE, BAR_METERMODE,
@ -101,9 +89,14 @@ typedef enum {
LAST_METERMODE LAST_METERMODE
} MeterModeId; } MeterModeId;
extern MeterType* Meter_types[];
extern MeterMode* Meter_modes[];
#include "CPUMeter.h"
#include "MemoryMeter.h"
#include "SwapMeter.h"
#include "TasksMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
#include "ClockMeter.h"
#ifndef MIN #ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
@ -112,15 +105,19 @@ extern MeterMode* Meter_modes[];
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
#ifdef DEBUG
extern char* METER_CLASS;
#else
#define METER_CLASS NULL
#endif
extern MeterType* Meter_types[];
#ifdef USE_FUNKY_MODES #ifdef USE_FUNKY_MODES
#endif #endif
extern MeterMode* Meter_modes[];
Meter* Meter_new(ProcessList* pl, int param, MeterType* type); Meter* Meter_new(ProcessList* pl, int param, MeterType* type);
@ -128,7 +125,6 @@ void Meter_delete(Object* cast);
void Meter_setCaption(Meter* this, char* caption); void Meter_setCaption(Meter* this, char* caption);
void Meter_setMode(Meter* this, int modeIndex); void Meter_setMode(Meter* this, int modeIndex);
ListItem* Meter_toListItem(Meter* this); ListItem* Meter_toListItem(Meter* this);
@ -139,7 +135,6 @@ void TextMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- BarMeterMode ---------- */ /* ---------- BarMeterMode ---------- */
void BarMeterMode_draw(Meter* this, int x, int y, int w); void BarMeterMode_draw(Meter* this, int x, int y, int w);
#ifdef USE_FUNKY_MODES #ifdef USE_FUNKY_MODES
@ -148,14 +143,10 @@ void BarMeterMode_draw(Meter* this, int x, int y, int w);
#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)
void GraphMeterMode_draw(Meter* this, int x, int y, int w); void GraphMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- LEDMeterMode ---------- */ /* ---------- LEDMeterMode ---------- */
void LEDMeterMode_draw(Meter* this, int x, int y, int w); void LEDMeterMode_draw(Meter* this, int x, int y, int w);
#endif #endif

View File

@ -1,105 +0,0 @@
#include "MetersListBox.h"
#include "ListBox.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct MetersListBox_ {
ListBox super;
Settings* settings;
TypedVector* meters;
ScreenManager* scr;
} MetersListBox;
}*/
MetersListBox* MetersListBox_new(Settings* settings, char* header, TypedVector* meters, ScreenManager* scr) {
MetersListBox* this = (MetersListBox*) malloc(sizeof(MetersListBox));
ListBox* super = (ListBox*) this;
ListBox_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = MetersListBox_delete;
this->settings = settings;
this->meters = meters;
this->scr = scr;
super->eventHandler = MetersListBox_EventHandler;
ListBox_setHeader(super, header);
for (int i = 0; i < TypedVector_size(meters); i++) {
Meter* meter = (Meter*) TypedVector_get(meters, i);
ListBox_add(super, (Object*) Meter_toListItem(meter));
}
return this;
}
void MetersListBox_delete(Object* object) {
ListBox* super = (ListBox*) object;
MetersListBox* this = (MetersListBox*) object;
ListBox_done(super);
free(this);
}
HandlerResult MetersListBox_EventHandler(ListBox* super, int ch) {
MetersListBox* this = (MetersListBox*) super;
int selected = ListBox_getSelectedIndex(super);
HandlerResult result = IGNORED;
switch(ch) {
case 0x0a:
case 0x0d:
case KEY_ENTER:
case KEY_F(4):
case 't':
{
Meter* meter = (Meter*) TypedVector_get(this->meters, selected);
int mode = meter->mode + 1;
if (mode == LAST_METERMODE) mode = 1;
Meter_setMode(meter, mode);
ListBox_set(super, selected, (Object*) Meter_toListItem(meter));
result = HANDLED;
break;
}
case KEY_F(7):
case '[':
case '-':
{
TypedVector_moveUp(this->meters, selected);
ListBox_moveSelectedUp(super);
result = HANDLED;
break;
}
case KEY_F(8):
case ']':
case '+':
{
TypedVector_moveDown(this->meters, selected);
ListBox_moveSelectedDown(super);
result = HANDLED;
break;
}
case KEY_F(9):
case KEY_DC:
{
if (selected < TypedVector_size(this->meters)) {
TypedVector_remove(this->meters, selected);
ListBox_remove(super, selected);
}
result = HANDLED;
break;
}
}
if (result == HANDLED) {
Header* header = this->settings->header;
Header_calculateHeight(header);
Header_draw(header);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
}
return result;
}

View File

@ -1,30 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_MetersListBox
#define HEADER_MetersListBox
#include "ListBox.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
typedef struct MetersListBox_ {
ListBox super;
Settings* settings;
TypedVector* meters;
ScreenManager* scr;
} MetersListBox;
MetersListBox* MetersListBox_new(Settings* settings, char* header, TypedVector* meters, ScreenManager* scr);
void MetersListBox_delete(Object* object);
HandlerResult MetersListBox_EventHandler(ListBox* super, int ch);
#endif

105
MetersPanel.c Normal file
View File

@ -0,0 +1,105 @@
#include "MetersPanel.h"
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
/*{
typedef struct MetersPanel_ {
Panel super;
Settings* settings;
Vector* meters;
ScreenManager* scr;
} MetersPanel;
}*/
MetersPanel* MetersPanel_new(Settings* settings, char* header, Vector* meters, ScreenManager* scr) {
MetersPanel* this = (MetersPanel*) malloc(sizeof(MetersPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, LISTITEM_CLASS, true);
((Object*)this)->delete = MetersPanel_delete;
this->settings = settings;
this->meters = meters;
this->scr = scr;
super->eventHandler = MetersPanel_EventHandler;
Panel_setHeader(super, header);
for (int i = 0; i < Vector_size(meters); i++) {
Meter* meter = (Meter*) Vector_get(meters, i);
Panel_add(super, (Object*) Meter_toListItem(meter));
}
return this;
}
void MetersPanel_delete(Object* object) {
Panel* super = (Panel*) object;
MetersPanel* this = (MetersPanel*) object;
Panel_done(super);
free(this);
}
HandlerResult MetersPanel_EventHandler(Panel* super, int ch) {
MetersPanel* this = (MetersPanel*) super;
int selected = Panel_getSelectedIndex(super);
HandlerResult result = IGNORED;
switch(ch) {
case 0x0a:
case 0x0d:
case KEY_ENTER:
case KEY_F(4):
case 't':
{
Meter* meter = (Meter*) Vector_get(this->meters, selected);
int mode = meter->mode + 1;
if (mode == LAST_METERMODE) mode = 1;
Meter_setMode(meter, mode);
Panel_set(super, selected, (Object*) Meter_toListItem(meter));
result = HANDLED;
break;
}
case KEY_F(7):
case '[':
case '-':
{
Vector_moveUp(this->meters, selected);
Panel_moveSelectedUp(super);
result = HANDLED;
break;
}
case KEY_F(8):
case ']':
case '+':
{
Vector_moveDown(this->meters, selected);
Panel_moveSelectedDown(super);
result = HANDLED;
break;
}
case KEY_F(9):
case KEY_DC:
{
if (selected < Vector_size(this->meters)) {
Vector_remove(this->meters, selected);
Panel_remove(super, selected);
}
result = HANDLED;
break;
}
}
if (result == HANDLED) {
Header* header = this->settings->header;
Header_calculateHeight(header);
Header_draw(header);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
}
return result;
}

30
MetersPanel.h Normal file
View File

@ -0,0 +1,30 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_MetersPanel
#define HEADER_MetersPanel
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "debug.h"
#include <assert.h>
typedef struct MetersPanel_ {
Panel super;
Settings* settings;
Vector* meters;
ScreenManager* scr;
} MetersPanel;
MetersPanel* MetersPanel_new(Settings* settings, char* header, Vector* meters, ScreenManager* scr);
void MetersPanel_delete(Object* object);
HandlerResult MetersPanel_EventHandler(Panel* super, int ch);
#endif

View File

@ -15,38 +15,37 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.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 Object*, const Object*); typedef int(*Object_Compare)(const void*, const void*);
typedef void(*Object_Delete)(Object*); typedef void(*Object_Delete)(Object*);
struct Object_ { struct Object_ {
#ifdef DEBUG
char* class; char* class;
#endif
Object_Display display; Object_Display display;
Object_Compare compare;
Object_Delete delete; Object_Delete delete;
}; };
}*/ }*/
/* private property */ #ifdef DEBUG
char* OBJECT_CLASS = "Object"; char* OBJECT_CLASS = "Object";
void Object_new() { #else
Object* this; #define OBJECT_CLASS NULL
this = malloc(sizeof(Object)); #endif
this->class = OBJECT_CLASS;
this->display = Object_display;
this->compare = Object_compare;
this->delete = Object_delete;
}
bool Object_instanceOf(Object* this, char* class) { #ifdef DEBUG
return this->class == class;
}
void Object_delete(Object* this) { void Object_setClass(void* this, char* class) {
free(this); ((Object*)this)->class = class;
} }
void Object_display(Object* this, RichString* out) { void Object_display(Object* this, RichString* out) {
@ -55,6 +54,4 @@ void Object_display(Object* this, RichString* out) {
RichString_write(out, CRT_colors[DEFAULT_COLOR], objAddress); RichString_write(out, CRT_colors[DEFAULT_COLOR], objAddress);
} }
int Object_compare(const Object* this, const Object* o) { #endif
return (this - o);
}

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Object #ifndef HEADER_Object
#define HEADER_Object #define HEADER_Object
@ -17,28 +17,38 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.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 Object*, const Object*); typedef int(*Object_Compare)(const void*, const void*);
typedef void(*Object_Delete)(Object*); typedef void(*Object_Delete)(Object*);
struct Object_ { struct Object_ {
#ifdef DEBUG
char* class; char* class;
#endif
Object_Display display; Object_Display display;
Object_Compare compare;
Object_Delete delete; Object_Delete delete;
}; };
#ifdef DEBUG
extern char* OBJECT_CLASS;
void Object_new(); #else
#define OBJECT_CLASS NULL
#endif
bool Object_instanceOf(Object* this, char* class); #ifdef DEBUG
void Object_delete(Object* this); void Object_setClass(void* this, char* class);
void Object_display(Object* this, RichString* out); void Object_display(Object* this, RichString* out);
int Object_compare(const Object* this, const Object* o); #endif
#endif #endif

View File

@ -1,15 +1,16 @@
/* /*
htop - ListBox.c htop - Panel.c
(C) 2004-2006 Hisham H. Muhammad (C) 2004-2006 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 "ListBox.h" #include "Panel.h"
#include "TypedVector.h" #include "Vector.h"
#include "CRT.h" #include "CRT.h"
#include "RichString.h" #include "RichString.h"
#include "ListItem.h"
#include <math.h> #include <math.h>
#include <stdbool.h> #include <stdbool.h>
@ -22,7 +23,7 @@ in the source distribution for its full text.
/*{ /*{
typedef struct ListBox_ ListBox; typedef struct Panel_ Panel;
typedef enum HandlerResult_ { typedef enum HandlerResult_ {
HANDLED, HANDLED,
@ -30,23 +31,22 @@ typedef enum HandlerResult_ {
BREAK_LOOP BREAK_LOOP
} HandlerResult; } HandlerResult;
typedef HandlerResult(*ListBox_EventHandler)(ListBox*, int); typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
struct ListBox_ { struct Panel_ {
Object super; Object super;
int x, y, w, h; int x, y, w, h;
WINDOW* window; WINDOW* window;
TypedVector* items; Vector* items;
int selected; int selected;
int scrollV, scrollH; int scrollV, scrollH;
int scrollHAmount;
int oldSelected; int oldSelected;
bool needsRedraw; bool needsRedraw;
RichString header; RichString header;
ListBox_EventHandler eventHandler; Panel_EventHandler eventHandler;
}; };
extern char* LISTBOX_CLASS;
}*/ }*/
#ifndef MIN #ifndef MIN
@ -56,65 +56,70 @@ extern char* LISTBOX_CLASS;
#define MAX(a,b) ((a)>(b)?(a):(b)) #define MAX(a,b) ((a)>(b)?(a):(b))
#endif #endif
/* private property */ #ifdef DEBUG
char* LISTBOX_CLASS = "ListBox"; char* PANEL_CLASS = "Panel";
#else
#define PANEL_CLASS NULL
#endif
ListBox* ListBox_new(int x, int y, int w, int h, char* type, bool owner) {
ListBox* this; Panel* Panel_new(int x, int y, int w, int h, char* type, bool owner, Object_Compare compare) {
this = malloc(sizeof(ListBox)); Panel* this;
ListBox_init(this, x, y, w, h, type, owner); this = malloc(sizeof(Panel));
Panel_init(this, x, y, w, h, type, owner);
this->items->compare = compare;
return this; return this;
} }
void ListBox_delete(Object* cast) { void Panel_delete(Object* cast) {
ListBox* this = (ListBox*)cast; Panel* this = (Panel*)cast;
ListBox_done(this); Panel_done(this);
free(this); free(this);
} }
void ListBox_init(ListBox* 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, char* type, bool owner) {
Object* super = (Object*) this; Object* super = (Object*) this;
super->class = LISTBOX_CLASS; Object_setClass(this, PANEL_CLASS);
super->delete = ListBox_delete; 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->eventHandler = NULL;
this->items = TypedVector_new(type, owner, DEFAULT_SIZE); this->items = Vector_new(type, owner, DEFAULT_SIZE, ListItem_compare);
this->scrollV = 0; this->scrollV = 0;
this->scrollH = 0; this->scrollH = 0;
this->selected = 0; this->selected = 0;
this->oldSelected = 0; this->oldSelected = 0;
this->needsRedraw = true; this->needsRedraw = true;
this->header.len = 0; this->header.len = 0;
if (String_eq(CRT_termType, "linux"))
this->scrollHAmount = 40;
else
this->scrollHAmount = 5;
} }
void ListBox_done(ListBox* this) { void Panel_done(Panel* this) {
assert (this != NULL); assert (this != NULL);
RichString_delete(this->header); Vector_delete(this->items);
TypedVector_delete(this->items);
} }
inline void ListBox_setRichHeader(ListBox* this, RichString header) { inline void Panel_setRichHeader(Panel* this, RichString header) {
assert (this != NULL); assert (this != NULL);
if (this->header.len > 0) {
RichString_delete(this->header);
}
this->header = header; this->header = header;
this->needsRedraw = true; this->needsRedraw = true;
} }
inline void ListBox_setHeader(ListBox* this, char* header) { inline void Panel_setHeader(Panel* this, char* header) {
ListBox_setRichHeader(this, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], header)); Panel_setRichHeader(this, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], header));
} }
void ListBox_setEventHandler(ListBox* this, ListBox_EventHandler eh) { void Panel_setEventHandler(Panel* this, Panel_EventHandler eh) {
this->eventHandler = eh; this->eventHandler = eh;
} }
void ListBox_move(ListBox* this, int x, int y) { void Panel_move(Panel* this, int x, int y) {
assert (this != NULL); assert (this != NULL);
this->x = x; this->x = x;
@ -122,7 +127,7 @@ void ListBox_move(ListBox* this, int x, int y) {
this->needsRedraw = true; this->needsRedraw = true;
} }
void ListBox_resize(ListBox* this, int w, int h) { void Panel_resize(Panel* this, int w, int h) {
assert (this != NULL); assert (this != NULL);
if (this->header.len > 0) if (this->header.len > 0)
@ -132,98 +137,98 @@ void ListBox_resize(ListBox* this, int w, int h) {
this->needsRedraw = true; this->needsRedraw = true;
} }
void ListBox_prune(ListBox* this) { void Panel_prune(Panel* this) {
assert (this != NULL); assert (this != NULL);
TypedVector_prune(this->items); Vector_prune(this->items);
this->scrollV = 0; this->scrollV = 0;
this->selected = 0; this->selected = 0;
this->oldSelected = 0; this->oldSelected = 0;
this->needsRedraw = true; this->needsRedraw = true;
} }
void ListBox_add(ListBox* this, Object* o) { void Panel_add(Panel* this, Object* o) {
assert (this != NULL); assert (this != NULL);
TypedVector_add(this->items, o); Vector_add(this->items, o);
this->needsRedraw = true; this->needsRedraw = true;
} }
void ListBox_insert(ListBox* this, int i, Object* o) { void Panel_insert(Panel* this, int i, Object* o) {
assert (this != NULL); assert (this != NULL);
TypedVector_insert(this->items, i, o); Vector_insert(this->items, i, o);
this->needsRedraw = true; this->needsRedraw = true;
} }
void ListBox_set(ListBox* this, int i, Object* o) { void Panel_set(Panel* this, int i, Object* o) {
assert (this != NULL); assert (this != NULL);
TypedVector_set(this->items, i, o); Vector_set(this->items, i, o);
} }
Object* ListBox_get(ListBox* this, int i) { Object* Panel_get(Panel* this, int i) {
assert (this != NULL); assert (this != NULL);
return TypedVector_get(this->items, i); return Vector_get(this->items, i);
} }
Object* ListBox_remove(ListBox* this, int i) { Object* Panel_remove(Panel* this, int i) {
assert (this != NULL); assert (this != NULL);
this->needsRedraw = true; this->needsRedraw = true;
Object* removed = TypedVector_remove(this->items, i); Object* removed = Vector_remove(this->items, i);
if (this->selected > 0 && this->selected >= TypedVector_size(this->items)) if (this->selected > 0 && this->selected >= Vector_size(this->items))
this->selected--; this->selected--;
return removed; return removed;
} }
Object* ListBox_getSelected(ListBox* this) { Object* Panel_getSelected(Panel* this) {
assert (this != NULL); assert (this != NULL);
return TypedVector_get(this->items, this->selected); return Vector_get(this->items, this->selected);
} }
void ListBox_moveSelectedUp(ListBox* this) { void Panel_moveSelectedUp(Panel* this) {
assert (this != NULL); assert (this != NULL);
TypedVector_moveUp(this->items, this->selected); Vector_moveUp(this->items, this->selected);
if (this->selected > 0) if (this->selected > 0)
this->selected--; this->selected--;
} }
void ListBox_moveSelectedDown(ListBox* this) { void Panel_moveSelectedDown(Panel* this) {
assert (this != NULL); assert (this != NULL);
TypedVector_moveDown(this->items, this->selected); Vector_moveDown(this->items, this->selected);
if (this->selected + 1 < TypedVector_size(this->items)) if (this->selected + 1 < Vector_size(this->items))
this->selected++; this->selected++;
} }
int ListBox_getSelectedIndex(ListBox* this) { int Panel_getSelectedIndex(Panel* this) {
assert (this != NULL); assert (this != NULL);
return this->selected; return this->selected;
} }
int ListBox_getSize(ListBox* this) { int Panel_getSize(Panel* this) {
assert (this != NULL); assert (this != NULL);
return TypedVector_size(this->items); return Vector_size(this->items);
} }
void ListBox_setSelected(ListBox* this, int selected) { void Panel_setSelected(Panel* this, int selected) {
assert (this != NULL); assert (this != NULL);
selected = MAX(0, MIN(TypedVector_size(this->items) - 1, selected)); selected = MAX(0, MIN(Vector_size(this->items) - 1, selected));
this->selected = selected; this->selected = selected;
} }
void ListBox_draw(ListBox* this, bool focus) { void Panel_draw(Panel* this, bool focus) {
assert (this != NULL); assert (this != NULL);
int first, last; int first, last;
int itemCount = TypedVector_size(this->items); int itemCount = Vector_size(this->items);
int scrollH = this->scrollH; int scrollH = this->scrollH;
int y = this->y; int x = this->x; int y = this->y; int x = this->x;
first = this->scrollV; first = this->scrollV;
@ -269,8 +274,9 @@ void ListBox_draw(ListBox* this, bool focus) {
if (this->needsRedraw) { if (this->needsRedraw) {
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 = TypedVector_get(this->items, i); Object* itemObj = Vector_get(this->items, i);
RichString itemRef = RichString_new(); RichString itemRef;
RichString_initVal(itemRef);
itemObj->display(itemObj, &itemRef); itemObj->display(itemObj, &itemRef);
int amt = MIN(itemRef.len - scrollH, this->w); int amt = MIN(itemRef.len - scrollH, this->w);
if (i == this->selected) { if (i == this->selected) {
@ -291,11 +297,13 @@ void ListBox_draw(ListBox* this, bool focus) {
this->needsRedraw = false; this->needsRedraw = false;
} else { } else {
Object* oldObj = TypedVector_get(this->items, this->oldSelected); Object* oldObj = Vector_get(this->items, this->oldSelected);
RichString oldRef = RichString_new(); RichString oldRef;
RichString_initVal(oldRef);
oldObj->display(oldObj, &oldRef); oldObj->display(oldObj, &oldRef);
Object* newObj = TypedVector_get(this->items, this->selected); Object* newObj = Vector_get(this->items, this->selected);
RichString newRef = RichString_new(); RichString newRef;
RichString_initVal(newRef);
newObj->display(newObj, &newRef); newObj->display(newObj, &newRef);
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w); mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
if (scrollH < oldRef.len) if (scrollH < oldRef.len)
@ -311,11 +319,11 @@ void ListBox_draw(ListBox* this, bool focus) {
move(0, 0); move(0, 0);
} }
void ListBox_onKey(ListBox* this, int key) { void Panel_onKey(Panel* this, int key) {
assert (this != NULL); assert (this != NULL);
switch (key) { switch (key) {
case KEY_DOWN: case KEY_DOWN:
if (this->selected + 1 < TypedVector_size(this->items)) if (this->selected + 1 < Vector_size(this->items))
this->selected++; this->selected++;
break; break;
case KEY_UP: case KEY_UP:
@ -324,12 +332,12 @@ void ListBox_onKey(ListBox* this, int key) {
break; break;
case KEY_LEFT: case KEY_LEFT:
if (this->scrollH > 0) { if (this->scrollH > 0) {
this->scrollH -= 5; this->scrollH -= this->scrollHAmount;
this->needsRedraw = true; this->needsRedraw = true;
} }
break; break;
case KEY_RIGHT: case KEY_RIGHT:
this->scrollH += 5; this->scrollH += this->scrollHAmount;
this->needsRedraw = true; this->needsRedraw = true;
break; break;
case KEY_PPAGE: case KEY_PPAGE:
@ -339,7 +347,7 @@ void ListBox_onKey(ListBox* this, int key) {
break; break;
case KEY_NPAGE: case KEY_NPAGE:
this->selected += this->h; this->selected += this->h;
int size = TypedVector_size(this->items); int size = Vector_size(this->items);
if (this->selected >= size) if (this->selected >= size)
this->selected = size - 1; this->selected = size - 1;
break; break;
@ -347,7 +355,7 @@ void ListBox_onKey(ListBox* this, int key) {
this->selected = 0; this->selected = 0;
break; break;
case KEY_END: case KEY_END:
this->selected = TypedVector_size(this->items) - 1; this->selected = Vector_size(this->items) - 1;
break; break;
} }
} }

113
Panel.h Normal file
View File

@ -0,0 +1,113 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Panel
#define HEADER_Panel
/*
htop - Panel.h
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Object.h"
#include "Vector.h"
#include "CRT.h"
#include "RichString.h"
#include "ListItem.h"
#include <math.h>
#include <stdbool.h>
#include "debug.h"
#include <assert.h>
#include <curses.h>
//#link curses
typedef struct Panel_ Panel;
typedef enum HandlerResult_ {
HANDLED,
IGNORED,
BREAK_LOOP
} HandlerResult;
typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
struct Panel_ {
Object super;
int x, y, w, h;
WINDOW* window;
Vector* items;
int selected;
int scrollV, scrollH;
int scrollHAmount;
int oldSelected;
bool needsRedraw;
RichString header;
Panel_EventHandler eventHandler;
};
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#ifdef DEBUG
extern char* PANEL_CLASS;
#else
#define PANEL_CLASS NULL
#endif
Panel* Panel_new(int x, int y, int w, int h, char* type, bool owner, Object_Compare compare);
void Panel_delete(Object* cast);
void Panel_init(Panel* this, int x, int y, int w, int h, char* type, bool owner);
void Panel_done(Panel* this);
inline void Panel_setRichHeader(Panel* this, RichString header);
inline void Panel_setHeader(Panel* this, char* header);
void Panel_setEventHandler(Panel* this, Panel_EventHandler eh);
void Panel_move(Panel* this, int x, int y);
void Panel_resize(Panel* this, int w, int h);
void Panel_prune(Panel* this);
void Panel_add(Panel* this, Object* o);
void Panel_insert(Panel* this, int i, Object* o);
void Panel_set(Panel* this, int i, Object* o);
Object* Panel_get(Panel* this, int i);
Object* Panel_remove(Panel* this, int i);
Object* Panel_getSelected(Panel* this);
void Panel_moveSelectedUp(Panel* this);
void Panel_moveSelectedDown(Panel* this);
int Panel_getSelectedIndex(Panel* this);
int Panel_getSize(Panel* this);
void Panel_setSelected(Panel* this, int selected);
void Panel_draw(Panel* this, bool focus);
void Panel_onKey(Panel* this, int key);
#endif

130
Process.c
View File

@ -31,7 +31,6 @@ in the source distribution for its full text.
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 ) #define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
#define PROCESS_COMM_LEN 300 #define PROCESS_COMM_LEN 300
#define PROCESS_USER_LEN 10
/*{ /*{
@ -62,16 +61,19 @@ typedef struct Process_ {
int tty_nr; int tty_nr;
int tpgid; int tpgid;
unsigned long int flags; unsigned long int flags;
#ifdef DEBUG
unsigned long int minflt; unsigned long int minflt;
unsigned long int cminflt; unsigned long int cminflt;
unsigned long int majflt; unsigned long int majflt;
unsigned long int cmajflt; unsigned long int cmajflt;
#endif
unsigned long int utime; unsigned long int utime;
unsigned long int stime; unsigned long int stime;
long int cutime; long int cutime;
long int cstime; long int cstime;
long int priority; long int priority;
long int nice; long int nice;
#ifdef DEBUG
long int itrealvalue; long int itrealvalue;
unsigned long int starttime; unsigned long int starttime;
unsigned long int vsize; unsigned long int vsize;
@ -89,6 +91,7 @@ typedef struct Process_ {
unsigned long int wchan; unsigned long int wchan;
unsigned long int nswap; unsigned long int nswap;
unsigned long int cnswap; unsigned long int cnswap;
#endif
int exit_signal; int exit_signal;
int processor; int processor;
int m_size; int m_size;
@ -101,26 +104,27 @@ typedef struct Process_ {
uid_t st_uid; uid_t st_uid;
float percent_cpu; float percent_cpu;
float percent_mem; float percent_mem;
char user[PROCESS_USER_LEN + 1]; char* user;
} Process; } Process;
extern char* PROCESS_CLASS;
extern char* Process_fieldNames[];
}*/ }*/
/* private property */ #ifdef DEBUG
char* PROCESS_CLASS = "Process"; char* PROCESS_CLASS = "Process";
#else
#define PROCESS_CLASS NULL
#endif
/* private property */ char *Process_fieldNames[] = {
char *Process_fieldNames[] = { "", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION", "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT", "UTIME", "STIME", "CUTIME", "CSTIME", "PRIORITY", "NICE", "ITREALVALUE", "STARTTIME", "VSIZE", "RSS", "RLIM", "STARTCODE", "ENDCODE", "STARTSTACK", "KSTKESP", "KSTKEIP", "SIGNAL", "BLOCKED", "SIGIGNORE", "SIGCATCH", "WCHAN", "NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE", "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM", "USER", "TIME", "*** report bug! ***"}; "", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION", "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT", "UTIME", "STIME", "CUTIME", "CSTIME", "PRIORITY", "NICE", "ITREALVALUE", "STARTTIME", "VSIZE", "RSS", "RLIM", "STARTCODE", "ENDCODE", "STARTSTACK", "KSTKESP", "KSTKEIP", "SIGNAL", "BLOCKED", "SIGIGNORE", "SIGCATCH", "WCHAN", "NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE", "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM", "USER", "TIME", "*** report bug! ***"
};
static int Process_getuid = -1;
Process* Process_new(struct ProcessList_ *pl) { Process* Process_new(struct ProcessList_ *pl) {
Process* this = malloc(sizeof(Process)); Process* this = malloc(sizeof(Process));
((Object*)this)->class = PROCESS_CLASS; Object_setClass(this, PROCESS_CLASS);
((Object*)this)->display = Process_display; ((Object*)this)->display = Process_display;
((Object*)this)->compare = Process_compare;
((Object*)this)->delete = Process_delete; ((Object*)this)->delete = Process_delete;
this->pl = pl; this->pl = pl;
this->tag = false; this->tag = false;
@ -128,6 +132,7 @@ Process* Process_new(struct ProcessList_ *pl) {
this->utime = 0; this->utime = 0;
this->stime = 0; this->stime = 0;
this->comm = NULL; this->comm = NULL;
if (Process_getuid == -1) Process_getuid = getuid();
return this; return this;
} }
@ -147,10 +152,10 @@ void Process_delete(Object* cast) {
void Process_display(Object* cast, RichString* out) { void Process_display(Object* cast, RichString* out) {
Process* this = (Process*) cast; Process* this = (Process*) cast;
ProcessField* fields = this->pl->fields; ProcessField* fields = this->pl->fields;
RichString_prune(out); RichString_init(out);
for (int i = 0; fields[i]; i++) for (int i = 0; fields[i]; i++)
Process_writeField(this, out, fields[i]); Process_writeField(this, out, fields[i]);
if (this->pl->shadowOtherUsers && this->st_uid != getuid()) if (this->pl->shadowOtherUsers && this->st_uid != Process_getuid)
RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]); RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]);
if (this->tag == true) if (this->tag == true)
RichString_setAttr(out, CRT_colors[PROCESS_TAG]); RichString_setAttr(out, CRT_colors[PROCESS_TAG]);
@ -177,8 +182,7 @@ void Process_sendSignal(Process* this, int signal) {
#define ONE_M (ONE_K * ONE_K) #define ONE_M (ONE_K * ONE_K)
#define ONE_G (ONE_M * ONE_K) #define ONE_G (ONE_M * ONE_K)
/* private */ static void Process_printLargeNumber(Process* this, RichString *str, unsigned int number) {
void Process_printLargeNumber(Process* this, RichString *str, unsigned int number) {
char buffer[11]; char buffer[11];
int len; int len;
if(number >= (1000 * ONE_M)) { if(number >= (1000 * ONE_M)) {
@ -202,10 +206,8 @@ void Process_printLargeNumber(Process* this, RichString *str, unsigned int numbe
} }
} }
/* private property */ static double jiffy = 0.0;
double jiffy = 0.0;
/* private */
static void Process_printTime(RichString* str, unsigned long t) { static void Process_printTime(RichString* str, unsigned long t) {
if(jiffy == 0.0) jiffy = sysconf(_SC_CLK_TCK); if(jiffy == 0.0) jiffy = sysconf(_SC_CLK_TCK);
double jiffytime = 1.0 / jiffy; double jiffytime = 1.0 / jiffy;
@ -228,8 +230,7 @@ static void Process_printTime(RichString* str, unsigned long t) {
RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer); RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer);
} }
/* private */ static inline void Process_writeCommand(Process* this, int attr, RichString* str) {
inline static void Process_writeCommand(Process* this, int attr, RichString* str) {
if (this->pl->highlightBaseName) { if (this->pl->highlightBaseName) {
char* firstSpace = strchr(this->comm, ' '); char* firstSpace = strchr(this->comm, ' ');
if (firstSpace) { if (firstSpace) {
@ -316,9 +317,13 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
case M_SHARE: Process_printLargeNumber(this, str, this->m_share * PAGE_SIZE); return; case M_SHARE: Process_printLargeNumber(this, str, this->m_share * PAGE_SIZE); return;
case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break; case ST_UID: snprintf(buffer, n, "%4d ", this->st_uid); break;
case USER: { case USER: {
if (getuid() != this->st_uid) if (Process_getuid != this->st_uid)
attr = CRT_colors[PROCESS_SHADOW]; attr = CRT_colors[PROCESS_SHADOW];
if (this->user) {
snprintf(buffer, n, "%-8s ", this->user); snprintf(buffer, n, "%-8s ", this->user);
} else {
snprintf(buffer, n, "%-8d ", this->st_uid);
}
if (buffer[8] != '\0') { if (buffer[8] != '\0') {
buffer[8] = ' '; buffer[8] = ' ';
buffer[9] = '\0'; buffer[9] = '\0';
@ -353,44 +358,57 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
return; return;
} }
int Process_compare(const Object* v1, const Object* v2) { int Process_pidCompare(const void* v1, const void* v2) {
Process* p1 = (Process*)v1; Process* p1 = (Process*)v1;
Process* p2 = (Process*)v2; Process* p2 = (Process*)v2;
int direction = p1->pl->direction; return (p1->pid - p2->pid);
switch (p1->pl->sortKey) { }
case PID:
return (p2->pid - p1->pid) * direction; int Process_compare(const void* v1, const void* v2) {
case PPID: Process *p1, *p2;
return (p2->ppid - p1->ppid) * direction; ProcessList *pl = ((Process*)v1)->pl;
case USER: if (pl->direction == 1) {
return strcmp(p2->user, p1->user) * direction; p1 = (Process*)v1;
case PRIORITY: p2 = (Process*)v2;
return (p2->priority - p1->priority) * direction; } else {
case STATE: p2 = (Process*)v1;
return (p2->state - p1->state) * direction; p1 = (Process*)v2;
case NICE:
return (p2->nice - p1->nice) * direction;
case M_SIZE:
return (p1->m_size - p2->m_size) * direction;
case M_RESIDENT:
return (p1->m_resident - p2->m_resident) * direction;
case M_SHARE:
return (p1->m_share - p2->m_share) * direction;
case PERCENT_CPU:
return (p1->percent_cpu < p2->percent_cpu ? -1 : 1) * direction;
case PERCENT_MEM:
return (p1->percent_mem < p2->percent_mem ? -1 : 1) * direction;
case UTIME:
return (p1->utime - p2->utime) * direction;
case STIME:
return (p1->stime - p2->stime) * direction;
case TIME:
return ((p1->utime+p1->stime) - (p2->utime+p2->stime)) * direction;
case COMM:
return strcmp(p2->comm, p1->comm) * direction;
default:
return (p2->pid - p1->pid) * direction;
} }
switch (pl->sortKey) {
case PID:
return (p1->pid - p2->pid);
case PPID:
return (p1->ppid - p2->ppid);
case USER:
return strcmp(p1->user, p2->user);
case PRIORITY:
return (p1->priority - p2->priority);
case STATE:
return (p1->state - p2->state);
case NICE:
return (p1->nice - p2->nice);
case M_SIZE:
return (p2->m_size - p1->m_size);
case M_RESIDENT:
return (p2->m_resident - p1->m_resident);
case M_SHARE:
return (p2->m_share - p1->m_share);
case PERCENT_CPU:
return (p2->percent_cpu > p1->percent_cpu ? 1 : -1);
case PERCENT_MEM:
return (p2->m_resident - p1->m_resident);
case UTIME:
return (p2->utime - p1->utime);
case STIME:
return (p2->stime - p1->stime);
case TIME:
return ((p2->utime+p2->stime) - (p1->utime+p1->stime));
case COMM:
return strcmp(p1->comm, p2->comm);
default:
return (p1->pid - p2->pid);
}
} }
char* Process_printField(ProcessField field) { char* Process_printField(ProcessField field) {

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Process #ifndef HEADER_Process
#define HEADER_Process #define HEADER_Process
@ -34,7 +34,6 @@ in the source distribution for its full text.
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 ) #define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
#define PROCESS_COMM_LEN 300 #define PROCESS_COMM_LEN 300
#define PROCESS_USER_LEN 10
typedef enum ProcessField_ { typedef enum ProcessField_ {
@ -64,16 +63,19 @@ typedef struct Process_ {
int tty_nr; int tty_nr;
int tpgid; int tpgid;
unsigned long int flags; unsigned long int flags;
#ifdef DEBUG
unsigned long int minflt; unsigned long int minflt;
unsigned long int cminflt; unsigned long int cminflt;
unsigned long int majflt; unsigned long int majflt;
unsigned long int cmajflt; unsigned long int cmajflt;
#endif
unsigned long int utime; unsigned long int utime;
unsigned long int stime; unsigned long int stime;
long int cutime; long int cutime;
long int cstime; long int cstime;
long int priority; long int priority;
long int nice; long int nice;
#ifdef DEBUG
long int itrealvalue; long int itrealvalue;
unsigned long int starttime; unsigned long int starttime;
unsigned long int vsize; unsigned long int vsize;
@ -91,6 +93,7 @@ typedef struct Process_ {
unsigned long int wchan; unsigned long int wchan;
unsigned long int nswap; unsigned long int nswap;
unsigned long int cnswap; unsigned long int cnswap;
#endif
int exit_signal; int exit_signal;
int processor; int processor;
int m_size; int m_size;
@ -103,15 +106,17 @@ typedef struct Process_ {
uid_t st_uid; uid_t st_uid;
float percent_cpu; float percent_cpu;
float percent_mem; float percent_mem;
char user[PROCESS_USER_LEN + 1]; char* user;
} Process; } Process;
#ifdef DEBUG
extern char* PROCESS_CLASS; extern char* PROCESS_CLASS;
#else
#define PROCESS_CLASS NULL
#endif
extern char* Process_fieldNames[]; extern char *Process_fieldNames[];
Process* Process_new(struct ProcessList_ *pl); Process* Process_new(struct ProcessList_ *pl);
@ -133,7 +138,9 @@ void Process_sendSignal(Process* this, int signal);
void Process_writeField(Process* this, RichString* str, ProcessField field); void Process_writeField(Process* this, RichString* str, ProcessField field);
int Process_compare(const Object* v1, const Object* v2); int Process_pidCompare(const void* v1, const void* v2);
int Process_compare(const void* v1, const void* v2);
char* Process_printField(ProcessField field); char* Process_printField(ProcessField field);

View File

@ -12,9 +12,10 @@ in the source distribution for its full text.
#include "ProcessList.h" #include "ProcessList.h"
#include "Process.h" #include "Process.h"
#include "TypedVector.h" #include "Vector.h"
#include "UsersTable.h" #include "UsersTable.h"
#include "Hashtable.h" #include "Hashtable.h"
#include "String.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -48,16 +49,24 @@ in the source distribution for its full text.
#endif #endif
#ifndef MAX_READ #ifndef MAX_READ
#define MAX_READ 8192 #define MAX_READ 2048
#endif
#ifndef PER_PROCESSOR_FIELDS
#define PER_PROCESSOR_FIELDS 20
#endif #endif
}*/ }*/
/*{ /*{
#ifdef DEBUG
typedef int(*vxscanf)(void*, const char*, va_list);
#endif
typedef struct ProcessList_ { typedef struct ProcessList_ {
TypedVector* processes; Vector* processes;
TypedVector* processes2; Vector* processes2;
Hashtable* processTable; Hashtable* processTable;
Process* prototype; Process* prototype;
UsersTable* usersTable; UsersTable* usersTable;
@ -66,26 +75,37 @@ typedef struct ProcessList_ {
int totalTasks; int totalTasks;
int runningTasks; int runningTasks;
long int* totalTime; // Must match number of PER_PROCESSOR_FIELDS constant
long int* userTime; unsigned long long int* totalTime;
long int* systemTime; unsigned long long int* userTime;
long int* idleTime; unsigned long long int* systemTime;
long int* niceTime; unsigned long long int* systemAllTime;
long int* totalPeriod; unsigned long long int* idleTime;
long int* userPeriod; unsigned long long int* niceTime;
long int* systemPeriod; unsigned long long int* ioWaitTime;
long int* idlePeriod; unsigned long long int* irqTime;
long int* nicePeriod; unsigned long long int* softIrqTime;
unsigned long long int* stealTime;
unsigned long long int* totalPeriod;
unsigned long long int* userPeriod;
unsigned long long int* systemPeriod;
unsigned long long int* systemAllPeriod;
unsigned long long int* idlePeriod;
unsigned long long int* nicePeriod;
unsigned long long int* ioWaitPeriod;
unsigned long long int* irqPeriod;
unsigned long long int* softIrqPeriod;
unsigned long long int* stealPeriod;
long int totalMem; unsigned long long int totalMem;
long int usedMem; unsigned long long int usedMem;
long int freeMem; unsigned long long int freeMem;
long int sharedMem; unsigned long long int sharedMem;
long int buffersMem; unsigned long long int buffersMem;
long int cachedMem; unsigned long long int cachedMem;
long int totalSwap; unsigned long long int totalSwap;
long int usedSwap; unsigned long long int usedSwap;
long int freeSwap; unsigned long long int freeSwap;
ProcessField* fields; ProcessField* fields;
ProcessField sortKey; ProcessField sortKey;
@ -97,6 +117,7 @@ typedef struct ProcessList_ {
bool treeView; bool treeView;
bool highlightBaseName; bool highlightBaseName;
bool highlightMegabytes; bool highlightMegabytes;
bool expandSystemTime;
#ifdef DEBUG #ifdef DEBUG
FILE* traceFile; FILE* traceFile;
#endif #endif
@ -104,24 +125,18 @@ typedef struct ProcessList_ {
} ProcessList; } ProcessList;
}*/ }*/
/* private property */ static ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
#ifdef DEBUG #ifdef DEBUG
/* private property */
typedef int(*vxscanf)(void*, const char*, va_list);
#define ProcessList_read(this, buffer, format, ...) ProcessList_xread(this, (vxscanf) vsscanf, buffer, format, ## __VA_ARGS__ ) #define ProcessList_read(this, buffer, format, ...) ProcessList_xread(this, (vxscanf) vsscanf, buffer, format, ## __VA_ARGS__ )
#define ProcessList_fread(this, file, format, ...) ProcessList_xread(this, (vxscanf) vfscanf, file, format, ## __VA_ARGS__ ) #define ProcessList_fread(this, file, format, ...) ProcessList_xread(this, (vxscanf) vfscanf, file, format, ## __VA_ARGS__ )
/* private */ static FILE* ProcessList_fopen(ProcessList* this, const char* path, const char* mode) {
FILE* ProcessList_fopen(ProcessList* this, const char* path, const char* mode) {
fprintf(this->traceFile, "[%s]\n", path); fprintf(this->traceFile, "[%s]\n", path);
return fopen(path, mode); return fopen(path, mode);
} }
/* private */
static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer, char* format, ...) { static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer, char* format, ...) {
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
@ -130,7 +145,10 @@ static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer,
va_start(ap, format); va_start(ap, format);
while (*format) { while (*format) {
char ch = *format; char ch = *format;
char* c; int* d; long int* ld; unsigned long int* lu; char** s; char* c; int* d;
long int* ld; unsigned long int* lu;
long long int* lld; unsigned long long int* llu;
char** s;
if (ch != '%') { if (ch != '%') {
fprintf(this->traceFile, "%c", ch); fprintf(this->traceFile, "%c", ch);
format++; format++;
@ -146,6 +164,12 @@ static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer,
switch (*format) { switch (*format) {
case 'd': ld = va_arg(ap, long int*); fprintf(this->traceFile, "%ld", *ld); break; case 'd': ld = va_arg(ap, long int*); fprintf(this->traceFile, "%ld", *ld); break;
case 'u': lu = va_arg(ap, unsigned long int*); fprintf(this->traceFile, "%lu", *lu); break; case 'u': lu = va_arg(ap, unsigned long int*); fprintf(this->traceFile, "%lu", *lu); break;
case 'l':
format++;
switch (*format) {
case 'd': lld = va_arg(ap, long long int*); fprintf(this->traceFile, "%lld", *lld); break;
case 'u': llu = va_arg(ap, unsigned long long int*); fprintf(this->traceFile, "%llu", *llu); break;
}
} }
} }
format++; format++;
@ -165,16 +189,26 @@ static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer,
#endif #endif
static inline void ProcessList_allocatePerProcessorBuffers(ProcessList* this, int procs) {
unsigned long long int** bufferPtr = &(this->totalTime);
unsigned long long int* buffer = calloc(procs * PER_PROCESSOR_FIELDS, sizeof(unsigned long long int));
for (int i = 0; i < PER_PROCESSOR_FIELDS; i++) {
*bufferPtr = buffer;
bufferPtr++;
buffer += procs;
}
}
ProcessList* ProcessList_new(UsersTable* usersTable) { ProcessList* ProcessList_new(UsersTable* usersTable) {
ProcessList* this; ProcessList* this;
this = malloc(sizeof(ProcessList)); this = malloc(sizeof(ProcessList));
this->processes = TypedVector_new(PROCESS_CLASS, true, DEFAULT_SIZE); this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
this->processTable = Hashtable_new(20, false); this->processTable = Hashtable_new(70, false);
this->prototype = Process_new(this); this->prototype = Process_new(this);
this->usersTable = usersTable; this->usersTable = usersTable;
/* tree-view auxiliary buffers */ /* tree-view auxiliary buffers */
this->processes2 = TypedVector_new(PROCESS_CLASS, true, DEFAULT_SIZE); this->processes2 = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
#ifdef DEBUG #ifdef DEBUG
this->traceFile = fopen("/tmp/htop-proc-trace", "w"); this->traceFile = fopen("/tmp/htop-proc-trace", "w");
@ -190,23 +224,16 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
} while (String_startsWith(buffer, "cpu")); } while (String_startsWith(buffer, "cpu"));
fclose(status); fclose(status);
this->processorCount = procs - 1; this->processorCount = procs - 1;
this->totalTime = calloc(procs, sizeof(long int));
this->userTime = calloc(procs, sizeof(long int)); ProcessList_allocatePerProcessorBuffers(this, procs);
this->systemTime = calloc(procs, sizeof(long int));
this->niceTime = calloc(procs, sizeof(long int));
this->idleTime = calloc(procs, sizeof(long int));
this->totalPeriod = calloc(procs, sizeof(long int));
this->userPeriod = calloc(procs, sizeof(long int));
this->systemPeriod = calloc(procs, sizeof(long int));
this->nicePeriod = calloc(procs, sizeof(long int));
this->idlePeriod = calloc(procs, sizeof(long int));
for (int i = 0; i < procs; i++) { for (int i = 0; i < procs; i++) {
this->totalTime[i] = 1; this->totalTime[i] = 1;
this->totalPeriod[i] = 1; this->totalPeriod[i] = 1;
} }
this->fields = calloc(sizeof(ProcessField), LAST_PROCESSFIELD+1); this->fields = calloc(sizeof(ProcessField), LAST_PROCESSFIELD+1);
// TODO: turn 'fields' into a TypedVector, // TODO: turn 'fields' into a Vector,
// (and ProcessFields into proper objects). // (and ProcessFields into proper objects).
for (int i = 0; defaultHeaders[i]; i++) { for (int i = 0; defaultHeaders[i]; i++) {
this->fields[i] = defaultHeaders[i]; this->fields[i] = defaultHeaders[i];
@ -220,26 +247,20 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
this->treeView = false; this->treeView = false;
this->highlightBaseName = false; this->highlightBaseName = false;
this->highlightMegabytes = false; this->highlightMegabytes = false;
this->expandSystemTime = false;
return this; return this;
} }
void ProcessList_delete(ProcessList* this) { void ProcessList_delete(ProcessList* this) {
Hashtable_delete(this->processTable); Hashtable_delete(this->processTable);
TypedVector_delete(this->processes); Vector_delete(this->processes);
TypedVector_delete(this->processes2); Vector_delete(this->processes2);
Process_delete((Object*)this->prototype); Process_delete((Object*)this->prototype);
// Free first entry only;
// other fields are offsets of the same buffer
free(this->totalTime); free(this->totalTime);
free(this->userTime);
free(this->systemTime);
free(this->niceTime);
free(this->idleTime);
free(this->totalPeriod);
free(this->userPeriod);
free(this->systemPeriod);
free(this->nicePeriod);
free(this->idlePeriod);
#ifdef DEBUG #ifdef DEBUG
fclose(this->traceFile); fclose(this->traceFile);
@ -257,7 +278,8 @@ void ProcessList_invertSortOrder(ProcessList* this) {
} }
RichString ProcessList_printHeader(ProcessList* this) { RichString ProcessList_printHeader(ProcessList* this) {
RichString out = RichString_new(); RichString out;
RichString_init(&out);
ProcessField* fields = this->fields; ProcessField* fields = this->fields;
for (int i = 0; fields[i]; i++) { for (int i = 0; fields[i]; i++) {
char* field = Process_printField(fields[i]); char* field = Process_printField(fields[i]);
@ -271,85 +293,80 @@ RichString ProcessList_printHeader(ProcessList* this) {
void ProcessList_prune(ProcessList* this) { void ProcessList_prune(ProcessList* this) {
TypedVector_prune(this->processes); Vector_prune(this->processes);
} }
void ProcessList_add(ProcessList* this, Process* p) { void ProcessList_add(ProcessList* this, Process* p) {
TypedVector_add(this->processes, p); Vector_add(this->processes, p);
Hashtable_put(this->processTable, p->pid, p); Hashtable_put(this->processTable, p->pid, p);
} }
void ProcessList_remove(ProcessList* this, Process* p) { void ProcessList_remove(ProcessList* this, Process* p) {
Hashtable_remove(this->processTable, p->pid); Hashtable_remove(this->processTable, p->pid);
ProcessField pf = this->sortKey; int index = Vector_indexOf(this->processes, p, Process_pidCompare);
this->sortKey = PID; Vector_remove(this->processes, index);
int index = TypedVector_indexOf(this->processes, p);
TypedVector_remove(this->processes, index);
this->sortKey = pf;
} }
Process* ProcessList_get(ProcessList* this, int index) { Process* ProcessList_get(ProcessList* this, int index) {
return (Process*) (TypedVector_get(this->processes, index)); return (Process*) (Vector_get(this->processes, index));
} }
int ProcessList_size(ProcessList* this) { int ProcessList_size(ProcessList* this) {
return (TypedVector_size(this->processes)); return (Vector_size(this->processes));
} }
/* private */ static void ProcessList_buildTree(ProcessList* this, int pid, int level, int indent, int direction) {
void ProcessList_buildTree(ProcessList* this, int pid, int level, int indent, int direction) { Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare);
TypedVector* children = TypedVector_new(PROCESS_CLASS, false, DEFAULT_SIZE);
for (int i = 0; i < TypedVector_size(this->processes); i++) { for (int i = 0; i < Vector_size(this->processes); i++) {
Process* process = (Process*) (TypedVector_get(this->processes, i)); Process* process = (Process*) (Vector_get(this->processes, i));
if (process->ppid == pid) { if (process->ppid == pid) {
Process* process = (Process*) (TypedVector_take(this->processes, i)); Process* process = (Process*) (Vector_take(this->processes, i));
TypedVector_add(children, process); Vector_add(children, process);
i--; i--;
} }
} }
int size = TypedVector_size(children); int size = Vector_size(children);
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Process* process = (Process*) (TypedVector_get(children, i)); Process* process = (Process*) (Vector_get(children, i));
if (direction == 1) if (direction == 1)
TypedVector_add(this->processes2, process); Vector_add(this->processes2, process);
else else
TypedVector_insert(this->processes2, 0, process); Vector_insert(this->processes2, 0, process);
int nextIndent = indent; int nextIndent = indent;
if (i < size - 1) if (i < size - 1)
nextIndent = indent | (1 << level); nextIndent = indent | (1 << level);
ProcessList_buildTree(this, process->pid, level+1, nextIndent, direction); ProcessList_buildTree(this, process->pid, level+1, nextIndent, direction);
process->indent = indent | (1 << level); process->indent = indent | (1 << level);
} }
TypedVector_delete(children); Vector_delete(children);
} }
void ProcessList_sort(ProcessList* this) { void ProcessList_sort(ProcessList* this) {
if (!this->treeView) { if (!this->treeView) {
TypedVector_sort(this->processes); Vector_sort(this->processes);
} else { } else {
int direction = this->direction; int direction = this->direction;
int sortKey = this->sortKey; int sortKey = this->sortKey;
this->sortKey = PID; this->sortKey = PID;
this->direction = 1; this->direction = 1;
TypedVector_sort(this->processes); Vector_sort(this->processes);
this->sortKey = sortKey; this->sortKey = sortKey;
this->direction = direction; this->direction = direction;
Process* init = (Process*) (TypedVector_take(this->processes, 0)); Process* init = (Process*) (Vector_take(this->processes, 0));
assert(init->pid == 1); assert(init->pid == 1);
init->indent = 0; init->indent = 0;
TypedVector_add(this->processes2, init); Vector_add(this->processes2, init);
ProcessList_buildTree(this, init->pid, 0, 0, direction); ProcessList_buildTree(this, init->pid, 0, 0, direction);
TypedVector* t = this->processes; Vector* t = this->processes;
this->processes = this->processes2; this->processes = this->processes2;
this->processes2 = t; this->processes2 = t;
} }
} }
/* private */ static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *command) {
int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *command) {
static char buf[MAX_READ]; static char buf[MAX_READ];
long int zero; unsigned long int zero;
int size = fread(buf, 1, MAX_READ, f); int size = fread(buf, 1, MAX_READ, f);
if(!size) return 0; if(!size) return 0;
@ -367,6 +384,7 @@ int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *co
command[commsize] = '\0'; command[commsize] = '\0';
location = end + 2; location = end + 2;
#ifdef DEBUG
int num = ProcessList_read(this, location, int num = ProcessList_read(this, location,
"%c %d %d %d %d %d %lu %lu %lu %lu " "%c %d %d %d %d %d %lu %lu %lu %lu "
"%lu %lu %lu %ld %ld %ld %ld %ld %ld " "%lu %lu %lu %ld %ld %ld %ld %ld %ld "
@ -374,14 +392,34 @@ int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *co
"%lu %lu %lu %lu %lu %lu %lu %lu " "%lu %lu %lu %lu %lu %lu %lu %lu "
"%d %d", "%d %d",
&proc->state, &proc->ppid, &proc->pgrp, &proc->session, &proc->tty_nr, &proc->state, &proc->ppid, &proc->pgrp, &proc->session, &proc->tty_nr,
&proc->tpgid, &proc->flags, &proc->minflt, &proc->cminflt, &proc->majflt, &proc->tpgid, &proc->flags,
&proc->cmajflt, &proc->utime, &proc->stime, &proc->cutime, &proc->cstime, &proc->minflt, &proc->cminflt, &proc->majflt, &proc->cmajflt,
&proc->utime, &proc->stime, &proc->cutime, &proc->cstime,
&proc->priority, &proc->nice, &zero, &proc->itrealvalue, &proc->priority, &proc->nice, &zero, &proc->itrealvalue,
&proc->starttime, &proc->vsize, &proc->rss, &proc->rlim, &proc->starttime, &proc->vsize, &proc->rss, &proc->rlim,
&proc->startcode, &proc->endcode, &proc->startstack, &proc->kstkesp, &proc->startcode, &proc->endcode, &proc->startstack, &proc->kstkesp,
&proc->kstkeip, &proc->signal, &proc->blocked, &proc->sigignore, &proc->kstkeip, &proc->signal, &proc->blocked, &proc->sigignore,
&proc->sigcatch, &proc->wchan, &proc->nswap, &proc->cnswap, &proc->sigcatch, &proc->wchan, &proc->nswap, &proc->cnswap,
&proc->exit_signal, &proc->processor); &proc->exit_signal, &proc->processor);
#else
long int uzero;
int num = ProcessList_read(this, location,
"%c %d %d %d %d %d %lu %lu %lu %lu "
"%lu %lu %lu %ld %ld %ld %ld %ld %ld "
"%lu %lu %ld %lu %lu %lu %lu %lu "
"%lu %lu %lu %lu %lu %lu %lu %lu "
"%d %d",
&proc->state, &proc->ppid, &proc->pgrp, &proc->session, &proc->tty_nr,
&proc->tpgid, &proc->flags,
&zero, &zero, &zero, &zero,
&proc->utime, &proc->stime, &proc->cutime, &proc->cstime,
&proc->priority, &proc->nice, &uzero, &uzero,
&zero, &zero, &uzero, &zero,
&zero, &zero, &zero, &zero,
&zero, &zero, &zero, &zero,
&zero, &zero, &zero, &zero,
&proc->exit_signal, &proc->processor);
#endif
// This assert is always valid on 2.4, but reportedly not always valid on 2.6. // This assert is always valid on 2.4, but reportedly not always valid on 2.6.
// TODO: Check if the semantics of this field has changed. // TODO: Check if the semantics of this field has changed.
@ -394,14 +432,15 @@ int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *co
bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name) { bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name) {
char statusfilename[MAX_NAME+1]; char statusfilename[MAX_NAME+1];
statusfilename[MAX_NAME] = '\0'; statusfilename[MAX_NAME] = '\0';
/*
bool success = false;
char buffer[256];
buffer[255] = '\0';
snprintf(statusfilename, MAX_NAME, "%s/%s/status", dirname, name); snprintf(statusfilename, MAX_NAME, "%s/%s/status", dirname, name);
FILE* status = ProcessList_fopen(this, statusfilename, "r"); FILE* status = ProcessList_fopen(this, statusfilename, "r");
bool success = false;
if (status) { if (status) {
char buffer[1024];
buffer[1023] = '\0';
while (!feof(status)) { while (!feof(status)) {
char* ok = fgets(buffer, 1023, status); char* ok = fgets(buffer, 255, status);
if (!ok) if (!ok)
break; break;
if (String_startsWith(buffer, "Uid:")) { if (String_startsWith(buffer, "Uid:")) {
@ -418,14 +457,18 @@ bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname,
fclose(status); fclose(status);
} }
if (!success) { if (!success) {
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name); */
snprintf(statusfilename, MAX_NAME, "%s/%s", dirname, name);
struct stat sstat; struct stat sstat;
int statok = stat(statusfilename, &sstat); int statok = stat(statusfilename, &sstat);
if (statok == -1) if (statok == -1)
return false; return false;
proc->st_uid = sstat.st_uid; proc->st_uid = sstat.st_uid;
} return true;
return success; /*
} else
return true;
*/
} }
void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period) { void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period) {
@ -466,24 +509,36 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
char command[PROCESS_COMM_LEN + 1]; char command[PROCESS_COMM_LEN + 1];
Process* process; Process* process;
Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid); Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid);
if (!existingProcess) { if (existingProcess) {
process = Process_clone(prototype); process = existingProcess;
} else {
process = prototype;
process->comm = NULL;
process->pid = pid; process->pid = pid;
ProcessList_add(this, process);
if (! ProcessList_readStatusFile(this, process, dirname, name)) if (! ProcessList_readStatusFile(this, process, dirname, name))
goto errorReadingProcess; goto errorReadingProcess;
} else {
process = existingProcess;
} }
process->updated = true; process->updated = true;
char* username = UsersTable_getRef(this->usersTable, process->st_uid); snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
if (username) { status = ProcessList_fopen(this, statusfilename, "r");
strncpy(process->user, username, PROCESS_USER_LEN);
} else { if(!status) {
snprintf(process->user, PROCESS_USER_LEN, "%d", process->st_uid); goto errorReadingProcess;
} }
int num = ProcessList_fread(this, status, "%d %d %d %d %d %d %d",
&process->m_size, &process->m_resident, &process->m_share,
&process->m_trs, &process->m_drs, &process->m_lrs,
&process->m_dt);
fclose(status);
if(num != 7)
goto errorReadingProcess;
if (this->hideKernelThreads && process->m_size == 0)
goto errorReadingProcess;
int lasttimes = (process->utime + process->stime); int lasttimes = (process->utime + process->stime);
@ -495,14 +550,12 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
int success = ProcessList_readStatFile(this, process, status, command); int success = ProcessList_readStatFile(this, process, status, command);
fclose(status); fclose(status);
if(!success) { if(!success)
goto errorReadingProcess; goto errorReadingProcess;
}
process->percent_cpu = (process->utime + process->stime - lasttimes) /
period * 100.0;
if(!existingProcess) { if(!existingProcess) {
process->user = UsersTable_getRef(this->usersTable, process->st_uid);
snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name); snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r"); status = ProcessList_fopen(this, statusfilename, "r");
if (!status) { if (!status) {
@ -521,20 +574,8 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
fclose(status); fclose(status);
} }
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name); process->percent_cpu = (process->utime + process->stime - lasttimes) /
status = ProcessList_fopen(this, statusfilename, "r"); period * 100.0;
if(!status) {
goto errorReadingProcess;
}
int num = ProcessList_fread(this, status, "%d %d %d %d %d %d %d",
&process->m_size, &process->m_resident, &process->m_share,
&process->m_trs, &process->m_drs, &process->m_lrs,
&process->m_dt);
fclose(status);
if(num != 7)
goto errorReadingProcess;
process->percent_mem = process->m_resident / process->percent_mem = process->m_resident /
(float)(this->usedMem - this->cachedMem - this->buffersMem) * (float)(this->usedMem - this->cachedMem - this->buffersMem) *
@ -545,23 +586,31 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
this->runningTasks++; this->runningTasks++;
} }
if (this->hideKernelThreads && process->m_size == 0) if (!existingProcess) {
ProcessList_remove(this, process); process = Process_clone(process);
ProcessList_add(this, process);
}
continue; continue;
// Exception handler. // Exception handler.
errorReadingProcess: { errorReadingProcess: {
if (existingProcess)
ProcessList_remove(this, process); ProcessList_remove(this, process);
else {
if (process->comm)
free(process->comm);
} }
} }
} }
}
prototype->comm = NULL;
closedir(dir); closedir(dir);
} }
void ProcessList_scan(ProcessList* this) { void ProcessList_scan(ProcessList* this) {
long int usertime, nicetime, systemtime, idletime, totaltime; unsigned long long int usertime, nicetime, systemtime, systemalltime, idletime, totaltime;
long int swapFree; unsigned long long int swapFree;
FILE* status; FILE* status;
char buffer[128]; char buffer[128];
@ -573,25 +622,25 @@ void ProcessList_scan(ProcessList* this) {
switch (buffer[0]) { switch (buffer[0]) {
case 'M': case 'M':
if (String_startsWith(buffer, "MemTotal:")) if (String_startsWith(buffer, "MemTotal:"))
ProcessList_read(this, buffer, "MemTotal: %ld kB", &this->totalMem); ProcessList_read(this, buffer, "MemTotal: %llu kB", &this->totalMem);
else if (String_startsWith(buffer, "MemFree:")) else if (String_startsWith(buffer, "MemFree:"))
ProcessList_read(this, buffer, "MemFree: %ld kB", &this->freeMem); ProcessList_read(this, buffer, "MemFree: %llu kB", &this->freeMem);
else if (String_startsWith(buffer, "MemShared:")) else if (String_startsWith(buffer, "MemShared:"))
ProcessList_read(this, buffer, "MemShared: %ld kB", &this->sharedMem); ProcessList_read(this, buffer, "MemShared: %llu kB", &this->sharedMem);
break; break;
case 'B': case 'B':
if (String_startsWith(buffer, "Buffers:")) if (String_startsWith(buffer, "Buffers:"))
ProcessList_read(this, buffer, "Buffers: %ld kB", &this->buffersMem); ProcessList_read(this, buffer, "Buffers: %llu kB", &this->buffersMem);
break; break;
case 'C': case 'C':
if (String_startsWith(buffer, "Cached:")) if (String_startsWith(buffer, "Cached:"))
ProcessList_read(this, buffer, "Cached: %ld kB", &this->cachedMem); ProcessList_read(this, buffer, "Cached: %llu kB", &this->cachedMem);
break; break;
case 'S': case 'S':
if (String_startsWith(buffer, "SwapTotal:")) if (String_startsWith(buffer, "SwapTotal:"))
ProcessList_read(this, buffer, "SwapTotal: %ld kB", &this->totalSwap); ProcessList_read(this, buffer, "SwapTotal: %llu kB", &this->totalSwap);
if (String_startsWith(buffer, "SwapFree:")) if (String_startsWith(buffer, "SwapFree:"))
ProcessList_read(this, buffer, "SwapFree: %ld kB", &swapFree); ProcessList_read(this, buffer, "SwapFree: %llu kB", &swapFree);
break; break;
} }
} }
@ -606,57 +655,69 @@ void ProcessList_scan(ProcessList* this) {
for (int i = 0; i <= this->processorCount; i++) { for (int i = 0; i <= this->processorCount; i++) {
char buffer[256]; char buffer[256];
int cpuid; int cpuid;
long int ioWait, irq, softIrq, steal; unsigned long long int ioWait, irq, softIrq, steal;
ioWait = irq = softIrq = steal = 0; ioWait = irq = softIrq = steal = 0;
// Dependending on your kernel version, // Dependending on your kernel version,
// 5, 7 or 8 of these fields will be set. // 5, 7 or 8 of these fields will be set.
// The rest will remain at zero. // The rest will remain at zero.
fgets(buffer, 255, status); fgets(buffer, 255, status);
if (i == 0) if (i == 0)
ProcessList_read(this, buffer, "cpu %ld %ld %ld %ld %ld %ld %ld %ld", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal); ProcessList_read(this, buffer, "cpu %llu %llu %llu %llu %llu %llu %llu %llu", &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal);
else { else {
ProcessList_read(this, buffer, "cpu%d %ld %ld %ld %ld %ld %ld %ld %ld", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal); ProcessList_read(this, buffer, "cpu%d %llu %llu %llu %llu %llu %llu %llu %llu", &cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal);
assert(cpuid == i - 1); assert(cpuid == i - 1);
} }
// Fields existing on kernels >= 2.6 // Fields existing on kernels >= 2.6
// (and RHEL's patched kernel 2.4...) // (and RHEL's patched kernel 2.4...)
systemtime += ioWait + irq + softIrq + steal; systemalltime = systemtime + ioWait + irq + softIrq + steal;
totaltime = usertime + nicetime + systemtime + idletime; totaltime = usertime + nicetime + systemalltime + idletime;
assert (usertime >= this->userTime[i]); assert (usertime >= this->userTime[i]);
assert (nicetime >= this->niceTime[i]); assert (nicetime >= this->niceTime[i]);
assert (systemtime >= this->systemTime[i]); assert (systemtime >= this->systemTime[i]);
assert (idletime >= this->idleTime[i]); assert (idletime >= this->idleTime[i]);
assert (totaltime >= this->totalTime[i]); assert (totaltime >= this->totalTime[i]);
assert (systemalltime >= this->systemAllTime[i]);
assert (ioWait >= this->ioWaitTime[i]);
assert (irq >= this->irqTime[i]);
assert (softIrq >= this->softIrqTime[i]);
assert (steal >= this->stealTime[i]);
this->userPeriod[i] = usertime - this->userTime[i]; this->userPeriod[i] = usertime - this->userTime[i];
this->nicePeriod[i] = nicetime - this->niceTime[i]; this->nicePeriod[i] = nicetime - this->niceTime[i];
this->systemPeriod[i] = systemtime - this->systemTime[i]; this->systemPeriod[i] = systemtime - this->systemTime[i];
this->systemAllPeriod[i] = systemalltime - this->systemAllTime[i];
this->idlePeriod[i] = idletime - this->idleTime[i]; this->idlePeriod[i] = idletime - this->idleTime[i];
this->ioWaitPeriod[i] = ioWait - this->ioWaitTime[i];
this->irqPeriod[i] = irq - this->irqTime[i];
this->softIrqPeriod[i] = softIrq - this->softIrqTime[i];
this->stealPeriod[i] = steal - this->stealTime[i];
this->totalPeriod[i] = totaltime - this->totalTime[i]; this->totalPeriod[i] = totaltime - this->totalTime[i];
this->userTime[i] = usertime; this->userTime[i] = usertime;
this->niceTime[i] = nicetime; this->niceTime[i] = nicetime;
this->systemTime[i] = systemtime; this->systemTime[i] = systemtime;
this->systemAllTime[i] = systemalltime;
this->idleTime[i] = idletime; this->idleTime[i] = idletime;
this->ioWaitTime[i] = ioWait;
this->irqTime[i] = irq;
this->softIrqTime[i] = softIrq;
this->stealTime[i] = steal;
this->totalTime[i] = totaltime; this->totalTime[i] = totaltime;
} }
float period = (float)this->totalPeriod[0] / this->processorCount; float period = (float)this->totalPeriod[0] / this->processorCount;
fclose(status); fclose(status);
// mark all process as "dirty" // mark all process as "dirty"
for (int i = 0; i < TypedVector_size(this->processes); i++) { for (int i = 0; i < Vector_size(this->processes); i++) {
Process* p = (Process*) TypedVector_get(this->processes, i); Process* p = (Process*) Vector_get(this->processes, i);
p->updated = false; p->updated = false;
} }
this->totalTasks = 0; this->totalTasks = 0;
this->runningTasks = 0; this->runningTasks = 0;
signal(11, ProcessList_dontCrash);
ProcessList_processEntries(this, PROCDIR, 0, period); ProcessList_processEntries(this, PROCDIR, 0, period);
signal(11, SIG_DFL);
for (int i = TypedVector_size(this->processes) - 1; i >= 0; i--) { for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
Process* p = (Process*) TypedVector_get(this->processes, i); Process* p = (Process*) Vector_get(this->processes, i);
if (p->updated == false) if (p->updated == false)
ProcessList_remove(this, p); ProcessList_remove(this, p);
else else
@ -664,9 +725,3 @@ void ProcessList_scan(ProcessList* this) {
} }
} }
void ProcessList_dontCrash(int signal) {
// This ugly hack was added because I suspect some
// crashes were caused by contents of /proc vanishing
// away while we read them.
}

View File

@ -3,7 +3,7 @@
#ifndef HEADER_ProcessList #ifndef HEADER_ProcessList
#define HEADER_ProcessList #define HEADER_ProcessList
/* /*
htop - ProcessList.c htop - ProcessList.h
(C) 2004,2005 Hisham H. Muhammad (C) 2004,2005 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.
@ -15,9 +15,10 @@ in the source distribution for its full text.
#endif #endif
#include "Process.h" #include "Process.h"
#include "TypedVector.h" #include "Vector.h"
#include "UsersTable.h" #include "UsersTable.h"
#include "Hashtable.h" #include "Hashtable.h"
#include "String.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -50,14 +51,22 @@ in the source distribution for its full text.
#endif #endif
#ifndef MAX_READ #ifndef MAX_READ
#define MAX_READ 8192 #define MAX_READ 2048
#endif
#ifndef PER_PROCESSOR_FIELDS
#define PER_PROCESSOR_FIELDS 20
#endif #endif
#ifdef DEBUG
typedef int(*vxscanf)(void*, const char*, va_list);
#endif
typedef struct ProcessList_ { typedef struct ProcessList_ {
TypedVector* processes; Vector* processes;
TypedVector* processes2; Vector* processes2;
Hashtable* processTable; Hashtable* processTable;
Process* prototype; Process* prototype;
UsersTable* usersTable; UsersTable* usersTable;
@ -66,26 +75,37 @@ typedef struct ProcessList_ {
int totalTasks; int totalTasks;
int runningTasks; int runningTasks;
long int* totalTime; // Must match number of PER_PROCESSOR_FIELDS constant
long int* userTime; unsigned long long int* totalTime;
long int* systemTime; unsigned long long int* userTime;
long int* idleTime; unsigned long long int* systemTime;
long int* niceTime; unsigned long long int* systemAllTime;
long int* totalPeriod; unsigned long long int* idleTime;
long int* userPeriod; unsigned long long int* niceTime;
long int* systemPeriod; unsigned long long int* ioWaitTime;
long int* idlePeriod; unsigned long long int* irqTime;
long int* nicePeriod; unsigned long long int* softIrqTime;
unsigned long long int* stealTime;
unsigned long long int* totalPeriod;
unsigned long long int* userPeriod;
unsigned long long int* systemPeriod;
unsigned long long int* systemAllPeriod;
unsigned long long int* idlePeriod;
unsigned long long int* nicePeriod;
unsigned long long int* ioWaitPeriod;
unsigned long long int* irqPeriod;
unsigned long long int* softIrqPeriod;
unsigned long long int* stealPeriod;
long int totalMem; unsigned long long int totalMem;
long int usedMem; unsigned long long int usedMem;
long int freeMem; unsigned long long int freeMem;
long int sharedMem; unsigned long long int sharedMem;
long int buffersMem; unsigned long long int buffersMem;
long int cachedMem; unsigned long long int cachedMem;
long int totalSwap; unsigned long long int totalSwap;
long int usedSwap; unsigned long long int usedSwap;
long int freeSwap; unsigned long long int freeSwap;
ProcessField* fields; ProcessField* fields;
ProcessField sortKey; ProcessField sortKey;
@ -97,21 +117,18 @@ typedef struct ProcessList_ {
bool treeView; bool treeView;
bool highlightBaseName; bool highlightBaseName;
bool highlightMegabytes; bool highlightMegabytes;
bool expandSystemTime;
#ifdef DEBUG #ifdef DEBUG
FILE* traceFile; FILE* traceFile;
#endif #endif
} ProcessList; } ProcessList;
#ifdef DEBUG #ifdef DEBUG
#define ProcessList_read(this, buffer, format, ...) ProcessList_xread(this, (vxscanf) vsscanf, buffer, format, ## __VA_ARGS__ ) #define ProcessList_read(this, buffer, format, ...) ProcessList_xread(this, (vxscanf) vsscanf, buffer, format, ## __VA_ARGS__ )
#define ProcessList_fread(this, file, format, ...) ProcessList_xread(this, (vxscanf) vfscanf, file, format, ## __VA_ARGS__ ) #define ProcessList_fread(this, file, format, ...) ProcessList_xread(this, (vxscanf) vfscanf, file, format, ## __VA_ARGS__ )
#else #else
#ifndef ProcessList_read #ifndef ProcessList_read
@ -141,16 +158,12 @@ Process* ProcessList_get(ProcessList* this, int index);
int ProcessList_size(ProcessList* this); int ProcessList_size(ProcessList* this);
void ProcessList_sort(ProcessList* this); void ProcessList_sort(ProcessList* this);
bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name); bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name);
void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period); void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period);
void ProcessList_scan(ProcessList* this); void ProcessList_scan(ProcessList* this);
void ProcessList_dontCrash(int signal);
#endif #endif

6
README
View File

@ -2,13 +2,15 @@
htop htop
by Hisham Muhammad <loderunner@users.sourceforge.net> by Hisham Muhammad <loderunner@users.sourceforge.net>
May, 2004 - March, 2006 May, 2004 - July, 2006
Introduction Introduction
~~~~~~~~~~~~ ~~~~~~~~~~~~
This is htop, an interactive process viewer. This is htop, an interactive process viewer.
It requires ncurses. Tested with Linux 2.4 and 2.6. It requires ncurses. It is tested with Linux 2.6,
but is also reported to work (and was originally developed)
with the 2.4 series.
Note that, while, htop is Linux specific -- it is based Note that, while, htop is Linux specific -- it is based
on the Linux /proc filesystem -- it is also reported to work on the Linux /proc filesystem -- it is also reported to work

View File

@ -12,6 +12,9 @@
/*{ /*{
#define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0
typedef struct RichString_ { typedef struct RichString_ {
int len; int len;
chtype chstr[RICHSTRING_MAXLEN+1]; chtype chstr[RICHSTRING_MAXLEN+1];
@ -23,24 +26,8 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b)) #define MIN(a,b) ((a)<(b)?(a):(b))
#endif #endif
/* private property */
WINDOW* workArea = NULL;
RichString RichString_new() {
RichString this;
this.len = 0;
return this;
}
void RichString_delete(RichString this) {
}
void RichString_prune(RichString* this) {
this->len = 0;
}
void RichString_write(RichString* this, int attrs, char* data) { void RichString_write(RichString* this, int attrs, char* data) {
this->len = 0; RichString_init(this);
RichString_append(this, attrs, data); RichString_append(this, attrs, data);
} }
@ -49,35 +36,32 @@ inline void RichString_append(RichString* this, int attrs, char* data) {
} }
inline void RichString_appendn(RichString* this, int attrs, char* data, int len) { inline void RichString_appendn(RichString* this, int attrs, char* data, int len) {
if (!workArea) { int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
workArea = newpad(1, RICHSTRING_MAXLEN); for (int i = this->len, j = 0; i < last; i++, j++)
} this->chstr[i] = data[j] | attrs;
assert(workArea); this->chstr[last] = 0;
wattrset(workArea, attrs); this->len = last;
int maxToWrite = (RICHSTRING_MAXLEN - 1) - this->len;
int wrote = MIN(maxToWrite, len);
mvwaddnstr(workArea, 0, 0, data, maxToWrite);
int oldstrlen = this->len;
this->len += wrote;
mvwinchnstr(workArea, 0, 0, this->chstr + oldstrlen, wrote);
wattroff(workArea, attrs);
} }
void RichString_setAttr(RichString *this, int attrs) { void RichString_setAttr(RichString *this, int attrs) {
chtype* ch = this->chstr;
for (int i = 0; i < this->len; i++) { for (int i = 0; i < this->len; i++) {
char c = this->chstr[i]; *ch = (*ch & 0xff) | attrs;
this->chstr[i] = c | attrs; ch++;
} }
} }
void RichString_applyAttr(RichString *this, int attrs) { void RichString_applyAttr(RichString *this, int attrs) {
for (int i = 0; i < this->len - 1; i++) { chtype* ch = this->chstr;
this->chstr[i] |= attrs; for (int i = 0; i < this->len; i++) {
*ch |= attrs;
ch++;
} }
} }
RichString RichString_quickString(int attrs, char* data) { RichString RichString_quickString(int attrs, char* data) {
RichString str = RichString_new(); RichString str;
RichString_initVal(str);
RichString_write(&str, attrs, data); RichString_write(&str, attrs, data);
return str; return str;
} }

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_RichString #ifndef HEADER_RichString
#define HEADER_RichString #define HEADER_RichString
@ -7,7 +7,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <curses.h> #include <curses.h>
#include <sys/param.h>
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
@ -15,18 +14,18 @@
#define RICHSTRING_MAXLEN 300 #define RICHSTRING_MAXLEN 300
#define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0
typedef struct RichString_ { typedef struct RichString_ {
int len; int len;
chtype chstr[RICHSTRING_MAXLEN+1]; chtype chstr[RICHSTRING_MAXLEN+1];
} RichString; } RichString;
#ifndef MIN
RichString RichString_new(); #define MIN(a,b) ((a)<(b)?(a):(b))
#endif
void RichString_delete(RichString this);
void RichString_prune(RichString* this);
void RichString_write(RichString* this, int attrs, char* data); void RichString_write(RichString* this, int attrs, char* data);

View File

@ -6,9 +6,9 @@ in the source distribution for its full text.
*/ */
#include "ScreenManager.h" #include "ScreenManager.h"
#include "ListBox.h" #include "Panel.h"
#include "Object.h" #include "Object.h"
#include "TypedVector.h" #include "Vector.h"
#include "FunctionBar.h" #include "FunctionBar.h"
#include "debug.h" #include "debug.h"
@ -29,8 +29,8 @@ typedef struct ScreenManager_ {
int x2; int x2;
int y2; int y2;
Orientation orientation; Orientation orientation;
TypedVector* items; Vector* items;
TypedVector* fuBars; Vector* fuBars;
int itemCount; int itemCount;
FunctionBar* fuBar; FunctionBar* fuBar;
bool owner; bool owner;
@ -47,16 +47,16 @@ 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->items = TypedVector_new(LISTBOX_CLASS, owner, DEFAULT_SIZE); this->items = Vector_new(PANEL_CLASS, owner, DEFAULT_SIZE, NULL);
this->fuBars = TypedVector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE); this->fuBars = Vector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE, NULL);
this->itemCount = 0; this->itemCount = 0;
this->owner = owner; this->owner = owner;
return this; return this;
} }
void ScreenManager_delete(ScreenManager* this) { void ScreenManager_delete(ScreenManager* this) {
TypedVector_delete(this->items); Vector_delete(this->items);
TypedVector_delete(this->fuBars); Vector_delete(this->fuBars);
free(this); free(this);
} }
@ -64,38 +64,38 @@ inline int ScreenManager_size(ScreenManager* this) {
return this->itemCount; return this->itemCount;
} }
void ScreenManager_add(ScreenManager* this, ListBox* item, FunctionBar* fuBar, int size) { void ScreenManager_add(ScreenManager* this, Panel* item, FunctionBar* fuBar, int size) {
if (this->orientation == HORIZONTAL) { if (this->orientation == HORIZONTAL) {
int lastX = 0; int lastX = 0;
if (this->itemCount > 0) { if (this->itemCount > 0) {
ListBox* last = (ListBox*) TypedVector_get(this->items, this->itemCount - 1); Panel* last = (Panel*) Vector_get(this->items, this->itemCount - 1);
lastX = last->x + last->w + 1; lastX = last->x + last->w + 1;
} }
if (size > 0) { if (size > 0) {
ListBox_resize(item, size, LINES-this->y1+this->y2); Panel_resize(item, size, LINES-this->y1+this->y2);
} else { } else {
ListBox_resize(item, COLS-this->x1+this->x2-lastX, LINES-this->y1+this->y2); Panel_resize(item, COLS-this->x1+this->x2-lastX, LINES-this->y1+this->y2);
} }
ListBox_move(item, lastX, this->y1); Panel_move(item, lastX, this->y1);
} }
// TODO: VERTICAL // TODO: VERTICAL
TypedVector_add(this->items, item); Vector_add(this->items, item);
if (fuBar) if (fuBar)
TypedVector_add(this->fuBars, fuBar); Vector_add(this->fuBars, fuBar);
else else
TypedVector_add(this->fuBars, FunctionBar_new(0, NULL, NULL, NULL)); Vector_add(this->fuBars, FunctionBar_new(0, NULL, NULL, NULL));
if (!this->fuBar && fuBar) this->fuBar = fuBar; if (!this->fuBar && fuBar) this->fuBar = fuBar;
item->needsRedraw = true; item->needsRedraw = true;
this->itemCount++; this->itemCount++;
} }
ListBox* ScreenManager_remove(ScreenManager* this, int index) { Panel* ScreenManager_remove(ScreenManager* this, int index) {
assert(this->itemCount > index); assert(this->itemCount > index);
ListBox* lb = (ListBox*) TypedVector_remove(this->items, index); Panel* panel = (Panel*) Vector_remove(this->items, index);
TypedVector_remove(this->fuBars, index); Vector_remove(this->fuBars, index);
this->fuBar = NULL; this->fuBar = NULL;
this->itemCount--; this->itemCount--;
return lb; return panel;
} }
void ScreenManager_setFunctionBar(ScreenManager* this, FunctionBar* fuBar) { void ScreenManager_setFunctionBar(ScreenManager* this, FunctionBar* fuBar) {
@ -112,37 +112,37 @@ void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2) {
int items = this->itemCount; int items = this->itemCount;
int lastX = 0; int lastX = 0;
for (int i = 0; i < items - 1; i++) { for (int i = 0; i < items - 1; i++) {
ListBox* lb = (ListBox*) TypedVector_get(this->items, i); Panel* panel = (Panel*) Vector_get(this->items, i);
ListBox_resize(lb, lb->w, LINES-y1+y2); Panel_resize(panel, panel->w, LINES-y1+y2);
ListBox_move(lb, lastX, y1); Panel_move(panel, lastX, y1);
lastX = lb->x + lb->w + 1; lastX = panel->x + panel->w + 1;
} }
ListBox* lb = (ListBox*) TypedVector_get(this->items, items-1); Panel* panel = (Panel*) Vector_get(this->items, items-1);
ListBox_resize(lb, COLS-x1+x2-lastX, LINES-y1+y2); Panel_resize(panel, COLS-x1+x2-lastX, LINES-y1+y2);
ListBox_move(lb, lastX, y1); Panel_move(panel, lastX, y1);
} }
void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) { void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
bool quit = false; bool quit = false;
int focus = 0; int focus = 0;
ListBox* lbFocus = (ListBox*) TypedVector_get(this->items, focus); Panel* panelFocus = (Panel*) Vector_get(this->items, focus);
if (this->fuBar) if (this->fuBar)
FunctionBar_draw(this->fuBar, NULL); FunctionBar_draw(this->fuBar, NULL);
int ch; int ch = 0;
while (!quit) { while (!quit) {
int items = this->itemCount; int items = this->itemCount;
for (int i = 0; i < items; i++) { for (int i = 0; i < items; i++) {
ListBox* lb = (ListBox*) TypedVector_get(this->items, i); Panel* panel = (Panel*) Vector_get(this->items, i);
ListBox_draw(lb, i == focus); Panel_draw(panel, i == focus);
if (i < items) { if (i < items) {
if (this->orientation == HORIZONTAL) { if (this->orientation == HORIZONTAL) {
mvvline(lb->y, lb->x+lb->w, ' ', lb->h+1); mvvline(panel->y, panel->x+panel->w, ' ', panel->h+1);
} }
} }
} }
FunctionBar* bar = (FunctionBar*) TypedVector_get(this->fuBars, focus); FunctionBar* bar = (FunctionBar*) Vector_get(this->fuBars, focus);
if (bar) if (bar)
this->fuBar = bar; this->fuBar = bar;
if (this->fuBar) if (this->fuBar)
@ -159,12 +159,12 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
ch = FunctionBar_synthesizeEvent(this->fuBar, mevent.x); ch = FunctionBar_synthesizeEvent(this->fuBar, mevent.x);
} else { } else {
for (int i = 0; i < this->itemCount; i++) { for (int i = 0; i < this->itemCount; i++) {
ListBox* lb = (ListBox*) TypedVector_get(this->items, i); Panel* panel = (Panel*) Vector_get(this->items, i);
if (mevent.x > lb->x && mevent.x <= lb->x+lb->w && if (mevent.x > panel->x && mevent.x <= panel->x+panel->w &&
mevent.y > lb->y && mevent.y <= lb->y+lb->h) { mevent.y > panel->y && mevent.y <= panel->y+panel->h) {
focus = i; focus = i;
lbFocus = lb; panelFocus = panel;
ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV - 1); Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
loop = true; loop = true;
break; break;
} }
@ -174,8 +174,8 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
} }
if (loop) continue; if (loop) continue;
if (lbFocus->eventHandler) { if (panelFocus->eventHandler) {
HandlerResult result = lbFocus->eventHandler(lbFocus, ch); HandlerResult result = panelFocus->eventHandler(panelFocus, ch);
if (result == HANDLED) { if (result == HANDLED) {
continue; continue;
} else if (result == BREAK_LOOP) { } else if (result == BREAK_LOOP) {
@ -196,8 +196,8 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
tryLeft: tryLeft:
if (focus > 0) if (focus > 0)
focus--; focus--;
lbFocus = (ListBox*) TypedVector_get(this->items, focus); panelFocus = (Panel*) Vector_get(this->items, focus);
if (ListBox_getSize(lbFocus) == 0 && focus > 0) if (Panel_getSize(panelFocus) == 0 && focus > 0)
goto tryLeft; goto tryLeft;
break; break;
case KEY_RIGHT: case KEY_RIGHT:
@ -205,8 +205,8 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
tryRight: tryRight:
if (focus < this->itemCount - 1) if (focus < this->itemCount - 1)
focus++; focus++;
lbFocus = (ListBox*) TypedVector_get(this->items, focus); panelFocus = (Panel*) Vector_get(this->items, focus);
if (ListBox_getSize(lbFocus) == 0 && focus < this->itemCount - 1) if (Panel_getSize(panelFocus) == 0 && focus < this->itemCount - 1)
goto tryRight; goto tryRight;
break; break;
case KEY_F(10): case KEY_F(10):
@ -215,11 +215,11 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
quit = true; quit = true;
continue; continue;
default: default:
ListBox_onKey(lbFocus, ch); Panel_onKey(panelFocus, ch);
break; break;
} }
} }
*lastFocus = lbFocus; *lastFocus = panelFocus;
*lastKey = ch; *lastKey = ch;
} }

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_ScreenManager #ifndef HEADER_ScreenManager
#define HEADER_ScreenManager #define HEADER_ScreenManager
@ -9,9 +9,9 @@ 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 "ListBox.h" #include "Panel.h"
#include "Object.h" #include "Object.h"
#include "TypedVector.h" #include "Vector.h"
#include "FunctionBar.h" #include "FunctionBar.h"
#include "debug.h" #include "debug.h"
@ -31,10 +31,10 @@ typedef struct ScreenManager_ {
int x2; int x2;
int y2; int y2;
Orientation orientation; Orientation orientation;
TypedVector* items; Vector* items;
Vector* fuBars;
int itemCount; int itemCount;
FunctionBar* fuBar; FunctionBar* fuBar;
TypedVector* fuBars;
bool owner; bool owner;
} ScreenManager; } ScreenManager;
@ -45,14 +45,14 @@ void ScreenManager_delete(ScreenManager* this);
inline int ScreenManager_size(ScreenManager* this); inline int ScreenManager_size(ScreenManager* this);
void ScreenManager_add(ScreenManager* this, ListBox* item, FunctionBar* fuBar, int size); void ScreenManager_add(ScreenManager* this, Panel* item, FunctionBar* fuBar, int size);
ListBox* ScreenManager_remove(ScreenManager* this, int index); Panel* ScreenManager_remove(ScreenManager* this, int index);
void ScreenManager_setFunctionBar(ScreenManager* this, FunctionBar* fuBar); void ScreenManager_setFunctionBar(ScreenManager* this, FunctionBar* fuBar);
void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2); void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2);
void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey); void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey);
#endif #endif

View File

@ -65,8 +65,7 @@ void Settings_delete(Settings* this) {
free(this); free(this);
} }
/* private */ static void Settings_readMeters(Settings* this, char* line, HeaderSide side) {
void Settings_readMeters(Settings* this, char* line, HeaderSide side) {
char* trim = String_trim(line); char* trim = String_trim(line);
char** ids = String_split(trim, ' '); char** ids = String_split(trim, ' ');
free(trim); free(trim);
@ -77,8 +76,7 @@ void Settings_readMeters(Settings* this, char* line, HeaderSide side) {
String_freeArray(ids); String_freeArray(ids);
} }
/* private */ static void Settings_readMeterModes(Settings* this, char* line, HeaderSide side) {
void Settings_readMeterModes(Settings* this, char* line, HeaderSide side) {
char* trim = String_trim(line); char* trim = String_trim(line);
char** ids = String_split(trim, ' '); char** ids = String_split(trim, ' ');
free(trim); free(trim);
@ -141,6 +139,8 @@ bool Settings_read(Settings* this, char* fileName) {
this->pl->highlightMegabytes = atoi(option[1]); this->pl->highlightMegabytes = atoi(option[1]);
} else if (String_eq(option[0], "header_margin")) { } else if (String_eq(option[0], "header_margin")) {
this->header->margin = atoi(option[1]); this->header->margin = atoi(option[1]);
} else if (String_eq(option[0], "expand_system_time")) {
this->pl->expandSystemTime = atoi(option[1]);
} else if (String_eq(option[0], "delay")) { } else if (String_eq(option[0], "delay")) {
this->delay = atoi(option[1]); this->delay = atoi(option[1]);
} else if (String_eq(option[0], "color_scheme")) { } else if (String_eq(option[0], "color_scheme")) {
@ -197,6 +197,7 @@ bool Settings_write(Settings* this) {
fprintf(fd, "highlight_megabytes=%d\n", (int) this->pl->highlightMegabytes); fprintf(fd, "highlight_megabytes=%d\n", (int) this->pl->highlightMegabytes);
fprintf(fd, "tree_view=%d\n", (int) this->pl->treeView); fprintf(fd, "tree_view=%d\n", (int) this->pl->treeView);
fprintf(fd, "header_margin=%d\n", (int) this->header->margin); fprintf(fd, "header_margin=%d\n", (int) this->header->margin);
fprintf(fd, "expand_system_time=%d\n", (int) this->pl->expandSystemTime);
fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme); fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme);
fprintf(fd, "delay=%d\n", (int) this->delay); fprintf(fd, "delay=%d\n", (int) this->delay);
fprintf(fd, "left_meters="); fprintf(fd, "left_meters=");

View File

@ -3,7 +3,7 @@
#ifndef HEADER_Settings #ifndef HEADER_Settings
#define HEADER_Settings #define HEADER_Settings
/* /*
htop - Settings.c htop - Settings.h
(C) 2004-2006 Hisham H. Muhammad (C) 2004-2006 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.
@ -32,8 +32,6 @@ Settings* Settings_new(ProcessList* pl, Header* header);
void Settings_delete(Settings* this); void Settings_delete(Settings* this);
bool Settings_read(Settings* this, char* fileName); bool Settings_read(Settings* this, char* fileName);
bool Settings_write(Settings* this); bool Settings_write(Settings* this);

View File

@ -23,15 +23,17 @@ typedef struct Signal_ {
int number; int number;
} Signal; } Signal;
extern char* SIGNAL_CLASS;
}*/ }*/
/* private property */ #ifdef DEBUG
char* SIGNAL_CLASS = "Signal"; char* SIGNAL_CLASS = "Signal";
#else
#define SIGNAL_CLASS NULL
#endif
Signal* Signal_new(char* name, int number) { Signal* Signal_new(char* name, int number) {
Signal* this = malloc(sizeof(Signal)); Signal* this = malloc(sizeof(Signal));
((Object*)this)->class = SIGNAL_CLASS; Object_setClass(this, SIGNAL_CLASS);
((Object*)this)->display = Signal_display; ((Object*)this)->display = Signal_display;
((Object*)this)->delete = Signal_delete; ((Object*)this)->delete = Signal_delete;
this->name = name; this->name = name;

View File

@ -1,9 +1,9 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Signal #ifndef HEADER_SignalItem
#define HEADER_Signal #define HEADER_SignalItem
/* /*
htop htop - SignalItem.h
(C) 2004-2006 Hisham H. Muhammad (C) 2004-2006 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.
@ -25,8 +25,12 @@ typedef struct Signal_ {
int number; int number;
} Signal; } Signal;
extern char* SIGNAL_CLASS;
#ifdef DEBUG
extern char* SIGNAL_CLASS;
#else
#define SIGNAL_CLASS NULL
#endif
Signal* Signal_new(char* name, int number); Signal* Signal_new(char* name, int number);

View File

@ -1,77 +0,0 @@
#include "SignalsListBox.h"
#include "ListBox.h"
#include "SignalItem.h"
#include "RichString.h"
#include "debug.h"
#include <assert.h>
#include <ctype.h>
/*{
typedef struct SignalsListBox_ {
ListBox super;
int state;
Signal** signals;
} SignalsListBox;
}*/
SignalsListBox* SignalsListBox_new(int x, int y, int w, int h) {
SignalsListBox* this = (SignalsListBox*) malloc(sizeof(SignalsListBox));
ListBox* super = (ListBox*) this;
ListBox_init(super, x, y, w, h, SIGNAL_CLASS, true);
((Object*)this)->delete = SignalsListBox_delete;
this->signals = Signal_getSignalTable();
super->eventHandler = SignalsListBox_EventHandler;
int sigCount = Signal_getSignalCount();
for(int i = 0; i < sigCount; i++)
ListBox_set(super, i, (Object*) this->signals[i]);
SignalsListBox_reset(this);
return this;
}
void SignalsListBox_delete(Object* object) {
ListBox* super = (ListBox*) object;
SignalsListBox* this = (SignalsListBox*) object;
ListBox_done(super);
free(this->signals);
free(this);
}
void SignalsListBox_reset(SignalsListBox* this) {
ListBox* super = (ListBox*) this;
ListBox_setHeader(super, "Send signal:");
ListBox_setSelected(super, 16); // 16th item is SIGTERM
this->state = 0;
}
HandlerResult SignalsListBox_EventHandler(ListBox* super, int ch) {
SignalsListBox* this = (SignalsListBox*) super;
int size = ListBox_getSize(super);
if (ch <= 255 && isdigit(ch)) {
int signal = ch-48 + this->state;
for (int i = 0; i < size; i++)
if (((Signal*) ListBox_get(super, i))->number == signal) {
ListBox_setSelected(super, i);
break;
}
this->state = signal * 10;
if (this->state > 100)
this->state = 0;
return HANDLED;
} else {
this->state = 0;
}
if (ch == 13) {
return BREAK_LOOP;
}
return IGNORED;
}

View File

@ -1,32 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_SignalsListBox
#define HEADER_SignalsListBox
#include "ListBox.h"
#include "SignalItem.h"
#include "RichString.h"
#include "debug.h"
#include <assert.h>
#include <ctype.h>
typedef struct SignalsListBox_ {
ListBox super;
int state;
Signal** signals;
} SignalsListBox;
SignalsListBox* SignalsListBox_new(int x, int y, int w, int h);
void SignalsListBox_delete(Object* object);
void SignalsListBox_reset(SignalsListBox* this);
HandlerResult SignalsListBox_EventHandler(ListBox* super, int ch);
#endif

77
SignalsPanel.c Normal file
View File

@ -0,0 +1,77 @@
#include "SignalsPanel.h"
#include "Panel.h"
#include "SignalItem.h"
#include "RichString.h"
#include "debug.h"
#include <assert.h>
#include <ctype.h>
/*{
typedef struct SignalsPanel_ {
Panel super;
int state;
Signal** signals;
} SignalsPanel;
}*/
SignalsPanel* SignalsPanel_new(int x, int y, int w, int h) {
SignalsPanel* this = (SignalsPanel*) malloc(sizeof(SignalsPanel));
Panel* super = (Panel*) this;
Panel_init(super, x, y, w, h, SIGNAL_CLASS, true);
((Object*)this)->delete = SignalsPanel_delete;
this->signals = Signal_getSignalTable();
super->eventHandler = SignalsPanel_EventHandler;
int sigCount = Signal_getSignalCount();
for(int i = 0; i < sigCount; i++)
Panel_set(super, i, (Object*) this->signals[i]);
SignalsPanel_reset(this);
return this;
}
void SignalsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
SignalsPanel* this = (SignalsPanel*) object;
Panel_done(super);
free(this->signals);
free(this);
}
void SignalsPanel_reset(SignalsPanel* this) {
Panel* super = (Panel*) this;
Panel_setHeader(super, "Send signal:");
Panel_setSelected(super, 16); // 16th item is SIGTERM
this->state = 0;
}
HandlerResult SignalsPanel_EventHandler(Panel* super, int ch) {
SignalsPanel* this = (SignalsPanel*) super;
int size = Panel_getSize(super);
if (ch <= 255 && isdigit(ch)) {
int signal = ch-48 + this->state;
for (int i = 0; i < size; i++)
if (((Signal*) Panel_get(super, i))->number == signal) {
Panel_setSelected(super, i);
break;
}
this->state = signal * 10;
if (this->state > 100)
this->state = 0;
return HANDLED;
} else {
this->state = 0;
}
if (ch == 13) {
return BREAK_LOOP;
}
return IGNORED;
}

32
SignalsPanel.h Normal file
View File

@ -0,0 +1,32 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_SignalsPanel
#define HEADER_SignalsPanel
#include "Panel.h"
#include "SignalItem.h"
#include "RichString.h"
#include "debug.h"
#include <assert.h>
#include <ctype.h>
typedef struct SignalsPanel_ {
Panel super;
int state;
Signal** signals;
} SignalsPanel;
SignalsPanel* SignalsPanel_new(int x, int y, int w, int h);
void SignalsPanel_delete(Object* object);
void SignalsPanel_reset(SignalsPanel* this);
HandlerResult SignalsPanel_EventHandler(Panel* super, int ch);
#endif

View File

@ -14,6 +14,10 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
/*{
#define String_startsWith(s, match) (strstr((s), (match)) == (s))
}*/
inline void String_delete(char* s) { inline void String_delete(char* s) {
free(s); free(s);
} }
@ -92,7 +96,7 @@ void String_printPointer(void* p) {
printf("%p", p); printf("%p", p);
} }
inline int String_eq(char* s1, char* s2) { inline int String_eq(const char* s1, const char* s2) {
if (s1 == NULL || s2 == NULL) { if (s1 == NULL || s2 == NULL) {
if (s1 == NULL && s2 == NULL) if (s1 == NULL && s2 == NULL)
return 1; return 1;
@ -102,10 +106,6 @@ inline int String_eq(char* s1, char* s2) {
return (strcmp(s1, s2) == 0); return (strcmp(s1, s2) == 0);
} }
inline int String_startsWith(char* s, char* match) {
return (strstr(s, match) == s);
}
char** String_split(char* s, char sep) { char** String_split(char* s, char sep) {
const int rate = 10; const int rate = 10;
char** out = (char**) malloc(sizeof(char*) * rate); char** out = (char**) malloc(sizeof(char*) * rate);

View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_String #ifndef HEADER_String
#define HEADER_String #define HEADER_String
@ -17,6 +17,8 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
#define String_startsWith(s, match) (strstr((s), (match)) == (s))
inline void String_delete(char* s); inline void String_delete(char* s);
inline char* String_copy(char* orig); inline char* String_copy(char* orig);
@ -37,9 +39,7 @@ void String_printInt(int i);
void String_printPointer(void* p); void String_printPointer(void* p);
inline int String_eq(char* s1, char* s2); inline int String_eq(const char* s1, const char* s2);
inline int String_startsWith(char* s, char* match);
char** String_split(char* s, char sep); char** String_split(char* s, char sep);

View File

@ -19,10 +19,10 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
/* private property */ int SwapMeter_attributes[] = {
static int SwapMeter_attributes[] = { SWAP }; SWAP
};
/* private */
MeterType SwapMeter = { MeterType SwapMeter = {
.setValues = SwapMeter_setValues, .setValues = SwapMeter_setValues,
.display = SwapMeter_display, .display = SwapMeter_display,
@ -46,7 +46,7 @@ void SwapMeter_display(Object* cast, RichString* out) {
char buffer[50]; char buffer[50];
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
long int swap = (long int) this->values[0]; long int swap = (long int) this->values[0];
RichString_prune(out); RichString_init(out);
RichString_append(out, CRT_colors[METER_TEXT], ":"); RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, "%ldM ", (long int) this->total / 1024); sprintf(buffer, "%ldM ", (long int) this->total / 1024);
RichString_append(out, CRT_colors[METER_VALUE], buffer); RichString_append(out, CRT_colors[METER_VALUE], buffer);

View File

@ -22,7 +22,9 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
extern int SwapMeter_attributes[];
extern MeterType SwapMeter;
void SwapMeter_setValues(Meter* this, char* buffer, int len); void SwapMeter_setValues(Meter* this, char* buffer, int len);

18
TODO Normal file
View File

@ -0,0 +1,18 @@
BUGS:
* tagged files are cleared if 'kill' fails
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=375219
* add swap column for swap usage in MB
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=365038
FEATURES:
* expand/collapse on tree
* handle saving of .htoprc more elegantly
* make bars display refresh independent from list refresh
* auto-calibrate delay
* add some more 'top' features
* add more command-line parameters
* show 'process view'
* make keybindings configurable, blah blah blah...

View File

@ -14,10 +14,10 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
/* private property */ int TasksMeter_attributes[] = {
int TasksMeter_attributes[] = { TASKS_RUNNING }; TASKS_RUNNING
};
/* private */
MeterType TasksMeter = { MeterType TasksMeter = {
.setValues = TasksMeter_setValues, .setValues = TasksMeter_setValues,
.display = TasksMeter_display, .display = TasksMeter_display,
@ -38,7 +38,7 @@ void TasksMeter_setValues(Meter* this, char* buffer, int len) {
void TasksMeter_display(Object* cast, RichString* out) { void TasksMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast; Meter* this = (Meter*)cast;
RichString_prune(out); RichString_init(out);
char buffer[20]; char buffer[20];
sprintf(buffer, "%d", (int)this->total); sprintf(buffer, "%d", (int)this->total);
RichString_append(out, CRT_colors[METER_VALUE], buffer); RichString_append(out, CRT_colors[METER_VALUE], buffer);

View File

@ -17,7 +17,9 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
extern int TasksMeter_attributes[];
extern MeterType TasksMeter;
void TasksMeter_setValues(Meter* this, char* buffer, int len); void TasksMeter_setValues(Meter* this, char* buffer, int len);

View File

@ -18,40 +18,37 @@ in the source distribution for its full text.
#include "ProcessList.h" #include "ProcessList.h"
#include "Process.h" #include "Process.h"
#include "ListItem.h" #include "ListItem.h"
#include "ListBox.h" #include "Panel.h"
#include "FunctionBar.h" #include "FunctionBar.h"
/*{ /*{
typedef struct TraceScreen_ { typedef struct TraceScreen_ {
Process* process; Process* process;
ListBox* display; Panel* display;
FunctionBar* bar; FunctionBar* bar;
bool tracing; bool tracing;
} TraceScreen; } TraceScreen;
}*/ }*/
/* private property */
static char* tbFunctions[3] = {"AutoScroll ", "Stop Tracing ", "Done "}; static char* tbFunctions[3] = {"AutoScroll ", "Stop Tracing ", "Done "};
/* private property */
static char* tbKeys[3] = {"F4", "F5", "Esc"}; static char* tbKeys[3] = {"F4", "F5", "Esc"};
/* private property */
static int tbEvents[3] = {KEY_F(4), KEY_F(5), 27}; static int tbEvents[3] = {KEY_F(4), KEY_F(5), 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 = ListBox_new(0, 1, COLS, LINES-2, LISTITEM_CLASS, true); this->display = Panel_new(0, 1, COLS, LINES-2, LISTITEM_CLASS, true, ListItem_compare);
this->bar = FunctionBar_new(3, tbFunctions, tbKeys, tbEvents); this->bar = FunctionBar_new(3, tbFunctions, tbKeys, tbEvents);
this->tracing = true; this->tracing = true;
return this; return this;
} }
void TraceScreen_delete(TraceScreen* this) { void TraceScreen_delete(TraceScreen* this) {
ListBox_delete((Object*)this->display); Panel_delete((Object*)this->display);
FunctionBar_delete((Object*)this->bar); FunctionBar_delete((Object*)this->bar);
free(this); free(this);
} }
@ -77,11 +74,13 @@ void TraceScreen_run(TraceScreen* this) {
fcntl(fdpair[1], F_SETFL, O_NONBLOCK); fcntl(fdpair[1], F_SETFL, O_NONBLOCK);
sprintf(buffer, "%d", this->process->pid); sprintf(buffer, "%d", this->process->pid);
execlp("strace", "strace", "-p", buffer, NULL); execlp("strace", "strace", "-p", buffer, NULL);
const char* message = "Could not execute 'strace'. Please make sure it is available in your $PATH.";
write(fdpair[1], message, strlen(message));
exit(1); exit(1);
} }
fcntl(fdpair[0], F_SETFL, O_NONBLOCK); fcntl(fdpair[0], F_SETFL, O_NONBLOCK);
FILE* strace = fdopen(fdpair[0], "r"); FILE* strace = fdopen(fdpair[0], "r");
ListBox* lb = this->display; Panel* panel = this->display;
int fd_strace = fileno(strace); int fd_strace = fileno(strace);
TraceScreen_draw(this); TraceScreen_draw(this);
CRT_disableDelay(); CRT_disableDelay();
@ -105,31 +104,31 @@ void TraceScreen_run(TraceScreen* this) {
if (buffer[i] == '\n') { if (buffer[i] == '\n') {
buffer[i] = '\0'; buffer[i] = '\0';
if (contLine) { if (contLine) {
ListItem_append((ListItem*)ListBox_get(lb, ListItem_append((ListItem*)Panel_get(panel,
ListBox_getSize(lb)-1), line); Panel_getSize(panel)-1), line);
contLine = false; contLine = false;
} else { } else {
ListBox_add(lb, (Object*) ListItem_new(line, 0)); Panel_add(panel, (Object*) ListItem_new(line, 0));
} }
line = buffer+i+1; line = buffer+i+1;
} }
} }
if (line < buffer+nread) { if (line < buffer+nread) {
ListBox_add(lb, (Object*) ListItem_new(line, 0)); Panel_add(panel, (Object*) ListItem_new(line, 0));
buffer[nread] = '\0'; buffer[nread] = '\0';
contLine = true; contLine = true;
} }
if (follow) if (follow)
ListBox_setSelected(lb, ListBox_getSize(lb)-1); Panel_setSelected(panel, Panel_getSize(panel)-1);
ListBox_draw(lb, true); Panel_draw(panel, true);
} }
int ch = getch(); int ch = getch();
if (ch == KEY_MOUSE) { if (ch == KEY_MOUSE) {
MEVENT mevent; MEVENT mevent;
int ok = getmouse(&mevent); int ok = getmouse(&mevent);
if (ok == OK) if (ok == OK)
if (mevent.y >= lb->y && mevent.y < LINES - 1) { if (mevent.y >= panel->y && mevent.y < LINES - 1) {
ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV); Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV);
follow = false; follow = false;
ch = 0; ch = 0;
} if (mevent.y == LINES - 1) } if (mevent.y == LINES - 1)
@ -147,23 +146,24 @@ void TraceScreen_run(TraceScreen* this) {
case KEY_F(4): case KEY_F(4):
follow = !follow; follow = !follow;
if (follow) if (follow)
ListBox_setSelected(lb, ListBox_getSize(lb)-1); Panel_setSelected(panel, Panel_getSize(panel)-1);
break; break;
case 'q': case 'q':
case 27: case 27:
looping = false; looping = false;
break; break;
case KEY_RESIZE: case KEY_RESIZE:
ListBox_resize(lb, COLS, LINES-2); Panel_resize(panel, COLS, LINES-2);
TraceScreen_draw(this); TraceScreen_draw(this);
break; break;
default: default:
follow = false; follow = false;
ListBox_onKey(lb, ch); Panel_onKey(panel, ch);
} }
ListBox_draw(lb, true); Panel_draw(panel, true);
} }
kill(child, SIGTERM); kill(child, SIGTERM);
waitpid(child, NULL, 0); waitpid(child, NULL, 0);
fclose(strace); fclose(strace);
CRT_enableDelay();
} }

View File

@ -1,11 +1,13 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_TraceScreen
#define HEADER_TraceScreen
/* /*
htop - TraceScreen.h htop - TraceScreen.h
(C) 2005 Hisham H. Muhammad (C) 2005-2006 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.
*/ */
#ifndef HEADER_TraceScreen
#define HEADER_TraceScreen
#define _GNU_SOURCE #define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
@ -13,18 +15,24 @@ in the source distribution for its full text.
#include <stdbool.h> #include <stdbool.h>
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "ProcessList.h" #include "ProcessList.h"
#include "ListBox.h" #include "Process.h"
#include "ListItem.h"
#include "Panel.h"
#include "FunctionBar.h" #include "FunctionBar.h"
typedef struct TraceScreen_ { typedef struct TraceScreen_ {
Process* process; Process* process;
ListBox* display; Panel* display;
FunctionBar* bar; FunctionBar* bar;
bool tracing; bool tracing;
} TraceScreen; } TraceScreen;
TraceScreen* TraceScreen_new(Process* process); TraceScreen* TraceScreen_new(Process* process);
void TraceScreen_delete(TraceScreen* this); void TraceScreen_delete(TraceScreen* this);
@ -34,4 +42,3 @@ void TraceScreen_draw(TraceScreen* this);
void TraceScreen_run(TraceScreen* this); void TraceScreen_run(TraceScreen* this);
#endif #endif

View File

@ -1,69 +0,0 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_TypedVector
#define HEADER_TypedVector
/*
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Object.h"
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "debug.h"
#include <assert.h>
#ifndef DEFAULT_SIZE
#define DEFAULT_SIZE -1
#endif
typedef void(*TypedVector_procedure)(void*);
typedef struct TypedVector_ {
Object **array;
int arraySize;
int growthRate;
int items;
char* vectorType;
bool owner;
} TypedVector;
TypedVector* TypedVector_new(char* vectorType_, bool owner, int size);
void TypedVector_delete(TypedVector* this);
void TypedVector_prune(TypedVector* this);
void TypedVector_sort(TypedVector* this);
void TypedVector_insert(TypedVector* this, int index, void* data_);
Object* TypedVector_take(TypedVector* this, int index);
Object* TypedVector_remove(TypedVector* this, int index);
void TypedVector_moveUp(TypedVector* this, int index);
void TypedVector_moveDown(TypedVector* this, int index);
void TypedVector_set(TypedVector* this, int index, void* data_);
inline Object* TypedVector_get(TypedVector* this, int index);
inline int TypedVector_size(TypedVector* this);
void TypedVector_merge(TypedVector* this, TypedVector* v2);
void TypedVector_add(TypedVector* this, void* data_);
inline int TypedVector_indexOf(TypedVector* this, void* search_);
void TypedVector_foreach(TypedVector* this, TypedVector_procedure f);
#endif

View File

@ -14,10 +14,10 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
/* private property */ int UptimeMeter_attributes[] = {
static int UptimeMeter_attributes[] = { UPTIME }; UPTIME
};
/* private */
MeterType UptimeMeter = { MeterType UptimeMeter = {
.setValues = UptimeMeter_setValues, .setValues = UptimeMeter_setValues,
.display = NULL, .display = NULL,
@ -44,7 +44,7 @@ void UptimeMeter_setValues(Meter* this, char* buffer, int len) {
if (days > this->total) { if (days > this->total) {
this->total = days; this->total = days;
} }
char daysbuf[10]; char daysbuf[15];
if (days > 100) { if (days > 100) {
sprintf(daysbuf, "%d days(!), ", days); sprintf(daysbuf, "%d days(!), ", days);
} else if (days > 1) { } else if (days > 1) {

View File

@ -17,8 +17,10 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
extern int UptimeMeter_attributes[];
extern MeterType UptimeMeter;
void UptimeMeter_setValues(Meter* cast, char* buffer, int len); void UptimeMeter_setValues(Meter* this, char* buffer, int len);
#endif #endif

View File

@ -1,9 +1,9 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_UsersTable #ifndef HEADER_UsersTable
#define HEADER_UsersTable #define HEADER_UsersTable
/* /*
htop htop - UsersTable.h
(C) 2004-2006 Hisham H. Muhammad (C) 2004-2006 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.
@ -20,10 +20,6 @@ in the source distribution for its full text.
#include "debug.h" #include "debug.h"
#include <assert.h> #include <assert.h>
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
typedef struct UsersTable_ { typedef struct UsersTable_ {
Hashtable* users; Hashtable* users;
} UsersTable; } UsersTable;
@ -36,6 +32,6 @@ char* UsersTable_getRef(UsersTable* this, int uid);
inline int UsersTable_size(UsersTable* this); inline int UsersTable_size(UsersTable* this);
void UsersTable_foreach(UsersTable*, Hashtable_PairFunction, void*); inline void UsersTable_foreach(UsersTable* this, Hashtable_PairFunction f, void* userData);
#endif #endif

View File

@ -5,7 +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 "TypedVector.h" #include "Vector.h"
#include "Object.h" #include "Object.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -20,35 +20,37 @@ in the source distribution for its full text.
#define DEFAULT_SIZE -1 #define DEFAULT_SIZE -1
#endif #endif
typedef void(*TypedVector_procedure)(void*); typedef void(*Vector_procedure)(void*);
typedef struct TypedVector_ { typedef struct Vector_ {
Object **array; Object **array;
Object_Compare compare;
int arraySize; int arraySize;
int growthRate; int growthRate;
int items; int items;
char* vectorType; char* vectorType;
bool owner; bool owner;
} TypedVector; } Vector;
}*/ }*/
TypedVector* TypedVector_new(char* vectorType_, bool owner, int size) { Vector* Vector_new(char* vectorType_, bool owner, int size, Object_Compare compare) {
TypedVector* this; Vector* this;
if (size == DEFAULT_SIZE) if (size == DEFAULT_SIZE)
size = 10; size = 10;
this = (TypedVector*) malloc(sizeof(TypedVector)); this = (Vector*) malloc(sizeof(Vector));
this->growthRate = size; this->growthRate = size;
this->array = (Object**) calloc(size, sizeof(Object*)); this->array = (Object**) calloc(size, sizeof(Object*));
this->arraySize = size; this->arraySize = size;
this->items = 0; this->items = 0;
this->vectorType = vectorType_; this->vectorType = vectorType_;
this->owner = owner; this->owner = owner;
this->compare = compare;
return this; return this;
} }
void TypedVector_delete(TypedVector* this) { 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])
@ -58,8 +60,9 @@ void TypedVector_delete(TypedVector* this) {
free(this); free(this);
} }
/* private */ #ifdef DEBUG
bool TypedVector_isConsistent(TypedVector* this) {
static inline bool Vector_isConsistent(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] && this->array[i]->class != this->vectorType) if (this->array[i] && this->array[i]->class != this->vectorType)
@ -70,8 +73,10 @@ bool TypedVector_isConsistent(TypedVector* this) {
} }
} }
void TypedVector_prune(TypedVector* this) { #endif
assert(TypedVector_isConsistent(this));
void Vector_prune(Vector* this) {
assert(Vector_isConsistent(this));
int i; int i;
for (i = 0; i < this->items; i++) for (i = 0; i < this->items; i++)
@ -83,33 +88,23 @@ void TypedVector_prune(TypedVector* this) {
this->items = 0; this->items = 0;
} }
void TypedVector_sort(TypedVector* this) { void Vector_sort(Vector* this) {
assert(TypedVector_isConsistent(this)); assert(this->compare);
int i, j; assert(Vector_isConsistent(this));
for (i = 1; i < this->items; i++) { Object_Compare compare = this->compare;
/* Insertion sort works best on mostly-sorted arrays. */
for (int i = 1; i < this->items; i++) {
int j;
void* t = this->array[i]; void* t = this->array[i];
for (j = i-1; j >= 0 && this->array[j]->compare(this->array[j], t) < 0; j--) for (j = i-1; j >= 0 && compare(this->array[j], t) > 0; j--)
this->array[j+1] = this->array[j]; this->array[j+1] = this->array[j];
this->array[j+1] = t; this->array[j+1] = t;
} }
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
/*
for (int i = 0; i < this->items; i++) {
for (int j = i+1; j < this->items; j++) {
if (this->array[j]->compare(this->array[j], t) < 0) {
void* tmp = this->array[i];
this->array[i] = this->array[j];
this->array[j] = tmp;
}
}
}
*/
} }
/* private */ static void Vector_checkArraySize(Vector* this) {
void TypedVector_checkArraySize(TypedVector* this) { assert(Vector_isConsistent(this));
assert(TypedVector_isConsistent(this));
if (this->items >= this->arraySize) { if (this->items >= this->arraySize) {
int i; int i;
i = this->arraySize; i = this->arraySize;
@ -118,40 +113,40 @@ void TypedVector_checkArraySize(TypedVector* this) {
for (; i < this->arraySize; i++) for (; i < this->arraySize; i++)
this->array[i] = NULL; this->array[i] = NULL;
} }
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
void TypedVector_insert(TypedVector* this, int index, void* data_) { void Vector_insert(Vector* this, int index, void* data_) {
assert(index >= 0); assert(index >= 0);
assert(((Object*)data_)->class == this->vectorType); assert(((Object*)data_)->class == this->vectorType);
Object* data = data_; Object* data = data_;
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
TypedVector_checkArraySize(this); Vector_checkArraySize(this);
assert(this->array[this->items] == NULL); assert(this->array[this->items] == NULL);
for (int i = this->items; i >= index; i--) { for (int i = this->items; i >= index; i--) {
this->array[i+1] = this->array[i]; this->array[i+1] = this->array[i];
} }
this->array[index] = data; this->array[index] = data;
this->items++; this->items++;
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
Object* TypedVector_take(TypedVector* this, int index) { Object* Vector_take(Vector* this, int index) {
assert(index >= 0 && index < this->items); assert(index >= 0 && index < this->items);
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
Object* removed = this->array[index]; Object* removed = this->array[index];
assert (removed != NULL); assert (removed != NULL);
this->items--; this->items--;
for (int i = index; i < this->items; i++) for (int i = index; i < this->items; i++)
this->array[i] = this->array[i+1]; this->array[i] = this->array[i+1];
this->array[this->items] = NULL; this->array[this->items] = NULL;
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
return removed; return removed;
} }
Object* TypedVector_remove(TypedVector* this, int index) { Object* Vector_remove(Vector* this, int index) {
Object* removed = TypedVector_take(this, index); Object* removed = Vector_take(this, index);
if (this->owner) { if (this->owner) {
removed->delete(removed); removed->delete(removed);
return NULL; return NULL;
@ -159,9 +154,9 @@ Object* TypedVector_remove(TypedVector* this, int index) {
return removed; return removed;
} }
void TypedVector_moveUp(TypedVector* this, int index) { void Vector_moveUp(Vector* this, int index) {
assert(index >= 0 && index < this->items); assert(index >= 0 && index < this->items);
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
if (index == 0) if (index == 0)
return; return;
Object* temp = this->array[index]; Object* temp = this->array[index];
@ -169,9 +164,9 @@ void TypedVector_moveUp(TypedVector* this, int index) {
this->array[index - 1] = temp; this->array[index - 1] = temp;
} }
void TypedVector_moveDown(TypedVector* this, int index) { void Vector_moveDown(Vector* this, int index) {
assert(index >= 0 && index < this->items); assert(index >= 0 && index < this->items);
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
if (index == this->items - 1) if (index == this->items - 1)
return; return;
Object* temp = this->array[index]; Object* temp = this->array[index];
@ -179,13 +174,13 @@ void TypedVector_moveDown(TypedVector* this, int index) {
this->array[index + 1] = temp; this->array[index + 1] = temp;
} }
void TypedVector_set(TypedVector* this, int index, void* data_) { void Vector_set(Vector* this, int index, void* data_) {
assert(index >= 0); assert(index >= 0);
assert(((Object*)data_)->class == this->vectorType); assert(((Object*)data_)->class == this->vectorType);
Object* data = data_; Object* data = data_;
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
TypedVector_checkArraySize(this); Vector_checkArraySize(this);
if (index >= this->items) { if (index >= this->items) {
this->items = index+1; this->items = index+1;
} else { } else {
@ -198,60 +193,58 @@ void TypedVector_set(TypedVector* this, int index, void* data_) {
} }
} }
this->array[index] = data; this->array[index] = data;
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
inline Object* TypedVector_get(TypedVector* this, int index) { inline Object* Vector_get(Vector* this, int index) {
assert(index < this->items); assert(index < this->items);
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
return this->array[index]; return this->array[index];
} }
inline int TypedVector_size(TypedVector* this) { inline int Vector_size(Vector* this) {
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
return this->items; return this->items;
} }
void TypedVector_merge(TypedVector* this, TypedVector* v2) { void Vector_merge(Vector* this, Vector* v2) {
int i; int i;
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
for (i = 0; i < v2->items; i++) for (i = 0; i < v2->items; i++)
TypedVector_add(this, v2->array[i]); Vector_add(this, v2->array[i]);
v2->items = 0; v2->items = 0;
TypedVector_delete(v2); Vector_delete(v2);
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
void TypedVector_add(TypedVector* this, void* data_) { void Vector_add(Vector* this, void* data_) {
assert(data_ && ((Object*)data_)->class == this->vectorType); assert(data_ && ((Object*)data_)->class == this->vectorType);
Object* data = data_; Object* data = data_;
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
TypedVector_set(this, this->items, data); Vector_set(this, this->items, data);
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
} }
inline int TypedVector_indexOf(TypedVector* this, void* search_) { inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare) {
assert(((Object*)search_)->class == this->vectorType); assert(((Object*)search_)->class == this->vectorType);
assert(this->compare);
Object* search = search_; Object* search = search_;
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
for (int i = 0; i < this->items; i++) {
int i;
for (i = 0; i < this->items; i++) {
Object* o = (Object*)this->array[i]; Object* o = (Object*)this->array[i];
if (o && o->compare(o, search) == 0) if (o && compare(search, o) == 0)
return i; return i;
} }
return -1; return -1;
} }
void TypedVector_foreach(TypedVector* this, TypedVector_procedure f) { void Vector_foreach(Vector* this, Vector_procedure f) {
int i; int i;
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
for (i = 0; i < this->items; i++) for (i = 0; i < this->items; i++)
f(this->array[i]); f(this->array[i]);
assert(TypedVector_isConsistent(this)); assert(Vector_isConsistent(this));
} }

74
Vector.h Normal file
View File

@ -0,0 +1,74 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Vector
#define HEADER_Vector
/*
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Object.h"
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "debug.h"
#include <assert.h>
#ifndef DEFAULT_SIZE
#define DEFAULT_SIZE -1
#endif
typedef void(*Vector_procedure)(void*);
typedef struct Vector_ {
Object **array;
Object_Compare compare;
int arraySize;
int growthRate;
int items;
char* vectorType;
bool owner;
} Vector;
Vector* Vector_new(char* vectorType_, bool owner, int size, Object_Compare compare);
void Vector_delete(Vector* this);
#ifdef DEBUG
#endif
void Vector_prune(Vector* this);
void Vector_sort(Vector* this);
void Vector_insert(Vector* this, int index, void* data_);
Object* Vector_take(Vector* this, int index);
Object* Vector_remove(Vector* this, int index);
void Vector_moveUp(Vector* this, int index);
void Vector_moveDown(Vector* this, int index);
void Vector_set(Vector* this, int index, void* data_);
inline Object* Vector_get(Vector* this, int index);
inline int Vector_size(Vector* this);
void Vector_merge(Vector* this, Vector* v2);
void Vector_add(Vector* this, void* data_);
inline int Vector_indexOf(Vector* this, void* search_, Object_Compare compare);
void Vector_foreach(Vector* this, Vector_procedure f);
#endif

0
autogen.sh Normal file → Executable file
View File

View File

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57) AC_PREREQ(2.57)
AC_INIT([htop],[0.6.2],[loderunner@users.sourceforge.net]) AC_INIT([htop],[0.6.4],[loderunner@users.sourceforge.net])
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([htop.c]) AC_CONFIG_SRCDIR([htop.c])
AC_CONFIG_HEADER([config.h]) AC_CONFIG_HEADER([config.h])
@ -11,13 +11,23 @@ AC_CONFIG_HEADER([config.h])
AC_PROG_CC AC_PROG_CC
# Checks for libraries. # Checks for libraries.
AC_CHECK_LIB([ncurses], [refresh]) AC_CHECK_LIB([ncurses], [refresh], [], [missing_libraries="$missing_libraries libncurses"])
AC_CHECK_LIB([m], [ceil]) AC_CHECK_LIB([m], [ceil], [], [missing_libraries="$missing_libraries libm"])
if test ! -z "$missing_libraries"; then
AC_MSG_ERROR([missing libraries:$missing_headers])
fi
# Checks for header files. # Checks for header files.
AC_HEADER_DIRENT AC_HEADER_DIRENT
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS([stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h curses.h]) AC_CHECK_HEADERS([stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h curses.h],[:],[
missing_headers="$missing_headers $ac_header"
])
if test ! -z "$missing_headers"; then
AC_MSG_ERROR([missing headers:$missing_headers])
fi
# Checks for typedefs, structures, and compiler characteristics. # Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL AC_HEADER_STDBOOL

36
debug.h
View File

@ -1,22 +1,28 @@
#ifdef DEBUG #if defined(DEBUG)
#include "DebugMemory.h" /* Full debug */
#include "DebugMemory.h"
#define calloc(a, b) DebugMemory_calloc(a, b, __FILE__, __LINE__)
#define malloc(x) DebugMemory_malloc(x, __FILE__, __LINE__, #x)
#define realloc(x,s) DebugMemory_realloc(x, s, __FILE__, __LINE__, #x)
#define strdup(x) DebugMemory_strdup(x, __FILE__, __LINE__)
#define free(x) DebugMemory_free(x, __FILE__, __LINE__)
#define debug_done() DebugMemory_report()
#define calloc(a, b) DebugMemory_calloc(a, b, __FILE__, __LINE__); #elif defined(DEBUGLITE)
#define malloc(x) DebugMemory_malloc(x, __FILE__, __LINE__);
#define realloc(x,s) DebugMemory_realloc(x, s, __FILE__, __LINE__);
#define strdup(x) DebugMemory_strdup(x, __FILE__, __LINE__);
#define free(x) DebugMemory_free(x, __FILE__, __LINE__);
#define debug_done() DebugMemory_report(); /* Assertions and core only */
#ifdef NDEBUG
#undef NDEBUG
#endif
#define debug_done() sleep(0)
#else
/* No debugging */
#define NDEBUG
#define debug_done() sleep(0)
#endif #endif
#ifndef DEBUG
#define NDEBUG
#define debug_done() sleep(0)
#endif

4
htop.1
View File

@ -1,4 +1,4 @@
.TH "htop" "1" "0.6.2" "Bartosz Fenski <fenio@o2.pl>" "Utils" .TH "htop" "1" "0.6.4" "Bartosz Fenski <fenio@o2.pl>" "Utils"
.SH "NAME" .SH "NAME"
htop \- interactive process viewer htop \- interactive process viewer
.SH "SYNTAX" .SH "SYNTAX"
@ -113,7 +113,7 @@ PID search: type in process ID and the selection highlight will be moved to it.
.SH "AUTHORS" .SH "AUTHORS"
.LP .LP
htop is developed by Hisham Muhammad <lode@gobolinux.org>. htop is developed by Hisham Muhammad <loderunner@users.sourceforge.net>.
.br .br
This man page was written by Bartosz Fenski <fenio@o2.pl> for the This man page was written by Bartosz Fenski <fenio@o2.pl> for the
Debian GNU/Linux distribution (but it may be used by others), and Debian GNU/Linux distribution (but it may be used by others), and

214
htop.c
View File

@ -14,7 +14,7 @@ in the source distribution for its full text.
#include "ProcessList.h" #include "ProcessList.h"
#include "CRT.h" #include "CRT.h"
#include "ListBox.h" #include "Panel.h"
#include "UsersTable.h" #include "UsersTable.h"
#include "SignalItem.h" #include "SignalItem.h"
#include "RichString.h" #include "RichString.h"
@ -22,8 +22,8 @@ in the source distribution for its full text.
#include "ScreenManager.h" #include "ScreenManager.h"
#include "FunctionBar.h" #include "FunctionBar.h"
#include "ListItem.h" #include "ListItem.h"
#include "CategoriesListBox.h" #include "CategoriesPanel.h"
#include "SignalsListBox.h" #include "SignalsPanel.h"
#include "TraceScreen.h" #include "TraceScreen.h"
#include "config.h" #include "config.h"
@ -33,9 +33,6 @@ in the source distribution for its full text.
#define INCSEARCH_MAX 40 #define INCSEARCH_MAX 40
/* private property */
char htop_barCharacters[] = "|#*@$%&";
void printVersionFlag() { void printVersionFlag() {
clear(); clear();
printf("htop " VERSION " - (C) 2004-2006 Hisham Muhammad.\n"); printf("htop " VERSION " - (C) 2004-2006 Hisham Muhammad.\n");
@ -49,12 +46,13 @@ void printHelpFlag() {
printf("Released under the GNU GPL.\n\n"); printf("Released under the GNU GPL.\n\n");
printf("-d DELAY Delay between updates, in tenths of seconds\n\n"); printf("-d DELAY Delay between updates, in tenths of seconds\n\n");
printf("-u USERNAME Show only processes of a given user\n\n"); printf("-u USERNAME Show only processes of a given user\n\n");
printf("--sort-key COLUMN Sort by this column (use --sort-key help for a column list)\n\n");
printf("Press F1 inside htop for online help.\n"); printf("Press F1 inside htop for online help.\n");
printf("See the man page for full information.\n\n"); printf("See the man page for full information.\n\n");
exit(0); exit(0);
} }
void showHelp() { void showHelp(ProcessList* pl) {
clear(); clear();
attrset(CRT_colors[HELP_BOLD]); attrset(CRT_colors[HELP_BOLD]);
mvaddstr(0, 0, "htop " VERSION " - (C) 2004-2006 Hisham Muhammad."); mvaddstr(0, 0, "htop " VERSION " - (C) 2004-2006 Hisham Muhammad.");
@ -64,10 +62,20 @@ void showHelp() {
mvaddstr(3, 0, "CPU usage bar: "); mvaddstr(3, 0, "CPU usage bar: ");
#define addattrstr(a,s) attrset(a);addstr(s) #define addattrstr(a,s) attrset(a);addstr(s)
addattrstr(CRT_colors[BAR_BORDER], "["); addattrstr(CRT_colors[BAR_BORDER], "[");
if (pl->expandSystemTime) {
addattrstr(CRT_colors[CPU_NICE], "low"); addstr("/");
addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/");
addattrstr(CRT_colors[CPU_KERNEL], "kernel"); addstr("/");
addattrstr(CRT_colors[CPU_IOWAIT], "io-wait"); addstr("/");
addattrstr(CRT_colors[CPU_IRQ], "irq"); addstr("/");
addattrstr(CRT_colors[CPU_SOFTIRQ], "soft-irq");
addattrstr(CRT_colors[BAR_SHADOW], " used%");
} else {
addattrstr(CRT_colors[CPU_NICE], "low-priority"); addstr("/"); addattrstr(CRT_colors[CPU_NICE], "low-priority"); addstr("/");
addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/"); addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/");
addattrstr(CRT_colors[CPU_KERNEL], "kernel"); addattrstr(CRT_colors[CPU_KERNEL], "kernel");
addattrstr(CRT_colors[BAR_SHADOW], " used%"); addattrstr(CRT_colors[BAR_SHADOW], " used%");
}
addattrstr(CRT_colors[BAR_BORDER], "]"); addattrstr(CRT_colors[BAR_BORDER], "]");
attrset(CRT_colors[DEFAULT_COLOR]); attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(4, 0, "Memory bar: "); mvaddstr(4, 0, "Memory bar: ");
@ -84,7 +92,7 @@ void showHelp() {
addattrstr(CRT_colors[BAR_SHADOW], " used/total"); addattrstr(CRT_colors[BAR_SHADOW], " used/total");
addattrstr(CRT_colors[BAR_BORDER], "]"); addattrstr(CRT_colors[BAR_BORDER], "]");
attrset(CRT_colors[DEFAULT_COLOR]); attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(6,0, "Type and layout of header meters is configurable in the setup screen."); mvaddstr(6,0, "Type and layout of header meters are configurable in the setup screen.");
mvaddstr( 8, 0, " Arrows: scroll process list F5 t: tree view"); mvaddstr( 8, 0, " Arrows: scroll process list F5 t: tree view");
mvaddstr( 9, 0, " Digits: incremental PID search u: show processes of a single user"); mvaddstr( 9, 0, " Digits: incremental PID search u: show processes of a single user");
@ -126,62 +134,62 @@ void showHelp() {
static void Setup_run(Settings* settings, int headerHeight) { static void Setup_run(Settings* settings, int headerHeight) {
ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true); ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true);
CategoriesListBox* lbCategories = CategoriesListBox_new(settings, scr); CategoriesPanel* panelCategories = CategoriesPanel_new(settings, scr);
ScreenManager_add(scr, (ListBox*) lbCategories, NULL, 16); ScreenManager_add(scr, (Panel*) panelCategories, NULL, 16);
CategoriesListBox_makeMetersPage(lbCategories); CategoriesPanel_makeMetersPage(panelCategories);
ListBox* lbFocus; Panel* panelFocus;
int ch; int ch;
ScreenManager_run(scr, &lbFocus, &ch); ScreenManager_run(scr, &panelFocus, &ch);
ScreenManager_delete(scr); ScreenManager_delete(scr);
} }
static bool changePriority(ListBox* lb, int delta) { static bool changePriority(Panel* panel, int delta) {
bool anyTagged = false; bool anyTagged = false;
for (int i = 0; i < ListBox_getSize(lb); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) ListBox_get(lb, i); Process* p = (Process*) Panel_get(panel, i);
if (p->tag) { if (p->tag) {
Process_setPriority(p, p->nice + delta); Process_setPriority(p, p->nice + delta);
anyTagged = true; anyTagged = true;
} }
} }
if (!anyTagged) { if (!anyTagged) {
Process* p = (Process*) ListBox_getSelected(lb); Process* p = (Process*) Panel_getSelected(panel);
Process_setPriority(p, p->nice + delta); Process_setPriority(p, p->nice + delta);
} }
return anyTagged; return anyTagged;
} }
static HandlerResult pickWithEnter(ListBox* lb, int ch) { static HandlerResult pickWithEnter(Panel* panel, int ch) {
if (ch == 13) if (ch == 13)
return BREAK_LOOP; return BREAK_LOOP;
return IGNORED; return IGNORED;
} }
static Object* pickFromList(ListBox* lb, ListBox* list, int x, int y, char** keyLabels, FunctionBar* prevBar) { static Object* pickFromList(Panel* panel, Panel* list, int x, int y, char** keyLabels, FunctionBar* prevBar) {
char* fuKeys[2] = {"Enter", "Esc"}; char* fuKeys[2] = {"Enter", "Esc"};
int fuEvents[2] = {13, 27}; int fuEvents[2] = {13, 27};
if (!lb->eventHandler) if (!panel->eventHandler)
ListBox_setEventHandler(list, pickWithEnter); Panel_setEventHandler(list, pickWithEnter);
ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, false); ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, false);
ScreenManager_add(scr, list, FunctionBar_new(2, keyLabels, fuKeys, fuEvents), x - 1); ScreenManager_add(scr, list, FunctionBar_new(2, keyLabels, fuKeys, fuEvents), x - 1);
ScreenManager_add(scr, lb, NULL, -1); ScreenManager_add(scr, panel, NULL, -1);
ListBox* lbFocus; Panel* panelFocus;
int ch; int ch;
ScreenManager_run(scr, &lbFocus, &ch); ScreenManager_run(scr, &panelFocus, &ch);
ScreenManager_delete(scr); ScreenManager_delete(scr);
ListBox_move(lb, 0, y); Panel_move(panel, 0, y);
ListBox_resize(lb, COLS, LINES-y-1); Panel_resize(panel, COLS, LINES-y-1);
FunctionBar_draw(prevBar, NULL); FunctionBar_draw(prevBar, NULL);
if (lbFocus == list && ch == 13) { if (panelFocus == list && ch == 13) {
return ListBox_getSelected(list); return Panel_getSelected(list);
} }
return NULL; return NULL;
} }
void addUserToList(int key, void* userCast, void* lbCast) { void addUserToList(int key, void* userCast, void* panelCast) {
char* user = (char*) userCast; char* user = (char*) userCast;
ListBox* lb = (ListBox*) lbCast; Panel* panel = (Panel*) panelCast;
ListBox_add(lb, (Object*) ListItem_new(user, key)); Panel_add(panel, (Object*) ListItem_new(user, key));
} }
void setUserOnly(const char* userName, bool* userOnly, uid_t* userId) { void setUserOnly(const char* userName, bool* userOnly, uid_t* userId) {
@ -197,12 +205,25 @@ int main(int argc, char** argv) {
int delay = -1; int delay = -1;
bool userOnly = false; bool userOnly = false;
uid_t userId = 0; uid_t userId = 0;
int sortKey = 0;
if (argc > 0) { if (argc > 0) {
if (String_eq(argv[1], "--help")) { if (String_eq(argv[1], "--help")) {
printHelpFlag(); printHelpFlag();
} else if (String_eq(argv[1], "--version")) { } else if (String_eq(argv[1], "--version")) {
printVersionFlag(); printVersionFlag();
} else if (String_eq(argv[1], "--sort-key")) {
if (argc < 2) printHelpFlag();
if (String_eq(argv[2], "help")) {
for (int j = 1; j < LAST_PROCESSFIELD; j++)
printf ("%s\n", Process_fieldNames[j]);
exit(0);
}
sortKey = ColumnsPanel_fieldNameToIndex(argv[2]);
if (sortKey == -1) {
fprintf(stderr, "Error: invalid column \"%s\".\n", argv[2]);
exit(1);
}
} else if (String_eq(argv[1], "-d")) { } else if (String_eq(argv[1], "-d")) {
if (argc < 2) printHelpFlag(); if (argc < 2) printHelpFlag();
sscanf(argv[2], "%d", &delay); sscanf(argv[2], "%d", &delay);
@ -219,14 +240,14 @@ int main(int argc, char** argv) {
exit(1); exit(1);
} }
ListBox* lb; Panel* panel;
int quit = 0; int quit = 0;
int refreshTimeout = 0; int refreshTimeout = 0;
int resetRefreshTimeout = 5; int resetRefreshTimeout = 5;
bool doRefresh = true; bool doRefresh = true;
Settings* settings; Settings* settings;
ListBox* lbk = NULL; Panel* killPanel = NULL;
char incSearchBuffer[INCSEARCH_MAX]; char incSearchBuffer[INCSEARCH_MAX];
int incSearchIndex = 0; int incSearchIndex = 0;
@ -240,6 +261,10 @@ int main(int argc, char** argv) {
Header* header = Header_new(pl); Header* header = Header_new(pl);
settings = Settings_new(pl, header); settings = Settings_new(pl, header);
if (sortKey > 0) {
pl->sortKey = sortKey;
pl->treeView = false;
}
int headerHeight = Header_calculateHeight(header); int headerHeight = Header_calculateHeight(header);
// FIXME: move delay code to settings // FIXME: move delay code to settings
@ -248,8 +273,8 @@ int main(int argc, char** argv) {
CRT_init(settings->delay, settings->colorScheme); CRT_init(settings->delay, settings->colorScheme);
lb = ListBox_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false); panel = Panel_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false, NULL);
ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); Panel_setRichHeader(panel, ProcessList_printHeader(pl));
char* searchFunctions[3] = {"Next ", "Exit ", " Search: "}; char* searchFunctions[3] = {"Next ", "Exit ", " Search: "};
char* searchKeys[3] = {"F3", "Esc", " "}; char* searchKeys[3] = {"F3", "Esc", " "};
@ -285,9 +310,9 @@ int main(int argc, char** argv) {
if (doRefresh) { if (doRefresh) {
incSearchIndex = 0; incSearchIndex = 0;
incSearchBuffer[0] = 0; incSearchBuffer[0] = 0;
int currPos = ListBox_getSelectedIndex(lb); int currPos = Panel_getSelectedIndex(panel);
int currPid = 0; int currPid = 0;
int currScrollV = lb->scrollV; int currScrollV = panel->scrollV;
if (follow) if (follow)
currPid = ProcessList_get(pl, currPos)->pid; currPid = ProcessList_get(pl, currPos)->pid;
if (recalculate) if (recalculate)
@ -296,18 +321,18 @@ int main(int argc, char** argv) {
ProcessList_sort(pl); ProcessList_sort(pl);
refreshTimeout = 1; refreshTimeout = 1;
} }
ListBox_prune(lb); Panel_prune(panel);
int size = ProcessList_size(pl); int size = ProcessList_size(pl);
int lbi = 0; int index = 0;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Process* p = ProcessList_get(pl, i); Process* p = ProcessList_get(pl, i);
if (!userOnly || (p->st_uid == userId)) { if (!userOnly || (p->st_uid == userId)) {
ListBox_set(lb, lbi, (Object*)p); Panel_set(panel, index, (Object*)p);
if ((!follow && lbi == currPos) || (follow && p->pid == currPid)) { if ((!follow && index == currPos) || (follow && p->pid == currPid)) {
ListBox_setSelected(lb, lbi); Panel_setSelected(panel, index);
lb->scrollV = currScrollV; panel->scrollV = currScrollV;
} }
lbi++; index++;
} }
} }
} }
@ -315,7 +340,7 @@ int main(int argc, char** argv) {
Header_draw(header); Header_draw(header);
ListBox_draw(lb, true); Panel_draw(panel, true);
int prev = ch; int prev = ch;
ch = getch(); ch = getch();
@ -334,7 +359,7 @@ int main(int argc, char** argv) {
if (incSearchMode) { if (incSearchMode) {
doRefresh = false; doRefresh = false;
if (ch == KEY_F(3)) { if (ch == KEY_F(3)) {
int here = ListBox_getSelectedIndex(lb); int here = Panel_getSelectedIndex(panel);
int size = ProcessList_size(pl); int size = ProcessList_size(pl);
int i = here+1; int i = here+1;
while (i != here) { while (i != here) {
@ -342,7 +367,7 @@ int main(int argc, char** argv) {
i = 0; i = 0;
Process* p = ProcessList_get(pl, i); Process* p = ProcessList_get(pl, i);
if (String_contains_i(p->comm, incSearchBuffer)) { if (String_contains_i(p->comm, incSearchBuffer)) {
ListBox_setSelected(lb, i); Panel_setSelected(panel, i);
break; break;
} }
i++; i++;
@ -367,7 +392,7 @@ int main(int argc, char** argv) {
for (int i = 0; i < ProcessList_size(pl); i++) { for (int i = 0; i < ProcessList_size(pl); i++) {
Process* p = ProcessList_get(pl, i); Process* p = ProcessList_get(pl, i);
if (String_contains_i(p->comm, incSearchBuffer)) { if (String_contains_i(p->comm, incSearchBuffer)) {
ListBox_setSelected(lb, i); Panel_setSelected(panel, i);
found = true; found = true;
break; break;
} }
@ -381,8 +406,8 @@ int main(int argc, char** argv) {
} }
if (isdigit((char)ch)) { if (isdigit((char)ch)) {
int pid = ch-48 + acc; int pid = ch-48 + acc;
for (int i = 0; i < ProcessList_size(pl) && ((Process*) ListBox_getSelected(lb))->pid != pid; i++) for (int i = 0; i < ProcessList_size(pl) && ((Process*) Panel_getSelected(panel))->pid != pid; i++)
ListBox_setSelected(lb, i); Panel_setSelected(panel, i);
acc = pid * 10; acc = pid * 10;
if (acc > 100000) if (acc > 100000)
acc = 0; acc = 0;
@ -395,8 +420,8 @@ int main(int argc, char** argv) {
MEVENT mevent; MEVENT mevent;
int ok = getmouse(&mevent); int ok = getmouse(&mevent);
if (ok == OK) { if (ok == OK) {
if (mevent.y >= lb->y + 1 && mevent.y < LINES - 1) { if (mevent.y >= panel->y + 1 && mevent.y < LINES - 1) {
ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV - 1); Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
doRefresh = false; doRefresh = false;
refreshTimeout = resetRefreshTimeout; refreshTimeout = resetRefreshTimeout;
follow = true; follow = true;
@ -413,7 +438,7 @@ int main(int argc, char** argv) {
switch (ch) { switch (ch) {
case KEY_RESIZE: case KEY_RESIZE:
ListBox_resize(lb, COLS, LINES-headerHeight-1); Panel_resize(panel, COLS, LINES-headerHeight-1);
if (incSearchMode) if (incSearchMode)
FunctionBar_draw(searchBar, incSearchBuffer); FunctionBar_draw(searchBar, incSearchBuffer);
else else
@ -425,7 +450,7 @@ int main(int argc, char** argv) {
pl->sortKey = PERCENT_MEM; pl->sortKey = PERCENT_MEM;
pl->treeView = false; pl->treeView = false;
settings->changed = true; settings->changed = true;
ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); Panel_setRichHeader(panel, ProcessList_printHeader(pl));
break; break;
} }
case 'T': case 'T':
@ -434,13 +459,13 @@ int main(int argc, char** argv) {
pl->sortKey = TIME; pl->sortKey = TIME;
pl->treeView = false; pl->treeView = false;
settings->changed = true; settings->changed = true;
ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); Panel_setRichHeader(panel, ProcessList_printHeader(pl));
break; break;
} }
case 'U': case 'U':
{ {
for (int i = 0; i < ListBox_getSize(lb); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) ListBox_get(lb, i); Process* p = (Process*) Panel_get(panel, i);
p->tag = false; p->tag = false;
} }
doRefresh = true; doRefresh = true;
@ -452,13 +477,13 @@ int main(int argc, char** argv) {
pl->sortKey = PERCENT_CPU; pl->sortKey = PERCENT_CPU;
pl->treeView = false; pl->treeView = false;
settings->changed = true; settings->changed = true;
ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); Panel_setRichHeader(panel, ProcessList_printHeader(pl));
break; break;
} }
case KEY_F(1): case KEY_F(1):
case 'h': case 'h':
{ {
showHelp(); showHelp(pl);
FunctionBar_draw(defaultBar, NULL); FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0; refreshTimeout = 0;
break; break;
@ -472,14 +497,14 @@ int main(int argc, char** argv) {
} }
case ' ': case ' ':
{ {
Process* p = (Process*) ListBox_getSelected(lb); Process* p = (Process*) Panel_getSelected(panel);
Process_toggleTag(p); Process_toggleTag(p);
ListBox_onKey(lb, KEY_DOWN); Panel_onKey(panel, KEY_DOWN);
break; break;
} }
case 's': case 's':
{ {
TraceScreen* ts = TraceScreen_new((Process*) ListBox_getSelected(lb)); TraceScreen* ts = TraceScreen_new((Process*) Panel_getSelected(panel));
TraceScreen_run(ts); TraceScreen_run(ts);
TraceScreen_delete(ts); TraceScreen_delete(ts);
clear(); clear();
@ -494,10 +519,10 @@ int main(int argc, char** argv) {
{ {
Setup_run(settings, headerHeight); Setup_run(settings, headerHeight);
// TODO: shouldn't need this, colors should be dynamic // TODO: shouldn't need this, colors should be dynamic
ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); Panel_setRichHeader(panel, ProcessList_printHeader(pl));
headerHeight = Header_calculateHeight(header); headerHeight = Header_calculateHeight(header);
ListBox_move(lb, 0, headerHeight); Panel_move(panel, 0, headerHeight);
ListBox_resize(lb, COLS, LINES-headerHeight-1); Panel_resize(panel, COLS, LINES-headerHeight-1);
FunctionBar_draw(defaultBar, NULL); FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0; refreshTimeout = 0;
break; break;
@ -509,14 +534,14 @@ int main(int argc, char** argv) {
} }
case 'u': case 'u':
{ {
ListBox* lbu = ListBox_new(0, 0, 0, 0, LISTITEM_CLASS, true); Panel* usersPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare);
ListBox_setHeader(lbu, "Show processes of:"); Panel_setHeader(usersPanel, "Show processes of:");
UsersTable_foreach(ut, addUserToList, lbu); UsersTable_foreach(ut, addUserToList, usersPanel);
TypedVector_sort(lbu->items); Vector_sort(usersPanel->items);
ListItem* allUsers = ListItem_new("All users", -1); ListItem* allUsers = ListItem_new("All users", -1);
ListBox_insert(lbu, 0, (Object*) allUsers); Panel_insert(usersPanel, 0, (Object*) allUsers);
char* fuFunctions[2] = {"Show ", "Cancel "}; char* fuFunctions[2] = {"Show ", "Cancel "};
ListItem* picked = (ListItem*) pickFromList(lb, lbu, 20, headerHeight, fuFunctions, defaultBar); ListItem* picked = (ListItem*) pickFromList(panel, usersPanel, 20, headerHeight, fuFunctions, defaultBar);
if (picked) { if (picked) {
if (picked == allUsers) { if (picked == allUsers) {
userOnly = false; userOnly = false;
@ -530,34 +555,33 @@ int main(int argc, char** argv) {
case KEY_F(9): case KEY_F(9):
case 'k': case 'k':
{ {
if (!lbk) { if (!killPanel) {
lbk = (ListBox*) SignalsListBox_new(0, 0, 0, 0); killPanel = (Panel*) SignalsPanel_new(0, 0, 0, 0);
} }
SignalsListBox_reset((SignalsListBox*) lbk); SignalsPanel_reset((SignalsPanel*) killPanel);
char* fuFunctions[2] = {"Send ", "Cancel "}; char* fuFunctions[2] = {"Send ", "Cancel "};
Signal* signal = (Signal*) pickFromList(lb, lbk, 15, headerHeight, fuFunctions, defaultBar); Signal* signal = (Signal*) pickFromList(panel, killPanel, 15, headerHeight, fuFunctions, defaultBar);
if (signal) { if (signal) {
if (signal->number != 0) { if (signal->number != 0) {
ListBox_setHeader(lb, "Sending..."); Panel_setHeader(panel, "Sending...");
ListBox_draw(lb, true); Panel_draw(panel, true);
refresh(); refresh();
bool anyTagged = false; bool anyTagged = false;
for (int i = 0; i < ListBox_getSize(lb); i++) { for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) ListBox_get(lb, i); Process* p = (Process*) Panel_get(panel, i);
if (p->tag) { if (p->tag) {
Process_sendSignal(p, signal->number); Process_sendSignal(p, signal->number);
Process_toggleTag(p);
anyTagged = true; anyTagged = true;
} }
} }
if (!anyTagged) { if (!anyTagged) {
Process* p = (Process*) ListBox_getSelected(lb); Process* p = (Process*) Panel_getSelected(panel);
Process_sendSignal(p, signal->number); Process_sendSignal(p, signal->number);
} }
napms(500); napms(500);
} }
} }
ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); Panel_setRichHeader(panel, ProcessList_printHeader(pl));
refreshTimeout = 0; refreshTimeout = 0;
break; break;
} }
@ -572,25 +596,25 @@ int main(int argc, char** argv) {
case '.': case '.':
case KEY_F(6): case KEY_F(6):
{ {
ListBox* lbf = ListBox_new(0,0,0,0,LISTITEM_CLASS,true); Panel* sortPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare);
ListBox_setHeader(lbf, "Sort by"); Panel_setHeader(sortPanel, "Sort by");
char* fuFunctions[2] = {"Sort ", "Cancel "}; char* fuFunctions[2] = {"Sort ", "Cancel "};
ProcessField* fields = pl->fields; ProcessField* fields = pl->fields;
for (int i = 0; fields[i]; i++) { for (int i = 0; fields[i]; i++) {
char* name = String_trim(Process_printField(fields[i])); char* name = String_trim(Process_printField(fields[i]));
ListBox_add(lbf, (Object*) ListItem_new(name, fields[i])); Panel_add(sortPanel, (Object*) ListItem_new(name, fields[i]));
if (fields[i] == pl->sortKey) if (fields[i] == pl->sortKey)
ListBox_setSelected(lbf, i); Panel_setSelected(sortPanel, i);
free(name); free(name);
} }
ListItem* field = (ListItem*) pickFromList(lb, lbf, 15, headerHeight, fuFunctions, defaultBar); ListItem* field = (ListItem*) pickFromList(panel, sortPanel, 15, headerHeight, fuFunctions, defaultBar);
if (field) { if (field) {
pl->treeView = false; pl->treeView = false;
settings->changed = true; settings->changed = true;
pl->sortKey = field->key; pl->sortKey = field->key;
} }
((Object*)lbf)->delete((Object*)lbf); ((Object*)sortPanel)->delete((Object*)sortPanel);
ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); Panel_setRichHeader(panel, ProcessList_printHeader(pl));
refreshTimeout = 0; refreshTimeout = 0;
break; break;
} }
@ -607,14 +631,14 @@ int main(int argc, char** argv) {
case '=': case '=':
case '+': case '+':
{ {
doRefresh = changePriority(lb, 1); doRefresh = changePriority(panel, 1);
break; break;
} }
case KEY_F(7): case KEY_F(7):
case ']': case ']':
case '-': case '-':
{ {
doRefresh = changePriority(lb, -1); doRefresh = changePriority(panel, -1);
break; break;
} }
case KEY_F(3): case KEY_F(3):
@ -641,7 +665,7 @@ int main(int argc, char** argv) {
default: default:
doRefresh = false; doRefresh = false;
refreshTimeout = resetRefreshTimeout; refreshTimeout = resetRefreshTimeout;
ListBox_onKey(lb, ch); Panel_onKey(panel, ch);
break; break;
} }
follow = false; follow = false;
@ -658,9 +682,9 @@ int main(int argc, char** argv) {
ProcessList_delete(pl); ProcessList_delete(pl);
FunctionBar_delete((Object*)searchBar); FunctionBar_delete((Object*)searchBar);
FunctionBar_delete((Object*)defaultBar); FunctionBar_delete((Object*)defaultBar);
((Object*)lb)->delete((Object*)lb); ((Object*)panel)->delete((Object*)panel);
if (lbk) if (killPanel)
((Object*)lbk)->delete((Object*)lbk); ((Object*)killPanel)->delete((Object*)killPanel);
UsersTable_delete(ut); UsersTable_delete(ut);
Settings_delete(settings); Settings_delete(settings);
debug_done(); debug_done();

View File

@ -1,6 +1,6 @@
[Desktop Entry] [Desktop Entry]
Encoding=UTF-8 Encoding=UTF-8
Version=0.6.2 Version=0.6.4
Name=Htop Name=Htop
Type=Application Type=Application
Comment=Show System Processes Comment=Show System Processes

29
htop.h
View File

@ -1,4 +1,4 @@
/* Do not edit this file. It was automatically genarated. */ /* Do not edit this file. It was automatically generated. */
#ifndef HEADER_htop #ifndef HEADER_htop
#define HEADER_htop #define HEADER_htop
@ -9,9 +9,16 @@ 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.
*/ */
#define _GNU_SOURCE
#include <unistd.h>
#include <math.h>
#include <sys/param.h>
#include <ctype.h>
#include <stdbool.h>
#include "ProcessList.h" #include "ProcessList.h"
#include "CRT.h" #include "CRT.h"
#include "ListBox.h" #include "Panel.h"
#include "UsersTable.h" #include "UsersTable.h"
#include "SignalItem.h" #include "SignalItem.h"
#include "RichString.h" #include "RichString.h"
@ -19,34 +26,26 @@ in the source distribution for its full text.
#include "ScreenManager.h" #include "ScreenManager.h"
#include "FunctionBar.h" #include "FunctionBar.h"
#include "ListItem.h" #include "ListItem.h"
#include "CategoriesListBox.h" #include "CategoriesPanel.h"
#include "SignalsListBox.h" #include "SignalsPanel.h"
#include "TraceScreen.h"
#include "config.h" #include "config.h"
#include "debug.h" #include "debug.h"
#include <unistd.h>
#include <math.h>
#include <sys/param.h>
#include <ctype.h>
#include <stdbool.h>
int usleep(int usec);
//#link m //#link m
#define INCSEARCH_MAX 40 #define INCSEARCH_MAX 40
void printVersionFlag(); void printVersionFlag();
void printHelpFlag(); void printHelpFlag();
void showHelp(); void showHelp();
void showColumnConfig(ProcessList* pl); void addUserToList(int key, void* userCast, void* panelCast);
void Setup_run(Settings* settings, int headerHeight); void setUserOnly(const char* userName, bool* userOnly, uid_t* userId);
int main(int argc, char** argv); int main(int argc, char** argv);

27
scripts/MakeHeader.py Normal file → Executable file
View File

@ -8,6 +8,7 @@ SKIP=3
SKIPONE=4 SKIPONE=4
state = ANY state = ANY
static = 0
file = open(sys.argv[1]) file = open(sys.argv[1])
name = sys.argv[1][:-2] name = sys.argv[1][:-2]
@ -34,15 +35,27 @@ for line in file.readlines():
state = COPY state = COPY
elif line == selfheader: elif line == selfheader:
pass pass
elif string.find(line, "typedef") == 0 or line == "/* private */": elif line.find("htop - ") == 0 and line[-2:] == ".c":
out.write(line[:-2] + ".h")
elif line.find("static ") != -1:
if line[-1] == "{":
state = SKIP state = SKIP
elif string.find(line, "/* private property */") == 0: static = 1
else:
state = SKIPONE state = SKIPONE
elif len(line) > 1 and line[-1] == "{": elif len(line) > 1:
static = 0
equals = line.find(" = ")
if line[-3:] == "= {":
out.write( "extern " + line[:-4] + ";" )
state = SKIP
elif equals != -1:
out.write("extern " + line[:equals] + ";" )
elif line[-1] == "{":
out.write( line[:-2] + ";" ) out.write( line[:-2] + ";" )
state = SKIP state = SKIP
elif line == "": else:
out.write( "" ) out.write( line )
else: else:
out.write( line ) out.write( line )
elif state == COPY: elif state == COPY:
@ -52,7 +65,11 @@ for line in file.readlines():
out.write( line ) out.write( line )
elif state == SKIP: elif state == SKIP:
if len(line) >= 1 and line[0] == "}": if len(line) >= 1 and line[0] == "}":
if static == 1:
state = SKIPONE
else:
state = ANY state = ANY
static = 0
elif state == SKIPONE: elif state == SKIPONE:
state = ANY state = ANY