57 Commits
0.6.2 ... 0.6.5

Author SHA1 Message Date
0a5e68652d Tag release 0.6.5 in revision history. 2006-12-01 17:53:52 +00:00
e3198ca63b Fix gcc warning. 2006-11-29 18:35:25 +00:00
92a5a691fd Report change suggested by Bo Liu 2006-11-20 16:46:20 +00:00
6b6b4373b5 Changes suggested by Bo Liu 2006-11-20 16:42:03 +00:00
2a025bf4c6 Add information about the status column
(which I always forget) in the help page
2006-11-16 15:20:44 +00:00
14808f7f70 Getting ready for 0.6.5... 2006-11-14 17:24:09 +00:00
a26ef71ed8 Minor tweak. 2006-11-13 22:04:17 +00:00
a8f45d5743 Sanity cleanup. 2006-11-13 22:00:16 +00:00
9076b9edeb Add latest changes to the log 2006-11-13 21:59:01 +00:00
0f027ded2c Fix for missing libraries message, as reported by Jon 780 2006-11-13 20:06:31 +00:00
3d62edb678 Bugfix: collect orphaned items during tree generation
at the end of the tree.
Add debugging sanity checks.
2006-11-12 21:53:56 +00:00
36848494f5 Add debugging sanity checks. 2006-11-12 21:52:14 +00:00
c90a445103 Don't double-free comm when it's an existingProcess 2006-11-09 01:44:20 +00:00
97ea7a1a8c Ok, second take on fixing the handling of comm.- 2006-11-08 22:16:46 +00:00
adbfe82e63 Oops. 2006-11-08 22:09:13 +00:00
45fab61da3 Avoid double free of prototype's comm. 2006-11-08 22:08:00 +00:00
8adc7ac00f Fix asserts, don't use freed memory. 2006-11-08 21:49:52 +00:00
2713119249 Add missing header. 2006-11-08 21:49:07 +00:00
59c3dd806b Yet another sanity check. 2006-11-08 21:47:11 +00:00
c494308b21 Add an additional debug mode for Hardened GCC. 2006-11-08 21:46:40 +00:00
c4fbd7fc8b Assign creation of the allocation log file to a separate #define. 2006-11-08 20:40:10 +00:00
febe259e91 Add lots of debugging asserts and try to clean up behavior of lists in general.
Make dumping of proc data controlled by a separate debug define.
2006-11-08 20:12:57 +00:00
110ce71b9b Add consistency checks. 2006-11-08 20:09:48 +00:00
46b35b2c7f Initialize variable. 2006-11-08 20:09:12 +00:00
b25ac6b0f7 Handle situation instead of assuming it would never happen,
as it was seen out in the field and tested here.
2006-10-26 23:06:52 +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 2624 additions and 2261 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 <assert.h>
/* private property */
static int CPUMeter_attributes[] = { CPU_NICE, CPU_NORMAL, CPU_KERNEL };
int CPUMeter_attributes[] = {
CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IOWAIT, CPU_IRQ, CPU_SOFTIRQ
};
/* private */
MeterType CPUMeter = {
.setValues = CPUMeter_setValues,
.display = CPUMeter_display,
.mode = BAR_METERMODE,
.items = 3,
.items = 6,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "CPU",
@ -35,7 +35,6 @@ MeterType CPUMeter = {
.init = CPUMeter_init
};
/* private */
MeterType AllCPUsMeter = {
.mode = 0,
.items = 1,
@ -72,26 +71,56 @@ void CPUMeter_setValues(Meter* this, char* buffer, int size) {
ProcessList* pl = this->pl;
int processor = this->param;
double total = (double) pl->totalPeriod[processor];
double cpu;
this->values[0] = pl->nicePeriod[processor] / total * 100.0;
this->values[1] = pl->userPeriod[processor] / total * 100.0;
this->values[2] = pl->systemPeriod[processor] / total * 100.0;
double cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2])));
if (pl->expandSystemTime) {
this->values[2] = pl->systemPeriod[processor] / total * 100.0;
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 );
}
void CPUMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* this = (Meter*)cast;
RichString_prune(out);
RichString_init(out);
sprintf(buffer, "%5.1f%% ", this->values[1]);
RichString_append(out, CRT_colors[METER_TEXT], ":");
RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[2]);
RichString_append(out, CRT_colors[METER_TEXT], "sys:");
RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[0]);
RichString_append(out, CRT_colors[METER_TEXT], "low:");
RichString_append(out, CRT_colors[CPU_NICE], 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]);
RichString_append(out, CRT_colors[METER_TEXT], "sys:");
RichString_append(out, CRT_colors[CPU_KERNEL], buffer);
sprintf(buffer, "%5.1f%% ", this->values[0]);
RichString_append(out, CRT_colors[METER_TEXT], "low:");
RichString_append(out, CRT_colors[CPU_NICE], buffer);
}
}
void AllCPUsMeter_init(Meter* this) {

View File

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

43
CRT.c
View File

@ -93,27 +93,23 @@ typedef enum ColorElements_ {
CPU_NORMAL,
CPU_KERNEL,
HELP_BOLD,
CPU_IOWAIT,
CPU_IRQ,
CPU_SOFTIRQ,
LAST_COLORELEMENT
} ColorElements;
extern int CRT_delay;
extern int CRT_colors[LAST_COLORELEMENT];
extern int CRT_colorScheme;
}*/
// TODO: centralize these in Settings.
/* private property */
int CRT_delay;
int CRT_delay = 0;
/* private property */
int CRT_colorScheme;
int CRT_colorScheme = 0;
/* private property */
int CRT_colors[LAST_COLORELEMENT];
int CRT_colors[LAST_COLORELEMENT] = { 0 };
char* CRT_termType;
// TODO: pass an instance of Settings instead.
@ -133,8 +129,8 @@ void CRT_init(int delay, int colorScheme) {
} else {
CRT_hasColors = false;
}
char* termType = getenv("TERM");
if (String_eq(termType, "xterm") || String_eq(termType, "xterm-color") || String_eq(termType, "vt220")) {
CRT_termType = getenv("TERM");
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[F", KEY_END);
define_key("\033OP", KEY_F(1));
@ -167,6 +163,7 @@ void CRT_done() {
int CRT_readKey() {
nocbreak();
cbreak();
nodelay(stdscr, FALSE);
int ret = getch();
halfdelay(CRT_delay);
return ret;
@ -257,6 +254,9 @@ void CRT_setColors(int colorScheme) {
CRT_colors[CHECK_BOX] = A_BOLD;
CRT_colors[CHECK_MARK] = 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) {
CRT_colors[RESET_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_MARK] = 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) {
CRT_colors[RESET_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_MARK] = 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) {
CRT_colors[RESET_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_MARK] = A_BOLD | 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) {
CRT_colors[RESET_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_MARK] = A_BOLD | ColorPair(Green,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 {
/* Default */
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_MARK] = A_BOLD;
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
#define HEADER_CRT
@ -19,6 +19,8 @@ in the source distribution for its full text.
#include "debug.h"
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
#define COLORSCHEME_DEFAULT 0
#define COLORSCHEME_MONOCHROME 1
#define COLORSCHEME_BLACKONWHITE 2
@ -26,6 +28,15 @@ in the source distribution for its full text.
#define COLORSCHEME_MIDNIGHT 4
#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
bool CRT_hasColors;
@ -84,29 +95,39 @@ typedef enum ColorElements_ {
CPU_NORMAL,
CPU_KERNEL,
HELP_BOLD,
CPU_IOWAIT,
CPU_IRQ,
CPU_SOFTIRQ,
LAST_COLORELEMENT
} ColorElements;
extern int CRT_colors[LAST_COLORELEMENT];
extern int CRT_colorScheme;
// TODO: centralize these in Settings.
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();
int CRT_readKey();
void CRT_disableDelay();
void CRT_enableDelay();
void CRT_handleSIGSEGV(int signal);
void CRT_handleSIGTERM(int signal);
void CRT_setColors(int colorScheme);
void CRT_enableDelay();
void CRT_disableDelay();
#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,50 @@
What's new in version 0.6.5
* Add hardened-debug flags for debugging with Hardened GCC
* BUGFIX: Handle error condition when a directory vanishes
from /proc
* BUGFIX: Fix leak of process command line
* BUGFIX: Collect orphaned items when arranging the tree view.
(thanks to Wolfram Schlich for assistance with debugging)
* Separate proc and memory debugging into separate #defines.
* BUGFIX: Fix message when configure fails due to
missing libraries
(thanks to Jon)
* BUGFIX: Don't truncate value when displaying a very large
process
(thanks to Bo Liu)
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
* BUGFIX: Fixed crash when using some .htoprc files from 0.6
@ -137,7 +183,7 @@ What's new in version 0.4
* Clock and load average meters
(thanks to Marc Calahan)
* 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
* Press "F3" during search to walk through the results
* Improved navigation on column configuration screen

View File

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

View File

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

View File

@ -15,6 +15,9 @@ in the source distribution for its full text.
#include "debug.h"
extern int ClockMeter_attributes[];
extern MeterType ClockMeter;
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 "ColorsListBox.h"
#include "ColorsPanel.h"
#include "ListBox.h"
#include "Panel.h"
#include "CheckItem.h"
#include "Settings.h"
#include "ScreenManager.h"
@ -11,24 +11,23 @@
#include <assert.h>
// 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 a define in CRT.h that matches the order of the array
// * Add the colors in CRT_setColors
/*{
typedef struct ColorsListBox_ {
ListBox super;
typedef struct ColorsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
bool check[5];
} ColorsListBox;
} ColorsPanel;
}*/
/* private */
static char* ColorSchemes[] = {
"Default",
"Monochromatic",
@ -39,37 +38,37 @@ static char* ColorSchemes[] = {
NULL
};
ColorsListBox* ColorsListBox_new(Settings* settings, ScreenManager* scr) {
ColorsListBox* this = (ColorsListBox*) malloc(sizeof(ColorsListBox));
ListBox* super = (ListBox*) this;
ListBox_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true);
((Object*)this)->delete = ColorsListBox_delete;
ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr) {
ColorsPanel* this = (ColorsPanel*) malloc(sizeof(ColorsPanel));
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, CHECKITEM_CLASS, true);
((Object*)this)->delete = ColorsPanel_delete;
this->settings = settings;
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++) {
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[settings->colorScheme] = true;
return this;
}
void ColorsListBox_delete(Object* object) {
ListBox* super = (ListBox*) object;
ColorsListBox* this = (ColorsListBox*) object;
ListBox_done(super);
void ColorsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
ColorsPanel* this = (ColorsPanel*) object;
Panel_done(super);
free(this);
}
HandlerResult ColorsListBox_EventHandler(ListBox* super, int ch) {
ColorsListBox* this = (ColorsListBox*) super;
HandlerResult ColorsPanel_EventHandler(Panel* super, int ch) {
ColorsPanel* this = (ColorsPanel*) super;
HandlerResult result = IGNORED;
int mark = ListBox_getSelectedIndex(super);
int mark = Panel_getSelectedIndex(super);
switch(ch) {
case 0x0a:
@ -88,10 +87,10 @@ HandlerResult ColorsListBox_EventHandler(ListBox* super, int ch) {
this->settings->changed = true;
Header* header = this->settings->header;
CRT_setColors(mark);
ListBox* lbMenu = (ListBox*) TypedVector_get(this->scr->items, 0);
Panel* menu = (Panel*) Vector_get(this->scr->items, 0);
Header_draw(header);
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);
}
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
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include "DebugMemory.h"
#undef strdup
#undef malloc
#undef realloc
#undef calloc
#undef free
#include "DebugMemory.h"
/*{
typedef struct DebugMemoryItem_ DebugMemoryItem;
struct DebugMemoryItem_ {
int magic;
void* data;
char* file;
int line;
@ -31,12 +31,15 @@ typedef struct DebugMemory_ {
int allocations;
int deallocations;
int size;
bool totals;
FILE* file;
} DebugMemory;
}*/
/* private property */
DebugMemory* singleton = NULL;
#if defined(DEBUG)
static DebugMemory* singleton = NULL;
void DebugMemory_new() {
if (singleton)
@ -46,41 +49,65 @@ void DebugMemory_new() {
singleton->allocations = 0;
singleton->deallocations = 0;
singleton->size = 0;
#ifdef DEBUG_ALLOC
singleton->file = fopen("/tmp/htop-debug-alloc.txt", "w");
#else
singleton->file = NULL;
#endif
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);
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;
}
void* DebugMemory_calloc(int a, int b, char* file, int line) {
void* data = calloc(a, b);
DebugMemory_registerAllocation(data, file, line);
fprintf(singleton->file, "%d\t%s:%d\n", a*b, 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);
}
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)
DebugMemory_registerDeallocation(ptr, file, line);
void* data = realloc(ptr, size);
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;
}
void* DebugMemory_strdup(char* str, char* file, int line) {
assert(str);
char* data = strdup(str);
DebugMemory_registerAllocation(data, file, line);
fprintf(singleton->file, "%d\t%s:%d\n", (int) strlen(str), 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);
}
return data;
}
void DebugMemory_free(void* data, char* file, int line) {
assert(data);
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);
}
@ -91,6 +118,7 @@ void DebugMemory_assertSize() {
DebugMemoryItem* walk = singleton->first;
int i = 0;
while (walk != NULL) {
assert(walk->magic == 11061980);
i++;
walk = walk->next;
}
@ -104,6 +132,7 @@ int DebugMemory_getBlockCount() {
DebugMemoryItem* walk = singleton->first;
int i = 0;
while (walk != NULL) {
assert(walk->magic == 11061980);
i++;
walk = walk->next;
}
@ -115,6 +144,7 @@ void DebugMemory_registerAllocation(void* data, char* file, int line) {
DebugMemory_new();
DebugMemory_assertSize();
DebugMemoryItem* item = (DebugMemoryItem*) malloc(sizeof(DebugMemoryItem));
item->magic = 11061980;
item->data = data;
item->file = file;
item->line = line;
@ -130,6 +160,7 @@ void DebugMemory_registerAllocation(void* data, char* file, int line) {
walk->next = item;
break;
}
assert(walk->magic == 11061980);
walk = walk->next;
}
}
@ -141,14 +172,13 @@ void DebugMemory_registerAllocation(void* data, char* file, int line) {
}
void DebugMemory_registerDeallocation(void* data, char* file, int line) {
if (!data)
return;
assert(singleton);
assert(singleton->first);
DebugMemoryItem* walk = singleton->first;
DebugMemoryItem* prev = NULL;
int val = DebugMemory_getBlockCount();
while (walk != NULL) {
assert(walk->magic == 11061980);
if (walk->data == data) {
if (prev == NULL) {
singleton->first = walk->next;
@ -176,6 +206,7 @@ void DebugMemory_report() {
DebugMemoryItem* walk = singleton->first;
int i = 0;
while (walk != NULL) {
assert(walk->magic == 11061980);
i++;
fprintf(stderr, "%p %s:%d\n", walk->data, walk->file, walk->line);
walk = walk->next;
@ -185,5 +216,12 @@ void DebugMemory_report() {
fprintf(stderr, "%d deallocations\n", singleton->deallocations);
fprintf(stderr, "%d size\n", singleton->size);
fprintf(stderr, "%d non-freed blocks\n", i);
fclose(singleton->file);
if (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
#define HEADER_DebugMemory
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#undef strdup
#undef malloc
#undef realloc
#undef calloc
#undef free
typedef struct DebugMemoryItem_ DebugMemoryItem;
struct DebugMemoryItem_ {
int magic;
void* data;
char* file;
int line;
@ -33,17 +33,20 @@ typedef struct DebugMemory_ {
int allocations;
int deallocations;
int size;
bool totals;
FILE* file;
} DebugMemory;
#if defined(DEBUG)
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_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);
@ -59,4 +62,10 @@ void DebugMemory_registerDeallocation(void* data, char* file, int line);
void DebugMemory_report();
#elif defined(DEBUGLITE)
//#include "efence.h"
#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;
} FunctionBar;
extern char* FUNCTIONBAR_CLASS;
}*/
/* private property */
#ifdef DEBUG
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"};
/* private property */
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)};
FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events) {
FunctionBar* this = malloc(sizeof(FunctionBar));
((Object*) this)->class = FUNCTIONBAR_CLASS;
Object_setClass(this, FUNCTIONBAR_CLASS);
((Object*) this)->delete = FunctionBar_delete;
this->functions = functions;
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
#define HEADER_FunctionBar
/*
htop
htop - FunctionBar.h
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -30,16 +30,21 @@ typedef struct FunctionBar_ {
bool staticData;
} FunctionBar;
#ifdef DEBUG
extern char* FUNCTIONBAR_CLASS;
#else
#define FUNCTIONBAR_CLASS NULL
#endif
FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events);
void FunctionBar_delete(Object* this);
void FunctionBar_draw(FunctionBar* this, char* buffer);
void FunctionBar_delete(Object* cast);
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);
int FunctionBar_synthesizeEvent(FunctionBar* this, int pos);

View File

@ -9,6 +9,7 @@ in the source distribution for its full text.
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include "debug.h"
@ -16,7 +17,6 @@ in the source distribution for its full text.
typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem {
int key;
@ -28,11 +28,39 @@ struct Hashtable_ {
int size;
HashtableItem** buckets;
int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner;
};
}*/
#ifdef DEBUG
bool Hashtable_isConsistent(Hashtable* this) {
int items = 0;
for (int i = 0; i < this->size; i++) {
HashtableItem* bucket = this->buckets[i];
while (bucket) {
items++;
bucket = bucket->next;
}
}
return items == this->items;
}
int Hashtable_count(Hashtable* this) {
int items = 0;
for (int i = 0; i < this->size; i++) {
HashtableItem* bucket = this->buckets[i];
while (bucket) {
items++;
bucket = bucket->next;
}
}
assert(items == this->items);
return items;
}
#endif
HashtableItem* HashtableItem_new(int key, void* value) {
HashtableItem* this;
@ -47,18 +75,16 @@ Hashtable* Hashtable_new(int size, bool owner) {
Hashtable* this;
this = (Hashtable*) malloc(sizeof(Hashtable));
this->items = 0;
this->size = size;
this->buckets = (HashtableItem**) calloc(sizeof(HashtableItem*), size);
this->hashAlgorithm = Hashtable_hashAlgorithm;
this->owner = owner;
assert(Hashtable_isConsistent(this));
return this;
}
int Hashtable_hashAlgorithm(Hashtable* this, int key) {
return (key % this->size);
}
void Hashtable_delete(Hashtable* this) {
assert(Hashtable_isConsistent(this));
for (int i = 0; i < this->size; i++) {
HashtableItem* walk = this->buckets[i];
while (walk != NULL) {
@ -74,11 +100,12 @@ void Hashtable_delete(Hashtable* this) {
}
inline int Hashtable_size(Hashtable* this) {
assert(Hashtable_isConsistent(this));
return this->items;
}
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]);
while (true)
if (*bucketPtr == NULL) {
@ -92,44 +119,53 @@ void Hashtable_put(Hashtable* this, int key, void* value) {
break;
} else
bucketPtr = &((*bucketPtr)->next);
assert(Hashtable_isConsistent(this));
}
void* Hashtable_remove(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key);
HashtableItem** bucketPtr = &(this->buckets[index]);
while (true)
if (*bucketPtr == NULL) {
return NULL;
break;
} else if ((*bucketPtr)->key == key) {
void* savedValue = (*bucketPtr)->value;
HashtableItem* savedNext = (*bucketPtr)->next;
free(*bucketPtr);
(*bucketPtr) = savedNext;
int index = key % this->size;
assert(Hashtable_isConsistent(this));
HashtableItem** bucket;
for (bucket = &(this->buckets[index]); *bucket; bucket = &((*bucket)->next) ) {
if ((*bucket)->key == key) {
void* value = (*bucket)->value;
HashtableItem* next = (*bucket)->next;
free(*bucket);
(*bucket) = next;
this->items--;
if (this->owner) {
free(savedValue);
free(value);
assert(Hashtable_isConsistent(this));
return NULL;
} else {
return savedValue;
assert(Hashtable_isConsistent(this));
return value;
}
} else
bucketPtr = &((*bucketPtr)->next);
}
}
assert(Hashtable_isConsistent(this));
return NULL;
}
inline void* Hashtable_get(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key);
int index = key % this->size;
HashtableItem* bucketPtr = this->buckets[index];
while (true)
while (true) {
if (bucketPtr == NULL) {
assert(Hashtable_isConsistent(this));
return NULL;
} else if (bucketPtr->key == key) {
assert(Hashtable_isConsistent(this));
return bucketPtr->value;
} else
bucketPtr = bucketPtr->next;
}
}
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) {
assert(Hashtable_isConsistent(this));
for (int i = 0; i < this->size; i++) {
HashtableItem* walk = this->buckets[i];
while (walk != NULL) {
@ -137,4 +173,5 @@ void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData
walk = walk->next;
}
}
assert(Hashtable_isConsistent(this));
}

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
#define HEADER_Hashtable
@ -12,13 +12,13 @@ in the source distribution for its full text.
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include "debug.h"
typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem {
int key;
@ -30,16 +30,21 @@ struct Hashtable_ {
int size;
HashtableItem** buckets;
int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner;
};
#ifdef DEBUG
bool Hashtable_isConsistent(Hashtable* this);
int Hashtable_count(Hashtable* this);
#endif
HashtableItem* HashtableItem_new(int key, void* value);
Hashtable* Hashtable_new(int size, bool owner);
int Hashtable_hashAlgorithm(Hashtable* this, int key);
void Hashtable_delete(Hashtable* this);
inline int Hashtable_size(Hashtable* this);

View File

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

View File

@ -3,7 +3,7 @@
#ifndef HEADER_Header
#define HEADER_Header
/*
htop - Header.c
htop - Header.h
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -21,8 +21,8 @@ typedef enum HeaderSide_ {
} HeaderSide;
typedef struct Header_ {
TypedVector* leftMeters;
TypedVector* rightMeters;
Vector* leftMeters;
Vector* rightMeters;
ProcessList* pl;
bool margin;
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;
} ListItem;
extern char* LISTITEM_CLASS;
}*/
/* private property */
#ifdef DEBUG
char* LISTITEM_CLASS = "ListItem";
#else
#define LISTITEM_CLASS NULL
#endif
ListItem* ListItem_new(char* value, int key) {
ListItem* this = malloc(sizeof(ListItem));
((Object*)this)->class = LISTITEM_CLASS;
Object_setClass(this, LISTITEM_CLASS);
((Object*)this)->display = ListItem_display;
((Object*)this)->delete = ListItem_delete;
((Object*)this)->compare = ListItem_compare;
this->value = String_copy(value);
this->key = key;
return this;
@ -64,7 +65,7 @@ const char* ListItem_getRef(ListItem* this) {
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* obj2 = (ListItem*) cast2;
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
#define HEADER_ListItem
/*
htop
htop - ListItem.h
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -16,24 +16,31 @@ in the source distribution for its full text.
#include "debug.h"
typedef struct ListItem_ {
Object super;
char* value;
int key;
} ListItem;
#ifdef DEBUG
extern char* LISTITEM_CLASS;
#else
#define LISTITEM_CLASS NULL
#endif
ListItem* ListItem_new(char* value, int key);
void ListItem_append(ListItem* this, char* text);
void ListItem_delete(Object* cast);
void ListItem_display(Object* cast, RichString* out);
void ListItem_append(ListItem* this, char* text);
const char* ListItem_getRef(ListItem* this);
int ListItem_compare(const Object*, const Object*);
int ListItem_compare(const void* cast1, const void* cast2);
#endif

View File

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

View File

@ -15,10 +15,13 @@ in the source distribution for its full text.
#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);

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
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
applications_DATA = htop.desktop
pixmapdir = $(datadir)/pixmaps
@ -10,22 +11,32 @@ pixmap_DATA = htop.png
AM_CFLAGS = -pedantic -Wall -std=c99
AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
htop_SOURCES = AvailableMetersListBox.c CategoriesListBox.c ClockMeter.c \
CPUMeter.c CRT.c DebugMemory.c DisplayOptionsListBox.c FunctionBar.c \
Hashtable.c Header.c htop.c ListBox.c ListItem.c LoadAverageMeter.c \
MemoryMeter.c Meter.c MetersListBox.c Object.c Process.c \
htop_SOURCES = AvailableMetersPanel.c CategoriesPanel.c ClockMeter.c \
CPUMeter.c CRT.c DebugMemory.c DisplayOptionsPanel.c FunctionBar.c \
Hashtable.c Header.c htop.c Panel.c ListItem.c LoadAverageMeter.c \
MemoryMeter.c Meter.c MetersPanel.c Object.c Process.c \
ProcessList.c RichString.c ScreenManager.c Settings.c SignalItem.c \
SignalsListBox.c String.c SwapMeter.c TasksMeter.c TypedVector.c \
UptimeMeter.c UsersTable.c AvailableMetersListBox.h CategoriesListBox.h \
SignalsPanel.c String.c SwapMeter.c TasksMeter.c Vector.c \
UptimeMeter.c UsersTable.c AvailableMetersPanel.h CategoriesPanel.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 \
MetersListBox.h Object.h Process.h ProcessList.h RichString.h ScreenManager.h \
Settings.h SignalItem.h SignalsListBox.h String.h SwapMeter.h TasksMeter.h \
TypedVector.h UptimeMeter.h UsersTable.h CheckItem.c CheckItem.h \
ColorsListBox.c ColorsListBox.h TraceScreen.c TraceScreen.h \
AvailableColumnsListBox.c AvailableColumnsListBox.h ColumnsListBox.c \
ColumnsListBox.h
MetersPanel.h Object.h Process.h ProcessList.h RichString.h ScreenManager.h \
Settings.h SignalItem.h SignalsPanel.h String.h SwapMeter.h TasksMeter.h \
Vector.h UptimeMeter.h UsersTable.h CheckItem.c CheckItem.h \
ColorsPanel.c ColorsPanel.h TraceScreen.c TraceScreen.h \
AvailableColumnsPanel.c AvailableColumnsPanel.h ColumnsPanel.c \
ColumnsPanel.h
profile:
$(MAKE) all CFLAGS="-pg -O2"
debug:
$(MAKE) all CFLAGS="-g -DDEBUG"
$(MAKE) all CFLAGS="-ggdb -DDEBUG"
hardened-debug:
$(MAKE) all CFLAGS="-ggdb -DDEBUG" LDFLAGS="-nopie"
debuglite:
$(MAKE) all CFLAGS="-ggdb -DDEBUGLITE"

View File

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

67
Meter.c
View File

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

39
Meter.h
View File

@ -3,7 +3,7 @@
#ifndef HEADER_Meter
#define HEADER_Meter
/*
htop - Meter.c
htop - Meter.h
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -78,18 +78,6 @@ struct Meter_ {
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 {
CUSTOM_METERMODE = 0,
BAR_METERMODE,
@ -101,9 +89,14 @@ typedef enum {
LAST_METERMODE
} 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
#define MIN(a,b) ((a)<(b)?(a):(b))
@ -112,15 +105,19 @@ extern MeterMode* Meter_modes[];
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#ifdef DEBUG
extern char* METER_CLASS;
#else
#define METER_CLASS NULL
#endif
extern MeterType* Meter_types[];
#ifdef USE_FUNKY_MODES
#endif
extern MeterMode* Meter_modes[];
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_setMode(Meter* this, int modeIndex);
ListItem* Meter_toListItem(Meter* this);
@ -139,7 +135,6 @@ void TextMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- BarMeterMode ---------- */
void BarMeterMode_draw(Meter* this, int x, int y, int w);
#ifdef USE_FUNKY_MODES
@ -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)
void GraphMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- LEDMeterMode ---------- */
void LEDMeterMode_draw(Meter* this, int x, int y, int w);
#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"
/*{
#ifndef DEBUG
#define Object_setClass(obj, class)
#endif
typedef struct Object_ Object;
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*);
struct Object_ {
#ifdef DEBUG
char* class;
#endif
Object_Display display;
Object_Compare compare;
Object_Delete delete;
};
}*/
/* private property */
#ifdef DEBUG
char* OBJECT_CLASS = "Object";
void Object_new() {
Object* this;
this = malloc(sizeof(Object));
this->class = OBJECT_CLASS;
this->display = Object_display;
this->compare = Object_compare;
this->delete = Object_delete;
}
#else
#define OBJECT_CLASS NULL
#endif
bool Object_instanceOf(Object* this, char* class) {
return this->class == class;
}
#ifdef DEBUG
void Object_delete(Object* this) {
free(this);
void Object_setClass(void* this, char* class) {
((Object*)this)->class = class;
}
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);
}
int Object_compare(const Object* this, const Object* o) {
return (this - o);
}
#endif

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
#define HEADER_Object
@ -17,28 +17,38 @@ in the source distribution for its full text.
#include "debug.h"
#ifndef DEBUG
#define Object_setClass(obj, class)
#endif
typedef struct Object_ Object;
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*);
struct Object_ {
#ifdef DEBUG
char* class;
#endif
Object_Display display;
Object_Compare compare;
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);
int Object_compare(const Object* this, const Object* o);
#endif
#endif

View File

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

150
Process.c
View File

@ -31,7 +31,6 @@ in the source distribution for its full text.
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
#define PROCESS_COMM_LEN 300
#define PROCESS_USER_LEN 10
/*{
@ -62,16 +61,19 @@ typedef struct Process_ {
int tty_nr;
int tpgid;
unsigned long int flags;
#ifdef DEBUG
unsigned long int minflt;
unsigned long int cminflt;
unsigned long int majflt;
unsigned long int cmajflt;
#endif
unsigned long int utime;
unsigned long int stime;
long int cutime;
long int cstime;
long int priority;
long int nice;
#ifdef DEBUG
long int itrealvalue;
unsigned long int starttime;
unsigned long int vsize;
@ -89,6 +91,7 @@ typedef struct Process_ {
unsigned long int wchan;
unsigned long int nswap;
unsigned long int cnswap;
#endif
int exit_signal;
int processor;
int m_size;
@ -101,56 +104,62 @@ typedef struct Process_ {
uid_t st_uid;
float percent_cpu;
float percent_mem;
char user[PROCESS_USER_LEN + 1];
char* user;
} Process;
extern char* PROCESS_CLASS;
extern char* Process_fieldNames[];
}*/
/* private property */
#ifdef DEBUG
char* PROCESS_CLASS = "Process";
#else
#define PROCESS_CLASS NULL
#endif
/* private property */
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! ***"};
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! ***"
};
static int Process_getuid = -1;
Process* Process_new(struct ProcessList_ *pl) {
Process* this = malloc(sizeof(Process));
((Object*)this)->class = PROCESS_CLASS;
Object_setClass(this, PROCESS_CLASS);
((Object*)this)->display = Process_display;
((Object*)this)->compare = Process_compare;
((Object*)this)->delete = Process_delete;
this->pid = 0;
this->pl = pl;
this->tag = false;
this->updated = false;
this->utime = 0;
this->stime = 0;
this->comm = NULL;
this->indent = 0;
if (Process_getuid == -1) Process_getuid = getuid();
return this;
}
Process* Process_clone(Process* this) {
Process* clone = malloc(sizeof(Process));
memcpy(clone, this, sizeof(Process));
this->comm = NULL;
this->pid = 0;
return clone;
}
void Process_delete(Object* cast) {
Process* this = (Process*) cast;
if (this->comm) free(this->comm);
assert (this != NULL);
if (this->comm) free(this->comm);
free(this);
}
void Process_display(Object* cast, RichString* out) {
Process* this = (Process*) cast;
ProcessField* fields = this->pl->fields;
RichString_prune(out);
RichString_init(out);
for (int i = 0; fields[i]; 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]);
if (this->tag == true)
RichString_setAttr(out, CRT_colors[PROCESS_TAG]);
@ -177,35 +186,32 @@ void Process_sendSignal(Process* this, int signal) {
#define ONE_M (ONE_K * ONE_K)
#define ONE_G (ONE_M * ONE_K)
/* private */
void Process_printLargeNumber(Process* this, RichString *str, unsigned int number) {
static void Process_printLargeNumber(Process* this, RichString *str, unsigned long number) {
char buffer[11];
int len;
if(number >= (1000 * ONE_M)) {
len = snprintf(buffer, 10, "%4.2fG ", (float)number / ONE_M);
RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len);
} else if(number >= (100000)) {
len = snprintf(buffer, 10, "%4dM ", number / ONE_K);
len = snprintf(buffer, 10, "%4ldM ", number / ONE_K);
int attr = this->pl->highlightMegabytes
? CRT_colors[PROCESS_MEGABYTES]
: CRT_colors[PROCESS];
RichString_appendn(str, attr, buffer, len);
} else if (this->pl->highlightMegabytes && number >= 1000) {
len = snprintf(buffer, 10, "%2d", number/1000);
len = snprintf(buffer, 10, "%2ld", number/1000);
RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer, len);
number %= 1000;
len = snprintf(buffer, 10, "%03d ", number);
len = snprintf(buffer, 10, "%03ld ", number);
RichString_appendn(str, CRT_colors[PROCESS], buffer, len);
} else {
len = snprintf(buffer, 10, "%5d ", number);
len = snprintf(buffer, 10, "%5ld ", number);
RichString_appendn(str, CRT_colors[PROCESS], buffer, len);
}
}
/* private property */
double jiffy = 0.0;
static double jiffy = 0.0;
/* private */
static void Process_printTime(RichString* str, unsigned long t) {
if(jiffy == 0.0) jiffy = sysconf(_SC_CLK_TCK);
double jiffytime = 1.0 / jiffy;
@ -228,8 +234,7 @@ static void Process_printTime(RichString* str, unsigned long t) {
RichString_append(str, CRT_colors[DEFAULT_COLOR], buffer);
}
/* private */
inline static void Process_writeCommand(Process* this, int attr, RichString* str) {
static inline void Process_writeCommand(Process* this, int attr, RichString* str) {
if (this->pl->highlightBaseName) {
char* firstSpace = strchr(this->comm, ' ');
if (firstSpace) {
@ -273,21 +278,21 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
for (int i = 0; i < 32; i++)
if (this->indent & (1 << i))
maxIndent = i+1;
for (int i = 0; i < maxIndent - 1; i++) {
for (int i = 0; i < maxIndent - 1; i++) {
if (this->indent & (1 << i))
snprintf(buf, n, " | ");
else
snprintf(buf, n, " ");
buf += 4;
n -= 4;
}
}
if (this->pl->direction == 1)
snprintf(buf, n, " `- ");
else
snprintf(buf, n, " ,- ");
RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
Process_writeCommand(this, attr, str);
return;
return;
}
}
case STATE: {
@ -316,9 +321,13 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
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 USER: {
if (getuid() != this->st_uid)
if (Process_getuid != this->st_uid)
attr = CRT_colors[PROCESS_SHADOW];
if (this->user) {
snprintf(buffer, n, "%-8s ", this->user);
} else {
snprintf(buffer, n, "%-8d ", this->st_uid);
}
if (buffer[8] != '\0') {
buffer[8] = ' ';
buffer[9] = '\0';
@ -353,44 +362,57 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
return;
}
int Process_compare(const Object* v1, const Object* v2) {
int Process_pidCompare(const void* v1, const void* v2) {
Process* p1 = (Process*)v1;
Process* p2 = (Process*)v2;
int direction = p1->pl->direction;
switch (p1->pl->sortKey) {
case PID:
return (p2->pid - p1->pid) * direction;
case PPID:
return (p2->ppid - p1->ppid) * direction;
case USER:
return strcmp(p2->user, p1->user) * direction;
case PRIORITY:
return (p2->priority - p1->priority) * direction;
case STATE:
return (p2->state - p1->state) * direction;
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;
return (p1->pid - p2->pid);
}
int Process_compare(const void* v1, const void* v2) {
Process *p1, *p2;
ProcessList *pl = ((Process*)v1)->pl;
if (pl->direction == 1) {
p1 = (Process*)v1;
p2 = (Process*)v2;
} else {
p2 = (Process*)v1;
p1 = (Process*)v2;
}
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) {

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
#define HEADER_Process
@ -34,7 +34,6 @@ in the source distribution for its full text.
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
#define PROCESS_COMM_LEN 300
#define PROCESS_USER_LEN 10
typedef enum ProcessField_ {
@ -64,16 +63,19 @@ typedef struct Process_ {
int tty_nr;
int tpgid;
unsigned long int flags;
#ifdef DEBUG
unsigned long int minflt;
unsigned long int cminflt;
unsigned long int majflt;
unsigned long int cmajflt;
#endif
unsigned long int utime;
unsigned long int stime;
long int cutime;
long int cstime;
long int priority;
long int nice;
#ifdef DEBUG
long int itrealvalue;
unsigned long int starttime;
unsigned long int vsize;
@ -91,6 +93,7 @@ typedef struct Process_ {
unsigned long int wchan;
unsigned long int nswap;
unsigned long int cnswap;
#endif
int exit_signal;
int processor;
int m_size;
@ -103,15 +106,17 @@ typedef struct Process_ {
uid_t st_uid;
float percent_cpu;
float percent_mem;
char user[PROCESS_USER_LEN + 1];
char* user;
} Process;
#ifdef DEBUG
extern char* PROCESS_CLASS;
#else
#define PROCESS_CLASS NULL
#endif
extern char* Process_fieldNames[];
extern char *Process_fieldNames[];
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);
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);

View File

@ -12,9 +12,10 @@ in the source distribution for its full text.
#include "ProcessList.h"
#include "Process.h"
#include "TypedVector.h"
#include "Vector.h"
#include "UsersTable.h"
#include "Hashtable.h"
#include "String.h"
#include <sys/types.h>
#include <sys/stat.h>
@ -48,16 +49,24 @@ in the source distribution for its full text.
#endif
#ifndef MAX_READ
#define MAX_READ 8192
#define MAX_READ 2048
#endif
#ifndef PER_PROCESSOR_FIELDS
#define PER_PROCESSOR_FIELDS 20
#endif
}*/
/*{
#ifdef DEBUG_PROC
typedef int(*vxscanf)(void*, const char*, va_list);
#endif
typedef struct ProcessList_ {
TypedVector* processes;
TypedVector* processes2;
Vector* processes;
Vector* processes2;
Hashtable* processTable;
Process* prototype;
UsersTable* usersTable;
@ -66,26 +75,37 @@ typedef struct ProcessList_ {
int totalTasks;
int runningTasks;
long int* totalTime;
long int* userTime;
long int* systemTime;
long int* idleTime;
long int* niceTime;
long int* totalPeriod;
long int* userPeriod;
long int* systemPeriod;
long int* idlePeriod;
long int* nicePeriod;
// Must match number of PER_PROCESSOR_FIELDS constant
unsigned long long int* totalTime;
unsigned long long int* userTime;
unsigned long long int* systemTime;
unsigned long long int* systemAllTime;
unsigned long long int* idleTime;
unsigned long long int* niceTime;
unsigned long long int* ioWaitTime;
unsigned long long int* irqTime;
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;
long int usedMem;
long int freeMem;
long int sharedMem;
long int buffersMem;
long int cachedMem;
long int totalSwap;
long int usedSwap;
long int freeSwap;
unsigned long long int totalMem;
unsigned long long int usedMem;
unsigned long long int freeMem;
unsigned long long int sharedMem;
unsigned long long int buffersMem;
unsigned long long int cachedMem;
unsigned long long int totalSwap;
unsigned long long int usedSwap;
unsigned long long int freeSwap;
ProcessField* fields;
ProcessField sortKey;
@ -97,31 +117,26 @@ typedef struct ProcessList_ {
bool treeView;
bool highlightBaseName;
bool highlightMegabytes;
#ifdef DEBUG
bool expandSystemTime;
#ifdef DEBUG_PROC
FILE* traceFile;
#endif
} ProcessList;
}*/
/* private property */
ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
static ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
#ifdef DEBUG
/* private property */
typedef int(*vxscanf)(void*, const char*, va_list);
#ifdef DEBUG_PROC
#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__ )
/* private */
FILE* ProcessList_fopen(ProcessList* this, const char* path, const char* mode) {
static FILE* ProcessList_fopen(ProcessList* this, const char* path, const char* mode) {
fprintf(this->traceFile, "[%s]\n", path);
return fopen(path, mode);
}
/* private */
static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer, char* format, ...) {
va_list ap;
va_start(ap, format);
@ -130,7 +145,10 @@ static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer,
va_start(ap, format);
while (*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 != '%') {
fprintf(this->traceFile, "%c", ch);
format++;
@ -146,6 +164,12 @@ static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer,
switch (*format) {
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 '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++;
@ -165,18 +189,29 @@ static inline int ProcessList_xread(ProcessList* this, vxscanf fn, void* buffer,
#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* this;
this = malloc(sizeof(ProcessList));
this->processes = TypedVector_new(PROCESS_CLASS, true, DEFAULT_SIZE);
this->processTable = Hashtable_new(20, false);
this->processes = Vector_new(PROCESS_CLASS, true, DEFAULT_SIZE, Process_compare);
this->processTable = Hashtable_new(70, false);
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
this->prototype = Process_new(this);
this->usersTable = usersTable;
/* 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_PROC
this->traceFile = fopen("/tmp/htop-proc-trace", "w");
#endif
@ -190,23 +225,16 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
} while (String_startsWith(buffer, "cpu"));
fclose(status);
this->processorCount = procs - 1;
this->totalTime = calloc(procs, sizeof(long int));
this->userTime = calloc(procs, sizeof(long int));
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));
ProcessList_allocatePerProcessorBuffers(this, procs);
for (int i = 0; i < procs; i++) {
this->totalTime[i] = 1;
this->totalPeriod[i] = 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).
for (int i = 0; defaultHeaders[i]; i++) {
this->fields[i] = defaultHeaders[i];
@ -220,28 +248,22 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
this->treeView = false;
this->highlightBaseName = false;
this->highlightMegabytes = false;
this->expandSystemTime = false;
return this;
}
void ProcessList_delete(ProcessList* this) {
Hashtable_delete(this->processTable);
TypedVector_delete(this->processes);
TypedVector_delete(this->processes2);
Vector_delete(this->processes);
Vector_delete(this->processes2);
Process_delete((Object*)this->prototype);
// Free first entry only;
// other fields are offsets of the same buffer
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_PROC
fclose(this->traceFile);
#endif
@ -257,7 +279,8 @@ void ProcessList_invertSortOrder(ProcessList* this) {
}
RichString ProcessList_printHeader(ProcessList* this) {
RichString out = RichString_new();
RichString out;
RichString_init(&out);
ProcessField* fields = this->fields;
for (int i = 0; fields[i]; i++) {
char* field = Process_printField(fields[i]);
@ -271,90 +294,106 @@ RichString ProcessList_printHeader(ProcessList* this) {
void ProcessList_prune(ProcessList* this) {
TypedVector_prune(this->processes);
Vector_prune(this->processes);
}
void ProcessList_add(ProcessList* this, Process* p) {
TypedVector_add(this->processes, p);
assert(Vector_indexOf(this->processes, p, Process_pidCompare) == -1);
assert(Hashtable_get(this->processTable, p->pid) == NULL);
Vector_add(this->processes, p);
Hashtable_put(this->processTable, p->pid, p);
assert(Vector_indexOf(this->processes, p, Process_pidCompare) != -1);
assert(Hashtable_get(this->processTable, p->pid) != NULL);
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
}
void ProcessList_remove(ProcessList* this, Process* p) {
Hashtable_remove(this->processTable, p->pid);
ProcessField pf = this->sortKey;
this->sortKey = PID;
int index = TypedVector_indexOf(this->processes, p);
TypedVector_remove(this->processes, index);
this->sortKey = pf;
assert(Vector_indexOf(this->processes, p, Process_pidCompare) != -1);
assert(Hashtable_get(this->processTable, p->pid) != NULL);
Process* pp = Hashtable_remove(this->processTable, p->pid);
assert(pp == p); (void)pp;
int pid = p->pid;
int index = Vector_indexOf(this->processes, p, Process_pidCompare);
assert(index != -1);
Vector_remove(this->processes, index);
assert(Hashtable_get(this->processTable, pid) == NULL); (void)pid;
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
}
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) {
return (TypedVector_size(this->processes));
return (Vector_size(this->processes));
}
/* private */
void ProcessList_buildTree(ProcessList* this, int pid, int level, int indent, int direction) {
TypedVector* children = TypedVector_new(PROCESS_CLASS, false, DEFAULT_SIZE);
static void ProcessList_buildTree(ProcessList* this, int pid, int level, int indent, int direction) {
Vector* children = Vector_new(PROCESS_CLASS, false, DEFAULT_SIZE, Process_compare);
for (int i = 0; i < TypedVector_size(this->processes); i++) {
Process* process = (Process*) (TypedVector_get(this->processes, i));
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
Process* process = (Process*) (Vector_get(this->processes, i));
if (process->ppid == pid) {
Process* process = (Process*) (TypedVector_take(this->processes, i));
TypedVector_add(children, process);
i--;
Process* process = (Process*) (Vector_take(this->processes, i));
Vector_add(children, process);
}
}
int size = TypedVector_size(children);
int size = Vector_size(children);
for (int i = 0; i < size; i++) {
Process* process = (Process*) (TypedVector_get(children, i));
Process* process = (Process*) (Vector_get(children, i));
int s = this->processes2->items;
if (direction == 1)
TypedVector_add(this->processes2, process);
Vector_add(this->processes2, process);
else
TypedVector_insert(this->processes2, 0, process);
Vector_insert(this->processes2, 0, process);
assert(this->processes2->items == s+1); (void)s;
int nextIndent = indent;
if (i < size - 1)
nextIndent = indent | (1 << level);
ProcessList_buildTree(this, process->pid, level+1, nextIndent, direction);
process->indent = indent | (1 << level);
}
TypedVector_delete(children);
Vector_delete(children);
}
void ProcessList_sort(ProcessList* this) {
if (!this->treeView) {
TypedVector_sort(this->processes);
Vector_sort(this->processes);
} else {
int direction = this->direction;
int sortKey = this->sortKey;
this->sortKey = PID;
this->direction = 1;
TypedVector_sort(this->processes);
Vector_sort(this->processes);
this->sortKey = sortKey;
this->direction = direction;
Process* init = (Process*) (TypedVector_take(this->processes, 0));
int vsize = Vector_size(this->processes);
Process* init = (Process*) (Vector_take(this->processes, 0));
assert(init->pid == 1);
init->indent = 0;
TypedVector_add(this->processes2, init);
Vector_add(this->processes2, init);
ProcessList_buildTree(this, init->pid, 0, 0, direction);
TypedVector* t = this->processes;
while (Vector_size(this->processes)) {
Process* p = (Process*) (Vector_take(this->processes, 0));
p->indent = 0;
Vector_add(this->processes2, p);
}
assert(Vector_size(this->processes2) == vsize); (void)vsize;
assert(Vector_size(this->processes) == 0);
Vector* t = this->processes;
this->processes = this->processes2;
this->processes2 = t;
}
}
/* private */
int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *command) {
static int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *command) {
static char buf[MAX_READ];
long int zero;
unsigned long int zero;
int size = fread(buf, 1, MAX_READ, f);
if(!size) return 0;
proc->pid = atoi(buf);
assert(proc->pid == atoi(buf));
char *location = strchr(buf, ' ');
if(!location) return 0;
@ -367,6 +406,7 @@ int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *co
command[commsize] = '\0';
location = end + 2;
#ifdef DEBUG_PROC
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 "
@ -374,14 +414,34 @@ int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *co
"%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, &proc->minflt, &proc->cminflt, &proc->majflt,
&proc->cmajflt, &proc->utime, &proc->stime, &proc->cutime, &proc->cstime,
&proc->tpgid, &proc->flags,
&proc->minflt, &proc->cminflt, &proc->majflt, &proc->cmajflt,
&proc->utime, &proc->stime, &proc->cutime, &proc->cstime,
&proc->priority, &proc->nice, &zero, &proc->itrealvalue,
&proc->starttime, &proc->vsize, &proc->rss, &proc->rlim,
&proc->startcode, &proc->endcode, &proc->startstack, &proc->kstkesp,
&proc->kstkeip, &proc->signal, &proc->blocked, &proc->sigignore,
&proc->sigcatch, &proc->wchan, &proc->nswap, &proc->cnswap,
&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.
// TODO: Check if the semantics of this field has changed.
@ -394,14 +454,15 @@ int ProcessList_readStatFile(ProcessList* this, Process *proc, FILE *f, char *co
bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name) {
char statusfilename[MAX_NAME+1];
statusfilename[MAX_NAME] = '\0';
/*
bool success = false;
char buffer[256];
buffer[255] = '\0';
snprintf(statusfilename, MAX_NAME, "%s/%s/status", dirname, name);
FILE* status = ProcessList_fopen(this, statusfilename, "r");
bool success = false;
if (status) {
char buffer[1024];
buffer[1023] = '\0';
while (!feof(status)) {
char* ok = fgets(buffer, 1023, status);
char* ok = fgets(buffer, 255, status);
if (!ok)
break;
if (String_startsWith(buffer, "Uid:")) {
@ -418,14 +479,18 @@ bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname,
fclose(status);
}
if (!success) {
snprintf(statusfilename, MAX_NAME, "%s/%s/stat", dirname, name);
*/
snprintf(statusfilename, MAX_NAME, "%s/%s", dirname, name);
struct stat sstat;
int statok = stat(statusfilename, &sstat);
if (statok == -1)
return false;
proc->st_uid = sstat.st_uid;
}
return success;
return true;
/*
} else
return true;
*/
}
void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period) {
@ -434,7 +499,7 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
Process* prototype = this->prototype;
dir = opendir(dirname);
assert(dir != NULL);
if (!dir) return;
while ((entry = readdir(dir)) != NULL) {
char* name = entry->d_name;
int pid;
@ -465,25 +530,40 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
char statusfilename[MAX_NAME+1];
char command[PROCESS_COMM_LEN + 1];
Process* process;
Process* process = NULL;
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
Process* existingProcess = (Process*) Hashtable_get(this->processTable, pid);
if (!existingProcess) {
process = Process_clone(prototype);
if (existingProcess) {
assert(Vector_indexOf(this->processes, existingProcess, Process_pidCompare) != -1);
process = existingProcess;
assert(process->pid == pid);
} else {
process = prototype;
assert(process->comm == NULL);
process->pid = pid;
ProcessList_add(this, process);
if (! ProcessList_readStatusFile(this, process, dirname, name))
goto errorReadingProcess;
} else {
process = existingProcess;
}
process->updated = true;
char* username = UsersTable_getRef(this->usersTable, process->st_uid);
if (username) {
strncpy(process->user, username, PROCESS_USER_LEN);
} else {
snprintf(process->user, PROCESS_USER_LEN, "%d", process->st_uid);
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r");
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;
if (this->hideKernelThreads && process->m_size == 0)
goto errorReadingProcess;
int lasttimes = (process->utime + process->stime);
@ -495,14 +575,12 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
int success = ProcessList_readStatFile(this, process, status, command);
fclose(status);
if(!success) {
if(!success)
goto errorReadingProcess;
}
process->percent_cpu = (process->utime + process->stime - lasttimes) /
period * 100.0;
if(!existingProcess) {
process->user = UsersTable_getRef(this->usersTable, process->st_uid);
snprintf(statusfilename, MAX_NAME, "%s/%s/cmdline", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r");
if (!status) {
@ -521,20 +599,8 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
fclose(status);
}
snprintf(statusfilename, MAX_NAME, "%s/%s/statm", dirname, name);
status = ProcessList_fopen(this, statusfilename, "r");
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_cpu = (process->utime + process->stime - lasttimes) /
period * 100.0;
process->percent_mem = process->m_resident /
(float)(this->usedMem - this->cachedMem - this->buffersMem) *
@ -545,14 +611,21 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
this->runningTasks++;
}
if (this->hideKernelThreads && process->m_size == 0)
ProcessList_remove(this, process);
if (!existingProcess) {
ProcessList_add(this, Process_clone(process));
}
continue;
// Exception handler.
errorReadingProcess: {
ProcessList_remove(this, process);
if (process->comm) {
free(process->comm);
process->comm = NULL;
}
if (existingProcess)
ProcessList_remove(this, process);
assert(Hashtable_count(this->processTable) == Vector_count(this->processes));
}
}
}
@ -560,8 +633,8 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl
}
void ProcessList_scan(ProcessList* this) {
long int usertime, nicetime, systemtime, idletime, totaltime;
long int swapFree;
unsigned long long int usertime, nicetime, systemtime, systemalltime, idletime, totaltime;
unsigned long long int swapFree;
FILE* status;
char buffer[128];
@ -573,25 +646,25 @@ void ProcessList_scan(ProcessList* this) {
switch (buffer[0]) {
case 'M':
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:"))
ProcessList_read(this, buffer, "MemFree: %ld kB", &this->freeMem);
ProcessList_read(this, buffer, "MemFree: %llu kB", &this->freeMem);
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;
case 'B':
if (String_startsWith(buffer, "Buffers:"))
ProcessList_read(this, buffer, "Buffers: %ld kB", &this->buffersMem);
ProcessList_read(this, buffer, "Buffers: %llu kB", &this->buffersMem);
break;
case 'C':
if (String_startsWith(buffer, "Cached:"))
ProcessList_read(this, buffer, "Cached: %ld kB", &this->cachedMem);
ProcessList_read(this, buffer, "Cached: %llu kB", &this->cachedMem);
break;
case 'S':
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:"))
ProcessList_read(this, buffer, "SwapFree: %ld kB", &swapFree);
ProcessList_read(this, buffer, "SwapFree: %llu kB", &swapFree);
break;
}
}
@ -606,57 +679,69 @@ void ProcessList_scan(ProcessList* this) {
for (int i = 0; i <= this->processorCount; i++) {
char buffer[256];
int cpuid;
long int ioWait, irq, softIrq, steal;
unsigned long long int ioWait, irq, softIrq, steal;
ioWait = irq = softIrq = steal = 0;
// Dependending on your kernel version,
// 5, 7 or 8 of these fields will be set.
// The rest will remain at zero.
fgets(buffer, 255, status);
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 {
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);
}
// Fields existing on kernels >= 2.6
// (and RHEL's patched kernel 2.4...)
systemtime += ioWait + irq + softIrq + steal;
totaltime = usertime + nicetime + systemtime + idletime;
systemalltime = systemtime + ioWait + irq + softIrq + steal;
totaltime = usertime + nicetime + systemalltime + idletime;
assert (usertime >= this->userTime[i]);
assert (nicetime >= this->niceTime[i]);
assert (systemtime >= this->systemTime[i]);
assert (idletime >= this->idleTime[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->nicePeriod[i] = nicetime - this->niceTime[i];
this->systemPeriod[i] = systemtime - this->systemTime[i];
this->systemAllPeriod[i] = systemalltime - this->systemAllTime[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->userTime[i] = usertime;
this->niceTime[i] = nicetime;
this->systemTime[i] = systemtime;
this->systemAllTime[i] = systemalltime;
this->idleTime[i] = idletime;
this->ioWaitTime[i] = ioWait;
this->irqTime[i] = irq;
this->softIrqTime[i] = softIrq;
this->stealTime[i] = steal;
this->totalTime[i] = totaltime;
}
float period = (float)this->totalPeriod[0] / this->processorCount;
fclose(status);
// mark all process as "dirty"
for (int i = 0; i < TypedVector_size(this->processes); i++) {
Process* p = (Process*) TypedVector_get(this->processes, i);
for (int i = 0; i < Vector_size(this->processes); i++) {
Process* p = (Process*) Vector_get(this->processes, i);
p->updated = false;
}
this->totalTasks = 0;
this->runningTasks = 0;
signal(11, ProcessList_dontCrash);
ProcessList_processEntries(this, PROCDIR, 0, period);
signal(11, SIG_DFL);
for (int i = TypedVector_size(this->processes) - 1; i >= 0; i--) {
Process* p = (Process*) TypedVector_get(this->processes, i);
for (int i = Vector_size(this->processes) - 1; i >= 0; i--) {
Process* p = (Process*) Vector_get(this->processes, i);
if (p->updated == false)
ProcessList_remove(this, p);
else
@ -664,9 +749,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
#define HEADER_ProcessList
/*
htop - ProcessList.c
htop - ProcessList.h
(C) 2004,2005 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -15,9 +15,10 @@ in the source distribution for its full text.
#endif
#include "Process.h"
#include "TypedVector.h"
#include "Vector.h"
#include "UsersTable.h"
#include "Hashtable.h"
#include "String.h"
#include <sys/types.h>
#include <sys/stat.h>
@ -50,14 +51,22 @@ in the source distribution for its full text.
#endif
#ifndef MAX_READ
#define MAX_READ 8192
#define MAX_READ 2048
#endif
#ifndef PER_PROCESSOR_FIELDS
#define PER_PROCESSOR_FIELDS 20
#endif
#ifdef DEBUG_PROC
typedef int(*vxscanf)(void*, const char*, va_list);
#endif
typedef struct ProcessList_ {
TypedVector* processes;
TypedVector* processes2;
Vector* processes;
Vector* processes2;
Hashtable* processTable;
Process* prototype;
UsersTable* usersTable;
@ -66,26 +75,37 @@ typedef struct ProcessList_ {
int totalTasks;
int runningTasks;
long int* totalTime;
long int* userTime;
long int* systemTime;
long int* idleTime;
long int* niceTime;
long int* totalPeriod;
long int* userPeriod;
long int* systemPeriod;
long int* idlePeriod;
long int* nicePeriod;
// Must match number of PER_PROCESSOR_FIELDS constant
unsigned long long int* totalTime;
unsigned long long int* userTime;
unsigned long long int* systemTime;
unsigned long long int* systemAllTime;
unsigned long long int* idleTime;
unsigned long long int* niceTime;
unsigned long long int* ioWaitTime;
unsigned long long int* irqTime;
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;
long int usedMem;
long int freeMem;
long int sharedMem;
long int buffersMem;
long int cachedMem;
long int totalSwap;
long int usedSwap;
long int freeSwap;
unsigned long long int totalMem;
unsigned long long int usedMem;
unsigned long long int freeMem;
unsigned long long int sharedMem;
unsigned long long int buffersMem;
unsigned long long int cachedMem;
unsigned long long int totalSwap;
unsigned long long int usedSwap;
unsigned long long int freeSwap;
ProcessField* fields;
ProcessField sortKey;
@ -97,21 +117,18 @@ typedef struct ProcessList_ {
bool treeView;
bool highlightBaseName;
bool highlightMegabytes;
#ifdef DEBUG
bool expandSystemTime;
#ifdef DEBUG_PROC
FILE* traceFile;
#endif
} ProcessList;
#ifdef DEBUG
#ifdef DEBUG_PROC
#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__ )
#else
#ifndef ProcessList_read
@ -141,16 +158,12 @@ Process* ProcessList_get(ProcessList* this, int index);
int ProcessList_size(ProcessList* this);
void ProcessList_sort(ProcessList* this);
bool ProcessList_readStatusFile(ProcessList* this, Process* proc, char* dirname, char* name);
void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, float period);
void ProcessList_scan(ProcessList* this);
void ProcessList_dontCrash(int signal);
#endif

6
README
View File

@ -2,13 +2,15 @@
htop
by Hisham Muhammad <loderunner@users.sourceforge.net>
May, 2004 - March, 2006
May, 2004 - July, 2006
Introduction
~~~~~~~~~~~~
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
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_ {
int len;
chtype chstr[RICHSTRING_MAXLEN+1];
@ -23,24 +26,8 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b))
#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) {
this->len = 0;
RichString_init(this);
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) {
if (!workArea) {
workArea = newpad(1, RICHSTRING_MAXLEN);
}
assert(workArea);
wattrset(workArea, attrs);
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);
int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
for (int i = this->len, j = 0; i < last; i++, j++)
this->chstr[i] = data[j] | attrs;
this->chstr[last] = 0;
this->len = last;
}
void RichString_setAttr(RichString *this, int attrs) {
chtype* ch = this->chstr;
for (int i = 0; i < this->len; i++) {
char c = this->chstr[i];
this->chstr[i] = c | attrs;
*ch = (*ch & 0xff) | attrs;
ch++;
}
}
void RichString_applyAttr(RichString *this, int attrs) {
for (int i = 0; i < this->len - 1; i++) {
this->chstr[i] |= attrs;
chtype* ch = this->chstr;
for (int i = 0; i < this->len; i++) {
*ch |= attrs;
ch++;
}
}
RichString RichString_quickString(int attrs, char* data) {
RichString str = RichString_new();
RichString str;
RichString_initVal(str);
RichString_write(&str, attrs, data);
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
#define HEADER_RichString
@ -7,7 +7,6 @@
#include <stdlib.h>
#include <string.h>
#include <curses.h>
#include <sys/param.h>
#include "debug.h"
#include <assert.h>
@ -15,18 +14,18 @@
#define RICHSTRING_MAXLEN 300
#define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0
typedef struct RichString_ {
int len;
chtype chstr[RICHSTRING_MAXLEN+1];
} RichString;
RichString RichString_new();
void RichString_delete(RichString this);
void RichString_prune(RichString* this);
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
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 "ListBox.h"
#include "Panel.h"
#include "Object.h"
#include "TypedVector.h"
#include "Vector.h"
#include "FunctionBar.h"
#include "debug.h"
@ -29,8 +29,8 @@ typedef struct ScreenManager_ {
int x2;
int y2;
Orientation orientation;
TypedVector* items;
TypedVector* fuBars;
Vector* items;
Vector* fuBars;
int itemCount;
FunctionBar* fuBar;
bool owner;
@ -47,16 +47,16 @@ ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation ori
this->y2 = y2;
this->fuBar = NULL;
this->orientation = orientation;
this->items = TypedVector_new(LISTBOX_CLASS, owner, DEFAULT_SIZE);
this->fuBars = TypedVector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE);
this->items = Vector_new(PANEL_CLASS, owner, DEFAULT_SIZE, NULL);
this->fuBars = Vector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE, NULL);
this->itemCount = 0;
this->owner = owner;
return this;
}
void ScreenManager_delete(ScreenManager* this) {
TypedVector_delete(this->items);
TypedVector_delete(this->fuBars);
Vector_delete(this->items);
Vector_delete(this->fuBars);
free(this);
}
@ -64,38 +64,38 @@ inline int ScreenManager_size(ScreenManager* this) {
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) {
int lastX = 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;
}
if (size > 0) {
ListBox_resize(item, size, LINES-this->y1+this->y2);
Panel_resize(item, size, LINES-this->y1+this->y2);
} 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
TypedVector_add(this->items, item);
Vector_add(this->items, item);
if (fuBar)
TypedVector_add(this->fuBars, fuBar);
Vector_add(this->fuBars, fuBar);
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;
item->needsRedraw = true;
this->itemCount++;
}
ListBox* ScreenManager_remove(ScreenManager* this, int index) {
Panel* ScreenManager_remove(ScreenManager* this, int index) {
assert(this->itemCount > index);
ListBox* lb = (ListBox*) TypedVector_remove(this->items, index);
TypedVector_remove(this->fuBars, index);
Panel* panel = (Panel*) Vector_remove(this->items, index);
Vector_remove(this->fuBars, index);
this->fuBar = NULL;
this->itemCount--;
return lb;
return panel;
}
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 lastX = 0;
for (int i = 0; i < items - 1; i++) {
ListBox* lb = (ListBox*) TypedVector_get(this->items, i);
ListBox_resize(lb, lb->w, LINES-y1+y2);
ListBox_move(lb, lastX, y1);
lastX = lb->x + lb->w + 1;
Panel* panel = (Panel*) Vector_get(this->items, i);
Panel_resize(panel, panel->w, LINES-y1+y2);
Panel_move(panel, lastX, y1);
lastX = panel->x + panel->w + 1;
}
ListBox* lb = (ListBox*) TypedVector_get(this->items, items-1);
ListBox_resize(lb, COLS-x1+x2-lastX, LINES-y1+y2);
ListBox_move(lb, lastX, y1);
Panel* panel = (Panel*) Vector_get(this->items, items-1);
Panel_resize(panel, COLS-x1+x2-lastX, LINES-y1+y2);
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;
int focus = 0;
ListBox* lbFocus = (ListBox*) TypedVector_get(this->items, focus);
Panel* panelFocus = (Panel*) Vector_get(this->items, focus);
if (this->fuBar)
FunctionBar_draw(this->fuBar, NULL);
int ch;
int ch = 0;
while (!quit) {
int items = this->itemCount;
for (int i = 0; i < items; i++) {
ListBox* lb = (ListBox*) TypedVector_get(this->items, i);
ListBox_draw(lb, i == focus);
Panel* panel = (Panel*) Vector_get(this->items, i);
Panel_draw(panel, i == focus);
if (i < items) {
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)
this->fuBar = bar;
if (this->fuBar)
@ -159,12 +159,12 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
ch = FunctionBar_synthesizeEvent(this->fuBar, mevent.x);
} else {
for (int i = 0; i < this->itemCount; i++) {
ListBox* lb = (ListBox*) TypedVector_get(this->items, i);
if (mevent.x > lb->x && mevent.x <= lb->x+lb->w &&
mevent.y > lb->y && mevent.y <= lb->y+lb->h) {
Panel* panel = (Panel*) Vector_get(this->items, i);
if (mevent.x > panel->x && mevent.x <= panel->x+panel->w &&
mevent.y > panel->y && mevent.y <= panel->y+panel->h) {
focus = i;
lbFocus = lb;
ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV - 1);
panelFocus = panel;
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
loop = true;
break;
}
@ -174,8 +174,8 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
}
if (loop) continue;
if (lbFocus->eventHandler) {
HandlerResult result = lbFocus->eventHandler(lbFocus, ch);
if (panelFocus->eventHandler) {
HandlerResult result = panelFocus->eventHandler(panelFocus, ch);
if (result == HANDLED) {
continue;
} else if (result == BREAK_LOOP) {
@ -196,8 +196,8 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
tryLeft:
if (focus > 0)
focus--;
lbFocus = (ListBox*) TypedVector_get(this->items, focus);
if (ListBox_getSize(lbFocus) == 0 && focus > 0)
panelFocus = (Panel*) Vector_get(this->items, focus);
if (Panel_getSize(panelFocus) == 0 && focus > 0)
goto tryLeft;
break;
case KEY_RIGHT:
@ -205,8 +205,8 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
tryRight:
if (focus < this->itemCount - 1)
focus++;
lbFocus = (ListBox*) TypedVector_get(this->items, focus);
if (ListBox_getSize(lbFocus) == 0 && focus < this->itemCount - 1)
panelFocus = (Panel*) Vector_get(this->items, focus);
if (Panel_getSize(panelFocus) == 0 && focus < this->itemCount - 1)
goto tryRight;
break;
case KEY_F(10):
@ -215,11 +215,11 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
quit = true;
continue;
default:
ListBox_onKey(lbFocus, ch);
Panel_onKey(panelFocus, ch);
break;
}
}
*lastFocus = lbFocus;
*lastFocus = panelFocus;
*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
#define HEADER_ScreenManager
@ -9,9 +9,9 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "ListBox.h"
#include "Panel.h"
#include "Object.h"
#include "TypedVector.h"
#include "Vector.h"
#include "FunctionBar.h"
#include "debug.h"
@ -31,10 +31,10 @@ typedef struct ScreenManager_ {
int x2;
int y2;
Orientation orientation;
TypedVector* items;
Vector* items;
Vector* fuBars;
int itemCount;
FunctionBar* fuBar;
TypedVector* fuBars;
bool owner;
} ScreenManager;
@ -45,14 +45,14 @@ void ScreenManager_delete(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_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

View File

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

View File

@ -3,7 +3,7 @@
#ifndef HEADER_Settings
#define HEADER_Settings
/*
htop - Settings.c
htop - Settings.h
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -32,8 +32,6 @@ Settings* Settings_new(ProcessList* pl, Header* header);
void Settings_delete(Settings* this);
bool Settings_read(Settings* this, char* fileName);
bool Settings_write(Settings* this);

View File

@ -23,15 +23,17 @@ typedef struct Signal_ {
int number;
} Signal;
extern char* SIGNAL_CLASS;
}*/
/* private property */
#ifdef DEBUG
char* SIGNAL_CLASS = "Signal";
#else
#define SIGNAL_CLASS NULL
#endif
Signal* Signal_new(char* name, int number) {
Signal* this = malloc(sizeof(Signal));
((Object*)this)->class = SIGNAL_CLASS;
Object_setClass(this, SIGNAL_CLASS);
((Object*)this)->display = Signal_display;
((Object*)this)->delete = Signal_delete;
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
#define HEADER_Signal
#ifndef HEADER_SignalItem
#define HEADER_SignalItem
/*
htop
htop - SignalItem.h
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -25,8 +25,12 @@ typedef struct Signal_ {
int number;
} Signal;
extern char* SIGNAL_CLASS;
#ifdef DEBUG
extern char* SIGNAL_CLASS;
#else
#define SIGNAL_CLASS NULL
#endif
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"
/*{
#define String_startsWith(s, match) (strstr((s), (match)) == (s))
}*/
inline void String_delete(char* s) {
free(s);
}
@ -92,7 +96,7 @@ void String_printPointer(void* 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)
return 1;
@ -102,10 +106,6 @@ inline int String_eq(char* s1, char* s2) {
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) {
const int rate = 10;
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
#define HEADER_String
@ -17,6 +17,8 @@ in the source distribution for its full text.
#include "debug.h"
#define String_startsWith(s, match) (strstr((s), (match)) == (s))
inline void String_delete(char* s);
inline char* String_copy(char* orig);
@ -37,9 +39,7 @@ void String_printInt(int i);
void String_printPointer(void* p);
inline int String_eq(char* s1, char* s2);
inline int String_startsWith(char* s, char* match);
inline int String_eq(const char* s1, const char* s2);
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 <assert.h>
/* private property */
static int SwapMeter_attributes[] = { SWAP };
int SwapMeter_attributes[] = {
SWAP
};
/* private */
MeterType SwapMeter = {
.setValues = SwapMeter_setValues,
.display = SwapMeter_display,
@ -46,7 +46,7 @@ void SwapMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* this = (Meter*)cast;
long int swap = (long int) this->values[0];
RichString_prune(out);
RichString_init(out);
RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, "%ldM ", (long int) this->total / 1024);
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 <assert.h>
extern int SwapMeter_attributes[];
extern MeterType SwapMeter;
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"
/* private property */
int TasksMeter_attributes[] = { TASKS_RUNNING };
int TasksMeter_attributes[] = {
TASKS_RUNNING
};
/* private */
MeterType TasksMeter = {
.setValues = TasksMeter_setValues,
.display = TasksMeter_display,
@ -38,7 +38,7 @@ void TasksMeter_setValues(Meter* this, char* buffer, int len) {
void TasksMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
RichString_prune(out);
RichString_init(out);
char buffer[20];
sprintf(buffer, "%d", (int)this->total);
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"
extern int TasksMeter_attributes[];
extern MeterType TasksMeter;
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 "Process.h"
#include "ListItem.h"
#include "ListBox.h"
#include "Panel.h"
#include "FunctionBar.h"
/*{
typedef struct TraceScreen_ {
Process* process;
ListBox* display;
Panel* display;
FunctionBar* bar;
bool tracing;
} TraceScreen;
}*/
/* private property */
static char* tbFunctions[3] = {"AutoScroll ", "Stop Tracing ", "Done "};
/* private property */
static char* tbKeys[3] = {"F4", "F5", "Esc"};
/* private property */
static int tbEvents[3] = {KEY_F(4), KEY_F(5), 27};
TraceScreen* TraceScreen_new(Process* process) {
TraceScreen* this = (TraceScreen*) malloc(sizeof(TraceScreen));
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->tracing = true;
return this;
}
void TraceScreen_delete(TraceScreen* this) {
ListBox_delete((Object*)this->display);
Panel_delete((Object*)this->display);
FunctionBar_delete((Object*)this->bar);
free(this);
}
@ -77,11 +74,13 @@ void TraceScreen_run(TraceScreen* this) {
fcntl(fdpair[1], F_SETFL, O_NONBLOCK);
sprintf(buffer, "%d", this->process->pid);
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);
}
fcntl(fdpair[0], F_SETFL, O_NONBLOCK);
FILE* strace = fdopen(fdpair[0], "r");
ListBox* lb = this->display;
Panel* panel = this->display;
int fd_strace = fileno(strace);
TraceScreen_draw(this);
CRT_disableDelay();
@ -105,31 +104,31 @@ void TraceScreen_run(TraceScreen* this) {
if (buffer[i] == '\n') {
buffer[i] = '\0';
if (contLine) {
ListItem_append((ListItem*)ListBox_get(lb,
ListBox_getSize(lb)-1), line);
ListItem_append((ListItem*)Panel_get(panel,
Panel_getSize(panel)-1), line);
contLine = false;
} else {
ListBox_add(lb, (Object*) ListItem_new(line, 0));
Panel_add(panel, (Object*) ListItem_new(line, 0));
}
line = buffer+i+1;
}
}
if (line < buffer+nread) {
ListBox_add(lb, (Object*) ListItem_new(line, 0));
Panel_add(panel, (Object*) ListItem_new(line, 0));
buffer[nread] = '\0';
contLine = true;
}
if (follow)
ListBox_setSelected(lb, ListBox_getSize(lb)-1);
ListBox_draw(lb, true);
Panel_setSelected(panel, Panel_getSize(panel)-1);
Panel_draw(panel, true);
}
int ch = getch();
if (ch == KEY_MOUSE) {
MEVENT mevent;
int ok = getmouse(&mevent);
if (ok == OK)
if (mevent.y >= lb->y && mevent.y < LINES - 1) {
ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV);
if (mevent.y >= panel->y && mevent.y < LINES - 1) {
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV);
follow = false;
ch = 0;
} if (mevent.y == LINES - 1)
@ -147,23 +146,24 @@ void TraceScreen_run(TraceScreen* this) {
case KEY_F(4):
follow = !follow;
if (follow)
ListBox_setSelected(lb, ListBox_getSize(lb)-1);
Panel_setSelected(panel, Panel_getSize(panel)-1);
break;
case 'q':
case 27:
looping = false;
break;
case KEY_RESIZE:
ListBox_resize(lb, COLS, LINES-2);
Panel_resize(panel, COLS, LINES-2);
TraceScreen_draw(this);
break;
default:
follow = false;
ListBox_onKey(lb, ch);
Panel_onKey(panel, ch);
}
ListBox_draw(lb, true);
Panel_draw(panel, true);
}
kill(child, SIGTERM);
waitpid(child, NULL, 0);
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
(C) 2005 Hisham H. Muhammad
(C) 2005-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#ifndef HEADER_TraceScreen
#define HEADER_TraceScreen
#define _GNU_SOURCE
#include <stdio.h>
@ -13,18 +15,24 @@ in the source distribution for its full text.
#include <stdbool.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "ProcessList.h"
#include "ListBox.h"
#include "Process.h"
#include "ListItem.h"
#include "Panel.h"
#include "FunctionBar.h"
typedef struct TraceScreen_ {
Process* process;
ListBox* display;
Panel* display;
FunctionBar* bar;
bool tracing;
} TraceScreen;
TraceScreen* TraceScreen_new(Process* process);
void TraceScreen_delete(TraceScreen* this);
@ -34,4 +42,3 @@ void TraceScreen_draw(TraceScreen* this);
void TraceScreen_run(TraceScreen* this);
#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"
/* private property */
static int UptimeMeter_attributes[] = { UPTIME };
int UptimeMeter_attributes[] = {
UPTIME
};
/* private */
MeterType UptimeMeter = {
.setValues = UptimeMeter_setValues,
.display = NULL,
@ -44,7 +44,7 @@ void UptimeMeter_setValues(Meter* this, char* buffer, int len) {
if (days > this->total) {
this->total = days;
}
char daysbuf[10];
char daysbuf[15];
if (days > 100) {
sprintf(daysbuf, "%d days(!), ", days);
} else if (days > 1) {

View File

@ -17,8 +17,10 @@ in the source distribution for its full text.
#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

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
#define HEADER_UsersTable
/*
htop
htop - UsersTable.h
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
@ -20,10 +20,6 @@ in the source distribution for its full text.
#include "debug.h"
#include <assert.h>
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
typedef struct UsersTable_ {
Hashtable* users;
} UsersTable;
@ -36,6 +32,6 @@ char* UsersTable_getRef(UsersTable* this, int uid);
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

View File

@ -5,7 +5,7 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "TypedVector.h"
#include "Vector.h"
#include "Object.h"
#include <stdlib.h>
#include <string.h>
@ -20,35 +20,37 @@ in the source distribution for its full text.
#define DEFAULT_SIZE -1
#endif
typedef void(*TypedVector_procedure)(void*);
typedef void(*Vector_procedure)(void*);
typedef struct TypedVector_ {
typedef struct Vector_ {
Object **array;
Object_Compare compare;
int arraySize;
int growthRate;
int items;
char* vectorType;
bool owner;
} TypedVector;
} Vector;
}*/
TypedVector* TypedVector_new(char* vectorType_, bool owner, int size) {
TypedVector* this;
Vector* Vector_new(char* vectorType_, bool owner, int size, Object_Compare compare) {
Vector* this;
if (size == DEFAULT_SIZE)
size = 10;
this = (TypedVector*) malloc(sizeof(TypedVector));
this = (Vector*) malloc(sizeof(Vector));
this->growthRate = size;
this->array = (Object**) calloc(size, sizeof(Object*));
this->arraySize = size;
this->items = 0;
this->vectorType = vectorType_;
this->owner = owner;
this->compare = compare;
return this;
}
void TypedVector_delete(TypedVector* this) {
void Vector_delete(Vector* this) {
if (this->owner) {
for (int i = 0; i < this->items; i++)
if (this->array[i])
@ -58,8 +60,10 @@ void TypedVector_delete(TypedVector* this) {
free(this);
}
/* private */
bool TypedVector_isConsistent(TypedVector* this) {
#ifdef DEBUG
static inline bool Vector_isConsistent(Vector* this) {
assert(this->items <= this->arraySize);
if (this->owner) {
for (int i = 0; i < this->items; i++)
if (this->array[i] && this->array[i]->class != this->vectorType)
@ -70,8 +74,20 @@ bool TypedVector_isConsistent(TypedVector* this) {
}
}
void TypedVector_prune(TypedVector* this) {
assert(TypedVector_isConsistent(this));
int Vector_count(Vector* this) {
int items = 0;
for (int i = 0; i < this->items; i++) {
if (this->array[i])
items++;
}
assert(items == this->items);
return items;
}
#endif
void Vector_prune(Vector* this) {
assert(Vector_isConsistent(this));
int i;
for (i = 0; i < this->items; i++)
@ -83,33 +99,23 @@ void TypedVector_prune(TypedVector* this) {
this->items = 0;
}
void TypedVector_sort(TypedVector* this) {
assert(TypedVector_isConsistent(this));
int i, j;
for (i = 1; i < this->items; i++) {
void Vector_sort(Vector* this) {
assert(this->compare);
assert(Vector_isConsistent(this));
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];
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] = t;
}
assert(TypedVector_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;
}
}
}
*/
assert(Vector_isConsistent(this));
}
/* private */
void TypedVector_checkArraySize(TypedVector* this) {
assert(TypedVector_isConsistent(this));
static void Vector_checkArraySize(Vector* this) {
assert(Vector_isConsistent(this));
if (this->items >= this->arraySize) {
int i;
i = this->arraySize;
@ -118,40 +124,40 @@ void TypedVector_checkArraySize(TypedVector* this) {
for (; i < this->arraySize; i++)
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(((Object*)data_)->class == this->vectorType);
Object* data = data_;
assert(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
TypedVector_checkArraySize(this);
Vector_checkArraySize(this);
assert(this->array[this->items] == NULL);
for (int i = this->items; i >= index; i--) {
this->array[i+1] = this->array[i];
}
this->array[index] = data;
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(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
Object* removed = this->array[index];
assert (removed != NULL);
this->items--;
for (int i = index; i < this->items; i++)
this->array[i] = this->array[i+1];
this->array[this->items] = NULL;
assert(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
return removed;
}
Object* TypedVector_remove(TypedVector* this, int index) {
Object* removed = TypedVector_take(this, index);
Object* Vector_remove(Vector* this, int index) {
Object* removed = Vector_take(this, index);
if (this->owner) {
removed->delete(removed);
return NULL;
@ -159,9 +165,9 @@ Object* TypedVector_remove(TypedVector* this, int index) {
return removed;
}
void TypedVector_moveUp(TypedVector* this, int index) {
void Vector_moveUp(Vector* this, int index) {
assert(index >= 0 && index < this->items);
assert(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
if (index == 0)
return;
Object* temp = this->array[index];
@ -169,9 +175,9 @@ void TypedVector_moveUp(TypedVector* this, int index) {
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(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
if (index == this->items - 1)
return;
Object* temp = this->array[index];
@ -179,13 +185,13 @@ void TypedVector_moveDown(TypedVector* this, int index) {
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(((Object*)data_)->class == this->vectorType);
Object* data = data_;
assert(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
TypedVector_checkArraySize(this);
Vector_checkArraySize(this);
if (index >= this->items) {
this->items = index+1;
} else {
@ -198,60 +204,59 @@ void TypedVector_set(TypedVector* this, int index, void* 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(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
return this->array[index];
}
inline int TypedVector_size(TypedVector* this) {
assert(TypedVector_isConsistent(this));
inline int Vector_size(Vector* this) {
assert(Vector_isConsistent(this));
return this->items;
}
void TypedVector_merge(TypedVector* this, TypedVector* v2) {
void Vector_merge(Vector* this, Vector* v2) {
int i;
assert(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
for (i = 0; i < v2->items; i++)
TypedVector_add(this, v2->array[i]);
Vector_add(this, v2->array[i]);
v2->items = 0;
TypedVector_delete(v2);
assert(TypedVector_isConsistent(this));
Vector_delete(v2);
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);
Object* data = data_;
assert(TypedVector_isConsistent(this));
TypedVector_set(this, this->items, data);
assert(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
int i = this->items;
Vector_set(this, this->items, data);
assert(this->items == i+1); (void)(i);
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(this->compare);
Object* search = search_;
assert(TypedVector_isConsistent(this));
int i;
for (i = 0; i < this->items; i++) {
assert(Vector_isConsistent(this));
for (int i = 0; i < this->items; i++) {
Object* o = (Object*)this->array[i];
if (o && o->compare(o, search) == 0)
if (o && compare(search, o) == 0)
return i;
}
return -1;
}
void TypedVector_foreach(TypedVector* this, TypedVector_procedure f) {
void Vector_foreach(Vector* this, Vector_procedure f) {
int i;
assert(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
for (i = 0; i < this->items; i++)
f(this->array[i]);
assert(TypedVector_isConsistent(this));
assert(Vector_isConsistent(this));
}

76
Vector.h Normal file
View File

@ -0,0 +1,76 @@
/* 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
int Vector_count(Vector* this);
#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.
AC_PREREQ(2.57)
AC_INIT([htop],[0.6.2],[loderunner@users.sourceforge.net])
AC_INIT([htop],[0.6.5],[loderunner@users.sourceforge.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([htop.c])
AC_CONFIG_HEADER([config.h])
@ -11,13 +11,23 @@ AC_CONFIG_HEADER([config.h])
AC_PROG_CC
# Checks for libraries.
AC_CHECK_LIB([ncurses], [refresh])
AC_CHECK_LIB([m], [ceil])
AC_CHECK_LIB([ncurses], [refresh], [], [missing_libraries="$missing_libraries libncurses"])
AC_CHECK_LIB([m], [ceil], [], [missing_libraries="$missing_libraries libm"])
if test ! -z "$missing_libraries"; then
AC_MSG_ERROR([missing libraries: $missing_libraries])
fi
# Checks for header files.
AC_HEADER_DIRENT
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.
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__);
#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__);
#elif defined(DEBUGLITE)
#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
#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.5" "Bartosz Fenski <fenio@o2.pl>" "Utils"
.SH "NAME"
htop \- interactive process viewer
.SH "SYNTAX"
@ -113,7 +113,7 @@ PID search: type in process ID and the selection highlight will be moved to it.
.SH "AUTHORS"
.LP
htop is developed by Hisham Muhammad <lode@gobolinux.org>.
htop is developed by Hisham Muhammad <loderunner@users.sourceforge.net>.
.br
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

279
htop.c
View File

@ -14,7 +14,7 @@ in the source distribution for its full text.
#include "ProcessList.h"
#include "CRT.h"
#include "ListBox.h"
#include "Panel.h"
#include "UsersTable.h"
#include "SignalItem.h"
#include "RichString.h"
@ -22,8 +22,8 @@ in the source distribution for its full text.
#include "ScreenManager.h"
#include "FunctionBar.h"
#include "ListItem.h"
#include "CategoriesListBox.h"
#include "SignalsListBox.h"
#include "CategoriesPanel.h"
#include "SignalsPanel.h"
#include "TraceScreen.h"
#include "config.h"
@ -33,9 +33,6 @@ in the source distribution for its full text.
#define INCSEARCH_MAX 40
/* private property */
char htop_barCharacters[] = "|#*@$%&";
void printVersionFlag() {
clear();
printf("htop " VERSION " - (C) 2004-2006 Hisham Muhammad.\n");
@ -49,12 +46,13 @@ void printHelpFlag() {
printf("Released under the GNU GPL.\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("--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("See the man page for full information.\n\n");
exit(0);
}
void showHelp() {
void showHelp(ProcessList* pl) {
clear();
attrset(CRT_colors[HELP_BOLD]);
mvaddstr(0, 0, "htop " VERSION " - (C) 2004-2006 Hisham Muhammad.");
@ -64,10 +62,20 @@ void showHelp() {
mvaddstr(3, 0, "CPU usage bar: ");
#define addattrstr(a,s) attrset(a);addstr(s)
addattrstr(CRT_colors[BAR_BORDER], "[");
addattrstr(CRT_colors[CPU_NICE], "low-priority"); addstr("/");
addattrstr(CRT_colors[CPU_NORMAL], "normal"); addstr("/");
addattrstr(CRT_colors[CPU_KERNEL], "kernel");
addattrstr(CRT_colors[BAR_SHADOW], " used%");
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_NORMAL], "normal"); addstr("/");
addattrstr(CRT_colors[CPU_KERNEL], "kernel");
addattrstr(CRT_colors[BAR_SHADOW], " used%");
}
addattrstr(CRT_colors[BAR_BORDER], "]");
attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(4, 0, "Memory bar: ");
@ -75,45 +83,46 @@ void showHelp() {
addattrstr(CRT_colors[MEMORY_USED], "used"); addstr("/");
addattrstr(CRT_colors[MEMORY_BUFFERS], "buffers"); addstr("/");
addattrstr(CRT_colors[MEMORY_CACHE], "cache");
addattrstr(CRT_colors[BAR_SHADOW], " used/total");
addattrstr(CRT_colors[BAR_SHADOW], " used/total");
addattrstr(CRT_colors[BAR_BORDER], "]");
attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(5, 0, "Swap bar: ");
addattrstr(CRT_colors[BAR_BORDER], "[");
addattrstr(CRT_colors[SWAP], "used");
addattrstr(CRT_colors[BAR_SHADOW], " used/total");
addattrstr(CRT_colors[BAR_SHADOW], " used/total");
addattrstr(CRT_colors[BAR_BORDER], "]");
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(7, 0, "Status: R: running; S: sleeping; T: traced/stopped; Z: zombie; D: disk sleep");
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(10, 0, " F3 /: incremental name search H: hide/show user threads");
mvaddstr(11, 0, " K: hide/show kernel threads");
mvaddstr(12, 0, " Space: tag processes F: cursor follows process");
mvaddstr(13, 0, " U: untag all processes");
mvaddstr(14, 0, " F9 k: kill process/tagged processes P: sort by CPU%");
mvaddstr(15, 0, " + [ F7: lower priority (+ nice) M: sort by MEM%");
mvaddstr(16, 0, " - ] F8: higher priority (root only) T: sort by TIME");
mvaddstr(17, 0, " F4 I: invert sort order");
mvaddstr(18, 0, " F2 S: setup F6 >: select sort column");
mvaddstr(19, 0, " F1 h: show this help screen");
mvaddstr(20, 0, " F10 q: quit s: trace syscalls with strace");
mvaddstr( 9, 0, " Arrows: scroll process list F5 t: tree view");
mvaddstr(10, 0, " Digits: incremental PID search u: show processes of a single user");
mvaddstr(11, 0, " F3 /: incremental name search H: hide/show user threads");
mvaddstr(12, 0, " K: hide/show kernel threads");
mvaddstr(13, 0, " Space: tag processes F: cursor follows process");
mvaddstr(14, 0, " U: untag all processes");
mvaddstr(15, 0, " F9 k: kill process/tagged processes P: sort by CPU%");
mvaddstr(16, 0, " + [ F7: lower priority (+ nice) M: sort by MEM%");
mvaddstr(17, 0, " - ] F8: higher priority (root only) T: sort by TIME");
mvaddstr(18, 0, " F4 I: invert sort order");
mvaddstr(19, 0, " F2 S: setup F6 >: select sort column");
mvaddstr(20, 0, " F1 h: show this help screen");
mvaddstr(21, 0, " F10 q: quit s: trace syscalls with strace");
attrset(CRT_colors[HELP_BOLD]);
mvaddstr( 8, 0, " Arrows"); mvaddstr( 8,40, " F5 t");
mvaddstr( 9, 0, " Digits"); mvaddstr( 9,40, " u");
mvaddstr(10, 0, " F3 /"); mvaddstr(10,40, " H");
mvaddstr(11,40, " K");
mvaddstr(12, 0, " Space"); mvaddstr(12,40, " F");
mvaddstr(13, 0, " U");
mvaddstr(14, 0, " F9 k"); mvaddstr(14,40, " P");
mvaddstr(15, 0, " + [ F7"); mvaddstr(15,40, " M");
mvaddstr(16, 0, " - ] F8"); mvaddstr(16,40, " T");
mvaddstr(17,40, " F4 I");
mvaddstr(18, 0, " F2 S"); mvaddstr(18,40, " F6 >");
mvaddstr(19, 0, " F1 h");
mvaddstr(20, 0, " F10 q"); mvaddstr(20,40, " s");
mvaddstr( 9, 0, " Arrows"); mvaddstr( 9,40, " F5 t");
mvaddstr(10, 0, " Digits"); mvaddstr(10,40, " u");
mvaddstr(11, 0, " F3 /"); mvaddstr(11,40, " H");
mvaddstr(12,40, " K");
mvaddstr(13, 0, " Space"); mvaddstr(13,40, " F");
mvaddstr(14, 0, " U");
mvaddstr(15, 0, " F9 k"); mvaddstr(15,40, " P");
mvaddstr(16, 0, " + [ F7"); mvaddstr(16,40, " M");
mvaddstr(17, 0, " - ] F8"); mvaddstr(17,40, " T");
mvaddstr(18,40, " F4 I");
mvaddstr(19, 0, " F2 S"); mvaddstr(19,40, " F6 >");
mvaddstr(20, 0, " F1 h");
mvaddstr(21, 0, " F10 q"); mvaddstr(21,40, " s");
attrset(CRT_colors[DEFAULT_COLOR]);
attrset(CRT_colors[HELP_BOLD]);
@ -126,62 +135,62 @@ void showHelp() {
static void Setup_run(Settings* settings, int headerHeight) {
ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true);
CategoriesListBox* lbCategories = CategoriesListBox_new(settings, scr);
ScreenManager_add(scr, (ListBox*) lbCategories, NULL, 16);
CategoriesListBox_makeMetersPage(lbCategories);
ListBox* lbFocus;
CategoriesPanel* panelCategories = CategoriesPanel_new(settings, scr);
ScreenManager_add(scr, (Panel*) panelCategories, NULL, 16);
CategoriesPanel_makeMetersPage(panelCategories);
Panel* panelFocus;
int ch;
ScreenManager_run(scr, &lbFocus, &ch);
ScreenManager_run(scr, &panelFocus, &ch);
ScreenManager_delete(scr);
}
static bool changePriority(ListBox* lb, int delta) {
static bool changePriority(Panel* panel, int delta) {
bool anyTagged = false;
for (int i = 0; i < ListBox_getSize(lb); i++) {
Process* p = (Process*) ListBox_get(lb, i);
for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i);
if (p->tag) {
Process_setPriority(p, p->nice + delta);
anyTagged = true;
}
}
if (!anyTagged) {
Process* p = (Process*) ListBox_getSelected(lb);
Process* p = (Process*) Panel_getSelected(panel);
Process_setPriority(p, p->nice + delta);
}
return anyTagged;
}
static HandlerResult pickWithEnter(ListBox* lb, int ch) {
static HandlerResult pickWithEnter(Panel* panel, int ch) {
if (ch == 13)
return BREAK_LOOP;
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"};
int fuEvents[2] = {13, 27};
if (!lb->eventHandler)
ListBox_setEventHandler(list, pickWithEnter);
if (!panel->eventHandler)
Panel_setEventHandler(list, pickWithEnter);
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, lb, NULL, -1);
ListBox* lbFocus;
ScreenManager_add(scr, panel, NULL, -1);
Panel* panelFocus;
int ch;
ScreenManager_run(scr, &lbFocus, &ch);
ScreenManager_run(scr, &panelFocus, &ch);
ScreenManager_delete(scr);
ListBox_move(lb, 0, y);
ListBox_resize(lb, COLS, LINES-y-1);
Panel_move(panel, 0, y);
Panel_resize(panel, COLS, LINES-y-1);
FunctionBar_draw(prevBar, NULL);
if (lbFocus == list && ch == 13) {
return ListBox_getSelected(list);
if (panelFocus == list && ch == 13) {
return Panel_getSelected(list);
}
return NULL;
}
void addUserToList(int key, void* userCast, void* lbCast) {
void addUserToList(int key, void* userCast, void* panelCast) {
char* user = (char*) userCast;
ListBox* lb = (ListBox*) lbCast;
ListBox_add(lb, (Object*) ListItem_new(user, key));
Panel* panel = (Panel*) panelCast;
Panel_add(panel, (Object*) ListItem_new(user, key));
}
void setUserOnly(const char* userName, bool* userOnly, uid_t* userId) {
@ -197,12 +206,25 @@ int main(int argc, char** argv) {
int delay = -1;
bool userOnly = false;
uid_t userId = 0;
int sortKey = 0;
if (argc > 0) {
if (String_eq(argv[1], "--help")) {
printHelpFlag();
} else if (String_eq(argv[1], "--version")) {
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")) {
if (argc < 2) printHelpFlag();
sscanf(argv[2], "%d", &delay);
@ -219,14 +241,14 @@ int main(int argc, char** argv) {
exit(1);
}
ListBox* lb;
Panel* panel;
int quit = 0;
int refreshTimeout = 0;
int resetRefreshTimeout = 5;
bool doRefresh = true;
Settings* settings;
ListBox* lbk = NULL;
Panel* killPanel = NULL;
char incSearchBuffer[INCSEARCH_MAX];
int incSearchIndex = 0;
@ -240,6 +262,10 @@ int main(int argc, char** argv) {
Header* header = Header_new(pl);
settings = Settings_new(pl, header);
if (sortKey > 0) {
pl->sortKey = sortKey;
pl->treeView = false;
}
int headerHeight = Header_calculateHeight(header);
// FIXME: move delay code to settings
@ -248,8 +274,8 @@ int main(int argc, char** argv) {
CRT_init(settings->delay, settings->colorScheme);
lb = ListBox_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false);
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
panel = Panel_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false, NULL);
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
char* searchFunctions[3] = {"Next ", "Exit ", " Search: "};
char* searchKeys[3] = {"F3", "Esc", " "};
@ -285,9 +311,9 @@ int main(int argc, char** argv) {
if (doRefresh) {
incSearchIndex = 0;
incSearchBuffer[0] = 0;
int currPos = ListBox_getSelectedIndex(lb);
int currPos = Panel_getSelectedIndex(panel);
int currPid = 0;
int currScrollV = lb->scrollV;
int currScrollV = panel->scrollV;
if (follow)
currPid = ProcessList_get(pl, currPos)->pid;
if (recalculate)
@ -296,18 +322,18 @@ int main(int argc, char** argv) {
ProcessList_sort(pl);
refreshTimeout = 1;
}
ListBox_prune(lb);
Panel_prune(panel);
int size = ProcessList_size(pl);
int lbi = 0;
int index = 0;
for (int i = 0; i < size; i++) {
Process* p = ProcessList_get(pl, i);
if (!userOnly || (p->st_uid == userId)) {
ListBox_set(lb, lbi, (Object*)p);
if ((!follow && lbi == currPos) || (follow && p->pid == currPid)) {
ListBox_setSelected(lb, lbi);
lb->scrollV = currScrollV;
Panel_set(panel, index, (Object*)p);
if ((!follow && index == currPos) || (follow && p->pid == currPid)) {
Panel_setSelected(panel, index);
panel->scrollV = currScrollV;
}
lbi++;
index++;
}
}
}
@ -315,7 +341,7 @@ int main(int argc, char** argv) {
Header_draw(header);
ListBox_draw(lb, true);
Panel_draw(panel, true);
int prev = ch;
ch = getch();
@ -334,7 +360,7 @@ int main(int argc, char** argv) {
if (incSearchMode) {
doRefresh = false;
if (ch == KEY_F(3)) {
int here = ListBox_getSelectedIndex(lb);
int here = Panel_getSelectedIndex(panel);
int size = ProcessList_size(pl);
int i = here+1;
while (i != here) {
@ -342,7 +368,7 @@ int main(int argc, char** argv) {
i = 0;
Process* p = ProcessList_get(pl, i);
if (String_contains_i(p->comm, incSearchBuffer)) {
ListBox_setSelected(lb, i);
Panel_setSelected(panel, i);
break;
}
i++;
@ -367,7 +393,7 @@ int main(int argc, char** argv) {
for (int i = 0; i < ProcessList_size(pl); i++) {
Process* p = ProcessList_get(pl, i);
if (String_contains_i(p->comm, incSearchBuffer)) {
ListBox_setSelected(lb, i);
Panel_setSelected(panel, i);
found = true;
break;
}
@ -381,8 +407,8 @@ int main(int argc, char** argv) {
}
if (isdigit((char)ch)) {
int pid = ch-48 + acc;
for (int i = 0; i < ProcessList_size(pl) && ((Process*) ListBox_getSelected(lb))->pid != pid; i++)
ListBox_setSelected(lb, i);
for (int i = 0; i < ProcessList_size(pl) && ((Process*) Panel_getSelected(panel))->pid != pid; i++)
Panel_setSelected(panel, i);
acc = pid * 10;
if (acc > 100000)
acc = 0;
@ -395,8 +421,8 @@ int main(int argc, char** argv) {
MEVENT mevent;
int ok = getmouse(&mevent);
if (ok == OK) {
if (mevent.y >= lb->y + 1 && mevent.y < LINES - 1) {
ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV - 1);
if (mevent.y >= panel->y + 1 && mevent.y < LINES - 1) {
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
doRefresh = false;
refreshTimeout = resetRefreshTimeout;
follow = true;
@ -413,7 +439,7 @@ int main(int argc, char** argv) {
switch (ch) {
case KEY_RESIZE:
ListBox_resize(lb, COLS, LINES-headerHeight-1);
Panel_resize(panel, COLS, LINES-headerHeight-1);
if (incSearchMode)
FunctionBar_draw(searchBar, incSearchBuffer);
else
@ -425,7 +451,7 @@ int main(int argc, char** argv) {
pl->sortKey = PERCENT_MEM;
pl->treeView = false;
settings->changed = true;
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
break;
}
case 'T':
@ -434,13 +460,13 @@ int main(int argc, char** argv) {
pl->sortKey = TIME;
pl->treeView = false;
settings->changed = true;
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
break;
}
case 'U':
{
for (int i = 0; i < ListBox_getSize(lb); i++) {
Process* p = (Process*) ListBox_get(lb, i);
for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i);
p->tag = false;
}
doRefresh = true;
@ -452,13 +478,13 @@ int main(int argc, char** argv) {
pl->sortKey = PERCENT_CPU;
pl->treeView = false;
settings->changed = true;
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
break;
}
case KEY_F(1):
case 'h':
{
showHelp();
showHelp(pl);
FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0;
break;
@ -472,14 +498,14 @@ int main(int argc, char** argv) {
}
case ' ':
{
Process* p = (Process*) ListBox_getSelected(lb);
Process* p = (Process*) Panel_getSelected(panel);
Process_toggleTag(p);
ListBox_onKey(lb, KEY_DOWN);
Panel_onKey(panel, KEY_DOWN);
break;
}
case 's':
{
TraceScreen* ts = TraceScreen_new((Process*) ListBox_getSelected(lb));
TraceScreen* ts = TraceScreen_new((Process*) Panel_getSelected(panel));
TraceScreen_run(ts);
TraceScreen_delete(ts);
clear();
@ -494,10 +520,10 @@ int main(int argc, char** argv) {
{
Setup_run(settings, headerHeight);
// 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);
ListBox_move(lb, 0, headerHeight);
ListBox_resize(lb, COLS, LINES-headerHeight-1);
Panel_move(panel, 0, headerHeight);
Panel_resize(panel, COLS, LINES-headerHeight-1);
FunctionBar_draw(defaultBar, NULL);
refreshTimeout = 0;
break;
@ -509,14 +535,14 @@ int main(int argc, char** argv) {
}
case 'u':
{
ListBox* lbu = ListBox_new(0, 0, 0, 0, LISTITEM_CLASS, true);
ListBox_setHeader(lbu, "Show processes of:");
UsersTable_foreach(ut, addUserToList, lbu);
TypedVector_sort(lbu->items);
Panel* usersPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare);
Panel_setHeader(usersPanel, "Show processes of:");
UsersTable_foreach(ut, addUserToList, usersPanel);
Vector_sort(usersPanel->items);
ListItem* allUsers = ListItem_new("All users", -1);
ListBox_insert(lbu, 0, (Object*) allUsers);
Panel_insert(usersPanel, 0, (Object*) allUsers);
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 == allUsers) {
userOnly = false;
@ -530,34 +556,33 @@ int main(int argc, char** argv) {
case KEY_F(9):
case 'k':
{
if (!lbk) {
lbk = (ListBox*) SignalsListBox_new(0, 0, 0, 0);
if (!killPanel) {
killPanel = (Panel*) SignalsPanel_new(0, 0, 0, 0);
}
SignalsListBox_reset((SignalsListBox*) lbk);
SignalsPanel_reset((SignalsPanel*) killPanel);
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->number != 0) {
ListBox_setHeader(lb, "Sending...");
ListBox_draw(lb, true);
Panel_setHeader(panel, "Sending...");
Panel_draw(panel, true);
refresh();
bool anyTagged = false;
for (int i = 0; i < ListBox_getSize(lb); i++) {
Process* p = (Process*) ListBox_get(lb, i);
for (int i = 0; i < Panel_getSize(panel); i++) {
Process* p = (Process*) Panel_get(panel, i);
if (p->tag) {
Process_sendSignal(p, signal->number);
Process_toggleTag(p);
anyTagged = true;
}
}
if (!anyTagged) {
Process* p = (Process*) ListBox_getSelected(lb);
Process* p = (Process*) Panel_getSelected(panel);
Process_sendSignal(p, signal->number);
}
napms(500);
}
}
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
refreshTimeout = 0;
break;
}
@ -572,25 +597,25 @@ int main(int argc, char** argv) {
case '.':
case KEY_F(6):
{
ListBox* lbf = ListBox_new(0,0,0,0,LISTITEM_CLASS,true);
ListBox_setHeader(lbf, "Sort by");
Panel* sortPanel = Panel_new(0, 0, 0, 0, LISTITEM_CLASS, true, ListItem_compare);
Panel_setHeader(sortPanel, "Sort by");
char* fuFunctions[2] = {"Sort ", "Cancel "};
ProcessField* fields = pl->fields;
for (int i = 0; fields[i]; 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)
ListBox_setSelected(lbf, i);
Panel_setSelected(sortPanel, i);
free(name);
}
ListItem* field = (ListItem*) pickFromList(lb, lbf, 15, headerHeight, fuFunctions, defaultBar);
ListItem* field = (ListItem*) pickFromList(panel, sortPanel, 15, headerHeight, fuFunctions, defaultBar);
if (field) {
pl->treeView = false;
settings->changed = true;
pl->sortKey = field->key;
}
((Object*)lbf)->delete((Object*)lbf);
ListBox_setRichHeader(lb, ProcessList_printHeader(pl));
((Object*)sortPanel)->delete((Object*)sortPanel);
Panel_setRichHeader(panel, ProcessList_printHeader(pl));
refreshTimeout = 0;
break;
}
@ -607,14 +632,14 @@ int main(int argc, char** argv) {
case '=':
case '+':
{
doRefresh = changePriority(lb, 1);
doRefresh = changePriority(panel, 1);
break;
}
case KEY_F(7):
case ']':
case '-':
{
doRefresh = changePriority(lb, -1);
doRefresh = changePriority(panel, -1);
break;
}
case KEY_F(3):
@ -641,7 +666,7 @@ int main(int argc, char** argv) {
default:
doRefresh = false;
refreshTimeout = resetRefreshTimeout;
ListBox_onKey(lb, ch);
Panel_onKey(panel, ch);
break;
}
follow = false;
@ -658,9 +683,9 @@ int main(int argc, char** argv) {
ProcessList_delete(pl);
FunctionBar_delete((Object*)searchBar);
FunctionBar_delete((Object*)defaultBar);
((Object*)lb)->delete((Object*)lb);
if (lbk)
((Object*)lbk)->delete((Object*)lbk);
((Object*)panel)->delete((Object*)panel);
if (killPanel)
((Object*)killPanel)->delete((Object*)killPanel);
UsersTable_delete(ut);
Settings_delete(settings);
debug_done();

View File

@ -1,6 +1,6 @@
[Desktop Entry]
Encoding=UTF-8
Version=0.6.2
Version=0.6.5
Name=Htop
Type=Application
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
#define HEADER_htop
@ -9,9 +9,16 @@ Released under the GNU GPL, see the COPYING file
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 "CRT.h"
#include "ListBox.h"
#include "Panel.h"
#include "UsersTable.h"
#include "SignalItem.h"
#include "RichString.h"
@ -19,34 +26,26 @@ in the source distribution for its full text.
#include "ScreenManager.h"
#include "FunctionBar.h"
#include "ListItem.h"
#include "CategoriesListBox.h"
#include "SignalsListBox.h"
#include "CategoriesPanel.h"
#include "SignalsPanel.h"
#include "TraceScreen.h"
#include "config.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
#define INCSEARCH_MAX 40
void printVersionFlag();
void printHelpFlag();
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);

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

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