1 Commits
1.0.3 ... 0.6.2

Author SHA1 Message Date
4148b587d1 Tag release 0.6.2 in revision history 2006-05-24 00:27:20 +00:00
125 changed files with 5259 additions and 9001 deletions

View File

@ -1,42 +0,0 @@
/*
htop - Affinity.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Affinity.h"
#include <stdlib.h>
/*{
typedef struct Affinity_ {
int size;
int used;
int* cpus;
} Affinity;
}*/
Affinity* Affinity_new() {
Affinity* this = calloc(1, sizeof(Affinity));
this->size = 8;
this->cpus = calloc(this->size, sizeof(int));
return this;
}
void Affinity_delete(Affinity* this) {
free(this->cpus);
free(this);
}
void Affinity_add(Affinity* this, int id) {
if (this->used == this->size) {
this->size *= 2;
this->cpus = realloc(this->cpus, sizeof(int) * this->size);
}
this->cpus[this->used] = id;
this->used++;
}

View File

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

View File

@ -1,74 +0,0 @@
/*
htop - AffinityPanel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "AffinityPanel.h"
#include "CheckItem.h"
#include <assert.h>
#include <string.h>
/*{
#include "Panel.h"
#include "Affinity.h"
#include "ProcessList.h"
#include "ListItem.h"
}*/
static HandlerResult AffinityPanel_eventHandler(Panel* this, int ch) {
CheckItem* selected = (CheckItem*) Panel_getSelected(this);
switch(ch) {
case KEY_MOUSE:
case ' ':
CheckItem_set(selected, ! (CheckItem_get(selected)) );
return HANDLED;
case 0x0a:
case 0x0d:
case KEY_ENTER:
return BREAK_LOOP;
}
return IGNORED;
}
PanelClass AffinityPanel_class = {
.super = {
.extends = Class(Panel),
.delete = Panel_delete
},
.eventHandler = AffinityPanel_eventHandler
};
Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) {
Panel* this = Panel_new(1, 1, 1, 1, true, Class(CheckItem));
Object_setClass(this, Class(AffinityPanel));
Panel_setHeader(this, "Use CPUs:");
int curCpu = 0;
for (int i = 0; i < pl->cpuCount; i++) {
char number[10];
snprintf(number, 9, "%d", ProcessList_cpuId(pl, i));
bool mode;
if (curCpu < affinity->used && affinity->cpus[curCpu] == i) {
mode = true;
curCpu++;
} else {
mode = false;
}
Panel_add(this, (Object*) CheckItem_new(strdup(number), NULL, mode));
}
return this;
}
Affinity* AffinityPanel_getAffinity(Panel* this) {
Affinity* affinity = Affinity_new();
int size = Panel_size(this);
for (int i = 0; i < size; i++) {
if (CheckItem_get((CheckItem*)Panel_get(this, i)))
Affinity_add(affinity, i);
}
return affinity;
}

View File

@ -1,23 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_AffinityPanel
#define HEADER_AffinityPanel
/*
htop - AffinityPanel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "Affinity.h"
#include "ProcessList.h"
#include "ListItem.h"
extern PanelClass AffinityPanel_class;
Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity);
Affinity* AffinityPanel_getAffinity(Panel* this);
#endif

72
AvailableColumnsListBox.c Normal file
View File

@ -0,0 +1,72 @@
#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;
}

31
AvailableColumnsListBox.h Normal file
View File

@ -0,0 +1,31 @@
/* 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

View File

@ -1,90 +0,0 @@
/*
htop - AvailableColumnsPanel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "AvailableColumnsPanel.h"
#include "Header.h"
#include "ColumnsPanel.h"
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
/*{
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct AvailableColumnsPanel_ {
Panel super;
Panel* columns;
Settings* settings;
ScreenManager* scr;
} AvailableColumnsPanel;
}*/
static void AvailableColumnsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
AvailableColumnsPanel* this = (AvailableColumnsPanel*) object;
Panel_done(super);
free(this);
}
static 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);
Panel_insert(this->columns, at, (Object*) ListItem_new(text, 0));
Panel_setSelected(this->columns, at+1);
ColumnsPanel_update(this->columns);
result = HANDLED;
break;
}
default:
{
if (isalpha(ch))
result = Panel_selectByTyping(super, ch);
break;
}
}
return result;
}
PanelClass AvailableColumnsPanel_class = {
.super = {
.extends = Class(Panel),
.delete = AvailableColumnsPanel_delete
},
.eventHandler = AvailableColumnsPanel_eventHandler
};
AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr) {
AvailableColumnsPanel* this = AllocThis(AvailableColumnsPanel);
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
this->settings = settings;
this->scr = scr;
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;
}

View File

@ -1,29 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_AvailableColumnsPanel
#define HEADER_AvailableColumnsPanel
/*
htop - AvailableColumnsPanel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct AvailableColumnsPanel_ {
Panel super;
Panel* columns;
Settings* settings;
ScreenManager* scr;
} AvailableColumnsPanel;
extern PanelClass AvailableColumnsPanel_class;
AvailableColumnsPanel* AvailableColumnsPanel_new(Settings* settings, Panel* columns, ScreenManager* scr);
#endif

106
AvailableMetersListBox.c Normal file
View File

@ -0,0 +1,106 @@
#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;
}

33
AvailableMetersListBox.h Normal file
View File

@ -0,0 +1,33 @@
/* 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

View File

@ -1,119 +0,0 @@
/*
htop - AvailableMetersPanel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "AvailableMetersPanel.h"
#include "CPUMeter.h"
#include "Header.h"
#include "ListItem.h"
#include <assert.h>
#include <stdlib.h>
/*{
#include "Settings.h"
#include "Panel.h"
#include "ScreenManager.h"
typedef struct AvailableMetersPanel_ {
Panel super;
Settings* settings;
Panel* leftPanel;
Panel* rightPanel;
ScreenManager* scr;
} AvailableMetersPanel;
}*/
static 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, MeterClass* type, int param, HeaderSide side) {
Meter* meter = (Meter*) Header_addMeter(header, type, param, side);
Panel_add(panel, (Object*) Meter_toListItem(meter));
}
static 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;
}
PanelClass AvailableMetersPanel_class = {
.super = {
.extends = Class(Panel),
.delete = AvailableMetersPanel_delete
},
.eventHandler = AvailableMetersPanel_eventHandler
};
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr) {
AvailableMetersPanel* this = AllocThis(AvailableMetersPanel);
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
this->settings = settings;
this->leftPanel = leftMeters;
this->rightPanel = rightMeters;
this->scr = scr;
Panel_setHeader(super, "Available meters");
for (int i = 1; Meter_types[i]; i++) {
MeterClass* type = Meter_types[i];
if (type != &CPUMeter_class) {
Panel_add(super, (Object*) ListItem_new(type->uiName, i << 16));
}
}
MeterClass* type = &CPUMeter_class;
int cpus = settings->pl->cpuCount;
if (cpus > 1) {
Panel_add(super, (Object*) ListItem_new("CPU average", 0));
for (int i = 1; i <= cpus; 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;
}

View File

@ -1,30 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_AvailableMetersPanel
#define HEADER_AvailableMetersPanel
/*
htop - AvailableMetersPanel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Settings.h"
#include "Panel.h"
#include "ScreenManager.h"
typedef struct AvailableMetersPanel_ {
Panel super;
Settings* settings;
Panel* leftPanel;
Panel* rightPanel;
ScreenManager* scr;
} AvailableMetersPanel;
extern PanelClass AvailableMetersPanel_class;
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr);
#endif

View File

@ -1,336 +0,0 @@
/*
htop - BatteryMeter.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
This meter written by Ian P. Hands (iphands@gmail.com, ihands@redhat.com).
*/
#include "BatteryMeter.h"
#include "ProcessList.h"
#include "CRT.h"
#include "String.h"
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
/*{
#include "Meter.h"
typedef enum ACPresence_ {
AC_ABSENT,
AC_PRESENT,
AC_ERROR
} ACPresence;
}*/
int BatteryMeter_attributes[] = {
BATTERY
};
static unsigned long int parseUevent(FILE * file, const char *key) {
char line[100];
unsigned long int dValue = 0;
char* saveptr;
while (fgets(line, sizeof line, file)) {
if (strncmp(line, key, strlen(key)) == 0) {
char *value;
strtok_r(line, "=", &saveptr);
value = strtok_r(NULL, "=", &saveptr);
dValue = atoi(value);
break;
}
}
return dValue;
}
static unsigned long int parseBatInfo(const char *fileName, const unsigned short int lineNum, const unsigned short int wordNum) {
const char batteryPath[] = PROCDIR "/acpi/battery/";
DIR* batteryDir = opendir(batteryPath);
if (!batteryDir)
return 0;
#define MAX_BATTERIES 64
char* batteries[MAX_BATTERIES];
unsigned int nBatteries = 0;
memset(batteries, 0, MAX_BATTERIES * sizeof(char*));
struct dirent result;
struct dirent* dirEntry;
while (nBatteries < MAX_BATTERIES) {
int err = readdir_r(batteryDir, &result, &dirEntry);
if (err || !dirEntry)
break;
char* entryName = dirEntry->d_name;
if (strncmp(entryName, "BAT", 3))
continue;
batteries[nBatteries] = strdup(entryName);
nBatteries++;
}
closedir(batteryDir);
unsigned long int total = 0;
for (unsigned int i = 0; i < nBatteries; i++) {
char infoPath[30];
snprintf(infoPath, sizeof infoPath, "%s%s/%s", batteryPath, batteries[i], fileName);
FILE* file = fopen(infoPath, "r");
if (!file) {
break;
}
char line[50] = "";
for (unsigned short int i = 0; i < lineNum; i++) {
char* ok = fgets(line, sizeof line, file);
if (!ok) break;
}
fclose(file);
char *foundNumStr = String_getToken(line, wordNum);
const unsigned long int foundNum = atoi(foundNumStr);
free(foundNumStr);
total += foundNum;
}
for (unsigned int i = 0; i < nBatteries; i++) {
free(batteries[i]);
}
return total;
}
static ACPresence procAcpiCheck() {
ACPresence isOn = AC_ERROR;
const char *power_supplyPath = PROCDIR "/acpi/ac_adapter";
DIR *power_supplyDir = opendir(power_supplyPath);
if (!power_supplyDir) {
return AC_ERROR;
}
struct dirent result;
struct dirent* dirEntry;
for (;;) {
int err = readdir_r((DIR *) power_supplyDir, &result, &dirEntry);
if (err || !dirEntry)
break;
char* entryName = (char *) dirEntry->d_name;
if (entryName[0] != 'A')
continue;
char statePath[50];
snprintf((char *) statePath, sizeof statePath, "%s/%s/state", power_supplyPath, entryName);
FILE* file = fopen(statePath, "r");
if (!file) {
isOn = AC_ERROR;
continue;
}
char line[100];
fgets(line, sizeof line, file);
line[sizeof(line) - 1] = '\0';
fclose(file);
const char *isOnline = String_getToken(line, 2);
if (strcmp(isOnline, "on-line") == 0) {
isOn = AC_PRESENT;
} else {
isOn = AC_ABSENT;
}
free((char *) isOnline);
if (isOn == AC_PRESENT) {
break;
}
}
if (power_supplyDir)
closedir(power_supplyDir);
return isOn;
}
static ACPresence sysCheck() {
ACPresence isOn = AC_ERROR;
const char *power_supplyPath = "/sys/class/power_supply";
DIR *power_supplyDir = opendir(power_supplyPath);
if (!power_supplyDir) {
return AC_ERROR;
}
struct dirent result;
struct dirent* dirEntry;
for (;;) {
int err = readdir_r((DIR *) power_supplyDir, &result, &dirEntry);
if (err || !dirEntry)
break;
char* entryName = (char *) dirEntry->d_name;
if (strncmp(entryName, "A", 1)) {
continue;
}
char onlinePath[50];
snprintf((char *) onlinePath, sizeof onlinePath, "%s/%s/online", power_supplyPath, entryName);
FILE* file = fopen(onlinePath, "r");
if (!file) {
isOn = AC_ERROR;
} else {
isOn = (fgetc(file) - '0');
fclose(file);
if (isOn == AC_PRESENT) {
// If any AC adapter is being used then stop
break;
}
}
}
if (power_supplyDir)
closedir(power_supplyDir);
return isOn;
}
static ACPresence chkIsOnline() {
if (access(PROCDIR "/acpi/ac_adapter", F_OK) == 0) {
return procAcpiCheck();
} else if (access("/sys/class/power_supply", F_OK) == 0) {
return sysCheck();
} else {
return AC_ERROR;
}
}
static double getProcBatData() {
const unsigned long int totalFull = parseBatInfo("info", 3, 4);
if (totalFull == 0)
return 0;
const unsigned long int totalRemain = parseBatInfo("state", 5, 3);
if (totalRemain == 0)
return 0;
return totalRemain * 100.0 / (double) totalFull;
}
static double getSysBatData() {
const char *power_supplyPath = "/sys/class/power_supply/";
DIR *power_supplyDir = opendir(power_supplyPath);
if (!power_supplyDir)
return 0;
unsigned long int totalFull = 0;
unsigned long int totalRemain = 0;
struct dirent result;
struct dirent* dirEntry;
for (;;) {
int err = readdir_r((DIR *) power_supplyDir, &result, &dirEntry);
if (err || !dirEntry)
break;
char* entryName = (char *) dirEntry->d_name;
if (strncmp(entryName, "BAT", 3)) {
continue;
}
const char ueventPath[50];
snprintf((char *) ueventPath, sizeof ueventPath, "%s%s/uevent", power_supplyPath, entryName);
FILE *file;
if ((file = fopen(ueventPath, "r")) == NULL) {
closedir(power_supplyDir);
return 0;
}
if ((totalFull += parseUevent(file, "POWER_SUPPLY_ENERGY_FULL="))) {
totalRemain += parseUevent(file, "POWER_SUPPLY_ENERGY_NOW=");
} else {
//reset file pointer
if (fseek(file, 0, SEEK_SET) < 0) {
closedir(power_supplyDir);
fclose(file);
return 0;
}
}
//Some systems have it as CHARGE instead of ENERGY.
if ((totalFull += parseUevent(file, "POWER_SUPPLY_CHARGE_FULL="))) {
totalRemain += parseUevent(file, "POWER_SUPPLY_CHARGE_NOW=");
} else {
//reset file pointer
if (fseek(file, 0, SEEK_SET) < 0) {
closedir(power_supplyDir);
fclose(file);
return 0;
}
}
fclose(file);
}
const double percent = totalFull > 0 ? ((double) totalRemain * 100) / (double) totalFull : 0;
closedir(power_supplyDir);
return percent;
}
static void BatteryMeter_setValues(Meter * this, char *buffer, int len) {
double percent = getProcBatData();
if (percent == 0) {
percent = getSysBatData();
if (percent == 0) {
snprintf(buffer, len, "n/a");
return;
}
}
this->values[0] = percent;
const char *onAcText, *onBatteryText, *unknownText;
unknownText = "%.1f%%";
if (this->mode == TEXT_METERMODE) {
onAcText = "%.1f%% (Running on A/C)";
onBatteryText = "%.1f%% (Running on battery)";
} else {
onAcText = "%.1f%%(A/C)";
onBatteryText = "%.1f%%(bat)";
}
ACPresence isOnLine = chkIsOnline();
if (isOnLine == AC_PRESENT) {
snprintf(buffer, len, onAcText, percent);
} else if (isOnLine == AC_ABSENT) {
snprintf(buffer, len, onBatteryText, percent);
} else {
snprintf(buffer, len, unknownText, percent);
}
return;
}
MeterClass BatteryMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete
},
.setValues = BatteryMeter_setValues,
.defaultMode = TEXT_METERMODE,
.total = 100.0,
.attributes = BatteryMeter_attributes,
.name = "Battery",
.uiName = "Battery",
.caption = "Battery: "
};

View File

@ -1,27 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_BatteryMeter
#define HEADER_BatteryMeter
/*
htop - BatteryMeter.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
This meter written by Ian P. Hands (iphands@gmail.com, ihands@redhat.com).
*/
#include "Meter.h"
typedef enum ACPresence_ {
AC_ABSENT,
AC_PRESENT,
AC_ERROR
} ACPresence;
extern int BatteryMeter_attributes[];
extern MeterClass BatteryMeter_class;
#endif

17
COPYING
View File

@ -337,20 +337,3 @@ proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
Appendix 2: Special exception concerning PLPA
In the following exception, "PLPA" means (i) code released by the
Portable Linux Processor Affinity Project, or (ii) derivative works of
such code, in both cases provided that the code is covered entirely by
free software licensing terms.
As a special exception to the GNU GPL, the licensors of htop give you
permission to combine GNU GPL-licensed code in htop (and derivative
works of such code) with PLPA. You may copy and distribute such a
combined work following the terms of the GNU GPL for htop and the
applicable licenses of the version of PLPA used in your combined work,
provided that you include the source code of such version of PLPA when
and as the GNU GPL requires distribution of source code.

View File

@ -1,26 +1,53 @@
/*
htop - CPUMeter.c
(C) 2004-2011 Hisham H. Muhammad
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "CPUMeter.h"
#include "Meter.h"
#include "CRT.h"
#include "ProcessList.h"
#include <assert.h>
#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <math.h>
/*{
#include "Meter.h"
}*/
#include "debug.h"
#include <assert.h>
int CPUMeter_attributes[] = {
CPU_NICE, CPU_NORMAL, CPU_KERNEL, CPU_IRQ, CPU_SOFTIRQ, CPU_STEAL, CPU_GUEST, CPU_IOWAIT
/* private property */
static int CPUMeter_attributes[] = { CPU_NICE, CPU_NORMAL, CPU_KERNEL };
/* private */
MeterType CPUMeter = {
.setValues = CPUMeter_setValues,
.display = CPUMeter_display,
.mode = BAR_METERMODE,
.items = 3,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "CPU",
.uiName = "CPU",
.caption = "CPU",
.init = CPUMeter_init
};
/* private */
MeterType AllCPUsMeter = {
.mode = 0,
.items = 1,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "AllCPUs",
.uiName = "All CPUs",
.caption = "CPU",
.draw = AllCPUsMeter_draw,
.init = AllCPUsMeter_init,
.setMode = AllCPUsMeter_setMode,
.done = AllCPUsMeter_done
};
#ifndef MIN
@ -30,318 +57,73 @@ int CPUMeter_attributes[] = {
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
static void CPUMeter_init(Meter* this) {
int cpu = this->param;
if (this->pl->cpuCount > 1) {
void CPUMeter_init(Meter* this) {
int processor = this->param;
if (this->pl->processorCount > 1) {
char caption[10];
sprintf(caption, "%-3d", ProcessList_cpuId(this->pl, cpu - 1));
sprintf(caption, "%-3d", processor);
Meter_setCaption(this, caption);
}
if (this->param == 0)
Meter_setCaption(this, "Avg");
}
static void CPUMeter_setValues(Meter* this, char* buffer, int size) {
void CPUMeter_setValues(Meter* this, char* buffer, int size) {
ProcessList* pl = this->pl;
int cpu = this->param;
if (cpu > this->pl->cpuCount) {
snprintf(buffer, size, "absent");
return;
}
CPUData* cpuData = &(pl->cpus[cpu]);
double total = (double) ( cpuData->totalPeriod == 0 ? 1 : cpuData->totalPeriod);
double percent;
double* v = this->values;
v[0] = cpuData->nicePeriod / total * 100.0;
v[1] = cpuData->userPeriod / total * 100.0;
if (pl->detailedCPUTime) {
v[2] = cpuData->systemPeriod / total * 100.0;
v[3] = cpuData->irqPeriod / total * 100.0;
v[4] = cpuData->softIrqPeriod / total * 100.0;
v[5] = cpuData->stealPeriod / total * 100.0;
v[6] = cpuData->guestPeriod / total * 100.0;
v[7] = cpuData->ioWaitPeriod / total * 100.0;
Meter_setItems(this, 8);
if (pl->accountGuestInCPUMeter) {
percent = v[0]+v[1]+v[2]+v[3]+v[4]+v[5]+v[6];
} else {
percent = v[0]+v[1]+v[2]+v[3]+v[4];
}
} else {
v[2] = cpuData->systemAllPeriod / total * 100.0;
v[3] = (cpuData->stealPeriod + cpuData->guestPeriod) / total * 100.0;
Meter_setItems(this, 4);
percent = v[0]+v[1]+v[2]+v[3];
}
percent = MIN(100.0, MAX(0.0, percent));
if (isnan(percent)) percent = 0.0;
snprintf(buffer, size, "%5.1f%%", percent);
int processor = this->param;
double total = (double) pl->totalPeriod[processor];
this->values[0] = pl->nicePeriod[processor] / total * 100.0;
this->values[1] = pl->userPeriod[processor] / total * 100.0;
this->values[2] = pl->systemPeriod[processor] / total * 100.0;
double cpu = MIN(100.0, MAX(0.0, (this->values[0]+this->values[1]+this->values[2])));
snprintf(buffer, size, "%5.1f%%", cpu );
}
static void CPUMeter_display(Object* cast, RichString* out) {
void CPUMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* this = (Meter*)cast;
RichString_prune(out);
if (this->param > this->pl->cpuCount) {
RichString_append(out, CRT_colors[METER_TEXT], "absent");
return;
}
sprintf(buffer, "%5.1f%% ", this->values[1]);
RichString_append(out, CRT_colors[METER_TEXT], ":");
RichString_append(out, CRT_colors[CPU_NORMAL], buffer);
if (this->pl->detailedCPUTime) {
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_TEXT], buffer);
sprintf(buffer, "%5.1f%% ", this->values[3]);
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);
if (this->values[5]) {
sprintf(buffer, "%5.1f%% ", this->values[5]);
RichString_append(out, CRT_colors[METER_TEXT], "st:");
RichString_append(out, CRT_colors[CPU_STEAL], buffer);
}
if (this->values[6]) {
sprintf(buffer, "%5.1f%% ", this->values[6]);
RichString_append(out, CRT_colors[METER_TEXT], "gu:");
RichString_append(out, CRT_colors[CPU_GUEST], buffer);
}
sprintf(buffer, "%5.1f%% ", this->values[7]);
RichString_append(out, CRT_colors[METER_TEXT], "wa:");
RichString_append(out, CRT_colors[CPU_IOWAIT], 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_TEXT], buffer);
if (this->values[3]) {
sprintf(buffer, "%5.1f%% ", this->values[3]);
RichString_append(out, CRT_colors[METER_TEXT], "vir:");
RichString_append(out, CRT_colors[CPU_GUEST], 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);
}
static void AllCPUsMeter_getRange(Meter* this, int* start, int* count) {
int cpus = this->pl->cpuCount;
switch(Meter_name(this)[0]) {
default:
case 'A': // All
*start = 0;
*count = cpus;
break;
case 'L': // First Half
*start = 0;
*count = (cpus+1) / 2;
break;
case 'R': // Second Half
*start = (cpus+1) / 2;
*count = cpus / 2;
break;
}
void AllCPUsMeter_init(Meter* this) {
int processors = this->pl->processorCount;
this->drawBuffer = malloc(sizeof(Meter*) * processors);
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++)
meters[i] = Meter_new(this->pl, i+1, &CPUMeter);
this->h = processors;
this->mode = BAR_METERMODE;
}
static void AllCPUsMeter_init(Meter* this) {
int cpus = this->pl->cpuCount;
if (!this->drawData)
this->drawData = calloc(cpus, sizeof(Meter*));
Meter** meters = (Meter**) this->drawData;
int start, count;
AllCPUsMeter_getRange(this, &start, &count);
for (int i = 0; i < count; i++) {
if (!meters[i])
meters[i] = Meter_new(this->pl, start+i+1, (MeterClass*) Class(CPUMeter));
Meter_init(meters[i]);
}
if (this->mode == 0)
this->mode = BAR_METERMODE;
int h = Meter_modes[this->mode]->h;
if (strchr(Meter_name(this), '2'))
this->h = h * ((count+1) / 2);
else
this->h = h * count;
}
static void AllCPUsMeter_done(Meter* this) {
Meter** meters = (Meter**) this->drawData;
int start, count;
AllCPUsMeter_getRange(this, &start, &count);
for (int i = 0; i < count; i++)
void AllCPUsMeter_done(Meter* this) {
int processors = this->pl->processorCount;
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++)
Meter_delete((Object*)meters[i]);
}
static void AllCPUsMeter_updateMode(Meter* this, int mode) {
Meter** meters = (Meter**) this->drawData;
void AllCPUsMeter_setMode(Meter* this, int mode) {
this->mode = mode;
int h = Meter_modes[mode]->h;
int start, count;
AllCPUsMeter_getRange(this, &start, &count);
for (int i = 0; i < count; i++) {
Meter_setMode(meters[i], mode);
}
if (strchr(Meter_name(this), '2'))
this->h = h * ((count+1) / 2);
else
this->h = h * count;
int processors = this->pl->processorCount;
int h = Meter_modes[this->mode]->h;
this->h = h * processors;
}
static void DualColCPUsMeter_draw(Meter* this, int x, int y, int w) {
Meter** meters = (Meter**) this->drawData;
int start, count;
AllCPUsMeter_getRange(this, &start, &count);
int height = (count+1)/2;
int startY = y;
for (int i = 0; i < height; i++) {
meters[i]->draw(meters[i], x, y, (w-2)/2);
y += meters[i]->h;
}
y = startY;
for (int i = height; i < count; i++) {
meters[i]->draw(meters[i], x+(w-1)/2+2, y, (w-2)/2);
y += meters[i]->h;
}
}
static void SingleColCPUsMeter_draw(Meter* this, int x, int y, int w) {
Meter** meters = (Meter**) this->drawData;
int start, count;
AllCPUsMeter_getRange(this, &start, &count);
for (int i = 0; i < count; i++) {
void AllCPUsMeter_draw(Meter* this, int x, int y, int w) {
int processors = this->pl->processorCount;
Meter** meters = (Meter**) this->drawBuffer;
for (int i = 0; i < processors; i++) {
Meter_setMode(meters[i], this->mode);
meters[i]->draw(meters[i], x, y, w);
y += meters[i]->h;
}
}
MeterClass CPUMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.setValues = CPUMeter_setValues,
.defaultMode = BAR_METERMODE,
.maxItems = 8,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "CPU",
.uiName = "CPU",
.caption = "CPU",
.init = CPUMeter_init
};
MeterClass AllCPUsMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "AllCPUs",
.uiName = "CPUs (1/1)",
.caption = "CPU",
.draw = SingleColCPUsMeter_draw,
.init = AllCPUsMeter_init,
.updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done
};
MeterClass AllCPUs2Meter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "AllCPUs2",
.uiName = "CPUs (1&2/2)",
.caption = "CPU",
.draw = DualColCPUsMeter_draw,
.init = AllCPUsMeter_init,
.updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done
};
MeterClass LeftCPUsMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "LeftCPUs",
.uiName = "CPUs (1/2)",
.caption = "CPU",
.draw = SingleColCPUsMeter_draw,
.init = AllCPUsMeter_init,
.updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done
};
MeterClass RightCPUsMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "RightCPUs",
.uiName = "CPUs (2/2)",
.caption = "CPU",
.draw = SingleColCPUsMeter_draw,
.init = AllCPUsMeter_init,
.updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done
};
MeterClass LeftCPUs2Meter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "LeftCPUs2",
.uiName = "CPUs (1&2/4)",
.caption = "CPU",
.draw = DualColCPUsMeter_draw,
.init = AllCPUsMeter_init,
.updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done
};
MeterClass RightCPUs2Meter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = CPUMeter_display
},
.defaultMode = CUSTOM_METERMODE,
.total = 100.0,
.attributes = CPUMeter_attributes,
.name = "RightCPUs2",
.uiName = "CPUs (3&4/4)",
.caption = "CPU",
.draw = DualColCPUsMeter_draw,
.init = AllCPUsMeter_init,
.updateMode = AllCPUsMeter_updateMode,
.done = AllCPUsMeter_done
};

View File

@ -3,15 +3,26 @@
#ifndef HEADER_CPUMeter
#define HEADER_CPUMeter
/*
htop - CPUMeter.h
(C) 2004-2011 Hisham H. Muhammad
htop - CPUMeter.c
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Meter.h"
extern int CPUMeter_attributes[];
#include "ProcessList.h"
#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <math.h>
#include "debug.h"
#include <assert.h>
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
@ -20,19 +31,18 @@ extern int CPUMeter_attributes[];
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
extern MeterClass CPUMeter_class;
void CPUMeter_init(Meter* this);
extern MeterClass AllCPUsMeter_class;
void CPUMeter_setValues(Meter* this, char* buffer, int size);
extern MeterClass AllCPUs2Meter_class;
void CPUMeter_display(Object* cast, RichString* out);
extern MeterClass LeftCPUsMeter_class;
void AllCPUsMeter_init(Meter* this);
extern MeterClass RightCPUsMeter_class;
void AllCPUsMeter_done(Meter* this);
extern MeterClass LeftCPUs2Meter_class;
extern MeterClass RightCPUs2Meter_class;
void AllCPUsMeter_setMode(Meter* this, int mode);
void AllCPUsMeter_draw(Meter* this, int x, int y, int w);
#endif

238
CRT.c
View File

@ -1,24 +1,20 @@
/*
htop - CRT.c
(C) 2004-2011 Hisham H. Muhammad
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "CRT.h"
#include "config.h"
#include "String.h"
#include "RichString.h"
#include <stdio.h>
#include <errno.h>
#include <curses.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
#endif
#include <stdbool.h>
#include "String.h"
#include "debug.h"
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
@ -40,8 +36,9 @@ in the source distribution for its full text.
//#link curses
bool CRT_hasColors;
/*{
#include <stdbool.h>
typedef enum ColorElements_ {
RESET_COLOR,
@ -58,7 +55,7 @@ typedef enum ColorElements_ {
METER_VALUE,
LED_COLOR,
UPTIME,
BATTERY,
TASKS_TOTAL,
TASKS_RUNNING,
SWAP,
PROCESS,
@ -70,8 +67,6 @@ typedef enum ColorElements_ {
PROCESS_BASENAME,
PROCESS_HIGH_PRIORITY,
PROCESS_LOW_PRIORITY,
PROCESS_THREAD,
PROCESS_THREAD_BASENAME,
BAR_BORDER,
BAR_SHADOW,
GRAPH_1,
@ -85,7 +80,6 @@ typedef enum ColorElements_ {
GRAPH_9,
MEMORY_USED,
MEMORY_BUFFERS,
MEMORY_BUFFERS_TEXT,
MEMORY_CACHE,
LOAD,
LOAD_AVERAGE_FIFTEEN,
@ -95,70 +89,31 @@ typedef enum ColorElements_ {
CHECK_MARK,
CHECK_TEXT,
CLOCK,
HELP_BOLD,
HOSTNAME,
CPU_NICE,
CPU_NICE_TEXT,
CPU_NORMAL,
CPU_KERNEL,
CPU_IOWAIT,
CPU_IRQ,
CPU_SOFTIRQ,
CPU_STEAL,
CPU_GUEST,
HELP_BOLD,
LAST_COLORELEMENT
} ColorElements;
void CRT_fatalError(const char* note) __attribute__ ((noreturn));
extern int CRT_delay;
extern int CRT_colors[LAST_COLORELEMENT];
extern int CRT_colorScheme;
}*/
// TODO: centralize these in Settings.
static bool CRT_hasColors;
/* private property */
int CRT_delay;
static int CRT_delay = 0;
/* private property */
int CRT_colorScheme;
int CRT_colorScheme = 0;
bool CRT_utf8 = false;
int CRT_colors[LAST_COLORELEMENT] = { 0 };
int CRT_cursorX = 0;
int CRT_scrollHAmount = 5;
char* CRT_termType;
void *backtraceArray[128];
static void CRT_handleSIGSEGV(int sgn) {
(void) sgn;
CRT_done();
#if __linux
fprintf(stderr, "\n\nhtop " VERSION " aborting. Please report bug at http://hisham.hm/htop\n");
#ifdef HAVE_EXECINFO_H
size_t size = backtrace(backtraceArray, sizeof(backtraceArray) / sizeof(void *));
fprintf(stderr, "\n Please include in your report the following backtrace: \n");
backtrace_symbols_fd(backtraceArray, size, 2);
fprintf(stderr, "\nAdditionally, in order to make the above backtrace useful,");
fprintf(stderr, "\nplease also run the following command to generate a disassembly of your binary:");
fprintf(stderr, "\n\n objdump -d `which htop` > ~/htop.objdump");
fprintf(stderr, "\n\nand then attach the file ~/htop.objdump to your bug report.");
fprintf(stderr, "\n\nThank you for helping to improve htop!\n\n");
#endif
#else
fprintf(stderr, "\n\nhtop " VERSION " aborting. Unsupported platform.\n");
#endif
abort();
}
static void CRT_handleSIGTERM(int sgn) {
(void) sgn;
CRT_done();
exit(0);
}
/* private property */
int CRT_colors[LAST_COLORELEMENT];
// TODO: pass an instance of Settings instead.
@ -167,7 +122,7 @@ void CRT_init(int delay, int colorScheme) {
noecho();
CRT_delay = delay;
CRT_colorScheme = colorScheme;
halfdelay(CRT_delay/2);
halfdelay(CRT_delay);
nonl();
intrflush(stdscr, false);
keypad(stdscr, true);
@ -178,16 +133,10 @@ void CRT_init(int delay, int colorScheme) {
} else {
CRT_hasColors = false;
}
CRT_termType = getenv("TERM");
if (String_eq(CRT_termType, "linux"))
CRT_scrollHAmount = 20;
else
CRT_scrollHAmount = 5;
if (String_eq(CRT_termType, "xterm") || String_eq(CRT_termType, "xterm-color") || String_eq(CRT_termType, "vt220")) {
char* termType = getenv("TERM");
if (String_eq(termType, "xterm") || String_eq(termType, "xterm-color") || String_eq(termType, "vt220")) {
define_key("\033[H", KEY_HOME);
define_key("\033[F", KEY_END);
define_key("\033[7~", KEY_HOME);
define_key("\033[8~", KEY_END);
define_key("\033OP", KEY_F(1));
define_key("\033OQ", KEY_F(2));
define_key("\033OR", KEY_F(3));
@ -215,19 +164,11 @@ void CRT_done() {
endwin();
}
void CRT_fatalError(const char* note) {
char* sysMsg = strerror(errno);
CRT_done();
fprintf(stderr, "%s: %s\n", note, sysMsg);
exit(2);
}
int CRT_readKey() {
nocbreak();
cbreak();
nodelay(stdscr, FALSE);
int ret = getch();
halfdelay(CRT_delay/2);
halfdelay(CRT_delay);
return ret;
}
@ -238,7 +179,18 @@ void CRT_disableDelay() {
}
void CRT_enableDelay() {
halfdelay(CRT_delay/2);
halfdelay(CRT_delay);
}
void CRT_handleSIGSEGV(int signal) {
CRT_done();
fprintf(stderr, "Aborted. Please report bug at http://htop.sf.net");
exit(1);
}
void CRT_handleSIGTERM(int signal) {
CRT_done();
exit(0);
}
void CRT_setColors(int colorScheme) {
@ -260,11 +212,10 @@ void CRT_setColors(int colorScheme) {
CRT_colors[FUNCTION_KEY] = A_NORMAL;
CRT_colors[PANEL_HEADER_FOCUS] = A_REVERSE;
CRT_colors[PANEL_HEADER_UNFOCUS] = A_REVERSE;
CRT_colors[PANEL_HIGHLIGHT_FOCUS] = A_REVERSE;
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD;
CRT_colors[PANEL_HIGHLIGHT_FOCUS] = A_REVERSE | A_BOLD;
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_REVERSE;
CRT_colors[FAILED_SEARCH] = A_REVERSE | A_BOLD;
CRT_colors[UPTIME] = A_BOLD;
CRT_colors[BATTERY] = A_BOLD;
CRT_colors[LARGE_NUMBER] = A_BOLD;
CRT_colors[METER_TEXT] = A_NORMAL;
CRT_colors[METER_VALUE] = A_BOLD;
@ -279,8 +230,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_R_STATE] = A_BOLD;
CRT_colors[PROCESS_HIGH_PRIORITY] = A_BOLD;
CRT_colors[PROCESS_LOW_PRIORITY] = A_DIM;
CRT_colors[PROCESS_THREAD] = A_BOLD;
CRT_colors[PROCESS_THREAD_BASENAME] = A_REVERSE;
CRT_colors[BAR_BORDER] = A_BOLD;
CRT_colors[BAR_SHADOW] = A_DIM;
CRT_colors[SWAP] = A_BOLD;
@ -295,27 +244,19 @@ void CRT_setColors(int colorScheme) {
CRT_colors[GRAPH_9] = A_DIM;
CRT_colors[MEMORY_USED] = A_BOLD;
CRT_colors[MEMORY_BUFFERS] = A_NORMAL;
CRT_colors[MEMORY_BUFFERS_TEXT] = A_NORMAL;
CRT_colors[MEMORY_CACHE] = A_NORMAL;
CRT_colors[LOAD_AVERAGE_FIFTEEN] = A_DIM;
CRT_colors[LOAD_AVERAGE_FIVE] = A_NORMAL;
CRT_colors[LOAD_AVERAGE_ONE] = A_BOLD;
CRT_colors[LOAD] = A_BOLD;
CRT_colors[HELP_BOLD] = A_BOLD;
CRT_colors[CPU_NICE] = A_NORMAL;
CRT_colors[CPU_NORMAL] = A_BOLD;
CRT_colors[CPU_KERNEL] = A_BOLD;
CRT_colors[CLOCK] = A_BOLD;
CRT_colors[CHECK_BOX] = A_BOLD;
CRT_colors[CHECK_MARK] = A_NORMAL;
CRT_colors[CHECK_TEXT] = A_NORMAL;
CRT_colors[HOSTNAME] = A_BOLD;
CRT_colors[CPU_NICE] = A_NORMAL;
CRT_colors[CPU_NICE_TEXT] = A_NORMAL;
CRT_colors[CPU_NORMAL] = A_BOLD;
CRT_colors[CPU_KERNEL] = A_BOLD;
CRT_colors[CPU_IOWAIT] = A_NORMAL;
CRT_colors[CPU_IRQ] = A_BOLD;
CRT_colors[CPU_SOFTIRQ] = A_BOLD;
CRT_colors[CPU_STEAL] = A_REVERSE;
CRT_colors[CPU_GUEST] = A_REVERSE;
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE) {
CRT_colors[RESET_COLOR] = ColorPair(Black,White);
CRT_colors[DEFAULT_COLOR] = ColorPair(Black,White);
@ -327,7 +268,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,White);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = ColorPair(Yellow,White);
CRT_colors[BATTERY] = ColorPair(Yellow,White);
CRT_colors[LARGE_NUMBER] = ColorPair(Red,White);
CRT_colors[METER_TEXT] = ColorPair(Blue,White);
CRT_colors[METER_VALUE] = ColorPair(Black,White);
@ -337,13 +277,11 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_SHADOW] = A_BOLD | ColorPair(Black,White);
CRT_colors[PROCESS_TAG] = ColorPair(White,Blue);
CRT_colors[PROCESS_MEGABYTES] = ColorPair(Blue,White);
CRT_colors[PROCESS_BASENAME] = ColorPair(Blue,White);
CRT_colors[PROCESS_TREE] = ColorPair(Green,White);
CRT_colors[PROCESS_BASENAME] = ColorPair(Green,White);
CRT_colors[PROCESS_TREE] = ColorPair(Blue,White);
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,White);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,White);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,White);
CRT_colors[PROCESS_THREAD] = ColorPair(Blue,White);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,White);
CRT_colors[BAR_BORDER] = ColorPair(Blue,White);
CRT_colors[BAR_SHADOW] = ColorPair(Black,White);
CRT_colors[SWAP] = ColorPair(Red,White);
@ -358,27 +296,19 @@ void CRT_setColors(int colorScheme) {
CRT_colors[GRAPH_9] = ColorPair(Yellow,White);
CRT_colors[MEMORY_USED] = ColorPair(Green,White);
CRT_colors[MEMORY_BUFFERS] = ColorPair(Cyan,White);
CRT_colors[MEMORY_BUFFERS_TEXT] = ColorPair(Cyan,White);
CRT_colors[MEMORY_CACHE] = ColorPair(Yellow,White);
CRT_colors[LOAD_AVERAGE_FIFTEEN] = ColorPair(Black,White);
CRT_colors[LOAD_AVERAGE_FIVE] = ColorPair(Black,White);
CRT_colors[LOAD_AVERAGE_ONE] = ColorPair(Black,White);
CRT_colors[LOAD] = ColorPair(Black,White);
CRT_colors[HELP_BOLD] = ColorPair(Blue,White);
CRT_colors[CLOCK] = ColorPair(Black,White);
CRT_colors[CPU_NICE] = ColorPair(Cyan,White);
CRT_colors[CPU_NORMAL] = ColorPair(Green,White);
CRT_colors[CPU_KERNEL] = ColorPair(Red,White);
CRT_colors[CLOCK] = ColorPair(White,White);
CRT_colors[CHECK_BOX] = ColorPair(Blue,White);
CRT_colors[CHECK_MARK] = ColorPair(Black,White);
CRT_colors[CHECK_TEXT] = ColorPair(Black,White);
CRT_colors[HOSTNAME] = ColorPair(Black,White);
CRT_colors[CPU_NICE] = ColorPair(Cyan,White);
CRT_colors[CPU_NICE_TEXT] = ColorPair(Cyan,White);
CRT_colors[CPU_NORMAL] = ColorPair(Green,White);
CRT_colors[CPU_KERNEL] = ColorPair(Red,White);
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, White);
CRT_colors[CPU_IRQ] = ColorPair(Blue,White);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,White);
CRT_colors[CPU_STEAL] = ColorPair(Cyan,White);
CRT_colors[CPU_GUEST] = ColorPair(Cyan,White);
} else if (CRT_colorScheme == COLORSCHEME_BLACKONWHITE2) {
CRT_colors[RESET_COLOR] = ColorPair(Black,Black);
CRT_colors[DEFAULT_COLOR] = ColorPair(Black,Black);
@ -390,7 +320,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Blue,Black);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = ColorPair(Yellow,Black);
CRT_colors[BATTERY] = ColorPair(Yellow,Black);
CRT_colors[LARGE_NUMBER] = ColorPair(Red,Black);
CRT_colors[METER_TEXT] = ColorPair(Blue,Black);
CRT_colors[METER_VALUE] = ColorPair(Black,Black);
@ -405,8 +334,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_THREAD] = ColorPair(Blue,Black);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[BAR_BORDER] = ColorPair(Blue,Black);
CRT_colors[BAR_SHADOW] = ColorPair(Black,Black);
CRT_colors[SWAP] = ColorPair(Red,Black);
@ -421,27 +348,19 @@ void CRT_setColors(int colorScheme) {
CRT_colors[GRAPH_9] = ColorPair(Yellow,Black);
CRT_colors[MEMORY_USED] = ColorPair(Green,Black);
CRT_colors[MEMORY_BUFFERS] = ColorPair(Cyan,Black);
CRT_colors[MEMORY_BUFFERS_TEXT] = ColorPair(Cyan,Black);
CRT_colors[MEMORY_CACHE] = ColorPair(Yellow,Black);
CRT_colors[LOAD_AVERAGE_FIFTEEN] = ColorPair(Black,Black);
CRT_colors[LOAD_AVERAGE_FIVE] = ColorPair(Black,Black);
CRT_colors[LOAD_AVERAGE_ONE] = ColorPair(Black,Black);
CRT_colors[LOAD] = ColorPair(White,Black);
CRT_colors[HELP_BOLD] = ColorPair(Blue,Black);
CRT_colors[CPU_NICE] = ColorPair(Cyan,Black);
CRT_colors[CPU_NORMAL] = ColorPair(Green,Black);
CRT_colors[CPU_KERNEL] = ColorPair(Red,Black);
CRT_colors[CLOCK] = ColorPair(White,Black);
CRT_colors[CHECK_BOX] = ColorPair(Blue,Black);
CRT_colors[CHECK_MARK] = ColorPair(Black,Black);
CRT_colors[CHECK_TEXT] = ColorPair(Black,Black);
CRT_colors[HOSTNAME] = ColorPair(White,Black);
CRT_colors[CPU_NICE] = ColorPair(Cyan,Black);
CRT_colors[CPU_NICE_TEXT] = ColorPair(Cyan,Black);
CRT_colors[CPU_NORMAL] = ColorPair(Green,Black);
CRT_colors[CPU_KERNEL] = ColorPair(Red,Black);
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black);
CRT_colors[CPU_STEAL] = ColorPair(Black,Black);
CRT_colors[CPU_GUEST] = ColorPair(Black,Black);
} else if (CRT_colorScheme == COLORSCHEME_MIDNIGHT) {
CRT_colors[RESET_COLOR] = ColorPair(White,Blue);
CRT_colors[DEFAULT_COLOR] = ColorPair(White,Blue);
@ -453,7 +372,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[BATTERY] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Blue);
CRT_colors[METER_TEXT] = ColorPair(Cyan,Blue);
CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Blue);
@ -468,8 +386,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Blue);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Blue);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Blue);
CRT_colors[PROCESS_THREAD] = ColorPair(Green,Blue);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green,Blue);
CRT_colors[BAR_BORDER] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[BAR_SHADOW] = ColorPair(Cyan,Blue);
CRT_colors[SWAP] = ColorPair(Red,Blue);
@ -484,27 +400,19 @@ void CRT_setColors(int colorScheme) {
CRT_colors[GRAPH_9] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[MEMORY_USED] = A_BOLD | ColorPair(Green,Blue);
CRT_colors[MEMORY_BUFFERS] = A_BOLD | ColorPair(Cyan,Blue);
CRT_colors[MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Cyan,Blue);
CRT_colors[MEMORY_CACHE] = A_BOLD | ColorPair(Yellow,Blue);
CRT_colors[LOAD_AVERAGE_FIFTEEN] = A_BOLD | ColorPair(Black,Blue);
CRT_colors[LOAD_AVERAGE_FIVE] = A_NORMAL | ColorPair(White,Blue);
CRT_colors[LOAD_AVERAGE_ONE] = A_BOLD | ColorPair(White,Blue);
CRT_colors[LOAD] = A_BOLD | ColorPair(White,Blue);
CRT_colors[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Blue);
CRT_colors[CPU_NICE] = A_BOLD | ColorPair(Cyan,Blue);
CRT_colors[CPU_NORMAL] = A_BOLD | ColorPair(Green,Blue);
CRT_colors[CPU_KERNEL] = A_BOLD | ColorPair(Red,Blue);
CRT_colors[CLOCK] = ColorPair(White,Blue);
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[HOSTNAME] = ColorPair(White,Blue);
CRT_colors[CPU_NICE] = A_BOLD | ColorPair(Cyan,Blue);
CRT_colors[CPU_NICE_TEXT] = A_BOLD | ColorPair(Cyan,Blue);
CRT_colors[CPU_NORMAL] = A_BOLD | ColorPair(Green,Blue);
CRT_colors[CPU_KERNEL] = A_BOLD | ColorPair(Red,Blue);
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Blue,Blue);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Black,Blue);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Black,Blue);
CRT_colors[CPU_STEAL] = ColorPair(White,Blue);
CRT_colors[CPU_GUEST] = ColorPair(White,Blue);
} else if (CRT_colorScheme == COLORSCHEME_BLACKNIGHT) {
CRT_colors[RESET_COLOR] = ColorPair(Cyan,Black);
CRT_colors[DEFAULT_COLOR] = ColorPair(Cyan,Black);
@ -516,7 +424,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = ColorPair(Green,Black);
CRT_colors[BATTERY] = ColorPair(Green,Black);
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black);
CRT_colors[METER_TEXT] = ColorPair(Cyan,Black);
CRT_colors[METER_VALUE] = ColorPair(Green,Black);
@ -528,8 +435,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_MEGABYTES] = A_BOLD | ColorPair(Green,Black);
CRT_colors[PROCESS_BASENAME] = A_BOLD | ColorPair(Green,Black);
CRT_colors[PROCESS_TREE] = ColorPair(Cyan,Black);
CRT_colors[PROCESS_THREAD] = ColorPair(Green,Black);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
@ -547,27 +452,19 @@ void CRT_setColors(int colorScheme) {
CRT_colors[GRAPH_9] = A_BOLD | ColorPair(Black,Black);
CRT_colors[MEMORY_USED] = ColorPair(Green,Black);
CRT_colors[MEMORY_BUFFERS] = ColorPair(Blue,Black);
CRT_colors[MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[MEMORY_CACHE] = ColorPair(Yellow,Black);
CRT_colors[LOAD_AVERAGE_FIFTEEN] = ColorPair(Green,Black);
CRT_colors[LOAD_AVERAGE_FIVE] = ColorPair(Green,Black);
CRT_colors[LOAD_AVERAGE_ONE] = A_BOLD | ColorPair(Green,Black);
CRT_colors[LOAD] = A_BOLD;
CRT_colors[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black);
CRT_colors[CLOCK] = ColorPair(Green,Black);
CRT_colors[CPU_NICE] = ColorPair(Blue,Black);
CRT_colors[CPU_NORMAL] = ColorPair(Green,Black);
CRT_colors[CPU_KERNEL] = ColorPair(Red,Black);
CRT_colors[CLOCK] = A_BOLD;
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[HOSTNAME] = ColorPair(Green,Black);
CRT_colors[CPU_NICE] = ColorPair(Blue,Black);
CRT_colors[CPU_NICE_TEXT] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_NORMAL] = ColorPair(Green,Black);
CRT_colors[CPU_KERNEL] = ColorPair(Red,Black);
CRT_colors[CPU_IOWAIT] = ColorPair(Yellow,Black);
CRT_colors[CPU_IRQ] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Blue,Black);
CRT_colors[CPU_STEAL] = ColorPair(Cyan,Black);
CRT_colors[CPU_GUEST] = ColorPair(Cyan,Black);
} else {
/* Default */
CRT_colors[RESET_COLOR] = ColorPair(White,Black);
@ -580,7 +477,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PANEL_HIGHLIGHT_UNFOCUS] = ColorPair(Black,White);
CRT_colors[FAILED_SEARCH] = ColorPair(Red,Cyan);
CRT_colors[UPTIME] = A_BOLD | ColorPair(Cyan,Black);
CRT_colors[BATTERY] = A_BOLD | ColorPair(Cyan,Black);
CRT_colors[LARGE_NUMBER] = A_BOLD | ColorPair(Red,Black);
CRT_colors[METER_TEXT] = ColorPair(Cyan,Black);
CRT_colors[METER_VALUE] = A_BOLD | ColorPair(Cyan,Black);
@ -595,8 +491,6 @@ void CRT_setColors(int colorScheme) {
CRT_colors[PROCESS_R_STATE] = ColorPair(Green,Black);
CRT_colors[PROCESS_HIGH_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_LOW_PRIORITY] = ColorPair(Red,Black);
CRT_colors[PROCESS_THREAD] = ColorPair(Green,Black);
CRT_colors[PROCESS_THREAD_BASENAME] = A_BOLD | ColorPair(Green,Black);
CRT_colors[BAR_BORDER] = A_BOLD;
CRT_colors[BAR_SHADOW] = A_BOLD | ColorPair(Black,Black);
CRT_colors[SWAP] = ColorPair(Red,Black);
@ -611,26 +505,18 @@ void CRT_setColors(int colorScheme) {
CRT_colors[GRAPH_9] = A_BOLD | ColorPair(Black,Black);
CRT_colors[MEMORY_USED] = ColorPair(Green,Black);
CRT_colors[MEMORY_BUFFERS] = ColorPair(Blue,Black);
CRT_colors[MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[MEMORY_CACHE] = ColorPair(Yellow,Black);
CRT_colors[LOAD_AVERAGE_FIFTEEN] = A_BOLD | ColorPair(Black,Black);
CRT_colors[LOAD_AVERAGE_FIVE] = A_NORMAL;
CRT_colors[LOAD_AVERAGE_ONE] = A_BOLD;
CRT_colors[LOAD] = A_BOLD;
CRT_colors[HELP_BOLD] = A_BOLD | ColorPair(Cyan,Black);
CRT_colors[CPU_NICE] = ColorPair(Blue,Black);
CRT_colors[CPU_NORMAL] = ColorPair(Green,Black);
CRT_colors[CPU_KERNEL] = ColorPair(Red,Black);
CRT_colors[CLOCK] = A_BOLD;
CRT_colors[CHECK_BOX] = ColorPair(Cyan,Black);
CRT_colors[CHECK_MARK] = A_BOLD;
CRT_colors[CHECK_TEXT] = A_NORMAL;
CRT_colors[HOSTNAME] = A_BOLD;
CRT_colors[CPU_NICE] = ColorPair(Blue,Black);
CRT_colors[CPU_NICE_TEXT] = A_BOLD | ColorPair(Blue,Black);
CRT_colors[CPU_NORMAL] = ColorPair(Green,Black);
CRT_colors[CPU_KERNEL] = ColorPair(Red,Black);
CRT_colors[CPU_IOWAIT] = A_BOLD | ColorPair(Black, Black);
CRT_colors[CPU_IRQ] = ColorPair(Yellow,Black);
CRT_colors[CPU_SOFTIRQ] = ColorPair(Magenta,Black);
CRT_colors[CPU_STEAL] = ColorPair(Cyan,Black);
CRT_colors[CPU_GUEST] = ColorPair(Cyan,Black);
}
}

72
CRT.h
View File

@ -1,18 +1,23 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_CRT
#define HEADER_CRT
/*
htop - CRT.h
(C) 2004-2011 Hisham H. Muhammad
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#ifdef HAVE_EXECINFO_H
#endif
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
#include <curses.h>
#include <signal.h>
#include <stdlib.h>
#include <stdbool.h>
#include "String.h"
#include "debug.h"
#define COLORSCHEME_DEFAULT 0
#define COLORSCHEME_MONOCHROME 1
@ -21,18 +26,10 @@ 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
#include <stdbool.h>
bool CRT_hasColors;
typedef enum ColorElements_ {
RESET_COLOR,
@ -49,7 +46,7 @@ typedef enum ColorElements_ {
METER_VALUE,
LED_COLOR,
UPTIME,
BATTERY,
TASKS_TOTAL,
TASKS_RUNNING,
SWAP,
PROCESS,
@ -61,8 +58,6 @@ typedef enum ColorElements_ {
PROCESS_BASENAME,
PROCESS_HIGH_PRIORITY,
PROCESS_LOW_PRIORITY,
PROCESS_THREAD,
PROCESS_THREAD_BASENAME,
BAR_BORDER,
BAR_SHADOW,
GRAPH_1,
@ -76,7 +71,6 @@ typedef enum ColorElements_ {
GRAPH_9,
MEMORY_USED,
MEMORY_BUFFERS,
MEMORY_BUFFERS_TEXT,
MEMORY_CACHE,
LOAD,
LOAD_AVERAGE_FIFTEEN,
@ -86,53 +80,33 @@ typedef enum ColorElements_ {
CHECK_MARK,
CHECK_TEXT,
CLOCK,
HELP_BOLD,
HOSTNAME,
CPU_NICE,
CPU_NICE_TEXT,
CPU_NORMAL,
CPU_KERNEL,
CPU_IOWAIT,
CPU_IRQ,
CPU_SOFTIRQ,
CPU_STEAL,
CPU_GUEST,
HELP_BOLD,
LAST_COLORELEMENT
} ColorElements;
void CRT_fatalError(const char* note) __attribute__ ((noreturn));
// TODO: centralize these in Settings.
extern int CRT_colors[LAST_COLORELEMENT];
extern int CRT_colorScheme;
extern bool CRT_utf8;
extern int CRT_delay;
extern int CRT_colors[LAST_COLORELEMENT];
extern int CRT_cursorX;
extern int CRT_scrollHAmount;
char* CRT_termType;
void *backtraceArray[128];
// TODO: pass an instance of Settings instead.
void CRT_init(int delay, int colorScheme);
void CRT_init();
void CRT_done();
void CRT_fatalError(const char* note);
int CRT_readKey();
void CRT_disableDelay();
void CRT_handleSIGSEGV(int signal);
void CRT_enableDelay();
void CRT_handleSIGTERM(int signal);
void CRT_setColors(int colorScheme);
void CRT_enableDelay();
void CRT_disableDelay();
#endif

134
CategoriesListBox.c Normal file
View File

@ -0,0 +1,134 @@
#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);
}

40
CategoriesListBox.h Normal file
View File

@ -0,0 +1,40 @@
/* 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

View File

@ -1,156 +0,0 @@
/*
htop - CategoriesPanel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "CategoriesPanel.h"
#include "AvailableMetersPanel.h"
#include "MetersPanel.h"
#include "DisplayOptionsPanel.h"
#include "ColumnsPanel.h"
#include "ColorsPanel.h"
#include "AvailableColumnsPanel.h"
#include <assert.h>
#include <stdlib.h>
/*{
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct CategoriesPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} CategoriesPanel;
}*/
static const char* MetersFunctions[] = {" ", " ", " ", "Type ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done ", NULL};
static const char* AvailableMetersFunctions[] = {" ", " ", " ", " ", "Add L ", "Add R ", " ", " ", " ", "Done ", NULL};
static const char* DisplayOptionsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL};
static const char* ColumnsFunctions[] = {" ", " ", " ", " ", " ", " ", "MoveUp", "MoveDn", "Remove", "Done ", NULL};
static const char* ColorsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL};
static const char* AvailableColumnsFunctions[] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done ", NULL};
static void CategoriesPanel_delete(Object* object) {
Panel* super = (Panel*) object;
CategoriesPanel* this = (CategoriesPanel*) object;
Panel_done(super);
free(this);
}
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(MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, rightMeters, FunctionBar_new(MetersFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableMeters, FunctionBar_new(AvailableMetersFunctions, NULL, NULL), -1);
}
static void CategoriesPanel_makeDisplayOptionsPage(CategoriesPanel* this) {
Panel* displayOptions = (Panel*) DisplayOptionsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, displayOptions, FunctionBar_new(DisplayOptionsFunctions, NULL, NULL), -1);
}
static void CategoriesPanel_makeColorsPage(CategoriesPanel* this) {
Panel* colors = (Panel*) ColorsPanel_new(this->settings, this->scr);
ScreenManager_add(this->scr, colors, FunctionBar_new(ColorsFunctions, NULL, NULL), -1);
}
static 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(ColumnsFunctions, NULL, NULL), 20);
ScreenManager_add(this->scr, availableColumns, FunctionBar_new(AvailableColumnsFunctions, NULL, NULL), -1);
}
static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
CategoriesPanel* this = (CategoriesPanel*) super;
HandlerResult result = IGNORED;
int selected = Panel_getSelectedIndex(super);
switch (ch) {
case EVENT_SETSELECTED:
result = HANDLED;
break;
case KEY_UP:
case KEY_CTRLP:
case KEY_DOWN:
case KEY_CTRLN:
case KEY_NPAGE:
case KEY_PPAGE:
case KEY_HOME:
case KEY_END: {
int previous = selected;
Panel_onKey(super, ch);
selected = Panel_getSelectedIndex(super);
if (previous != selected)
result = HANDLED;
break;
}
default:
if (isalpha(ch))
result = Panel_selectByTyping(super, ch);
if (result == BREAK_LOOP)
result = IGNORED;
break;
}
if (result == HANDLED) {
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;
}
}
return result;
}
PanelClass CategoriesPanel_class = {
.super = {
.extends = Class(Panel),
.delete = CategoriesPanel_delete
},
.eventHandler = CategoriesPanel_eventHandler
};
CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr) {
CategoriesPanel* this = AllocThis(CategoriesPanel);
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
this->settings = settings;
this->scr = scr;
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;
}

View File

@ -1,30 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_CategoriesPanel
#define HEADER_CategoriesPanel
/*
htop - CategoriesPanel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct CategoriesPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} CategoriesPanel;
void CategoriesPanel_makeMetersPage(CategoriesPanel* this);
extern PanelClass CategoriesPanel_class;
CategoriesPanel* CategoriesPanel_new(Settings* settings, ScreenManager* scr);
#endif

234
ChangeLog
View File

@ -1,236 +1,4 @@
What's new in version 1.0.3
* Tag all children ('c' key)
* Fixes in accounting of guest time when using virtualization
(thanks to Patrick Marlier)
* Performance improvements
(thanks to Jann Horn)
* Further performance improvements due to conditional parsing
of IO data depending on selected fields.
* Better consistency in coloring.
* Increase limit of buffer when tracing a deep nested process tree.
* Display pagefault stats.
* BUGFIX: Fix crash when adding meters and toggling detailed CPU time.
(thanks to Dawid Gajownik)
* Add column to track the OOM-killer score of processes
(thanks to Leigh Simpson)
What's new in version 1.0.2
* Add IO priority support ('i' key)
* Avoid deleting .htoprc if it is a symlink
* Fail gracefully when /proc is not mounted
(thanks to Philipp Hagemeister)
* Option to update process names on every refresh
(thanks to Rob Hoelz)
* BUGFIX: Fix crashes when process list is empty
What's new in version 1.0.1
* Move .htoprc to XDG-compliant path ~/.config/htop/htoprc,
respecting $XDG_CONFIG_HOME
(thanks to Hadzhimurad Ustarkhan for the suggestion.)
* Safer behavior on the kill screen, to make it harder to kill the wrong process.
* Fix for building in FreeBSD 8.2
(thanks to Trond Endrestol)
* BUGFIX: behavior of 'F' (follow) key was broken, also affecting the
persistence of mouse selections.
* BUGFIX: keep main panel up-to-date when running the screen manager,
to fix crash when processes die while on the F9/Kill screen.
What's new in version 1.0
* Performance improvements
* Support for splitting CPU meters into two or four columns
(thanks to Wim Heirman)
* Switch from PLPA, which is now deprecated, to HWLOC.
* Bring back support for native Linux sched_setaffinity,
so we don't have to use HWLOC where we don't need to.
* Support for typing in user names and column fields in selection panels.
* Support for UTF-8 tree drawing
(thanks to Bin Guo)
* Option for counting CPUs from zero
(thanks to Sean Noonan)
* Meters update in every screen (no longer halting while on Setup, etc.)
* Stricter checks for command-line options
(thanks to Sebastian Pipping)
* Incremental filtering
(thanks to Seth Heeren for the idea and initial implementation)
* Try harder to find the ncurses header
(thanks to Moritz Barsnick)
* Man page updates
(thanks to Vincent Launchbury)
* BUGFIX: Support larger numbers for process times.
(thanks to Tristan Nakagawa for the report.)
* BUGFIX: Segfault in BarMeterMode_draw() for small terminal widths
(patch by Sebastian Pipping)
What's new in version 0.9
* Add support for "steal"/guest CPU time measurement
in virtualization environments
* Expand and collapse subtrees using '+' and '-' when in tree-view
* Support for cgroups
(thanks to Guillaume Zitta and Daniel Lezcano)
* Show custom thread names
(thanks to Anders Torger)
* Add support for STARTTIME field
* Upgrade PLPA to version 1.3.2
* Fix license terms with regard to PLPA
(thanks to Tom Callaway)
* getopt-based long options and --no-color
(thanks to Vincent Launchbury)
* BUGFIX: Fix display of nan% in CPU meters
(thanks to Steven Hampson)
* BUGFIX: Fix memory leak
(thanks to Pavol Rusnak)
* Add Bash/emacs style navigation keys
(thanks to Daniel Schuler)
* Improve battery meter support
(thanks to Richard W.)
* BUGFIX: Fix IO-wait color in "Black on White" scheme
* BUGFIX: Fix search by process name when list is filtered by user.
(thanks to Sergej Pupykin for the report.)
* BUGFIX: Fix alignment for display of memory values above 100G (sign of the times!)
(thanks to Jan van Haarst for the report.)
What's new in version 0.8.3
* BUGFIX: Fix crash on F6 key
(thanks to Rainer Suhm)
* BUGFIX: Fix a minor bug which affected the build process.
What's new in version 0.8.2
* Integrated lsof (press 'l')
* Fix display of gigabyte-sized values
(thanks to Andika Triwidada)
* Option to display hostname in the meters area
* Rename VEID to CTID in OpenVZ systems
(thanks to Thorsten Schifferdecker)
* Corrections to the desktop entry file
(thanks by Samuli Suominen)
* BUGFIX: Correct page size calculation for FreeBSD systems
(thanks to Andrew Paulsen)
* Allow compilation without PLPA on systems that don't support it
(thanks to Timothy Redaelli)
* BUGFIX: Fix missing tree view when userland threads are hidden
(thanks to Josh Stone)
* BUGFIX: Fix for VPID on OpenVZ systems
(thanks to Wolfgang Frisch)
What's new in version 0.8.1
* Linux-VServer support
(thanks to Jonathan Sambrook and Benedikt Bohm)
* Battery meter
(thanks to Ian Page Hands)
* BUGFIX: Fix collection of IO stats in multithreaded processes
(thanks to Gerhard Heift)
* Remove assertion that fails on hardened kernels
(thanks to Wolfram Schlich for the report)
What's new in version 0.8
* Ability to change sort column with the mouse by
clicking column titles (click again to invert order)
* Add support for Linux per-process IO statistics,
enabled with the --enable-taskstats flag, which
requires a kernel compiled with taskstats support.
(thanks to Tobias Oetiker)
* Add Unicode support, enabled with the --enable-unicode
flag, which requires libncursesw.
(thanks to Sergej Pupykin)
* BUGFIX: Fix display of CPU count for threaded processes.
When user threads are hidden, process now shows the
sum of processor usage for all processors. When user
threads are displayed, each thread shows its own
processor usage, including the root thread.
(thanks to Bert Wesarg for the report)
* BUGFIX: avoid crashing when using many meters
(thanks to David Cho for the report)
What's new in version 0.7
* CPU affinity configuration ('a' key)
* Improve display of tree view, properly nesting
threads of the same app based on TGID.
* IO-wait time now counts as idle time, which is a more
accurate description. It is still available in
split time, now called detailed CPU time.
(thanks to Samuel Thibault for the report)
* BUGFIX: Correct display of TPGID field
* Add TGID field
* BUGFIX: Don't crash with invalid command-line flags
(thanks to Nico Golde for the report)
* Fix GCC 4.3 compilation issues
(thanks to Martin Michlmayr for the report)
* OpenVZ support, enabled at compile-time with
the --enable-openvz flag.
(thanks to Sergey Lychko)
What's new in version 0.6.6
* Add support of NLWP field
(thanks to Bert Wesarg)
* BUGFIX: Fix use of configurable /proc location
(thanks to Florent Thoumie)
* Fix memory percentage calculation and make it saner
(thanks to Olev Kartau for the report)
* Added display of DRS, DT, LRS and TRS
(thanks to Matthias Lederhofer)
* BUGFIX: LRS and DRS memory values were flipped
(thanks to Matthias Lederhofer)
* BUGFIX: Don't crash on very high UIDs
(thanks to Egmont Koblinger)
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
@ -369,7 +137,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 Panel widget
* BUGFIX: internal fixes on ListBox widget
* Clear the bottom line when exiting
* Press "F3" during search to walk through the results
* Improved navigation on column configuration screen

View File

@ -1,30 +1,41 @@
/*
htop - CheckItem.c
(C) 2004-2011 Hisham H. Muhammad
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 "CheckItem.h"
#include "Object.h"
#include "CRT.h"
#include <assert.h>
#include <stdlib.h>
#include "debug.h"
/*{
#include "Object.h"
typedef struct CheckItem_ {
Object super;
char* text;
bool* ref;
bool value;
bool* value;
} CheckItem;
extern char* CHECKITEM_CLASS;
}*/
static void CheckItem_delete(Object* cast) {
/* private property */
char* CHECKITEM_CLASS = "CheckItem";
CheckItem* CheckItem_new(char* text, bool* value) {
CheckItem* this = malloc(sizeof(CheckItem));
((Object*)this)->class = CHECKITEM_CLASS;
((Object*)this)->display = CheckItem_display;
((Object*)this)->delete = CheckItem_delete;
this->text = text;
this->value = value;
return this;
}
void CheckItem_delete(Object* cast) {
CheckItem* this = (CheckItem*)cast;
assert (this != NULL);
@ -32,41 +43,14 @@ static void CheckItem_delete(Object* cast) {
free(this);
}
static void CheckItem_display(Object* cast, RichString* out) {
void CheckItem_display(Object* cast, RichString* out) {
CheckItem* this = (CheckItem*)cast;
assert (this != NULL);
RichString_write(out, CRT_colors[CHECK_BOX], "[");
if (CheckItem_get(this))
if (*(this->value))
RichString_append(out, CRT_colors[CHECK_MARK], "x");
else
RichString_append(out, CRT_colors[CHECK_MARK], " ");
RichString_append(out, CRT_colors[CHECK_BOX], "] ");
RichString_append(out, CRT_colors[CHECK_TEXT], this->text);
}
ObjectClass CheckItem_class = {
.display = CheckItem_display,
.delete = CheckItem_delete
};
CheckItem* CheckItem_new(char* text, bool* ref, bool value) {
CheckItem* this = AllocThis(CheckItem);
this->text = text;
this->value = value;
this->ref = ref;
return this;
}
void CheckItem_set(CheckItem* this, bool value) {
if (this->ref)
*(this->ref) = value;
else
this->value = value;
}
bool CheckItem_get(CheckItem* this) {
if (this->ref)
return *(this->ref);
else
return this->value;
}

View File

@ -1,30 +1,33 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_CheckItem
#define HEADER_CheckItem
/*
htop - CheckItem.h
(C) 2004-2011 Hisham H. Muhammad
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 "CRT.h"
#include "debug.h"
typedef struct CheckItem_ {
Object super;
char* text;
bool* ref;
bool value;
bool* value;
} CheckItem;
extern char* CHECKITEM_CLASS;
extern ObjectClass CheckItem_class;
CheckItem* CheckItem_new(char* text, bool* ref, bool value);
CheckItem* CheckItem_new(char* text, bool* value);
void CheckItem_set(CheckItem* this, bool value);
void CheckItem_delete(Object* cast);
bool CheckItem_get(CheckItem* this);
void CheckItem_display(Object* cast, RichString* out);
#endif

View File

@ -1,42 +1,36 @@
/*
htop - ClockMeter.c
(C) 2004-2011 Hisham H. Muhammad
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 "ClockMeter.h"
#include "CRT.h"
#include "Meter.h"
#include <time.h>
/*{
#include "Meter.h"
}*/
#include "debug.h"
int ClockMeter_attributes[] = {
CLOCK
};
/* private */
static int ClockMeter_attributes[] = { CLOCK };
static void ClockMeter_setValues(Meter* this, char* buffer, int size) {
time_t t = time(NULL);
struct tm result;
struct tm *lt = localtime_r(&t, &result);
this->values[0] = lt->tm_hour * 60 + lt->tm_min;
strftime(buffer, size, "%H:%M:%S", lt);
}
MeterClass ClockMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete
},
/* private */
MeterType ClockMeter = {
.setValues = ClockMeter_setValues,
.defaultMode = TEXT_METERMODE,
.display = NULL,
.mode = TEXT_METERMODE,
.total = 100.0,
.items = 1,
.attributes = ClockMeter_attributes,
.name = "Clock",
.uiName = "Clock",
.caption = "Time: ",
};
void ClockMeter_setValues(Meter* this, char* buffer, int size) {
time_t t = time(NULL);
struct tm *lt = localtime(&t);
this->values[0] = lt->tm_hour * 60 + lt->tm_min;
strftime(buffer, size, "%H:%M:%S", lt);
}

View File

@ -3,16 +3,19 @@
#ifndef HEADER_ClockMeter
#define HEADER_ClockMeter
/*
htop - ClockMeter.h
(C) 2004-2011 Hisham H. Muhammad
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"
extern int ClockMeter_attributes[];
#include <time.h>
extern MeterClass ClockMeter_class;
#include "debug.h"
void ClockMeter_setValues(Meter* this, char* buffer, int size);
#endif

99
ColorsListBox.c Normal file
View File

@ -0,0 +1,99 @@
#include "CRT.h"
#include "ColorsListBox.h"
#include "ListBox.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 ColorsListBox.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;
Settings* settings;
ScreenManager* scr;
bool check[5];
} ColorsListBox;
}*/
/* private */
static char* ColorSchemes[] = {
"Default",
"Monochromatic",
"Black on White",
"Light Terminal",
"MC",
"Black Night",
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;
this->settings = settings;
this->scr = scr;
super->eventHandler = ColorsListBox_EventHandler;
ListBox_setHeader(super, "Colors");
for (int i = 0; ColorSchemes[i] != NULL; i++) {
ListBox_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);
free(this);
}
HandlerResult ColorsListBox_EventHandler(ListBox* super, int ch) {
ColorsListBox* this = (ColorsListBox*) super;
HandlerResult result = IGNORED;
int mark = ListBox_getSelectedIndex(super);
switch(ch) {
case 0x0a:
case 0x0d:
case KEY_ENTER:
case ' ':
for (int i = 0; ColorSchemes[i] != NULL; i++) {
this->check[i] = false;
}
this->check[mark] = true;
this->settings->colorScheme = mark;
result = HANDLED;
}
if (result == HANDLED) {
this->settings->changed = true;
Header* header = this->settings->header;
CRT_setColors(mark);
ListBox* lbMenu = (ListBox*) TypedVector_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]);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
}
return result;
}

32
ColorsListBox.h Normal file
View File

@ -0,0 +1,32 @@
/* 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,108 +0,0 @@
/*
htop - ColorsPanel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "ColorsPanel.h"
#include "CRT.h"
#include "CheckItem.h"
#include <assert.h>
#include <stdlib.h>
#include <string.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
/*{
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct ColorsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} ColorsPanel;
}*/
static const char* ColorSchemes[] = {
"Default",
"Monochromatic",
"Black on White",
"Light Terminal",
"MC",
"Black Night",
NULL
};
static void ColorsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
ColorsPanel* this = (ColorsPanel*) object;
Panel_done(super);
free(this);
}
static HandlerResult ColorsPanel_eventHandler(Panel* super, int ch) {
ColorsPanel* this = (ColorsPanel*) super;
HandlerResult result = IGNORED;
int mark = Panel_getSelectedIndex(super);
switch(ch) {
case 0x0a:
case 0x0d:
case KEY_ENTER:
case KEY_MOUSE:
case ' ':
for (int i = 0; ColorSchemes[i] != NULL; i++)
CheckItem_set((CheckItem*)Panel_get(super, i), false);
CheckItem_set((CheckItem*)Panel_get(super, mark), true);
this->settings->colorScheme = mark;
result = HANDLED;
}
if (result == HANDLED) {
this->settings->changed = true;
Header* header = this->settings->header;
CRT_setColors(mark);
Panel* menu = (Panel*) Vector_get(this->scr->panels, 0);
Header_draw(header);
RichString_setAttr(&(super->header), CRT_colors[PANEL_HEADER_FOCUS]);
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;
}
PanelClass ColorsPanel_class = {
.super = {
.extends = Class(Panel),
.delete = ColorsPanel_delete
},
.eventHandler = ColorsPanel_eventHandler
};
ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr) {
ColorsPanel* this = AllocThis(ColorsPanel);
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, Class(CheckItem), true);
this->settings = settings;
this->scr = scr;
Panel_setHeader(super, "Colors");
for (int i = 0; ColorSchemes[i] != NULL; i++) {
Panel_add(super, (Object*) CheckItem_new(strdup(ColorSchemes[i]), NULL, false));
}
CheckItem_set((CheckItem*)Panel_get(super, settings->colorScheme), true);
return this;
}

View File

@ -1,34 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_ColorsPanel
#define HEADER_ColorsPanel
/*
htop - ColorsPanel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
// 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
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct ColorsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} ColorsPanel;
extern PanelClass ColorsPanel_class;
ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr);
#endif

104
ColumnsListBox.c Normal file
View File

@ -0,0 +1,104 @@
#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;
}

32
ColumnsListBox.h Normal file
View File

@ -0,0 +1,32 @@
/* 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

View File

@ -1,136 +0,0 @@
/*
htop - ColumnsPanel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "ColumnsPanel.h"
#include "String.h"
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
/*{
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct ColumnsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} ColumnsPanel;
}*/
static void ColumnsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
ColumnsPanel* this = (ColumnsPanel*) object;
Panel_done(super);
free(this);
}
static HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch) {
int selected = Panel_getSelectedIndex(super);
HandlerResult result = IGNORED;
int size = Panel_size(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;
}
default:
{
if (isalpha(ch))
result = Panel_selectByTyping(super, ch);
if (result == BREAK_LOOP)
result = IGNORED;
break;
}
}
if (result == HANDLED)
ColumnsPanel_update(super);
return result;
}
PanelClass ColumnsPanel_class = {
.super = {
.extends = Class(Panel),
.delete = ColumnsPanel_delete
},
.eventHandler = ColumnsPanel_eventHandler
};
ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr) {
ColumnsPanel* this = AllocThis(ColumnsPanel);
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
this->settings = settings;
this->scr = scr;
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;
}
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_size(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));
this->settings->pl->flags = 0;
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->flags |= Process_fieldFlags[j];
}
}
this->settings->pl->fields[size] = 0;
}

View File

@ -1,33 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_ColumnsPanel
#define HEADER_ColumnsPanel
/*
htop - ColumnsPanel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct ColumnsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} ColumnsPanel;
extern PanelClass ColumnsPanel_class;
ColumnsPanel* ColumnsPanel_new(Settings* settings, ScreenManager* scr);
int ColumnsPanel_fieldNameToIndex(const char* name);
void ColumnsPanel_update(Panel* super);
#endif

189
DebugMemory.c Normal file
View File

@ -0,0 +1,189 @@
#define _GNU_SOURCE
#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
/*{
typedef struct DebugMemoryItem_ DebugMemoryItem;
struct DebugMemoryItem_ {
void* data;
char* file;
int line;
DebugMemoryItem* next;
};
typedef struct DebugMemory_ {
DebugMemoryItem* first;
int allocations;
int deallocations;
int size;
FILE* file;
} DebugMemory;
}*/
/* private property */
DebugMemory* singleton = NULL;
void DebugMemory_new() {
if (singleton)
return;
singleton = malloc(sizeof(DebugMemory));
singleton->first = NULL;
singleton->allocations = 0;
singleton->deallocations = 0;
singleton->size = 0;
singleton->file = fopen("/tmp/htop-debug-alloc.txt", "w");
}
void* DebugMemory_malloc(int size, char* file, int line) {
void* data = malloc(size);
DebugMemory_registerAllocation(data, file, line);
fprintf(singleton->file, "%d\t%s:%d\n", size, file, line);
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);
return data;
}
void* DebugMemory_realloc(void* ptr, int size, char* file, int line) {
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);
return data;
}
void* DebugMemory_strdup(char* str, char* file, int line) {
char* data = strdup(str);
DebugMemory_registerAllocation(data, file, line);
fprintf(singleton->file, "%d\t%s:%d\n", (int) strlen(str), file, line);
return data;
}
void DebugMemory_free(void* data, char* file, int line) {
DebugMemory_registerDeallocation(data, file, line);
free(data);
}
void DebugMemory_assertSize() {
if (!singleton->first) {
assert (singleton->size == 0);
}
DebugMemoryItem* walk = singleton->first;
int i = 0;
while (walk != NULL) {
i++;
walk = walk->next;
}
assert (i == singleton->size);
}
int DebugMemory_getBlockCount() {
if (!singleton->first) {
return 0;
}
DebugMemoryItem* walk = singleton->first;
int i = 0;
while (walk != NULL) {
i++;
walk = walk->next;
}
return i;
}
void DebugMemory_registerAllocation(void* data, char* file, int line) {
if (!singleton)
DebugMemory_new();
DebugMemory_assertSize();
DebugMemoryItem* item = (DebugMemoryItem*) malloc(sizeof(DebugMemoryItem));
item->data = data;
item->file = file;
item->line = line;
item->next = NULL;
int val = DebugMemory_getBlockCount();
if (singleton->first == NULL) {
assert (val == 0);
singleton->first = item;
} else {
DebugMemoryItem* walk = singleton->first;
while (true) {
if (walk->next == NULL) {
walk->next = item;
break;
}
walk = walk->next;
}
}
int nval = DebugMemory_getBlockCount();
assert(nval == val + 1);
singleton->allocations++;
singleton->size++;
DebugMemory_assertSize();
}
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) {
if (walk->data == data) {
if (prev == NULL) {
singleton->first = walk->next;
} else {
prev->next = walk->next;
}
free(walk);
assert(DebugMemory_getBlockCount() == val - 1);
singleton->deallocations++;
singleton->size--;
DebugMemory_assertSize();
return;
}
DebugMemoryItem* tmp = walk;
walk = walk->next;
prev = tmp;
}
DebugMemory_report();
fprintf(stderr, "Couldn't find allocation for memory freed at %s:%d\n", file, line);
assert(false);
}
void DebugMemory_report() {
assert(singleton);
DebugMemoryItem* walk = singleton->first;
int i = 0;
while (walk != NULL) {
i++;
fprintf(stderr, "%p %s:%d\n", walk->data, walk->file, walk->line);
walk = walk->next;
}
fprintf(stderr, "Total:\n");
fprintf(stderr, "%d allocations\n", singleton->allocations);
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);
}

62
DebugMemory.h Normal file
View File

@ -0,0 +1,62 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_DebugMemory
#define HEADER_DebugMemory
#define _GNU_SOURCE
#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_ {
void* data;
char* file;
int line;
DebugMemoryItem* next;
};
typedef struct DebugMemory_ {
DebugMemoryItem* first;
int allocations;
int deallocations;
int size;
FILE* file;
} DebugMemory;
void DebugMemory_new();
void* DebugMemory_malloc(int size, char* file, int line);
void* DebugMemory_calloc(int a, int b, char* file, int line);
void* DebugMemory_realloc(void* ptr, int size, char* file, int line);
void* DebugMemory_strdup(char* str, char* file, int line);
void DebugMemory_free(void* data, char* file, int line);
void DebugMemory_assertSize();
int DebugMemory_getBlockCount();
void DebugMemory_registerAllocation(void* data, char* file, int line);
void DebugMemory_registerDeallocation(void* data, char* file, int line);
void DebugMemory_report();
#endif

75
DisplayOptionsListBox.c Normal file
View File

@ -0,0 +1,75 @@
#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;
}

31
DisplayOptionsListBox.h Normal file
View File

@ -0,0 +1,31 @@
/* 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

View File

@ -1,95 +0,0 @@
/*
htop - DisplayOptionsPanel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "DisplayOptionsPanel.h"
#include "CheckItem.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
/*{
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct DisplayOptionsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} DisplayOptionsPanel;
}*/
static void DisplayOptionsPanel_delete(Object* object) {
Panel* super = (Panel*) object;
DisplayOptionsPanel* this = (DisplayOptionsPanel*) object;
Panel_done(super);
free(this);
}
static 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 KEY_MOUSE:
case ' ':
CheckItem_set(selected, ! (CheckItem_get(selected)) );
result = HANDLED;
}
if (result == HANDLED) {
this->settings->changed = true;
Header* header = this->settings->header;
Header_calculateHeight(header);
Header_reinit(header);
Header_draw(header);
ScreenManager_resize(this->scr, this->scr->x1, header->height, this->scr->x2, this->scr->y2);
}
return result;
}
PanelClass DisplayOptionsPanel_class = {
.super = {
.extends = Class(Panel),
.delete = DisplayOptionsPanel_delete
},
.eventHandler = DisplayOptionsPanel_eventHandler
};
DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr) {
DisplayOptionsPanel* this = AllocThis(DisplayOptionsPanel);
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, Class(CheckItem), true);
this->settings = settings;
this->scr = scr;
Panel_setHeader(super, "Display options");
Panel_add(super, (Object*) CheckItem_new(strdup("Tree view"), &(settings->pl->treeView), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Shadow other users' processes"), &(settings->pl->shadowOtherUsers), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Hide kernel threads"), &(settings->pl->hideKernelThreads), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Hide userland threads"), &(settings->pl->hideUserlandThreads), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Display threads in a different color"), &(settings->pl->highlightThreads), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Show custom thread names"), &(settings->pl->showThreadNames), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Highlight program \"basename\""), &(settings->pl->highlightBaseName), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Highlight large numbers in memory counters"), &(settings->pl->highlightMegabytes), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Leave a margin around header"), &(settings->header->margin), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Detailed CPU time (System/IO-Wait/Hard-IRQ/Soft-IRQ/Steal/Guest)"), &(settings->pl->detailedCPUTime), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Count CPUs from 0 instead of 1"), &(settings->pl->countCPUsFromZero), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Update process names on every refresh"), &(settings->pl->updateProcessNames), false));
Panel_add(super, (Object*) CheckItem_new(strdup("Add guest time in CPU meter percentage"), &(settings->pl->accountGuestInCPUMeter), false));
return this;
}

View File

@ -1,28 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_DisplayOptionsPanel
#define HEADER_DisplayOptionsPanel
/*
htop - DisplayOptionsPanel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct DisplayOptionsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr;
} DisplayOptionsPanel;
extern PanelClass DisplayOptionsPanel_class;
DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager* scr);
#endif

View File

@ -1,21 +1,23 @@
/*
htop - FunctionBar.c
(C) 2004-2011 Hisham H. Muhammad
(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 "FunctionBar.h"
#include "CRT.h"
#include "debug.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <curses.h>
/*{
#include "Object.h"
typedef struct FunctionBar_ {
Object super;
@ -26,78 +28,78 @@ typedef struct FunctionBar_ {
bool staticData;
} FunctionBar;
extern char* FUNCTIONBAR_CLASS;
}*/
static const char* FunctionBar_FKeys[] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", NULL};
/* private property */
char* FUNCTIONBAR_CLASS = "FunctionBar";
static const char* FunctionBar_FLabels[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " ", NULL};
/* private property */
static char* FunctionBar_FKeys[10] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"};
static int FunctionBar_FEvents[] = {KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10)};
/* private property */
static char* FunctionBar_FLabels[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
ObjectClass FunctionBar_class = {
.delete = FunctionBar_delete
};
/* 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(const char** functions, const char** keys, int* events) {
FunctionBar* this = AllocThis(FunctionBar);
this->functions = calloc(16, sizeof(char*));
if (!functions) {
functions = FunctionBar_FLabels;
}
for (int i = 0; i < 15 && functions[i]; i++) {
this->functions[i] = strdup(functions[i]);
}
FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events) {
FunctionBar* this = malloc(sizeof(FunctionBar));
((Object*) this)->class = FUNCTIONBAR_CLASS;
((Object*) this)->delete = FunctionBar_delete;
this->functions = functions;
this->size = size;
if (keys && events) {
this->staticData = false;
this->keys = malloc(sizeof(char*) * 15);
this->events = malloc(sizeof(int) * 15);
int i = 0;
while (i < 15 && functions[i]) {
this->keys[i] = strdup(keys[i]);
this->functions = malloc(sizeof(char*) * size);
this->keys = malloc(sizeof(char*) * size);
this->events = malloc(sizeof(int) * size);
for (int i = 0; i < size; i++) {
this->functions[i] = String_copy(functions[i]);
this->keys[i] = String_copy(keys[i]);
this->events[i] = events[i];
i++;
}
this->size = i;
} else {
this->staticData = true;
this->keys = (char**) FunctionBar_FKeys;
this->functions = functions ? functions : FunctionBar_FLabels;
this->keys = FunctionBar_FKeys;
this->events = FunctionBar_FEvents;
this->size = 10;
assert((!functions) || this->size == 10);
}
return this;
}
void FunctionBar_delete(Object* cast) {
FunctionBar* this = (FunctionBar*) cast;
for (int i = 0; i < 15 && this->functions[i]; i++) {
free(this->functions[i]);
}
free(this->functions);
if (!this->staticData) {
for (int i = 0; i < this->size; i++) {
free(this->functions[i]);
free(this->keys[i]);
}
free(this->functions);
free(this->keys);
free(this->events);
}
free(this);
}
void FunctionBar_setLabel(FunctionBar* this, int event, const char* text) {
void FunctionBar_setLabel(FunctionBar* this, int event, char* text) {
assert(!this->staticData);
for (int i = 0; i < this->size; i++) {
if (this->events[i] == event) {
free(this->functions[i]);
this->functions[i] = strdup(text);
this->functions[i] = String_copy(text);
break;
}
}
}
void FunctionBar_draw(const FunctionBar* this, char* buffer) {
void FunctionBar_draw(FunctionBar* this, char* buffer) {
FunctionBar_drawAttr(this, buffer, CRT_colors[FUNCTION_BAR]);
}
void FunctionBar_drawAttr(const FunctionBar* this, char* buffer, int attr) {
void FunctionBar_drawAttr(FunctionBar* this, char* buffer, int attr) {
attrset(CRT_colors[FUNCTION_BAR]);
mvhline(LINES-1, 0, ' ', COLS);
int x = 0;
@ -109,18 +111,14 @@ void FunctionBar_drawAttr(const FunctionBar* this, char* buffer, int attr) {
mvaddstr(LINES-1, x, this->functions[i]);
x += strlen(this->functions[i]);
}
if (buffer) {
if (buffer != NULL) {
attrset(attr);
mvaddstr(LINES-1, x, buffer);
CRT_cursorX = x + strlen(buffer);
curs_set(1);
} else {
curs_set(0);
}
attrset(CRT_colors[RESET_COLOR]);
}
int FunctionBar_synthesizeEvent(const FunctionBar* this, int pos) {
int FunctionBar_synthesizeEvent(FunctionBar* this, int pos) {
int x = 0;
for (int i = 0; i < this->size; i++) {
x += strlen(this->keys[i]);

View File

@ -1,15 +1,25 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_FunctionBar
#define HEADER_FunctionBar
/*
htop - FunctionBar.h
(C) 2004-2011 Hisham H. Muhammad
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 "CRT.h"
#include "debug.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <curses.h>
typedef struct FunctionBar_ {
Object super;
@ -20,19 +30,18 @@ typedef struct FunctionBar_ {
bool staticData;
} FunctionBar;
extern char* FUNCTIONBAR_CLASS;
extern ObjectClass FunctionBar_class;
FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events);
FunctionBar* FunctionBar_new(const char** functions, const char** keys, int* events);
void FunctionBar_delete(Object* this);
void FunctionBar_delete(Object* cast);
void FunctionBar_draw(FunctionBar* this, char* buffer);
void FunctionBar_setLabel(FunctionBar* this, int event, const char* text);
void FunctionBar_setLabel(FunctionBar* this, int event, char* text);
void FunctionBar_draw(const FunctionBar* this, char* buffer);
void FunctionBar_drawAttr(FunctionBar* this, char* buffer, int attr);
void FunctionBar_drawAttr(const FunctionBar* this, char* buffer, int attr);
int FunctionBar_synthesizeEvent(const FunctionBar* this, int pos);
int FunctionBar_synthesizeEvent(FunctionBar* this, int pos);
#endif

View File

@ -1,6 +1,6 @@
/*
htop - Hashtable.c
(C) 2004-2011 Hisham H. Muhammad
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
@ -8,17 +8,18 @@ in the source distribution for its full text.
#include "Hashtable.h"
#include <stdlib.h>
#include <assert.h>
/*{
#include <stdbool.h>
#include "debug.h"
/*{
typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem {
unsigned int key;
int key;
void* value;
struct HashtableItem* next;
} HashtableItem;
@ -27,40 +28,12 @@ struct Hashtable_ {
int size;
HashtableItem** buckets;
int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner;
};
}*/
#ifdef DEBUG
static 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
static HashtableItem* HashtableItem_new(unsigned int key, void* value) {
HashtableItem* HashtableItem_new(int key, void* value) {
HashtableItem* this;
this = (HashtableItem*) malloc(sizeof(HashtableItem));
@ -74,16 +47,18 @@ Hashtable* Hashtable_new(int size, bool owner) {
Hashtable* this;
this = (Hashtable*) malloc(sizeof(Hashtable));
this->items = 0;
this->size = size;
this->buckets = (HashtableItem**) calloc(size, sizeof(HashtableItem*));
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) {
@ -98,8 +73,12 @@ void Hashtable_delete(Hashtable* this) {
free(this);
}
void Hashtable_put(Hashtable* this, unsigned int key, void* value) {
unsigned int index = key % this->size;
inline int Hashtable_size(Hashtable* this) {
return this->items;
}
void Hashtable_put(Hashtable* this, int key, void* value) {
int index = this->hashAlgorithm(this, key);
HashtableItem** bucketPtr = &(this->buckets[index]);
while (true)
if (*bucketPtr == NULL) {
@ -113,53 +92,44 @@ void Hashtable_put(Hashtable* this, unsigned int key, void* value) {
break;
} else
bucketPtr = &((*bucketPtr)->next);
assert(Hashtable_isConsistent(this));
}
void* Hashtable_remove(Hashtable* this, unsigned int key) {
unsigned 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;
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;
this->items--;
if (this->owner) {
free(value);
assert(Hashtable_isConsistent(this));
free(savedValue);
return NULL;
} else {
assert(Hashtable_isConsistent(this));
return value;
return savedValue;
}
}
}
assert(Hashtable_isConsistent(this));
return NULL;
} else
bucketPtr = &((*bucketPtr)->next);
}
inline void* Hashtable_get(Hashtable* this, unsigned int key) {
unsigned int index = key % this->size;
inline void* Hashtable_get(Hashtable* this, int key) {
int index = this->hashAlgorithm(this, key);
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) {
@ -167,5 +137,4 @@ void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData
walk = walk->next;
}
}
assert(Hashtable_isConsistent(this));
}

View File

@ -1,22 +1,27 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_Hashtable
#define HEADER_Hashtable
/*
htop - Hashtable.h
(C) 2004-2011 Hisham H. Muhammad
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 <stdlib.h>
#include <stdbool.h>
#include "debug.h"
typedef struct Hashtable_ Hashtable;
typedef void(*Hashtable_PairFunction)(int, void*, void*);
typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int);
typedef struct HashtableItem {
unsigned int key;
int key;
void* value;
struct HashtableItem* next;
} HashtableItem;
@ -25,24 +30,25 @@ struct Hashtable_ {
int size;
HashtableItem** buckets;
int items;
Hashtable_HashAlgorithm hashAlgorithm;
bool owner;
};
#ifdef DEBUG
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);
void Hashtable_put(Hashtable* this, unsigned int key, void* value);
inline int Hashtable_size(Hashtable* this);
void* Hashtable_remove(Hashtable* this, unsigned int key);
void Hashtable_put(Hashtable* this, int key, void* value);
extern void* Hashtable_get(Hashtable* this, unsigned int key);
void* Hashtable_remove(Hashtable* this, int key);
inline void* Hashtable_get(Hashtable* this, int key);
void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData);

127
Header.c
View File

@ -1,32 +1,17 @@
/*
htop - Header.c
(C) 2004-2011 Hisham H. Muhammad
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Header.h"
#include "Meter.h"
#include "CRT.h"
#include "CPUMeter.h"
#include "MemoryMeter.h"
#include "SwapMeter.h"
#include "TasksMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
#include "BatteryMeter.h"
#include "ClockMeter.h"
#include "HostnameMeter.h"
#include "String.h"
#include "debug.h"
#include <assert.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
/*{
#include "ProcessList.h"
#include "Meter.h"
typedef enum HeaderSide_ {
LEFT_HEADER,
@ -34,12 +19,12 @@ typedef enum HeaderSide_ {
} HeaderSide;
typedef struct Header_ {
Vector* leftMeters;
Vector* rightMeters;
TypedVector* leftMeters;
TypedVector* rightMeters;
ProcessList* pl;
bool margin;
int height;
int pad;
bool margin;
} Header;
}*/
@ -49,79 +34,77 @@ typedef struct Header_ {
#endif
Header* Header_new(ProcessList* pl) {
Header* this = calloc(1, sizeof(Header));
this->leftMeters = Vector_new(Class(Meter), true, DEFAULT_SIZE);
this->rightMeters = Vector_new(Class(Meter), true, DEFAULT_SIZE);
Header* this = malloc(sizeof(Header));
this->leftMeters = TypedVector_new(METER_CLASS, true, DEFAULT_SIZE);
this->rightMeters = TypedVector_new(METER_CLASS, true, DEFAULT_SIZE);
this->margin = true;
this->pl = pl;
return this;
}
void Header_delete(Header* this) {
Vector_delete(this->leftMeters);
Vector_delete(this->rightMeters);
TypedVector_delete(this->leftMeters);
TypedVector_delete(this->rightMeters);
free(this);
}
void Header_createMeter(Header* this, char* name, HeaderSide side) {
Vector* meters = side == LEFT_HEADER
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
char* paren = strchr(name, '(');
int param = 0;
if (paren) {
int ok = sscanf(paren, "(%10d)", &param);
int ok = sscanf(paren, "(%d)", &param);
if (!ok) param = 0;
*paren = '\0';
}
for (MeterClass** type = Meter_types; *type; type++) {
for (MeterType** type = Meter_types; *type; type++) {
if (String_eq(name, (*type)->name)) {
Vector_add(meters, Meter_new(this->pl, param, *type));
TypedVector_add(meters, Meter_new(this->pl, param, *type));
break;
}
}
}
void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side) {
Vector* meters = side == LEFT_HEADER
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
if (i >= Vector_size(meters))
return;
Meter* meter = (Meter*) Vector_get(meters, i);
Meter* meter = (Meter*) TypedVector_get(meters, i);
Meter_setMode(meter, mode);
}
Meter* Header_addMeter(Header* this, MeterClass* type, int param, HeaderSide side) {
Vector* meters = side == LEFT_HEADER
Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side) {
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
Meter* meter = Meter_new(this->pl, param, type);
Vector_add(meters, meter);
TypedVector_add(meters, meter);
return meter;
}
int Header_size(Header* this, HeaderSide side) {
Vector* meters = side == LEFT_HEADER
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
return Vector_size(meters);
return TypedVector_size(meters);
}
char* Header_readMeterName(Header* this, int i, HeaderSide side) {
Vector* meters = side == LEFT_HEADER
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
Meter* meter = (Meter*) Vector_get(meters, i);
Meter* meter = (Meter*) TypedVector_get(meters, i);
int nameLen = strlen(Meter_name(meter));
int nameLen = strlen(meter->type->name);
int len = nameLen + 100;
char* name = malloc(len);
strncpy(name, Meter_name(meter), nameLen);
strncpy(name, meter->type->name, nameLen);
name[nameLen] = '\0';
if (meter->param)
snprintf(name + nameLen, len - nameLen, "(%d)", meter->param);
@ -130,58 +113,38 @@ char* Header_readMeterName(Header* this, int i, HeaderSide side) {
}
MeterModeId Header_readMeterMode(Header* this, int i, HeaderSide side) {
Vector* meters = side == LEFT_HEADER
TypedVector* meters = side == LEFT_HEADER
? this->leftMeters
: this->rightMeters;
Meter* meter = (Meter*) Vector_get(meters, i);
Meter* meter = (Meter*) TypedVector_get(meters, i);
return meter->mode;
}
void Header_defaultMeters(Header* this, int cpuCount) {
if (cpuCount > 8) {
Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(LeftCPUs2Meter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(RightCPUs2Meter)));
} else if (cpuCount > 4) {
Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(LeftCPUsMeter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(RightCPUsMeter)));
} else {
Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(AllCPUsMeter)));
}
Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(MemoryMeter)));
Vector_add(this->leftMeters, Meter_new(this->pl, 0, (MeterClass*) Class(SwapMeter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(TasksMeter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(LoadAverageMeter)));
Vector_add(this->rightMeters, Meter_new(this->pl, 0, (MeterClass*) Class(UptimeMeter)));
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));
}
void Header_reinit(Header* this) {
for (int i = 0; i < Vector_size(this->leftMeters); i++) {
Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
if (Meter_initFn(meter))
Meter_init(meter);
}
for (int i = 0; i < Vector_size(this->rightMeters); i++) {
Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
if (Meter_initFn(meter))
Meter_init(meter);
}
}
void Header_draw(const Header* this) {
void Header_draw(Header* this) {
int height = this->height;
int pad = this->pad;
attrset(CRT_colors[RESET_COLOR]);
for (int y = 0; y < height; y++) {
mvhline(y, 0, ' ', COLS);
}
for (int y = (pad / 2), i = 0; i < Vector_size(this->leftMeters); i++) {
Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
for (int y = (pad / 2), i = 0; i < TypedVector_size(this->leftMeters); i++) {
Meter* meter = (Meter*) TypedVector_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 < Vector_size(this->rightMeters); i++) {
Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
for (int y = (pad / 2), i = 0; i < TypedVector_size(this->rightMeters); i++) {
Meter* meter = (Meter*) TypedVector_get(this->rightMeters, i);
meter->draw(meter, COLS / 2 + pad, y, COLS / 2 - (pad * 2 - 1) - 1);
y += meter->h;
}
@ -192,12 +155,12 @@ int Header_calculateHeight(Header* this) {
int leftHeight = pad;
int rightHeight = pad;
for (int i = 0; i < Vector_size(this->leftMeters); i++) {
Meter* meter = (Meter*) Vector_get(this->leftMeters, i);
for (int i = 0; i < TypedVector_size(this->leftMeters); i++) {
Meter* meter = (Meter*) TypedVector_get(this->leftMeters, i);
leftHeight += meter->h;
}
for (int i = 0; i < Vector_size(this->rightMeters); i++) {
Meter* meter = (Meter*) Vector_get(this->rightMeters, i);
for (int i = 0; i < TypedVector_size(this->rightMeters); i++) {
Meter* meter = (Meter*) TypedVector_get(this->rightMeters, i);
rightHeight += meter->h;
}
this->pad = pad;

View File

@ -3,27 +3,30 @@
#ifndef HEADER_Header
#define HEADER_Header
/*
htop - Header.h
(C) 2004-2011 Hisham H. Muhammad
htop - Header.c
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "ProcessList.h"
#include "Meter.h"
#include "debug.h"
#include <assert.h>
typedef enum HeaderSide_ {
LEFT_HEADER,
RIGHT_HEADER
} HeaderSide;
typedef struct Header_ {
Vector* leftMeters;
Vector* rightMeters;
TypedVector* leftMeters;
TypedVector* rightMeters;
ProcessList* pl;
bool margin;
int height;
int pad;
bool margin;
} Header;
@ -39,7 +42,7 @@ void Header_createMeter(Header* this, char* name, HeaderSide side);
void Header_setMode(Header* this, int i, MeterModeId mode, HeaderSide side);
Meter* Header_addMeter(Header* this, MeterClass* type, int param, HeaderSide side);
Meter* Header_addMeter(Header* this, MeterType* type, int param, HeaderSide side);
int Header_size(Header* this, HeaderSide side);
@ -47,11 +50,9 @@ char* Header_readMeterName(Header* this, int i, HeaderSide side);
MeterModeId Header_readMeterMode(Header* this, int i, HeaderSide side);
void Header_defaultMeters(Header* this, int cpuCount);
void Header_defaultMeters(Header* this);
void Header_reinit(Header* this);
void Header_draw(const Header* this);
void Header_draw(Header* this);
int Header_calculateHeight(Header* this);

View File

@ -1,39 +0,0 @@
/*
htop - HostnameMeter.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "HostnameMeter.h"
#include "CRT.h"
#include <unistd.h>
/*{
#include "Meter.h"
}*/
int HostnameMeter_attributes[] = {
HOSTNAME
};
static void HostnameMeter_setValues(Meter* this, char* buffer, int size) {
(void) this;
gethostname(buffer, size-1);
}
MeterClass HostnameMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete
},
.setValues = HostnameMeter_setValues,
.defaultMode = TEXT_METERMODE,
.total = 100.0,
.attributes = HostnameMeter_attributes,
.name = "Hostname",
.uiName = "Hostname",
.caption = "Hostname: ",
};

View File

@ -1,18 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_HostnameMeter
#define HEADER_HostnameMeter
/*
htop - HostnameMeter.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Meter.h"
extern int HostnameMeter_attributes[];
extern MeterClass HostnameMeter_class;
#endif

View File

@ -1,41 +0,0 @@
/*
htop - IOPriority.c
(C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
Based on ionice,
Copyright (C) 2005 Jens Axboe <jens@axboe.dk>
Released under the terms of the GNU General Public License version 2
*/
#include "IOPriority.h"
/*{
enum {
IOPRIO_CLASS_NONE,
IOPRIO_CLASS_RT,
IOPRIO_CLASS_BE,
IOPRIO_CLASS_IDLE,
};
#define IOPRIO_WHO_PROCESS 1
#define IOPRIO_CLASS_SHIFT (13)
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
#define IOPriority_class(ioprio_) ((int) ((ioprio_) >> IOPRIO_CLASS_SHIFT) )
#define IOPriority_data(ioprio_) ((int) ((ioprio_) & IOPRIO_PRIO_MASK) )
typedef int IOPriority;
#define IOPriority_tuple(class_, data_) (((class_) << IOPRIO_CLASS_SHIFT) | data_)
#define IOPriority_error 0xffffffff
#define IOPriority_None IOPriority_tuple(IOPRIO_CLASS_NONE, 0)
#define IOPriority_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 0)
}*/

View File

@ -1,43 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_IOPriority
#define HEADER_IOPriority
/*
htop - IOPriority.h
(C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
Based on ionice,
Copyright (C) 2005 Jens Axboe <jens@axboe.dk>
Released under the terms of the GNU General Public License version 2
*/
enum {
IOPRIO_CLASS_NONE,
IOPRIO_CLASS_RT,
IOPRIO_CLASS_BE,
IOPRIO_CLASS_IDLE,
};
#define IOPRIO_WHO_PROCESS 1
#define IOPRIO_CLASS_SHIFT (13)
#define IOPRIO_PRIO_MASK ((1UL << IOPRIO_CLASS_SHIFT) - 1)
#define IOPriority_class(ioprio_) ((int) ((ioprio_) >> IOPRIO_CLASS_SHIFT) )
#define IOPriority_data(ioprio_) ((int) ((ioprio_) & IOPRIO_PRIO_MASK) )
typedef int IOPriority;
#define IOPriority_tuple(class_, data_) (((class_) << IOPRIO_CLASS_SHIFT) | data_)
#define IOPriority_error 0xffffffff
#define IOPriority_None IOPriority_tuple(IOPRIO_CLASS_NONE, 0)
#define IOPriority_Idle IOPriority_tuple(IOPRIO_CLASS_IDLE, 0)
#endif

View File

@ -1,43 +0,0 @@
/*
htop - IOPriorityPanel.c
(C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "IOPriorityPanel.h"
/*{
#include "Panel.h"
#include "IOPriority.h"
#include "ListItem.h"
}*/
Panel* IOPriorityPanel_new(IOPriority currPrio) {
Panel* this = Panel_new(1, 1, 1, 1, true, Class(ListItem));
Panel_setHeader(this, "IO Priority:");
Panel_add(this, (Object*) ListItem_new("None (based on nice)", IOPriority_None));
if (currPrio == IOPriority_None) Panel_setSelected(this, 0);
struct { int klass; const char* name; } classes[] = {
{ .klass = IOPRIO_CLASS_RT, .name = "Realtime" },
{ .klass = IOPRIO_CLASS_BE, .name = "Best-effort" },
{ .klass = 0, .name = NULL }
};
for (int c = 0; classes[c].name; c++) {
for (int i = 0; i < 8; i++) {
char name[50];
snprintf(name, sizeof(name)-1, "%s %d %s", classes[c].name, i, i == 0 ? "(High)" : (i == 7 ? "(Low)" : ""));
IOPriority ioprio = IOPriority_tuple(classes[c].klass, i);
Panel_add(this, (Object*) ListItem_new(name, ioprio));
if (currPrio == ioprio) Panel_setSelected(this, Panel_size(this) - 1);
}
}
Panel_add(this, (Object*) ListItem_new("Idle", IOPriority_Idle));
if (currPrio == IOPriority_Idle) Panel_setSelected(this, Panel_size(this) - 1);
return this;
}
IOPriority IOPriorityPanel_getIOPriority(Panel* this) {
return (IOPriority) ( ((ListItem*) Panel_getSelected(this))->key );
}

View File

@ -1,20 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_IOPriorityPanel
#define HEADER_IOPriorityPanel
/*
htop - IOPriorityPanel.h
(C) 2004-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "IOPriority.h"
#include "ListItem.h"
Panel* IOPriorityPanel_new(IOPriority currPrio);
IOPriority IOPriorityPanel_getIOPriority(Panel* this);
#endif

213
IncSet.c
View File

@ -1,213 +0,0 @@
/*
htop - IncSet.c
(C) 2005-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "IncSet.h"
#include "String.h"
#include "Panel.h"
#include "ListItem.h"
#include "CRT.h"
#include <string.h>
#include <stdlib.h>
/*{
#include "FunctionBar.h"
#include "Panel.h"
#include <stdbool.h>
#define INCMODE_MAX 40
typedef enum {
INC_SEARCH = 0,
INC_FILTER = 1
} IncType;
#define IncSet_filter(inc_) (inc_->filtering ? inc_->modes[INC_FILTER].buffer : NULL)
typedef struct IncMode_ {
char buffer[INCMODE_MAX+1];
int index;
FunctionBar* bar;
bool isFilter;
} IncMode;
typedef struct IncSet_ {
IncMode modes[2];
IncMode* active;
FunctionBar* bar;
FunctionBar* defaultBar;
bool filtering;
} IncSet;
typedef const char* (*IncMode_GetPanelValue)(Panel*, int);
}*/
static void IncMode_reset(IncMode* mode) {
mode->index = 0;
mode->buffer[0] = 0;
}
static const char* searchFunctions[] = {"Next ", "Cancel ", " Search: ", NULL};
static const char* searchKeys[] = {"F3", "Esc", " "};
static int searchEvents[] = {KEY_F(3), 27, ERR};
static inline void IncMode_initSearch(IncMode* search) {
memset(search, 0, sizeof(IncMode));
search->bar = FunctionBar_new(searchFunctions, searchKeys, searchEvents);
search->isFilter = false;
}
static const char* filterFunctions[] = {"Done ", "Clear ", " Filter: ", NULL};
static const char* filterKeys[] = {"Enter", "Esc", " "};
static int filterEvents[] = {13, 27, ERR};
static inline void IncMode_initFilter(IncMode* filter) {
memset(filter, 0, sizeof(IncMode));
filter->bar = FunctionBar_new(filterFunctions, filterKeys, filterEvents);
filter->isFilter = true;
}
static inline void IncMode_done(IncMode* mode) {
FunctionBar_delete((Object*)mode->bar);
}
IncSet* IncSet_new(FunctionBar* bar) {
IncSet* this = calloc(1, sizeof(IncSet));
IncMode_initSearch(&(this->modes[INC_SEARCH]));
IncMode_initFilter(&(this->modes[INC_FILTER]));
this->active = NULL;
this->filtering = false;
this->bar = bar;
this->defaultBar = bar;
return this;
}
void IncSet_delete(IncSet* this) {
IncMode_done(&(this->modes[0]));
IncMode_done(&(this->modes[1]));
free(this);
}
static void updateWeakPanel(IncSet* this, Panel* panel, Vector* lines) {
Object* selected = Panel_getSelected(panel);
Panel_prune(panel);
if (this->filtering) {
int n = 0;
const char* incFilter = this->modes[INC_FILTER].buffer;
for (int i = 0; i < Vector_size(lines); i++) {
ListItem* line = (ListItem*)Vector_get(lines, i);
if (String_contains_i(line->value, incFilter)) {
Panel_add(panel, (Object*)line);
if (selected == (Object*)line) Panel_setSelected(panel, n);
n++;
}
}
} else {
for (int i = 0; i < Vector_size(lines); i++) {
Object* line = Vector_get(lines, i);
Panel_add(panel, line);
if (selected == line) Panel_setSelected(panel, i);
}
}
}
static void search(IncMode* mode, Panel* panel, IncMode_GetPanelValue getPanelValue) {
int size = Panel_size(panel);
bool found = false;
for (int i = 0; i < size; i++) {
if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
Panel_setSelected(panel, i);
found = true;
break;
}
}
if (found)
FunctionBar_draw(mode->bar, mode->buffer);
else
FunctionBar_drawAttr(mode->bar, mode->buffer, CRT_colors[FAILED_SEARCH]);
}
bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue getPanelValue, Vector* lines) {
if (ch == ERR)
return true;
IncMode* mode = this->active;
int size = Panel_size(panel);
bool filterChange = false;
bool doSearch = true;
if (ch == KEY_F(3)) {
if (size == 0) return true;
int here = Panel_getSelectedIndex(panel);
int i = here;
for(;;) {
i++;
if (i == size) i = 0;
if (i == here) break;
if (String_contains_i(getPanelValue(panel, i), mode->buffer)) {
Panel_setSelected(panel, i);
break;
}
}
doSearch = false;
} else if (isprint((char)ch) && (mode->index < INCMODE_MAX)) {
mode->buffer[mode->index] = ch;
mode->index++;
mode->buffer[mode->index] = 0;
if (mode->isFilter) {
filterChange = true;
if (mode->index == 1) this->filtering = true;
}
} else if ((ch == KEY_BACKSPACE || ch == 127) && (mode->index > 0)) {
mode->index--;
mode->buffer[mode->index] = 0;
if (mode->isFilter) {
filterChange = true;
if (mode->index == 0) {
this->filtering = false;
IncMode_reset(mode);
}
}
} else {
if (mode->isFilter) {
filterChange = true;
if (ch == 27) {
this->filtering = false;
IncMode_reset(mode);
}
} else {
IncMode_reset(mode);
}
this->active = NULL;
this->bar = this->defaultBar;
FunctionBar_draw(this->defaultBar, NULL);
doSearch = false;
}
if (doSearch) {
search(mode, panel, getPanelValue);
}
if (filterChange && lines) {
updateWeakPanel(this, panel, lines);
}
return filterChange;
}
const char* IncSet_getListItemValue(Panel* panel, int i) {
ListItem* l = (ListItem*) Panel_get(panel, i);
if (l)
return l->value;
return "";
}
void IncSet_activate(IncSet* this, IncType type) {
this->active = &(this->modes[type]);
this->bar = this->active->bar;
FunctionBar_draw(this->active->bar, this->active->buffer);
}
void IncSet_drawBar(IncSet* this) {
FunctionBar_draw(this->bar, this->active ? this->active->buffer : NULL);
}

View File

@ -1,56 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_IncSet
#define HEADER_IncSet
/*
htop - IncSet.h
(C) 2005-2012 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "FunctionBar.h"
#include "Panel.h"
#include <stdbool.h>
#define INCMODE_MAX 40
typedef enum {
INC_SEARCH = 0,
INC_FILTER = 1
} IncType;
#define IncSet_filter(inc_) (inc_->filtering ? inc_->modes[INC_FILTER].buffer : NULL)
typedef struct IncMode_ {
char buffer[INCMODE_MAX+1];
int index;
FunctionBar* bar;
bool isFilter;
} IncMode;
typedef struct IncSet_ {
IncMode modes[2];
IncMode* active;
FunctionBar* bar;
FunctionBar* defaultBar;
bool filtering;
} IncSet;
typedef const char* (*IncMode_GetPanelValue)(Panel*, int);
IncSet* IncSet_new(FunctionBar* bar);
void IncSet_delete(IncSet* this);
bool IncSet_handleKey(IncSet* this, int ch, Panel* panel, IncMode_GetPanelValue getPanelValue, Vector* lines);
const char* IncSet_getListItemValue(Panel* panel, int i);
void IncSet_activate(IncSet* this, IncType type);
void IncSet_drawBar(IncSet* this);
#endif

353
ListBox.c Normal file
View File

@ -0,0 +1,353 @@
/*
htop - ListBox.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 "CRT.h"
#include "RichString.h"
#include <math.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;
}*/
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
/* private property */
char* LISTBOX_CLASS = "ListBox";
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);
return this;
}
void ListBox_delete(Object* cast) {
ListBox* this = (ListBox*)cast;
ListBox_done(this);
free(this);
}
void ListBox_init(ListBox* 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;
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->eventHandler = NULL;
this->items = TypedVector_new(type, owner, DEFAULT_SIZE);
this->scrollV = 0;
this->scrollH = 0;
this->selected = 0;
this->oldSelected = 0;
this->needsRedraw = true;
this->header.len = 0;
}
void ListBox_done(ListBox* this) {
assert (this != NULL);
RichString_delete(this->header);
TypedVector_delete(this->items);
}
inline void ListBox_setRichHeader(ListBox* 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));
}
void ListBox_setEventHandler(ListBox* this, ListBox_EventHandler eh) {
this->eventHandler = eh;
}
void ListBox_move(ListBox* this, int x, int y) {
assert (this != NULL);
this->x = x;
this->y = y;
this->needsRedraw = true;
}
void ListBox_resize(ListBox* this, int w, int h) {
assert (this != NULL);
if (this->header.len > 0)
h--;
this->w = w;
this->h = h;
this->needsRedraw = true;
}
void ListBox_prune(ListBox* this) {
assert (this != NULL);
TypedVector_prune(this->items);
this->scrollV = 0;
this->selected = 0;
this->oldSelected = 0;
this->needsRedraw = true;
}
void ListBox_add(ListBox* this, Object* o) {
assert (this != NULL);
TypedVector_add(this->items, o);
this->needsRedraw = true;
}
void ListBox_insert(ListBox* this, int i, Object* o) {
assert (this != NULL);
TypedVector_insert(this->items, i, o);
this->needsRedraw = true;
}
void ListBox_set(ListBox* this, int i, Object* o) {
assert (this != NULL);
TypedVector_set(this->items, i, o);
}
Object* ListBox_get(ListBox* this, int i) {
assert (this != NULL);
return TypedVector_get(this->items, i);
}
Object* ListBox_remove(ListBox* 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))
this->selected--;
return removed;
}
Object* ListBox_getSelected(ListBox* this) {
assert (this != NULL);
return TypedVector_get(this->items, this->selected);
}
void ListBox_moveSelectedUp(ListBox* this) {
assert (this != NULL);
TypedVector_moveUp(this->items, this->selected);
if (this->selected > 0)
this->selected--;
}
void ListBox_moveSelectedDown(ListBox* this) {
assert (this != NULL);
TypedVector_moveDown(this->items, this->selected);
if (this->selected + 1 < TypedVector_size(this->items))
this->selected++;
}
int ListBox_getSelectedIndex(ListBox* this) {
assert (this != NULL);
return this->selected;
}
int ListBox_getSize(ListBox* this) {
assert (this != NULL);
return TypedVector_size(this->items);
}
void ListBox_setSelected(ListBox* this, int selected) {
assert (this != NULL);
selected = MAX(0, MIN(TypedVector_size(this->items) - 1, selected));
this->selected = selected;
}
void ListBox_draw(ListBox* this, bool focus) {
assert (this != NULL);
int first, last;
int itemCount = TypedVector_size(this->items);
int scrollH = this->scrollH;
int y = this->y; int x = this->x;
first = this->scrollV;
if (this->h > itemCount) {
last = this->scrollV + itemCount;
move(y + last, x + 0);
} else {
last = MIN(itemCount, this->scrollV + this->h);
}
if (this->selected < first) {
first = this->selected;
this->scrollV = first;
this->needsRedraw = true;
}
if (this->selected >= last) {
last = MIN(itemCount, this->selected + 1);
first = MAX(0, last - this->h);
this->scrollV = first;
this->needsRedraw = true;
}
assert(first >= 0);
assert(last <= itemCount);
if (this->header.len > 0) {
int attr = focus
? CRT_colors[PANEL_HEADER_FOCUS]
: CRT_colors[PANEL_HEADER_UNFOCUS];
attrset(attr);
mvhline(y, x, ' ', this->w);
if (scrollH < this->header.len) {
mvaddchnstr(y, x, this->header.chstr + scrollH,
MIN(this->header.len - scrollH, this->w));
}
attrset(CRT_colors[RESET_COLOR]);
y++;
}
int highlight = focus
? CRT_colors[PANEL_HIGHLIGHT_FOCUS]
: CRT_colors[PANEL_HIGHLIGHT_UNFOCUS];
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();
itemObj->display(itemObj, &itemRef);
int amt = MIN(itemRef.len - scrollH, this->w);
if (i == this->selected) {
attrset(highlight);
RichString_setAttr(&itemRef, highlight);
mvhline(y + j, x+0, ' ', this->w);
if (amt > 0)
mvaddchnstr(y+j, x+0, itemRef.chstr + scrollH, amt);
attrset(CRT_colors[RESET_COLOR]);
} else {
mvhline(y+j, x+0, ' ', this->w);
if (amt > 0)
mvaddchnstr(y+j, x+0, itemRef.chstr + scrollH, amt);
}
}
for (int i = y + (last - first); i < y + this->h; i++)
mvhline(i, x+0, ' ', this->w);
this->needsRedraw = false;
} else {
Object* oldObj = TypedVector_get(this->items, this->oldSelected);
RichString oldRef = RichString_new();
oldObj->display(oldObj, &oldRef);
Object* newObj = TypedVector_get(this->items, this->selected);
RichString newRef = RichString_new();
newObj->display(newObj, &newRef);
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
if (scrollH < oldRef.len)
mvaddchnstr(y+ this->oldSelected - this->scrollV, x+0, oldRef.chstr + this->scrollH, MIN(oldRef.len - scrollH, this->w));
attrset(highlight);
mvhline(y+this->selected - this->scrollV, x+0, ' ', this->w);
RichString_setAttr(&newRef, highlight);
if (scrollH < newRef.len)
mvaddchnstr(y+this->selected - this->scrollV, x+0, newRef.chstr + this->scrollH, MIN(newRef.len - scrollH, this->w));
attrset(CRT_colors[RESET_COLOR]);
}
this->oldSelected = this->selected;
move(0, 0);
}
void ListBox_onKey(ListBox* this, int key) {
assert (this != NULL);
switch (key) {
case KEY_DOWN:
if (this->selected + 1 < TypedVector_size(this->items))
this->selected++;
break;
case KEY_UP:
if (this->selected > 0)
this->selected--;
break;
case KEY_LEFT:
if (this->scrollH > 0) {
this->scrollH -= 5;
this->needsRedraw = true;
}
break;
case KEY_RIGHT:
this->scrollH += 5;
this->needsRedraw = true;
break;
case KEY_PPAGE:
this->selected -= this->h;
if (this->selected < 0)
this->selected = 0;
break;
case KEY_NPAGE:
this->selected += this->h;
int size = TypedVector_size(this->items);
if (this->selected >= size)
this->selected = size - 1;
break;
case KEY_HOME:
this->selected = 0;
break;
case KEY_END:
this->selected = TypedVector_size(this->items) - 1;
break;
}
}

101
ListBox.h Normal file
View File

@ -0,0 +1,101 @@
/* 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

@ -1,22 +1,19 @@
/*
htop - ListItem.c
(C) 2004-2011 Hisham H. Muhammad
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "ListItem.h"
#include "CRT.h"
#include "String.h"
#include "Object.h"
#include "RichString.h"
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include "debug.h"
/*{
#include "Object.h"
typedef struct ListItem_ {
Object super;
@ -24,52 +21,50 @@ typedef struct ListItem_ {
int key;
} ListItem;
extern char* LISTITEM_CLASS;
}*/
static void ListItem_delete(Object* cast) {
/* private property */
char* LISTITEM_CLASS = "ListItem";
ListItem* ListItem_new(char* value, int key) {
ListItem* this = malloc(sizeof(ListItem));
((Object*)this)->class = 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;
}
void ListItem_append(ListItem* this, char* text) {
char* buf = malloc(strlen(this->value) + strlen(text) + 1);
sprintf(buf, "%s%s", this->value, text);
free(this->value);
this->value = buf;
}
void ListItem_delete(Object* cast) {
ListItem* this = (ListItem*)cast;
free(this->value);
free(this);
}
static void ListItem_display(Object* cast, RichString* out) {
void ListItem_display(Object* cast, RichString* out) {
ListItem* this = (ListItem*)cast;
assert (this != NULL);
/*
int len = strlen(this->value)+1;
char buffer[len+1];
snprintf(buffer, len, "%s", this->value);
*/
RichString_write(out, CRT_colors[DEFAULT_COLOR], this->value/*buffer*/);
}
ObjectClass ListItem_class = {
.display = ListItem_display,
.delete = ListItem_delete,
.compare = ListItem_compare
};
ListItem* ListItem_new(const char* value, int key) {
ListItem* this = AllocThis(ListItem);
this->value = strdup(value);
this->key = key;
return this;
}
void ListItem_append(ListItem* this, const char* text) {
int oldLen = strlen(this->value);
int textLen = strlen(text);
int newLen = strlen(this->value) + textLen;
this->value = realloc(this->value, newLen + 1);
memcpy(this->value + oldLen, text, textLen);
this->value[newLen] = '\0';
RichString_write(out, CRT_colors[DEFAULT_COLOR], buffer);
}
const char* ListItem_getRef(ListItem* this) {
return this->value;
}
int ListItem_compare(const void* cast1, const void* cast2) {
int ListItem_compare(const Object* cast1, const Object* cast2) {
ListItem* obj1 = (ListItem*) cast1;
ListItem* obj2 = (ListItem*) cast2;
return strcmp(obj1->value, obj2->value);

View File

@ -1,15 +1,20 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_ListItem
#define HEADER_ListItem
/*
htop - ListItem.h
(C) 2004-2011 Hisham H. Muhammad
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 "String.h"
#include "Object.h"
#include "RichString.h"
#include <string.h>
#include "debug.h"
typedef struct ListItem_ {
Object super;
@ -17,16 +22,18 @@ typedef struct ListItem_ {
int key;
} ListItem;
extern char* LISTITEM_CLASS;
extern ObjectClass ListItem_class;
ListItem* ListItem_new(char* value, int key);
ListItem* ListItem_new(const char* value, int key);
void ListItem_delete(Object* cast);
void ListItem_append(ListItem* this, const char* text);
void ListItem_display(Object* cast, RichString* out);
void ListItem_append(ListItem* this, char* text);
const char* ListItem_getRef(ListItem* this);
int ListItem_compare(const void* cast1, const void* cast2);
int ListItem_compare(const Object*, const Object*);
#endif

View File

@ -1,56 +1,78 @@
/*
htop - LoadAverageMeter.c
(C) 2004-2011 Hisham H. Muhammad
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 "LoadAverageMeter.h"
#include "CRT.h"
#include <assert.h>
/*{
#include "Meter.h"
}*/
int LoadAverageMeter_attributes[] = {
LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIVE, LOAD_AVERAGE_ONE
#include <curses.h>
#include "debug.h"
/* private property */
int LoadAverageMeter_attributes[] = { LOAD_AVERAGE_FIFTEEN, LOAD_AVERAGE_FIVE, LOAD_AVERAGE_ONE };
/* private */
MeterType LoadAverageMeter = {
.setValues = LoadAverageMeter_setValues,
.display = LoadAverageMeter_display,
.mode = TEXT_METERMODE,
.items = 3,
.total = 100.0,
.attributes = LoadAverageMeter_attributes,
.name = "LoadAverage",
.uiName = "Load average",
.caption = "Load average: "
};
/* private property */
int LoadMeter_attributes[] = { LOAD };
static inline void LoadAverageMeter_scan(double* one, double* five, double* fifteen) {
/* private */
MeterType LoadMeter = {
.setValues = LoadMeter_setValues,
.display = LoadMeter_display,
.mode = TEXT_METERMODE,
.items = 1,
.total = 100.0,
.attributes = LoadMeter_attributes,
.name = "Load",
.uiName = "Load",
.caption = "Load: "
};
/* private */
inline static void LoadAverageMeter_scan(double* one, double* five, double* fifteen) {
int activeProcs, totalProcs, lastProc;
*one = 0; *five = 0; *fifteen = 0;
FILE *fd = fopen(PROCDIR "/loadavg", "r");
if (fd) {
int total = fscanf(fd, "%32lf %32lf %32lf %32d/%32d %32d", one, five, fifteen,
&activeProcs, &totalProcs, &lastProc);
(void) total;
assert(total == 6);
fclose(fd);
}
int read = fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen,
&activeProcs, &totalProcs, &lastProc);
(void) read;
assert(read == 6);
fclose(fd);
}
static void LoadAverageMeter_setValues(Meter* this, char* buffer, int size) {
void LoadAverageMeter_setValues(Meter* this, char* buffer, int size) {
LoadAverageMeter_scan(&this->values[2], &this->values[1], &this->values[0]);
snprintf(buffer, size, "%.2f/%.2f/%.2f", this->values[2], this->values[1], this->values[0]);
}
static void LoadAverageMeter_display(Object* cast, RichString* out) {
void LoadAverageMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
char buffer[20];
RichString_prune(out);
sprintf(buffer, "%.2f ", this->values[2]);
RichString_write(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIFTEEN], buffer);
sprintf(buffer, "%.2f ", this->values[1]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_FIVE], buffer);
sprintf(buffer, "%.2f ", this->values[0]);
RichString_append(out, CRT_colors[LOAD_AVERAGE_ONE], buffer);
}
static void LoadMeter_setValues(Meter* this, char* buffer, int size) {
void LoadMeter_setValues(Meter* this, char* buffer, int size) {
double five, fifteen;
LoadAverageMeter_scan(&this->values[0], &five, &fifteen);
if (this->values[0] > this->total) {
@ -59,40 +81,10 @@ static void LoadMeter_setValues(Meter* this, char* buffer, int size) {
snprintf(buffer, size, "%.2f", this->values[0]);
}
static void LoadMeter_display(Object* cast, RichString* out) {
void LoadMeter_display(Object* cast, RichString* out) {
Meter* this = (Meter*)cast;
char buffer[20];
RichString_prune(out);
sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]);
RichString_write(out, CRT_colors[LOAD], buffer);
RichString_append(out, CRT_colors[LOAD], buffer);
}
MeterClass LoadAverageMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = LoadAverageMeter_display,
},
.setValues = LoadAverageMeter_setValues,
.defaultMode = TEXT_METERMODE,
.maxItems = 3,
.total = 100.0,
.attributes = LoadAverageMeter_attributes,
.name = "LoadAverage",
.uiName = "Load average",
.caption = "Load average: "
};
MeterClass LoadMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = LoadMeter_display,
},
.setValues = LoadMeter_setValues,
.defaultMode = TEXT_METERMODE,
.total = 100.0,
.attributes = LoadMeter_attributes,
.name = "Load",
.uiName = "Load",
.caption = "Load: "
};

View File

@ -3,20 +3,29 @@
#ifndef HEADER_LoadAverageMeter
#define HEADER_LoadAverageMeter
/*
htop - LoadAverageMeter.h
(C) 2004-2011 Hisham H. Muhammad
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"
extern int LoadAverageMeter_attributes[];
#include <curses.h>
extern int LoadMeter_attributes[];
#include "debug.h"
extern MeterClass LoadAverageMeter_class;
extern MeterClass LoadMeter_class;
void LoadAverageMeter_setValues(Meter* this, char* buffer, int size);
void LoadAverageMeter_display(Object* cast, RichString* out);
void LoadMeter_setValues(Meter* this, char* buffer, int size);
void LoadMeter_display(Object* cast, RichString* out);
#endif

63
LoadMeter.c Normal file
View File

@ -0,0 +1,63 @@
/*
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);
}

34
LoadMeter.h Normal file
View File

@ -0,0 +1,34 @@
/* 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,49 +1,31 @@
ACLOCAL_AMFLAGS = -I m4
bin_PROGRAMS = htop
dist_man_MANS = htop.1
EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png scripts/MakeHeader.py \
install-sh autogen.sh missing
EXTRA_DIST = $(dist_man_MANS) htop.desktop htop.png scripts/MakeHeader.py
applicationsdir = $(datadir)/applications
applications_DATA = htop.desktop
pixmapdir = $(datadir)/pixmaps
pixmap_DATA = htop.png
htop_CFLAGS = -pedantic -Wall -Wextra -std=c99 -rdynamic -D_XOPEN_SOURCE_EXTENDED -DSYSCONFDIR=\"$(sysconfdir)\"
AM_CPPFLAGS = -DNDEBUG
AM_CFLAGS = -pedantic -Wall -std=c99
AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
myhtopsources = AvailableMetersPanel.c CategoriesPanel.c CheckItem.c \
ClockMeter.c ColorsPanel.c ColumnsPanel.c CPUMeter.c CRT.c \
DisplayOptionsPanel.c FunctionBar.c Hashtable.c Header.c htop.c ListItem.c \
LoadAverageMeter.c MemoryMeter.c Meter.c MetersPanel.c Object.c Panel.c \
BatteryMeter.c Process.c ProcessList.c RichString.c ScreenManager.c Settings.c \
IOPriorityPanel.c SignalsPanel.c String.c SwapMeter.c TasksMeter.c TraceScreen.c \
UptimeMeter.c UsersTable.c Vector.c AvailableColumnsPanel.c AffinityPanel.c \
HostnameMeter.c OpenFilesScreen.c Affinity.c IOPriority.c IncSet.c
myhtopheaders = AvailableColumnsPanel.h AvailableMetersPanel.h \
CategoriesPanel.h CheckItem.h ClockMeter.h ColorsPanel.h ColumnsPanel.h \
IOPriorityPanel.h CPUMeter.h CRT.h DisplayOptionsPanel.h FunctionBar.h \
Hashtable.h Header.h htop.h ListItem.h LoadAverageMeter.h MemoryMeter.h \
BatteryMeter.h Meter.h MetersPanel.h Object.h Panel.h ProcessList.h RichString.h \
ScreenManager.h Settings.h SignalsPanel.h String.h SwapMeter.h TasksMeter.h \
TraceScreen.h UptimeMeter.h UsersTable.h Vector.h Process.h AffinityPanel.h \
HostnameMeter.h OpenFilesScreen.h Affinity.h IOPriority.h IncSet.h
SUFFIXES = .h
BUILT_SOURCES = $(myhtopheaders)
htop_SOURCES = $(myhtopheaders) $(myhtopsources) config.h
profile:
$(MAKE) all CFLAGS="-pg" AM_CPPFLAGS="-pg -O2 -DNDEBUG"
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 \
ProcessList.c RichString.c ScreenManager.c Settings.c SignalItem.c \
SignalsListBox.c String.c SwapMeter.c TasksMeter.c TypedVector.c \
UptimeMeter.c UsersTable.c AvailableMetersListBox.h CategoriesListBox.h \
ClockMeter.h config.h CPUMeter.h CRT.h debug.h DebugMemory.h \
DisplayOptionsListBox.h FunctionBar.h Hashtable.h Header.h htop.h ListBox.h \
ListItem.h LoadAverageMeter.h 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
debug:
$(MAKE) all CFLAGS="" AM_CPPFLAGS="-ggdb -DDEBUG"
.c.h:
@srcdir@/scripts/MakeHeader.py $<
cppcheck:
cppcheck -q -v . --enable=all -DHAVE_CGROUP -DHAVE_OPENVZ -DHAVE_TASKSTATS
$(MAKE) all CFLAGS="-g -DDEBUG"

View File

@ -1,30 +1,41 @@
/*
htop - MemoryMeter.c
(C) 2004-2011 Hisham H. Muhammad
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 "MemoryMeter.h"
#include "Meter.h"
#include "CRT.h"
#include "ProcessList.h"
#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <math.h>
#include <sys/param.h>
#include "debug.h"
#include <assert.h>
/*{
#include "Meter.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,
.mode = BAR_METERMODE,
.items = 3,
.total = 100.0,
.attributes = MemoryMeter_attributes,
"Memory",
"Memory",
"Mem"
};
static void MemoryMeter_setValues(Meter* this, char* buffer, int size) {
void MemoryMeter_setValues(Meter* this, char* buffer, int size) {
long int usedMem = this->pl->usedMem;
long int buffersMem = this->pl->buffersMem;
long int cachedMem = this->pl->cachedMem;
@ -36,15 +47,16 @@ static void MemoryMeter_setValues(Meter* this, char* buffer, int size) {
snprintf(buffer, size, "%ld/%ldMB", (long int) usedMem / 1024, (long int) this->total / 1024);
}
static void MemoryMeter_display(Object* cast, RichString* out) {
void MemoryMeter_display(Object* cast, RichString* out) {
char buffer[50];
Meter* this = (Meter*)cast;
int k = 1024; const char* format = "%ldM ";
long int totalMem = this->total / k;
long int usedMem = this->values[0] / k;
long int buffersMem = this->values[1] / k;
long int cachedMem = this->values[2] / k;
RichString_write(out, CRT_colors[METER_TEXT], ":");
int div = 1024; char* format = "%ldM ";
long int totalMem = this->total / div;
long int usedMem = this->values[0] / div;
long int buffersMem = this->values[1] / div;
long int cachedMem = this->values[2] / div;
RichString_prune(out);
RichString_append(out, CRT_colors[METER_TEXT], ":");
sprintf(buffer, format, totalMem);
RichString_append(out, CRT_colors[METER_VALUE], buffer);
sprintf(buffer, format, usedMem);
@ -52,24 +64,8 @@ static void MemoryMeter_display(Object* cast, RichString* out) {
RichString_append(out, CRT_colors[MEMORY_USED], buffer);
sprintf(buffer, format, buffersMem);
RichString_append(out, CRT_colors[METER_TEXT], "buffers:");
RichString_append(out, CRT_colors[MEMORY_BUFFERS_TEXT], buffer);
RichString_append(out, CRT_colors[MEMORY_BUFFERS], buffer);
sprintf(buffer, format, cachedMem);
RichString_append(out, CRT_colors[METER_TEXT], "cache:");
RichString_append(out, CRT_colors[MEMORY_CACHE], buffer);
}
MeterClass MemoryMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = MemoryMeter_display,
},
.setValues = MemoryMeter_setValues,
.defaultMode = BAR_METERMODE,
.maxItems = 3,
.total = 100.0,
.attributes = MemoryMeter_attributes,
"Memory",
"Memory",
"Mem"
};

View File

@ -3,16 +3,29 @@
#ifndef HEADER_MemoryMeter
#define HEADER_MemoryMeter
/*
htop - MemoryMeter.h
(C) 2004-2011 Hisham H. Muhammad
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"
extern int MemoryMeter_attributes[];
#include "ProcessList.h"
extern MeterClass MemoryMeter_class;
#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <math.h>
#include <sys/param.h>
#include "debug.h"
#include <assert.h>
void MemoryMeter_setValues(Meter* this, char* buffer, int size);
void MemoryMeter_display(Object* cast, RichString* out);
#endif

485
Meter.c
View File

@ -1,115 +1,106 @@
/*
htop - Meter.c
(C) 2004-2011 Hisham H. Muhammad
(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 "CPUMeter.h"
#include "MemoryMeter.h"
#include "SwapMeter.h"
#include "TasksMeter.h"
#include "LoadAverageMeter.h"
#include "UptimeMeter.h"
#include "BatteryMeter.h"
#include "ClockMeter.h"
#include "HostnameMeter.h"
#include "RichString.h"
#include "Object.h"
#include "CRT.h"
#include "String.h"
#include "ListItem.h"
#include "Settings.h"
#define _GNU_SOURCE
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <stdarg.h>
#include "Meter.h"
#include "Object.h"
#include "CRT.h"
#include "ListItem.h"
#include "String.h"
#include "ProcessList.h"
#include "debug.h"
#include <assert.h>
#include <sys/time.h>
#ifndef USE_FUNKY_MODES
#define USE_FUNKY_MODES 1
#endif
#define METER_BUFFER_LEN 128
/*{
#include "ListItem.h"
#include "ProcessList.h"
typedef struct Meter_ Meter;
typedef struct MeterType_ MeterType;
typedef struct MeterMode_ MeterMode;
typedef void(*Meter_Init)(Meter*);
typedef void(*Meter_Done)(Meter*);
typedef void(*Meter_UpdateMode)(Meter*, int);
typedef void(*MeterType_Init)(Meter*);
typedef void(*MeterType_Done)(Meter*);
typedef void(*MeterType_SetMode)(Meter*, int);
typedef void(*Meter_SetValues)(Meter*, char*, int);
typedef void(*Meter_Draw)(Meter*, int, int, int);
typedef struct MeterClass_ {
ObjectClass super;
const Meter_Init init;
const Meter_Done done;
const Meter_UpdateMode updateMode;
const Meter_Draw draw;
const Meter_SetValues setValues;
const int defaultMode;
const double total;
const int* attributes;
const char* name;
const char* uiName;
const char* caption;
const char maxItems;
char curItems;
} MeterClass;
struct MeterMode_ {
Meter_Draw draw;
char* uiName;
int h;
};
#define As_Meter(this_) ((MeterClass*)((this_)->super.klass))
#define Meter_initFn(this_) As_Meter(this_)->init
#define Meter_init(this_) As_Meter(this_)->init((Meter*)(this_))
#define Meter_done(this_) As_Meter(this_)->done((Meter*)(this_))
#define Meter_updateModeFn(this_) As_Meter(this_)->updateMode
#define Meter_updateMode(this_, m_) As_Meter(this_)->updateMode((Meter*)(this_), m_)
#define Meter_drawFn(this_) As_Meter(this_)->draw
#define Meter_doneFn(this_) As_Meter(this_)->done
#define Meter_setValues(this_, c_, i_) As_Meter(this_)->setValues((Meter*)(this_), c_, i_)
#define Meter_defaultMode(this_) As_Meter(this_)->defaultMode
#define Meter_getItems(this_) As_Meter(this_)->curItems
#define Meter_setItems(this_, n_) As_Meter(this_)->curItems = (n_)
#define Meter_attributes(this_) As_Meter(this_)->attributes
#define Meter_name(this_) As_Meter(this_)->name
#define Meter_uiName(this_) As_Meter(this_)->uiName
struct MeterType_ {
Meter_SetValues setValues;
Object_Display display;
int mode;
int items;
double total;
int* attributes;
char* name;
char* uiName;
char* caption;
MeterType_Init init;
MeterType_Done done;
MeterType_SetMode setMode;
Meter_Draw draw;
};
struct Meter_ {
Object super;
Meter_Draw draw;
char* caption;
MeterType* type;
int mode;
int param;
void* drawData;
Meter_Draw draw;
void* drawBuffer;
int h;
ProcessList* pl;
double* values;
double total;
};
typedef struct MeterMode_ {
Meter_Draw draw;
const char* uiName;
int h;
} MeterMode;
extern char* METER_CLASS;
extern MeterType CPUMeter;
extern MeterType ClockMeter;
extern MeterType LoadAverageMeter;
extern MeterType LoadMeter;
extern MeterType MemoryMeter;
extern MeterType SwapMeter;
extern MeterType TasksMeter;
extern MeterType UptimeMeter;
extern MeterType AllCPUsMeter;
typedef enum {
CUSTOM_METERMODE = 0,
BAR_METERMODE,
TEXT_METERMODE,
#ifdef USE_FUNKY_MODES
GRAPH_METERMODE,
LED_METERMODE,
#endif
LAST_METERMODE
} MeterModeId;
typedef struct GraphData_ {
struct timeval time;
double values[METER_BUFFER_LEN];
} GraphData;
extern MeterType* Meter_types[];
extern MeterMode* Meter_modes[];
}*/
@ -120,77 +111,113 @@ typedef struct GraphData_ {
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
MeterClass Meter_class = {
.super = {
.extends = Class(Object)
}
};
/* private property */
char* METER_CLASS = "Meter";
MeterClass* Meter_types[] = {
&CPUMeter_class,
&ClockMeter_class,
&LoadAverageMeter_class,
&LoadMeter_class,
&MemoryMeter_class,
&SwapMeter_class,
&TasksMeter_class,
&UptimeMeter_class,
&BatteryMeter_class,
&HostnameMeter_class,
&AllCPUsMeter_class,
&AllCPUs2Meter_class,
&LeftCPUsMeter_class,
&RightCPUsMeter_class,
&LeftCPUs2Meter_class,
&RightCPUs2Meter_class,
&BlankMeter_class,
/* private */
MeterType* Meter_types[] = {
&CPUMeter,
&ClockMeter,
&LoadAverageMeter,
&LoadMeter,
&MemoryMeter,
&SwapMeter,
&TasksMeter,
&UptimeMeter,
&AllCPUsMeter,
NULL
};
Meter* Meter_new(ProcessList* pl, int param, MeterClass* type) {
Meter* this = calloc(1, sizeof(Meter));
Object_setClass(this, type);
/* private */
static MeterMode BarMeterMode = {
.uiName = "Bar",
.h = 1,
.draw = BarMeterMode_draw,
};
/* private */
static MeterMode TextMeterMode = {
.uiName = "Text",
.h = 1,
.draw = TextMeterMode_draw,
};
#ifdef USE_FUNKY_MODES
/* private */
static MeterMode GraphMeterMode = {
.uiName = "Graph",
.h = 3,
.draw = GraphMeterMode_draw,
};
/* private */
static MeterMode LEDMeterMode = {
.uiName = "LED",
.h = 3,
.draw = LEDMeterMode_draw,
};
#endif
/* private */
MeterMode* Meter_modes[] = {
NULL,
&BarMeterMode,
&TextMeterMode,
#ifdef USE_FUNKY_MODES
&GraphMeterMode,
&LEDMeterMode,
#endif
NULL
};
/* private property */
static RichString Meter_stringBuffer;
Meter* Meter_new(ProcessList* pl, int param, MeterType* type) {
Meter* this = calloc(sizeof(Meter), 1);
this->h = 1;
this->type = type;
this->param = param;
this->pl = pl;
char maxItems = type->maxItems;
if (maxItems == 0) {
maxItems = 1;
}
type->curItems = maxItems;
this->values = calloc(maxItems, sizeof(double));
this->values = calloc(sizeof(double), type->items);
this->total = type->total;
this->caption = strdup(type->caption);
if (Meter_initFn(this))
Meter_init(this);
Meter_setMode(this, type->defaultMode);
((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);
return this;
}
void Meter_delete(Object* cast) {
if (!cast)
return;
Meter* this = (Meter*) cast;
if (Meter_doneFn(this)) {
Meter_done(this);
assert (this != NULL);
if (this->type->done) {
this->type->done(this);
}
if (this->drawData)
free(this->drawData);
if (this->drawBuffer)
free(this->drawBuffer);
free(this->caption);
free(this->values);
free(this);
}
void Meter_setCaption(Meter* this, const char* caption) {
void Meter_setCaption(Meter* this, char* caption) {
free(this->caption);
this->caption = strdup(caption);
}
static inline void Meter_displayBuffer(Meter* this, char* buffer, RichString* out) {
if (Object_displayFn(this)) {
Object_display(this, out);
/* private */
inline static void Meter_displayToStringBuffer(Meter* this, char* buffer) {
MeterType* type = this->type;
Object_Display display = ((Object*)this)->display;
if (display) {
display((Object*)this, &Meter_stringBuffer);
} else {
RichString_write(out, CRT_colors[Meter_attributes(this)[0]], buffer);
RichString_prune(&Meter_stringBuffer);
RichString_append(&Meter_stringBuffer, CRT_colors[type->attributes[0]], buffer);
}
}
@ -200,15 +227,15 @@ void Meter_setMode(Meter* this, int modeIndex) {
if (!modeIndex)
modeIndex = 1;
assert(modeIndex < LAST_METERMODE);
if (Meter_defaultMode(this) == CUSTOM_METERMODE) {
this->draw = Meter_drawFn(this);
if (Meter_updateModeFn(this))
Meter_updateMode(this, modeIndex);
if (this->type->mode == 0) {
this->draw = this->type->draw;
if (this->type->setMode)
this->type->setMode(this, modeIndex);
} else {
assert(modeIndex >= 1);
if (this->drawData)
free(this->drawData);
this->drawData = NULL;
if (this->drawBuffer)
free(this->drawBuffer);
this->drawBuffer = NULL;
MeterMode* mode = Meter_modes[modeIndex];
this->draw = mode->draw;
@ -218,6 +245,7 @@ void Meter_setMode(Meter* this, int modeIndex) {
}
ListItem* Meter_toListItem(Meter* this) {
MeterType* type = this->type;
char mode[21];
if (this->mode)
snprintf(mode, 20, " [%s]", Meter_modes[this->mode]->uiName);
@ -229,41 +257,42 @@ ListItem* Meter_toListItem(Meter* this) {
else
number[0] = '\0';
char buffer[51];
snprintf(buffer, 50, "%s%s%s", Meter_uiName(this), number, mode);
snprintf(buffer, 50, "%s%s%s", type->uiName, number, mode);
return ListItem_new(buffer, 0);
}
/* ---------- TextMeterMode ---------- */
static void TextMeterMode_draw(Meter* this, int x, int y, int w) {
void TextMeterMode_draw(Meter* this, int x, int y, int w) {
MeterType* type = this->type;
char buffer[METER_BUFFER_LEN];
Meter_setValues(this, buffer, METER_BUFFER_LEN - 1);
(void) w;
type->setValues(this, buffer, METER_BUFFER_LEN - 1);
attrset(CRT_colors[METER_TEXT]);
mvaddstr(y, x, this->caption);
int captionLen = strlen(this->caption);
w -= captionLen;
x += captionLen;
Meter_displayToStringBuffer(this, buffer);
mvhline(y, x, ' ', CRT_colors[DEFAULT_COLOR]);
attrset(CRT_colors[RESET_COLOR]);
RichString_begin(out);
Meter_displayBuffer(this, buffer, &out);
RichString_printVal(out, y, x);
RichString_end(out);
mvaddchstr(y, x, Meter_stringBuffer.chstr);
}
/* ---------- BarMeterMode ---------- */
static char BarMeterMode_characters[] = "|#*@$%&";
/* private property */
char BarMeterMode_characters[] = "|#*@$%&";
static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
void BarMeterMode_draw(Meter* this, int x, int y, int w) {
MeterType* type = this->type;
char buffer[METER_BUFFER_LEN];
Meter_setValues(this, buffer, METER_BUFFER_LEN - 1);
type->setValues(this, buffer, METER_BUFFER_LEN - 1);
w -= 2;
attrset(CRT_colors[METER_TEXT]);
int captionLen = 3;
mvaddnstr(y, x, this->caption, captionLen);
mvaddstr(y, x, this->caption);
int captionLen = strlen(this->caption);
x += captionLen;
w -= captionLen;
attrset(CRT_colors[BAR_BORDER]);
@ -272,24 +301,18 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
w--;
x++;
if (w < 1) {
attrset(CRT_colors[RESET_COLOR]);
return;
}
char bar[w + 1];
char bar[w];
int blockSizes[10];
for (int i = 0; i < w; i++)
bar[i] = ' ';
const size_t barOffset = w - MIN((int)strlen(buffer), w);
snprintf(bar + barOffset, w - barOffset + 1, "%s", buffer);
sprintf(bar + (w-strlen(buffer)), "%s", buffer);
// First draw in the bar[] buffer...
double total = 0.0;
int offset = 0;
int items = Meter_getItems(this);
for (int i = 0; i < items; i++) {
for (int i = 0; i < type->items; i++) {
double value = this->values[i];
value = MAX(value, 0);
value = MIN(value, this->total);
@ -310,12 +333,13 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
}
}
offset = nextOffset;
total += this->values[i];
}
// ...then print the buffer.
offset = 0;
for (int i = 0; i < items; i++) {
attrset(CRT_colors[Meter_attributes(this)[i]]);
for (int i = 0; i < type->items; i++) {
attrset(CRT_colors[type->attributes[i]]);
mvaddnstr(y, x + offset, bar + offset, blockSizes[i]);
offset += blockSizes[i];
offset = MAX(offset, 0);
@ -330,58 +354,49 @@ static void BarMeterMode_draw(Meter* this, int x, int y, int w) {
attrset(CRT_colors[RESET_COLOR]);
}
#ifdef USE_FUNKY_MODES
/* ---------- GraphMeterMode ---------- */
#define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0)
static int GraphMeterMode_colors[21] = {
GRAPH_1, GRAPH_1, GRAPH_1,
GRAPH_2, GRAPH_2, GRAPH_2,
GRAPH_3, GRAPH_3, GRAPH_3,
GRAPH_4, GRAPH_4, GRAPH_4,
GRAPH_5, GRAPH_5, GRAPH_6,
GRAPH_7, GRAPH_7, GRAPH_7,
GRAPH_8, GRAPH_8, GRAPH_9
/* 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 const char* GraphMeterMode_characters = "^`'-.,_~'`-.,_~'`-.,_";
/* private property */
static char* GraphMeterMode_characters = "^`'-.,_~'`-.,_~'`-.,_";
static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
if (!this->drawData) this->drawData = calloc(1, sizeof(GraphData));
GraphData* data = (GraphData*) this->drawData;
const int nValues = METER_BUFFER_LEN;
struct timeval now;
gettimeofday(&now, NULL);
if (!timercmp(&now, &(data->time), <)) {
struct timeval delay = { .tv_sec = (int)(DEFAULT_DELAY/10), .tv_usec = (DEFAULT_DELAY-((int)(DEFAULT_DELAY/10)*10)) * 100000 };
timeradd(&now, &delay, &(data->time));
if (!this->drawBuffer) this->drawBuffer = calloc(sizeof(double), METER_BUFFER_LEN);
double* drawBuffer = (double*) this->drawBuffer;
for (int i = 0; i < nValues - 1; i++)
data->values[i] = data->values[i+1];
char buffer[nValues];
Meter_setValues(this, buffer, nValues - 1);
double value = 0.0;
int items = Meter_getItems(this);
for (int i = 0; i < items; i++)
value += this->values[i];
value /= this->total;
data->values[nValues - 1] = value;
}
for (int i = nValues - w, k = 0; i < nValues; i++, k++) {
double value = data->values[i];
for (int i = 0; i < METER_BUFFER_LEN - 1; i++)
drawBuffer[i] = drawBuffer[i+1];
MeterType* type = this->type;
char buffer[METER_BUFFER_LEN];
type->setValues(this, buffer, METER_BUFFER_LEN - 1);
double value = 0.0;
for (int i = 0; i < type->items; i++)
value += this->values[i];
value /= this->total;
drawBuffer[METER_BUFFER_LEN - 1] = value;
for (int i = METER_BUFFER_LEN - w, k = 0; i < METER_BUFFER_LEN; i++, k++) {
double value = drawBuffer[i];
DrawDot( CRT_colors[DEFAULT_COLOR], y, ' ' );
DrawDot( CRT_colors[DEFAULT_COLOR], y+1, ' ' );
DrawDot( CRT_colors[DEFAULT_COLOR], y+2, ' ' );
double threshold = 1.00;
for (int j = 0; j < 21; j++, threshold -= 0.05)
for (int i = 0; i < 21; i++, threshold -= 0.05)
if (value >= threshold) {
DrawDot(CRT_colors[GraphMeterMode_colors[j]], y+(j/7.0), GraphMeterMode_characters[j]);
DrawDot(CRT_colors[GraphMeterMode_colors[i]], y+(i/7.0), GraphMeterMode_characters[i]);
break;
}
}
@ -390,114 +405,40 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
/* ---------- LEDMeterMode ---------- */
static const char* LEDMeterMode_digitsAscii[3][10] = {
/* private */
static char* LEDMeterMode_digits[3][10] = {
{ " __ "," "," __ "," __ "," "," __ "," __ "," __ "," __ "," __ "},
{ "| |"," |"," __|"," __|","|__|","|__ ","|__ "," |","|__|","|__|"},
{ "|__|"," |","|__ "," __|"," |"," __|","|__|"," |","|__|"," __|"},
};
static const char* LEDMeterMode_digitsUtf8[3][10] = {
{ "┌──┐","","╶──┐","╶──┐","╷ ╷","┌──╴","┌──╴","╶──┐","┌──┐","┌──┐"},
{ "│ │","","┌──┘"," ──┤","└──┤","└──┐","├──┐","","├──┤","└──┤"},
{ "└──┘","","└──╴","╶──┘","","╶──┘","└──┘","","└──┘"," ──┘"},
};
/* private */
static void LEDMeterMode_drawDigit(int x, int y, int n) {
if (CRT_utf8) {
for (int i = 0; i < 3; i++)
mvaddstr(y+i, x, LEDMeterMode_digitsUtf8[i][n]);
} else {
for (int i = 0; i < 3; i++)
mvaddstr(y+i, x, LEDMeterMode_digitsAscii[i][n]);
}
for (int i = 0; i < 3; i++)
mvaddstr(y+i, x, LEDMeterMode_digits[i][n]);
}
static void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
(void) w;
void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
MeterType* type = this->type;
char buffer[METER_BUFFER_LEN];
Meter_setValues(this, buffer, METER_BUFFER_LEN - 1);
RichString_begin(out);
Meter_displayBuffer(this, buffer, &out);
type->setValues(this, buffer, METER_BUFFER_LEN - 1);
Meter_displayToStringBuffer(this, buffer);
int yText = CRT_utf8 ? y+1 : y+2;
attrset(CRT_colors[LED_COLOR]);
mvaddstr(yText, x, this->caption);
mvaddstr(y+2, x, this->caption);
int xx = x + strlen(this->caption);
int len = RichString_sizeVal(out);
for (int i = 0; i < len; i++) {
char c = RichString_getCharVal(out, i);
for (int i = 0; i < Meter_stringBuffer.len; i++) {
char c = Meter_stringBuffer.chstr[i];
if (c >= '0' && c <= '9') {
LEDMeterMode_drawDigit(xx, y, c-48);
xx += 4;
} else {
mvaddch(yText, xx, c);
mvaddch(y+2, xx, c);
xx += 1;
}
}
attrset(CRT_colors[RESET_COLOR]);
RichString_end(out);
}
static MeterMode BarMeterMode = {
.uiName = "Bar",
.h = 1,
.draw = BarMeterMode_draw,
};
static MeterMode TextMeterMode = {
.uiName = "Text",
.h = 1,
.draw = TextMeterMode_draw,
};
static MeterMode GraphMeterMode = {
.uiName = "Graph",
.h = 3,
.draw = GraphMeterMode_draw,
};
static MeterMode LEDMeterMode = {
.uiName = "LED",
.h = 3,
.draw = LEDMeterMode_draw,
};
MeterMode* Meter_modes[] = {
NULL,
&BarMeterMode,
&TextMeterMode,
&GraphMeterMode,
&LEDMeterMode,
NULL
};
/* Blank meter */
static void BlankMeter_setValues(Meter* this, char* buffer, int size) {
(void) this; (void) buffer; (void) size;
}
static void BlankMeter_display(Object* cast, RichString* out) {
(void) cast;
RichString_prune(out);
}
int BlankMeter_attributes[] = {
DEFAULT_COLOR
};
MeterClass BlankMeter_class = {
.super = {
.extends = Class(Meter),
.delete = Meter_delete,
.display = BlankMeter_display,
},
.setValues = BlankMeter_setValues,
.defaultMode = TEXT_METERMODE,
.total = 100.0,
.attributes = BlankMeter_attributes,
.name = "Blank",
.uiName = "Blank",
.caption = ""
};
#endif

149
Meter.h
View File

@ -3,91 +3,106 @@
#ifndef HEADER_Meter
#define HEADER_Meter
/*
htop - Meter.h
(C) 2004-2011 Hisham H. Muhammad
htop - Meter.c
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define METER_BUFFER_LEN 128
#define _GNU_SOURCE
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <curses.h>
#include <stdarg.h>
#include "Object.h"
#include "CRT.h"
#include "ListItem.h"
#include "String.h"
#include "ProcessList.h"
typedef struct Meter_ Meter;
#include "debug.h"
#include <assert.h>
typedef void(*Meter_Init)(Meter*);
typedef void(*Meter_Done)(Meter*);
typedef void(*Meter_UpdateMode)(Meter*, int);
#ifndef USE_FUNKY_MODES
#define USE_FUNKY_MODES 1
#endif
#define METER_BUFFER_LEN 128
typedef struct Meter_ Meter;
typedef struct MeterType_ MeterType;
typedef struct MeterMode_ MeterMode;
typedef void(*MeterType_Init)(Meter*);
typedef void(*MeterType_Done)(Meter*);
typedef void(*MeterType_SetMode)(Meter*, int);
typedef void(*Meter_SetValues)(Meter*, char*, int);
typedef void(*Meter_Draw)(Meter*, int, int, int);
typedef struct MeterClass_ {
ObjectClass super;
const Meter_Init init;
const Meter_Done done;
const Meter_UpdateMode updateMode;
const Meter_Draw draw;
const Meter_SetValues setValues;
const int defaultMode;
const double total;
const int* attributes;
const char* name;
const char* uiName;
const char* caption;
const char maxItems;
char curItems;
} MeterClass;
struct MeterMode_ {
Meter_Draw draw;
char* uiName;
int h;
};
#define As_Meter(this_) ((MeterClass*)((this_)->super.klass))
#define Meter_initFn(this_) As_Meter(this_)->init
#define Meter_init(this_) As_Meter(this_)->init((Meter*)(this_))
#define Meter_done(this_) As_Meter(this_)->done((Meter*)(this_))
#define Meter_updateModeFn(this_) As_Meter(this_)->updateMode
#define Meter_updateMode(this_, m_) As_Meter(this_)->updateMode((Meter*)(this_), m_)
#define Meter_drawFn(this_) As_Meter(this_)->draw
#define Meter_doneFn(this_) As_Meter(this_)->done
#define Meter_setValues(this_, c_, i_) As_Meter(this_)->setValues((Meter*)(this_), c_, i_)
#define Meter_defaultMode(this_) As_Meter(this_)->defaultMode
#define Meter_getItems(this_) As_Meter(this_)->curItems
#define Meter_setItems(this_, n_) As_Meter(this_)->curItems = (n_)
#define Meter_attributes(this_) As_Meter(this_)->attributes
#define Meter_name(this_) As_Meter(this_)->name
#define Meter_uiName(this_) As_Meter(this_)->uiName
struct MeterType_ {
Meter_SetValues setValues;
Object_Display display;
int mode;
int items;
double total;
int* attributes;
char* name;
char* uiName;
char* caption;
MeterType_Init init;
MeterType_Done done;
MeterType_SetMode setMode;
Meter_Draw draw;
};
struct Meter_ {
Object super;
Meter_Draw draw;
char* caption;
MeterType* type;
int mode;
int param;
void* drawData;
Meter_Draw draw;
void* drawBuffer;
int h;
ProcessList* pl;
double* values;
double total;
};
typedef struct MeterMode_ {
Meter_Draw draw;
const char* uiName;
int h;
} MeterMode;
extern char* METER_CLASS;
extern MeterType CPUMeter;
extern MeterType ClockMeter;
extern MeterType LoadAverageMeter;
extern MeterType LoadMeter;
extern MeterType MemoryMeter;
extern MeterType SwapMeter;
extern MeterType TasksMeter;
extern MeterType UptimeMeter;
extern MeterType AllCPUsMeter;
typedef enum {
CUSTOM_METERMODE = 0,
BAR_METERMODE,
TEXT_METERMODE,
#ifdef USE_FUNKY_MODES
GRAPH_METERMODE,
LED_METERMODE,
#endif
LAST_METERMODE
} MeterModeId;
typedef struct GraphData_ {
struct timeval time;
double values[METER_BUFFER_LEN];
} GraphData;
extern MeterType* Meter_types[];
extern MeterMode* Meter_modes[];
#ifndef MIN
@ -97,15 +112,22 @@ typedef struct GraphData_ {
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
extern MeterClass Meter_class;
extern MeterClass* Meter_types[];
Meter* Meter_new(ProcessList* pl, int param, MeterClass* type);
#ifdef USE_FUNKY_MODES
#endif
Meter* Meter_new(ProcessList* pl, int param, MeterType* type);
void Meter_delete(Object* cast);
void Meter_setCaption(Meter* this, const char* caption);
void Meter_setCaption(Meter* this, char* caption);
void Meter_setMode(Meter* this, int modeIndex);
@ -113,20 +135,29 @@ ListItem* Meter_toListItem(Meter* this);
/* ---------- TextMeterMode ---------- */
void TextMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- BarMeterMode ---------- */
void BarMeterMode_draw(Meter* this, int x, int y, int w);
#ifdef USE_FUNKY_MODES
/* ---------- GraphMeterMode ---------- */
#define DrawDot(a,y,c) do { attrset(a); mvaddch(y, x+k, c); } while(0)
void GraphMeterMode_draw(Meter* this, int x, int y, int w);
/* ---------- LEDMeterMode ---------- */
extern MeterMode* Meter_modes[];
/* Blank meter */
extern int BlankMeter_attributes[];
extern MeterClass BlankMeter_class;
void LEDMeterMode_draw(Meter* this, int x, int y, int w);
#endif
#endif

105
MetersListBox.c Normal file
View File

@ -0,0 +1,105 @@
#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;
}

30
MetersListBox.h Normal file
View File

@ -0,0 +1,30 @@
/* 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

View File

@ -1,117 +0,0 @@
/*
htop - MetersPanel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "MetersPanel.h"
#include <stdlib.h>
#include <assert.h>
/*{
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct MetersPanel_ {
Panel super;
Settings* settings;
Vector* meters;
ScreenManager* scr;
} MetersPanel;
}*/
static void MetersPanel_delete(Object* object) {
Panel* super = (Panel*) object;
MetersPanel* this = (MetersPanel*) object;
Panel_done(super);
free(this);
}
static 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;
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;
}
PanelClass MetersPanel_class = {
.super = {
.extends = Class(Panel),
.delete = MetersPanel_delete
},
.eventHandler = MetersPanel_eventHandler
};
MetersPanel* MetersPanel_new(Settings* settings, const char* header, Vector* meters, ScreenManager* scr) {
MetersPanel* this = AllocThis(MetersPanel);
Panel* super = (Panel*) this;
Panel_init(super, 1, 1, 1, 1, Class(ListItem), true);
this->settings = settings;
this->meters = meters;
this->scr = scr;
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;
}

View File

@ -1,29 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_MetersPanel
#define HEADER_MetersPanel
/*
htop - MetersPanel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct MetersPanel_ {
Panel super;
Settings* settings;
Vector* meters;
ScreenManager* scr;
} MetersPanel;
extern PanelClass MetersPanel_class;
MetersPanel* MetersPanel_new(Settings* settings, const char* header, Vector* meters, ScreenManager* scr);
#endif

4
NEWS
View File

@ -1,5 +1,5 @@
See the commit history for news of the past.
See the bug tracker for news of the future.
See the ChangeLog for news of the past.
See the TODO list for news of the future.
Run the program for news of the present.

View File

@ -1,62 +1,60 @@
/*
htop - Object.c
(C) 2004-2012 Hisham H. Muhammad
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 "RichString.h"
#include "CRT.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "debug.h"
/*{
#include "RichString.h"
typedef struct Object_ Object;
typedef void(*Object_Display)(Object*, RichString*);
typedef int(*Object_Compare)(const void*, const void*);
typedef int(*Object_Compare)(const Object*, const Object*);
typedef void(*Object_Delete)(Object*);
#define Object_getClass(obj_) ((Object*)(obj_))->klass
#define Object_setClass(obj_, class_) Object_getClass(obj_) = (ObjectClass*) class_
#define Object_delete(obj_) Object_getClass(obj_)->delete((Object*)(obj_))
#define Object_displayFn(obj_) Object_getClass(obj_)->display
#define Object_display(obj_, str_) Object_getClass(obj_)->display((Object*)(obj_), str_)
#define Object_compare(obj_, other_) Object_getClass(obj_)->compare((const void*)(obj_), other_)
#define Class(class_) ((ObjectClass*)(&(class_ ## _class)))
#define AllocThis(class_) (class_*) malloc(sizeof(class_)); Object_setClass(this, Class(class_));
typedef struct ObjectClass_ {
const void* extends;
const Object_Display display;
const Object_Delete delete;
const Object_Compare compare;
} ObjectClass;
struct Object_ {
ObjectClass* klass;
char* class;
Object_Display display;
Object_Compare compare;
Object_Delete delete;
};
}*/
ObjectClass Object_class = {
.extends = NULL
};
/* private property */
char* OBJECT_CLASS = "Object";
#ifdef DEBUG
bool Object_isA(Object* o, const ObjectClass* klass) {
if (!o)
return false;
const ObjectClass* type = o->klass;
while (type) {
if (type == klass)
return true;
type = type->extends;
}
return false;
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;
}
#endif
bool Object_instanceOf(Object* this, char* class) {
return this->class == class;
}
void Object_delete(Object* this) {
free(this);
}
void Object_display(Object* this, RichString* out) {
char objAddress[50];
sprintf(objAddress, "%s @ %p", this->class, (void*) this);
RichString_write(out, CRT_colors[DEFAULT_COLOR], objAddress);
}
int Object_compare(const Object* this, const Object* o) {
return (this - o);
}

View File

@ -1,52 +1,44 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_Object
#define HEADER_Object
/*
htop - Object.h
(C) 2004-2012 Hisham H. Muhammad
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 "RichString.h"
#include "CRT.h"
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include "debug.h"
typedef struct Object_ Object;
typedef void(*Object_Display)(Object*, RichString*);
typedef int(*Object_Compare)(const void*, const void*);
typedef int(*Object_Compare)(const Object*, const Object*);
typedef void(*Object_Delete)(Object*);
#define Object_getClass(obj_) ((Object*)(obj_))->klass
#define Object_setClass(obj_, class_) Object_getClass(obj_) = (ObjectClass*) class_
#define Object_delete(obj_) Object_getClass(obj_)->delete((Object*)(obj_))
#define Object_displayFn(obj_) Object_getClass(obj_)->display
#define Object_display(obj_, str_) Object_getClass(obj_)->display((Object*)(obj_), str_)
#define Object_compare(obj_, other_) Object_getClass(obj_)->compare((const void*)(obj_), other_)
#define Class(class_) ((ObjectClass*)(&(class_ ## _class)))
#define AllocThis(class_) (class_*) malloc(sizeof(class_)); Object_setClass(this, Class(class_));
typedef struct ObjectClass_ {
const void* extends;
const Object_Display display;
const Object_Delete delete;
const Object_Compare compare;
} ObjectClass;
struct Object_ {
ObjectClass* klass;
char* class;
Object_Display display;
Object_Compare compare;
Object_Delete delete;
};
extern ObjectClass Object_class;
void Object_new();
#ifdef DEBUG
bool Object_instanceOf(Object* this, char* class);
bool Object_isA(Object* o, const ObjectClass* klass);
#endif
void Object_delete(Object* this);
void Object_display(Object* this, RichString* out);
int Object_compare(const Object* this, const Object* o);
#endif

View File

@ -1,246 +0,0 @@
/*
htop - OpenFilesScreen.c
(C) 2005-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "OpenFilesScreen.h"
#include "CRT.h"
#include "ProcessList.h"
#include "ListItem.h"
#include "IncSet.h"
#include "String.h"
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/wait.h>
/*{
#include "Process.h"
#include "Panel.h"
#include "FunctionBar.h"
typedef struct OpenFiles_Data_ {
char* data[256];
} OpenFiles_Data;
typedef struct OpenFiles_ProcessData_ {
OpenFiles_Data data;
int error;
struct OpenFiles_FileData_* files;
} OpenFiles_ProcessData;
typedef struct OpenFiles_FileData_ {
OpenFiles_Data data;
struct OpenFiles_FileData_* next;
} OpenFiles_FileData;
typedef struct OpenFilesScreen_ {
Process* process;
pid_t pid;
Panel* display;
FunctionBar* bar;
} OpenFilesScreen;
}*/
static const char* ofsFunctions[] = {"Search ", "Filter ", "Refresh", "Done ", NULL};
static const char* ofsKeys[] = {"F3", "F4", "F5", "Esc"};
static int ofsEvents[] = {KEY_F(3), KEY_F(4), KEY_F(5), 27};
OpenFilesScreen* OpenFilesScreen_new(Process* process) {
OpenFilesScreen* this = (OpenFilesScreen*) malloc(sizeof(OpenFilesScreen));
this->process = process;
this->display = Panel_new(0, 1, COLS, LINES-3, false, Class(ListItem));
if (Process_isThread(process))
this->pid = process->tgid;
else
this->pid = process->pid;
return this;
}
void OpenFilesScreen_delete(OpenFilesScreen* this) {
Panel_delete((Object*)this->display);
free(this);
}
static void OpenFilesScreen_draw(OpenFilesScreen* this, IncSet* inc) {
attrset(CRT_colors[METER_TEXT]);
mvhline(0, 0, ' ', COLS);
mvprintw(0, 0, "Snapshot of files open in process %d - %s", this->pid, this->process->comm);
attrset(CRT_colors[DEFAULT_COLOR]);
Panel_draw(this->display, true);
IncSet_drawBar(inc);
}
static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) {
char command[1025];
snprintf(command, 1024, "lsof -P -p %d -F 2> /dev/null", pid);
FILE* fd = popen(command, "r");
OpenFiles_ProcessData* pdata = calloc(1, sizeof(OpenFiles_ProcessData));
OpenFiles_FileData* fdata = NULL;
OpenFiles_Data* item = &(pdata->data);
if (!fd) {
pdata->error = 127;
return pdata;
}
while (!feof(fd)) {
int cmd = fgetc(fd);
if (cmd == EOF)
break;
char* entry = malloc(1024);
if (!fgets(entry, 1024, fd)) {
free(entry);
break;
}
char* newline = strrchr(entry, '\n');
*newline = '\0';
if (cmd == 'f') {
OpenFiles_FileData* nextFile = calloc(1, sizeof(OpenFiles_FileData));
if (fdata == NULL) {
pdata->files = nextFile;
} else {
fdata->next = nextFile;
}
fdata = nextFile;
item = &(fdata->data);
}
assert(cmd >= 0 && cmd <= 0xff);
item->data[cmd] = entry;
}
pdata->error = pclose(fd);
return pdata;
}
static inline void addLine(const char* line, Vector* lines, Panel* panel, const char* incFilter) {
Vector_add(lines, (Object*) ListItem_new(line, 0));
if (!incFilter || String_contains_i(line, incFilter))
Panel_add(panel, (Object*)Vector_get(lines, Vector_size(lines)-1));
}
static inline void OpenFiles_Data_clear(OpenFiles_Data* data) {
for (int i = 0; i < 255; i++)
if (data->data[i])
free(data->data[i]);
}
static void OpenFilesScreen_scan(OpenFilesScreen* this, Vector* lines, IncSet* inc) {
Panel* panel = this->display;
int idx = Panel_getSelectedIndex(panel);
Panel_prune(panel);
OpenFiles_ProcessData* pdata = OpenFilesScreen_getProcessData(this->pid);
if (pdata->error == 127) {
addLine("Could not execute 'lsof'. Please make sure it is available in your $PATH.", lines, panel, IncSet_filter(inc));
} else if (pdata->error == 1) {
addLine("Failed listing open files.", lines, panel, IncSet_filter(inc));
} else {
OpenFiles_FileData* fdata = pdata->files;
while (fdata) {
char entry[1024];
char** data = fdata->data.data;
sprintf(entry, "%5s %4s %10s %10s %10s %s",
data['f'] ? data['f'] : "",
data['t'] ? data['t'] : "",
data['D'] ? data['D'] : "",
data['s'] ? data['s'] : "",
data['i'] ? data['i'] : "",
data['n'] ? data['n'] : "");
addLine(entry, lines, panel, IncSet_filter(inc));
OpenFiles_Data_clear(&fdata->data);
OpenFiles_FileData* old = fdata;
fdata = fdata->next;
free(old);
}
OpenFiles_Data_clear(&pdata->data);
}
free(pdata);
Vector_insertionSort(lines);
Vector_insertionSort(panel->items);
Panel_setSelected(panel, idx);
}
void OpenFilesScreen_run(OpenFilesScreen* this) {
Panel* panel = this->display;
Panel_setHeader(panel, " FD TYPE DEVICE SIZE NODE NAME");
FunctionBar* bar = FunctionBar_new(ofsFunctions, ofsKeys, ofsEvents);
IncSet* inc = IncSet_new(bar);
Vector* lines = Vector_new(panel->items->type, true, DEFAULT_SIZE);
OpenFilesScreen_scan(this, lines, inc);
OpenFilesScreen_draw(this, inc);
bool looping = true;
while (looping) {
Panel_draw(panel, true);
if (inc->active)
move(LINES-1, CRT_cursorX);
int ch = getch();
if (ch == KEY_MOUSE) {
MEVENT mevent;
int ok = getmouse(&mevent);
if (ok == OK)
if (mevent.y >= panel->y && mevent.y < LINES - 1) {
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV);
ch = 0;
} if (mevent.y == LINES - 1)
ch = FunctionBar_synthesizeEvent(inc->bar, mevent.x);
}
if (inc->active) {
IncSet_handleKey(inc, ch, panel, IncSet_getListItemValue, lines);
continue;
}
switch(ch) {
case ERR:
continue;
case KEY_F(3):
case '/':
IncSet_activate(inc, INC_SEARCH);
break;
case KEY_F(4):
case '\\':
IncSet_activate(inc, INC_FILTER);
break;
case KEY_F(5):
clear();
OpenFilesScreen_scan(this, lines, inc);
OpenFilesScreen_draw(this, inc);
break;
case '\014': // Ctrl+L
clear();
OpenFilesScreen_draw(this, inc);
break;
case 'q':
case 27:
case KEY_F(10):
looping = false;
break;
case KEY_RESIZE:
Panel_resize(panel, COLS, LINES-2);
OpenFilesScreen_draw(this, inc);
break;
default:
Panel_onKey(panel, ch);
}
}
Vector_delete(lines);
FunctionBar_delete((Object*)bar);
IncSet_delete(inc);
}

View File

@ -1,45 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_OpenFilesScreen
#define HEADER_OpenFilesScreen
/*
htop - OpenFilesScreen.h
(C) 2005-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Process.h"
#include "Panel.h"
#include "FunctionBar.h"
typedef struct OpenFiles_Data_ {
char* data[256];
} OpenFiles_Data;
typedef struct OpenFiles_ProcessData_ {
OpenFiles_Data data;
int error;
struct OpenFiles_FileData_* files;
} OpenFiles_ProcessData;
typedef struct OpenFiles_FileData_ {
OpenFiles_Data data;
struct OpenFiles_FileData_* next;
} OpenFiles_FileData;
typedef struct OpenFilesScreen_ {
Process* process;
pid_t pid;
Panel* display;
FunctionBar* bar;
} OpenFilesScreen;
OpenFilesScreen* OpenFilesScreen_new(Process* process);
void OpenFilesScreen_delete(OpenFilesScreen* this);
void OpenFilesScreen_run(OpenFilesScreen* this);
#endif

451
Panel.c
View File

@ -1,451 +0,0 @@
/*
htop - Panel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "CRT.h"
#include "RichString.h"
#include "ListItem.h"
#include "String.h"
#include <math.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
//#link curses
/*{
#include "Object.h"
#include "Vector.h"
typedef struct Panel_ Panel;
typedef enum HandlerResult_ {
HANDLED,
IGNORED,
BREAK_LOOP
} HandlerResult;
#define EVENT_SETSELECTED -1
typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
typedef struct PanelClass_ {
const ObjectClass super;
const Panel_EventHandler eventHandler;
} PanelClass;
#define As_Panel(this_) ((PanelClass*)((this_)->super.klass))
#define Panel_eventHandlerFn(this_) As_Panel(this_)->eventHandler
#define Panel_eventHandler(this_, ev_) As_Panel(this_)->eventHandler((Panel*)(this_), ev_)
struct Panel_ {
Object super;
PanelClass* class;
int x, y, w, h;
WINDOW* window;
Vector* items;
int selected;
int oldSelected;
char* eventHandlerBuffer;
int scrollV;
short scrollH;
bool needsRedraw;
RichString header;
};
}*/
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#define KEY_CTRLN 0016 /* control-n key */
#define KEY_CTRLP 0020 /* control-p key */
#define KEY_CTRLF 0006 /* control-f key */
#define KEY_CTRLB 0002 /* control-b key */
PanelClass Panel_class = {
.super = {
.extends = Class(Object),
.delete = Panel_delete
},
.eventHandler = Panel_selectByTyping
};
Panel* Panel_new(int x, int y, int w, int h, bool owner, ObjectClass* type) {
Panel* this;
this = malloc(sizeof(Panel));
Object_setClass(this, Class(Panel));
Panel_init(this, x, y, w, h, type, owner);
return this;
}
void Panel_delete(Object* cast) {
Panel* this = (Panel*)cast;
Panel_done(this);
free(this);
}
void Panel_init(Panel* this, int x, int y, int w, int h, ObjectClass* type, bool owner) {
this->x = x;
this->y = y;
this->w = w;
this->h = h;
this->eventHandlerBuffer = NULL;
this->items = Vector_new(type, owner, DEFAULT_SIZE);
this->scrollV = 0;
this->scrollH = 0;
this->selected = 0;
this->oldSelected = 0;
this->needsRedraw = true;
RichString_beginAllocated(this->header);
}
void Panel_done(Panel* this) {
assert (this != NULL);
free(this->eventHandlerBuffer);
Vector_delete(this->items);
RichString_end(this->header);
}
RichString* Panel_getHeader(Panel* this) {
assert (this != NULL);
this->needsRedraw = true;
return &(this->header);
}
inline void Panel_setHeader(Panel* this, const char* header) {
RichString_write(&(this->header), CRT_colors[PANEL_HEADER_FOCUS], header);
this->needsRedraw = true;
}
void Panel_move(Panel* this, int x, int y) {
assert (this != NULL);
this->x = x;
this->y = y;
this->needsRedraw = true;
}
void Panel_resize(Panel* this, int w, int h) {
assert (this != NULL);
if (RichString_sizeVal(this->header) > 0)
h--;
this->w = w;
this->h = h;
this->needsRedraw = true;
}
void Panel_prune(Panel* this) {
assert (this != NULL);
Vector_prune(this->items);
this->scrollV = 0;
this->selected = 0;
this->oldSelected = 0;
this->needsRedraw = true;
}
void Panel_add(Panel* this, Object* o) {
assert (this != NULL);
Vector_add(this->items, o);
this->needsRedraw = true;
}
void Panel_insert(Panel* this, int i, Object* o) {
assert (this != NULL);
Vector_insert(this->items, i, o);
this->needsRedraw = true;
}
void Panel_set(Panel* this, int i, Object* o) {
assert (this != NULL);
Vector_set(this->items, i, o);
}
Object* Panel_get(Panel* this, int i) {
assert (this != NULL);
return Vector_get(this->items, i);
}
Object* Panel_remove(Panel* this, int i) {
assert (this != NULL);
this->needsRedraw = true;
Object* removed = Vector_remove(this->items, i);
if (this->selected > 0 && this->selected >= Vector_size(this->items))
this->selected--;
return removed;
}
Object* Panel_getSelected(Panel* this) {
assert (this != NULL);
if (Vector_size(this->items) > 0)
return Vector_get(this->items, this->selected);
else
return NULL;
}
void Panel_moveSelectedUp(Panel* this) {
assert (this != NULL);
Vector_moveUp(this->items, this->selected);
if (this->selected > 0)
this->selected--;
}
void Panel_moveSelectedDown(Panel* this) {
assert (this != NULL);
Vector_moveDown(this->items, this->selected);
if (this->selected + 1 < Vector_size(this->items))
this->selected++;
}
int Panel_getSelectedIndex(Panel* this) {
assert (this != NULL);
return this->selected;
}
int Panel_size(Panel* this) {
assert (this != NULL);
return Vector_size(this->items);
}
void Panel_setSelected(Panel* this, int selected) {
assert (this != NULL);
selected = MAX(0, MIN(Vector_size(this->items) - 1, selected));
this->selected = selected;
if (Panel_eventHandlerFn(this)) {
Panel_eventHandler(this, EVENT_SETSELECTED);
}
}
void Panel_draw(Panel* this, bool focus) {
assert (this != NULL);
int itemCount = Vector_size(this->items);
int scrollH = this->scrollH;
int y = this->y; int x = this->x;
int first = this->scrollV;
if (itemCount > this->h && first > itemCount - this->h) {
first = itemCount - this->h;
this->scrollV = first;
}
int last = MIN(itemCount, first + MIN(itemCount, this->h));
if (this->selected < first) {
first = this->selected;
this->scrollV = first;
this->needsRedraw = true;
}
if (this->selected >= last) {
last = MIN(itemCount, this->selected + 1);
first = MAX(0, last - this->h);
this->scrollV = first;
this->needsRedraw = true;
}
assert(first >= 0);
assert(last <= itemCount);
int headerLen = RichString_sizeVal(this->header);
if (headerLen > 0) {
int attr = focus
? CRT_colors[PANEL_HEADER_FOCUS]
: CRT_colors[PANEL_HEADER_UNFOCUS];
attrset(attr);
mvhline(y, x, ' ', this->w);
if (scrollH < headerLen) {
RichString_printoffnVal(this->header, y, x, scrollH,
MIN(headerLen - scrollH, this->w));
}
attrset(CRT_colors[RESET_COLOR]);
y++;
}
int highlight = focus
? CRT_colors[PANEL_HIGHLIGHT_FOCUS]
: CRT_colors[PANEL_HIGHLIGHT_UNFOCUS];
if (this->needsRedraw) {
for(int i = first, j = 0; j < this->h && i < last; i++, j++) {
Object* itemObj = Vector_get(this->items, i);
assert(itemObj); if(!itemObj) continue;
RichString_begin(item);
Object_display(itemObj, &item);
int itemLen = RichString_sizeVal(item);
int amt = MIN(itemLen - scrollH, this->w);
bool selected = (i == this->selected);
if (selected) {
attrset(highlight);
RichString_setAttr(&item, highlight);
}
mvhline(y + j, x, ' ', this->w);
if (amt > 0)
RichString_printoffnVal(item, y+j, x, scrollH, amt);
if (selected)
attrset(CRT_colors[RESET_COLOR]);
RichString_end(item);
}
for (int i = y + (last - first); i < y + this->h; i++)
mvhline(i, x+0, ' ', this->w);
this->needsRedraw = false;
} else {
Object* oldObj = Vector_get(this->items, this->oldSelected);
assert(oldObj);
RichString_begin(old);
Object_display(oldObj, &old);
int oldLen = RichString_sizeVal(old);
Object* newObj = Vector_get(this->items, this->selected);
RichString_begin(new);
Object_display(newObj, &new);
int newLen = RichString_sizeVal(new);
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
if (scrollH < oldLen)
RichString_printoffnVal(old, y+this->oldSelected - this->scrollV, x,
scrollH, MIN(oldLen - scrollH, this->w));
attrset(highlight);
mvhline(y+this->selected - this->scrollV, x+0, ' ', this->w);
RichString_setAttr(&new, highlight);
if (scrollH < newLen)
RichString_printoffnVal(new, y+this->selected - this->scrollV, x,
scrollH, MIN(newLen - scrollH, this->w));
attrset(CRT_colors[RESET_COLOR]);
RichString_end(new);
RichString_end(old);
}
this->oldSelected = this->selected;
move(0, 0);
}
bool Panel_onKey(Panel* this, int key) {
assert (this != NULL);
switch (key) {
case KEY_DOWN:
case KEY_CTRLN:
if (this->selected + 1 < Vector_size(this->items))
this->selected++;
return true;
case KEY_UP:
case KEY_CTRLP:
if (this->selected > 0)
this->selected--;
return true;
#ifdef KEY_C_DOWN
case KEY_C_DOWN:
if (this->selected + 1 < Vector_size(this->items)) {
this->selected++;
if (this->scrollV < Vector_size(this->items) - this->h) {
this->scrollV++;
this->needsRedraw = true;
}
}
return true;
#endif
#ifdef KEY_C_UP
case KEY_C_UP:
if (this->selected > 0) {
this->selected--;
if (this->scrollV > 0) {
this->scrollV--;
this->needsRedraw = true;
}
}
return true;
#endif
case KEY_LEFT:
case KEY_CTRLB:
if (this->scrollH > 0) {
this->scrollH -= CRT_scrollHAmount;
this->needsRedraw = true;
}
return true;
case KEY_RIGHT:
case KEY_CTRLF:
this->scrollH += CRT_scrollHAmount;
this->needsRedraw = true;
return true;
case KEY_PPAGE:
this->selected -= (this->h - 1);
this->scrollV -= (this->h - 1);
if (this->selected < 0)
this->selected = 0;
if (this->scrollV < 0)
this->scrollV = 0;
this->needsRedraw = true;
return true;
case KEY_NPAGE:
this->selected += (this->h - 1);
int size = Vector_size(this->items);
if (this->selected >= size)
this->selected = size - 1;
this->scrollV += (this->h - 1);
if (this->scrollV >= MAX(0, size - this->h))
this->scrollV = MAX(0, size - this->h - 1);
this->needsRedraw = true;
return true;
case KEY_HOME:
this->selected = 0;
return true;
case KEY_END:
this->selected = Vector_size(this->items) - 1;
return true;
}
return false;
}
HandlerResult Panel_selectByTyping(Panel* this, int ch) {
int size = Panel_size(this);
if (!this->eventHandlerBuffer)
this->eventHandlerBuffer = calloc(100, 1);
if (isalnum(ch)) {
int len = strlen(this->eventHandlerBuffer);
if (len < 99) {
this->eventHandlerBuffer[len] = ch;
this->eventHandlerBuffer[len+1] = '\0';
}
for (int try = 0; try < 2; try++) {
len = strlen(this->eventHandlerBuffer);
for (int i = 0; i < size; i++) {
char* cur = ((ListItem*) Panel_get(this, i))->value;
while (*cur == ' ') cur++;
if (strncasecmp(cur, this->eventHandlerBuffer, len) == 0) {
Panel_setSelected(this, i);
return HANDLED;
}
}
this->eventHandlerBuffer[0] = ch;
this->eventHandlerBuffer[1] = '\0';
}
return HANDLED;
} else if (ch != ERR) {
this->eventHandlerBuffer[0] = '\0';
}
if (ch == 13) {
return BREAK_LOOP;
}
return IGNORED;
}

114
Panel.h
View File

@ -1,114 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_Panel
#define HEADER_Panel
/*
htop - Panel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
//#link curses
#include "Object.h"
#include "Vector.h"
typedef struct Panel_ Panel;
typedef enum HandlerResult_ {
HANDLED,
IGNORED,
BREAK_LOOP
} HandlerResult;
#define EVENT_SETSELECTED -1
typedef HandlerResult(*Panel_EventHandler)(Panel*, int);
typedef struct PanelClass_ {
const ObjectClass super;
const Panel_EventHandler eventHandler;
} PanelClass;
#define As_Panel(this_) ((PanelClass*)((this_)->super.klass))
#define Panel_eventHandlerFn(this_) As_Panel(this_)->eventHandler
#define Panel_eventHandler(this_, ev_) As_Panel(this_)->eventHandler((Panel*)(this_), ev_)
struct Panel_ {
Object super;
PanelClass* class;
int x, y, w, h;
WINDOW* window;
Vector* items;
int selected;
int oldSelected;
char* eventHandlerBuffer;
int scrollV;
short scrollH;
bool needsRedraw;
RichString header;
};
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif
#define KEY_CTRLN 0016 /* control-n key */
#define KEY_CTRLP 0020 /* control-p key */
#define KEY_CTRLF 0006 /* control-f key */
#define KEY_CTRLB 0002 /* control-b key */
extern PanelClass Panel_class;
Panel* Panel_new(int x, int y, int w, int h, bool owner, ObjectClass* type);
void Panel_delete(Object* cast);
void Panel_init(Panel* this, int x, int y, int w, int h, ObjectClass* type, bool owner);
void Panel_done(Panel* this);
RichString* Panel_getHeader(Panel* this);
extern void Panel_setHeader(Panel* this, const char* header);
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_size(Panel* this);
void Panel_setSelected(Panel* this, int selected);
void Panel_draw(Panel* this, bool focus);
bool Panel_onKey(Panel* this, int key);
HandlerResult Panel_selectByTyping(Panel* this, int ch);
#endif

958
Process.c

File diff suppressed because it is too large Load Diff

233
Process.h
View File

@ -1,70 +1,48 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_Process
#define HEADER_Process
/*
htop - Process.h
(C) 2004-2011 Hisham H. Muhammad
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#ifdef HAVE_LIBHWLOC
#endif
#define _GNU_SOURCE
#include "ProcessList.h"
#include "Object.h"
#include "CRT.h"
#include "String.h"
#include "debug.h"
#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <stdbool.h>
#include <pwd.h>
// This works only with glibc 2.1+. On earlier versions
// the behavior is similar to have a hardcoded page size.
#ifndef PAGE_SIZE
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) )
#endif
#define PAGE_SIZE_KB ( PAGE_SIZE / ONE_K )
#define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 )
#include "Object.h"
#include "Affinity.h"
#include "IOPriority.h"
#include <sys/types.h>
#define PROCESS_COMM_LEN 300
#define PROCESS_USER_LEN 10
#define PROCESS_FLAG_IO 1
#define PROCESS_FLAG_IOPRIO 2
#define PROCESS_FLAG_OPENVZ 4
#define PROCESS_FLAG_VSERVER 8
#define PROCESS_FLAG_CGROUP 16
#ifndef Process_isKernelThread
#define Process_isKernelThread(_process) (_process->pgrp == 0)
#endif
#ifndef Process_isUserlandThread
#define Process_isUserlandThread(_process) (_process->pid != _process->tgid)
#endif
#ifndef Process_isThread
#define Process_isThread(_process) (Process_isUserlandThread(_process) || Process_isKernelThread(_process))
#endif
typedef enum ProcessField_ {
PID = 1, COMM, 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, SSIGIGNORE, 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, NLWP, TGID,
#ifdef HAVE_OPENVZ
CTID, VPID,
#endif
#ifdef HAVE_VSERVER
VXID,
#endif
#ifdef HAVE_TASKSTATS
RCHAR, WCHAR, SYSCR, SYSCW, RBYTES, WBYTES, CNCLWB, IO_READ_RATE, IO_WRITE_RATE, IO_RATE,
#endif
#ifdef HAVE_CGROUP
CGROUP,
#endif
#ifdef HAVE_OOM
OOM,
#endif
IO_PRIORITY,
LAST_PROCESSFIELD
USER, TIME, LAST_PROCESSFIELD
} ProcessField;
struct ProcessList_;
@ -73,86 +51,31 @@ typedef struct Process_ {
Object super;
struct ProcessList_ *pl;
bool updated;
pid_t pid;
int pid;
char* comm;
int indent;
char state;
bool tag;
bool showChildren;
bool show;
pid_t ppid;
unsigned int pgrp;
unsigned int session;
unsigned int tty_nr;
pid_t tgid;
int ppid;
int pgrp;
int session;
int tty_nr;
int tpgid;
unsigned long int flags;
uid_t st_uid;
float percent_cpu;
float percent_mem;
char* user;
unsigned long long int utime;
unsigned long long int stime;
unsigned long long int cutime;
unsigned long long int cstime;
long int priority;
long int nice;
long int nlwp;
IOPriority ioPriority;
char starttime_show[8];
time_t starttime_ctime;
#ifdef HAVE_TASKSTATS
unsigned long long io_rchar;
unsigned long long io_wchar;
unsigned long long io_syscr;
unsigned long long io_syscw;
unsigned long long io_read_bytes;
unsigned long long io_write_bytes;
unsigned long long io_cancelled_write_bytes;
double io_rate_read_bps;
unsigned long long io_rate_read_time;
double io_rate_write_bps;
unsigned long long io_rate_write_time;
#endif
int processor;
long m_size;
long m_resident;
long m_share;
long m_trs;
long m_drs;
long m_lrs;
long m_dt;
#ifdef HAVE_OPENVZ
unsigned int ctid;
unsigned int vpid;
#endif
#ifdef HAVE_VSERVER
unsigned int vxid;
#endif
#ifdef HAVE_CGROUP
char* cgroup;
#endif
#ifdef HAVE_OOM
unsigned int oom;
#endif
int exit_signal;
int basenameOffset;
bool updated;
unsigned long int minflt;
unsigned long int cminflt;
unsigned long int majflt;
unsigned long int cmajflt;
#ifdef DEBUG
unsigned long int utime;
unsigned long int stime;
long int cutime;
long int cstime;
long int priority;
long int nice;
long int itrealvalue;
unsigned long int starttime;
unsigned long int vsize;
long int rss;
unsigned long int rlim;
@ -168,72 +91,50 @@ typedef struct Process_ {
unsigned long int wchan;
unsigned long int nswap;
unsigned long int cnswap;
#endif
int exit_signal;
int processor;
int m_size;
int m_resident;
int m_share;
int m_trs;
int m_drs;
int m_lrs;
int m_dt;
uid_t st_uid;
float percent_cpu;
float percent_mem;
char user[PROCESS_USER_LEN + 1];
} Process;
extern char* PROCESS_CLASS;
extern const char *Process_fieldNames[];
extern const int Process_fieldFlags[];
extern const char *Process_fieldTitles[];
extern char* Process_fieldNames[];
void Process_getMaxPid();
#define ONE_K 1024L
#define ONE_M (ONE_K * ONE_K)
#define ONE_G (ONE_M * ONE_K)
#define ONE_DECIMAL_K 1000L
#define ONE_DECIMAL_M (ONE_DECIMAL_K * ONE_DECIMAL_K)
#define ONE_DECIMAL_G (ONE_DECIMAL_M * ONE_DECIMAL_K)
void Process_delete(Object* cast);
extern ObjectClass Process_class;
Process* Process_new(struct ProcessList_ *pl);
Process* Process_clone(Process* this);
void Process_delete(Object* cast);
void Process_display(Object* cast, RichString* out);
void Process_toggleTag(Process* this);
bool Process_setPriority(Process* this, int priority);
void Process_setPriority(Process* this, int priority);
bool Process_changePriorityBy(Process* this, size_t delta);
void Process_sendSignal(Process* this, int signal);
IOPriority Process_updateIOPriority(Process* this);
#define ONE_K 1024
#define ONE_M (ONE_K * ONE_K)
#define ONE_G (ONE_M * ONE_K)
bool Process_setIOPriority(Process* this, IOPriority ioprio);
void Process_writeField(Process* this, RichString* str, ProcessField field);
/*
[1] Note that before kernel 2.6.26 a process that has not asked for
an io priority formally uses "none" as scheduling class, but the
io scheduler will treat such processes as if it were in the best
effort class. The priority within the best effort class will be
dynamically derived from the cpu nice level of the process:
extern io_priority;
*/
#define Process_effectiveIOPriority(p_) (IOPriority_class(p_->ioPriority) == IOPRIO_CLASS_NONE ? IOPriority_tuple(IOPRIO_CLASS_BE, (p_->nice + 20) / 5) : p_->ioPriority)
int Process_compare(const Object* v1, const Object* v2);
#ifdef HAVE_LIBHWLOC
Affinity* Process_getAffinity(Process* this);
bool Process_setAffinity(Process* this, Affinity* affinity);
#elif HAVE_NATIVE_AFFINITY
Affinity* Process_getAffinity(Process* this);
bool Process_setAffinity(Process* this, Affinity* affinity);
#endif
void Process_sendSignal(Process* this, size_t sgn);
int Process_pidCompare(const void* v1, const void* v2);
int Process_compare(const void* v1, const void* v2);
char* Process_printField(ProcessField field);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -3,28 +3,46 @@
#ifndef HEADER_ProcessList
#define HEADER_ProcessList
/*
htop - ProcessList.h
htop - ProcessList.c
(C) 2004,2005 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Vector.h"
#include "Hashtable.h"
#include "UsersTable.h"
#include "Panel.h"
#ifndef CONFIG_H
#define CONFIG_H
#include "config.h"
#endif
#include "Process.h"
#include "TypedVector.h"
#include "UsersTable.h"
#include "Hashtable.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <stdbool.h>
#include <sys/utsname.h>
#include <stdarg.h>
#include "debug.h"
#include <assert.h>
#ifndef PROCDIR
#define PROCDIR "/proc"
#endif
#ifndef PROCSTATFILE
#define PROCSTATFILE PROCDIR "/stat"
#define PROCSTATFILE "/proc/stat"
#endif
#ifndef PROCMEMINFOFILE
#define PROCMEMINFOFILE PROCDIR "/meminfo"
#define PROCMEMINFOFILE "/proc/meminfo"
#endif
#ifndef MAX_NAME
@ -32,157 +50,107 @@ in the source distribution for its full text.
#endif
#ifndef MAX_READ
#define MAX_READ 2048
#define MAX_READ 8192
#endif
#ifndef ProcessList_cpuId
#define ProcessList_cpuId(pl, cpu) ((pl)->countCPUsFromZero ? (cpu) : (cpu)+1)
#endif
typedef enum TreeStr_ {
TREE_STR_HORZ,
TREE_STR_VERT,
TREE_STR_RTEE,
TREE_STR_BEND,
TREE_STR_TEND,
TREE_STR_OPEN,
TREE_STR_SHUT,
TREE_STR_COUNT
} TreeStr;
typedef struct CPUData_ {
unsigned long long int totalTime;
unsigned long long int userTime;
unsigned long long int systemTime;
unsigned long long int systemAllTime;
unsigned long long int idleAllTime;
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 guestTime;
unsigned long long int totalPeriod;
unsigned long long int userPeriod;
unsigned long long int systemPeriod;
unsigned long long int systemAllPeriod;
unsigned long long int idleAllPeriod;
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;
unsigned long long int guestPeriod;
} CPUData;
typedef struct ProcessList_ {
const char **treeStr;
Vector* processes;
Vector* processes2;
TypedVector* processes;
TypedVector* processes2;
Hashtable* processTable;
Process* prototype;
UsersTable* usersTable;
Panel* panel;
int following;
uid_t userId;
const char* incFilter;
Hashtable* pidWhiteList;
int cpuCount;
int processorCount;
int totalTasks;
int userlandThreads;
int kernelThreads;
int runningTasks;
#ifdef HAVE_LIBHWLOC
hwloc_topology_t topology;
bool topologyOk;
#endif
CPUData* cpus;
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;
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;
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;
int flags;
ProcessField* fields;
ProcessField sortKey;
int direction;
bool hideThreads;
bool shadowOtherUsers;
bool showThreadNames;
bool showingThreadNames;
bool hideKernelThreads;
bool hideUserlandThreads;
bool treeView;
bool highlightBaseName;
bool highlightMegabytes;
bool highlightThreads;
bool detailedCPUTime;
bool countCPUsFromZero;
bool updateProcessNames;
bool accountGuestInCPUMeter;
bool userOnly;
#ifdef DEBUG
FILE* traceFile;
#endif
} ProcessList;
extern const char *ProcessList_treeStrAscii[TREE_STR_COUNT];
#ifdef DEBUG
extern const char *ProcessList_treeStrUtf8[TREE_STR_COUNT];
ProcessList* ProcessList_new(UsersTable* usersTable, Hashtable* pidWhiteList);
#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
#define ProcessList_fopen(this, path, mode) fopen(path, mode)
#define ProcessList_read(this, buffer, format, ...) sscanf(buffer, format, ## __VA_ARGS__ )
#define ProcessList_fread(this, file, format, ...) fscanf(file, format, ## __VA_ARGS__ )
#endif
#endif
ProcessList* ProcessList_new(UsersTable* usersTable);
void ProcessList_delete(ProcessList* this);
void ProcessList_setPanel(ProcessList* this, Panel* panel);
void ProcessList_invertSortOrder(ProcessList* this);
void ProcessList_printHeader(ProcessList* this, RichString* header);
RichString ProcessList_printHeader(ProcessList* this);
Process* ProcessList_get(ProcessList* this, int idx);
void ProcessList_prune(ProcessList* this);
void ProcessList_add(ProcessList* this, Process* p);
void ProcessList_remove(ProcessList* this, Process* p);
Process* ProcessList_get(ProcessList* this, int index);
int ProcessList_size(ProcessList* this);
void ProcessList_sort(ProcessList* this);
#ifdef HAVE_TASKSTATS
#endif
#ifdef HAVE_OPENVZ
#endif
#ifdef HAVE_CGROUP
#endif
#ifdef HAVE_VSERVER
#endif
#ifdef HAVE_OOM
#endif
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);
ProcessField ProcessList_keyAt(ProcessList* this, int at);
void ProcessList_expandTree(ProcessList* this);
void ProcessList_rebuildPanel(ProcessList* this, bool flags, int following, bool userOnly, uid_t userId, const char* incFilter);
void ProcessList_dontCrash(int signal);
#endif

58
README
View File

@ -1,60 +1,46 @@
htop
====
by Hisham Muhammad <loderunner@users.sourceforge.net>
by Hisham Muhammad <hisham@gobolinux.org>
May, 2004 - January, 2014
Note
----
![Alert](http://i.imgur.com/ugIqB9s.png) **Mac users, [click here](https://www.bountysource.com/fundraisers/554-mac-os-x-support-in-the-official-htop-1-x-tree)!** The htop version you are using is a 5-year old fork -- help bring htop 1.x to the Mac!
May, 2004 - March, 2006
Introduction
------------
~~~~~~~~~~~~
This is htop, an interactive process viewer.
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.
It requires ncurses. Tested with Linux 2.4 and 2.6.
Note that, while, htop is Linux specific -- it is based
on the Linux /proc filesystem -- it is also reported to work
with FreeBSD systems featuring a Linux-compatible /proc.
This is, however, unsupported. Contact the packager for your
system when reporting problems on platforms other than Linux.
This software has evolved considerably during the last years,
This software has evolved considerably during the last months,
and is reasonably complete, but there is still room for
improvement. Read the TODO file to see what's known to be missing.
Comparison between 'htop' and 'top'
-----------------------------------
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* In 'htop' you can scroll the list vertically and horizontally
to see all processes and full command lines.
* In 'top' you are subject to a delay for each unassigned
key you press (especially annoying when multi-key escape
sequences are triggered by accident).
* 'htop' starts faster ('top' seems to collect data for a while
before displaying anything).
* In 'htop' you don't need to type the process number to
kill a process, in 'top' you do.
* In 'htop' you don't need to type the process number or
the priority value to renice a process, in 'top' you do.
* In 'htop' you can kill multiple processes at once.
* 'top' is older, hence, more tested.
* In 'htop' you can scroll the list vertically and horizontally
to see all processes and full command lines.
* In 'top' you are subject to a delay for each unassigned
key you press (especially annoying when multi-key escape
sequences are triggered by accident).
* 'htop' starts faster ('top' seems to collect data for a while
before displaying anything).
* In 'htop' you don't need to type the process number to
kill a process, in 'top' you do.
* In 'htop' you don't need to type the process number or
the priority value to renice a process, in 'top' you do.
* In 'htop' you can kill multiple processes at once.
* 'top' is older, hence, more tested.
Compilation instructions
------------------------
~~~~~~~~~~~~~~~~~~~~~~~~
This program is distributed as a standard autotools-based package.
See the INSTALL file for detailed instructions, but you are
probably used to the common `./configure`/`make`/`make install` routine.
When fetching the code from the development repository, you need
to run the `./autogen.sh` script, which in turn requires autotools
to be installed.
probably used to the common "configure/make/make install" routine.
See the manual page (man htop) or the on-line help ('F1' or 'h'
inside htop) for a list of supported key commands.

View File

@ -1 +0,0 @@
README

View File

@ -1,59 +1,20 @@
/*
htop - RichString.c
(C) 2004,2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "RichString.h"
#include <stdlib.h>
#include <string.h>
#include <curses.h>
#include "debug.h"
#include <assert.h>
#define RICHSTRING_MAXLEN 300
/*{
#include "config.h"
#include <ctype.h>
#include <assert.h>
#ifdef HAVE_NCURSESW_CURSES_H
#include <ncursesw/curses.h>
#elif HAVE_NCURSES_NCURSES_H
#include <ncurses/ncurses.h>
#elif HAVE_NCURSES_CURSES_H
#include <ncurses/curses.h>
#elif HAVE_NCURSES_H
#include <ncurses.h>
#elif HAVE_CURSES_H
#include <curses.h>
#endif
#define RichString_size(this) ((this)->chlen)
#define RichString_sizeVal(this) ((this).chlen)
#define RichString_begin(this) RichString (this); (this).chlen = 0; (this).chptr = (this).chstr;
#define RichString_beginAllocated(this) (this).chlen = 0; (this).chptr = (this).chstr;
#define RichString_end(this) RichString_prune(&(this));
#ifdef HAVE_LIBNCURSESW
#define RichString_printVal(this, y, x) mvadd_wchstr(y, x, (this).chptr)
#define RichString_printoffnVal(this, y, x, off, n) mvadd_wchnstr(y, x, (this).chptr + off, n)
#define RichString_getCharVal(this, i) ((this).chptr[i].chars[0] & 255)
#define RichString_setChar(this, at, ch) do{ (this)->chptr[(at)].chars[0] = ch; } while(0)
#define CharType cchar_t
#else
#define RichString_printVal(this, y, x) mvaddchstr(y, x, (this).chptr)
#define RichString_printoffnVal(this, y, x, off, n) mvaddchnstr(y, x, (this).chptr + off, n)
#define RichString_getCharVal(this, i) ((this).chptr[i])
#define RichString_setChar(this, at, ch) do{ (this)->chptr[(at)] = ch; } while(0)
#define CharType chtype
#endif
typedef struct RichString_ {
int chlen;
CharType chstr[RICHSTRING_MAXLEN+1];
CharType* chptr;
int len;
chtype chstr[RICHSTRING_MAXLEN+1];
} RichString;
}*/
@ -62,113 +23,61 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#define charBytes(n) (sizeof(CharType) * (n))
/* private property */
WINDOW* workArea = NULL;
static inline void RichString_setLen(RichString* this, int len) {
if (this->chlen <= RICHSTRING_MAXLEN) {
if (len > RICHSTRING_MAXLEN) {
this->chptr = malloc(charBytes(len+1));
memcpy(this->chptr, this->chstr, charBytes(this->chlen+1));
}
} else {
if (len <= RICHSTRING_MAXLEN) {
memcpy(this->chstr, this->chptr, charBytes(this->chlen));
free(this->chptr);
this->chptr = this->chstr;
} else {
this->chptr = realloc(this->chptr, charBytes(len+1));
}
}
RichString_setChar(this, len, 0);
this->chlen = len;
RichString RichString_new() {
RichString this;
this.len = 0;
return this;
}
#ifdef HAVE_LIBNCURSESW
static inline void RichString_writeFrom(RichString* this, int attrs, const char* data_c, int from, int len) {
wchar_t data[len+1];
len = mbstowcs(data, data_c, len);
if (len<0)
return;
int newLen = from + len;
RichString_setLen(this, newLen);
memset(&this->chptr[from], 0, sizeof(CharType) * (newLen - from));
for (int i = from, j = 0; i < newLen; i++, j++) {
this->chptr[i].chars[0] = data[j];
this->chptr[i].attr = attrs;
}
this->chptr[newLen].chars[0] = 0;
void RichString_delete(RichString this) {
}
inline void RichString_setAttrn(RichString* this, int attrs, int start, int finish) {
cchar_t* ch = this->chptr + start;
for (int i = start; i <= finish; i++) {
ch->attr = attrs;
ch++;
}
}
int RichString_findChar(RichString* this, char c, int start) {
wchar_t wc = btowc(c);
cchar_t* ch = this->chptr + start;
for (int i = start; i < this->chlen; i++) {
if (ch->chars[0] == wc)
return i;
ch++;
}
return -1;
}
#else
static inline void RichString_writeFrom(RichString* this, int attrs, const char* data_c, int from, int len) {
int newLen = from + len;
RichString_setLen(this, newLen);
for (int i = from, j = 0; i < newLen; i++, j++)
this->chptr[i] = (isprint(data_c[j]) ? data_c[j] : '?') | attrs;
this->chptr[newLen] = 0;
}
void RichString_setAttrn(RichString* this, int attrs, int start, int finish) {
chtype* ch = this->chptr + start;
for (int i = start; i <= finish; i++) {
*ch = (*ch & 0xff) | attrs;
ch++;
}
}
int RichString_findChar(RichString* this, char c, int start) {
chtype* ch = this->chptr + start;
for (int i = start; i < this->chlen; i++) {
if ((*ch & 0xff) == (chtype) c)
return i;
ch++;
}
return -1;
}
#endif
void RichString_prune(RichString* this) {
if (this->chlen > RICHSTRING_MAXLEN)
free(this->chptr);
this->chptr = this->chstr;
this->chlen = 0;
RichString_setChar(this, 0, 0);
this->len = 0;
}
void RichString_setAttr(RichString* this, int attrs) {
RichString_setAttrn(this, attrs, 0, this->chlen - 1);
void RichString_write(RichString* this, int attrs, char* data) {
this->len = 0;
RichString_append(this, attrs, data);
}
void RichString_append(RichString* this, int attrs, const char* data) {
RichString_writeFrom(this, attrs, data, this->chlen, strlen(data));
inline void RichString_append(RichString* this, int attrs, char* data) {
RichString_appendn(this, attrs, data, strlen(data));
}
void RichString_appendn(RichString* this, int attrs, const char* data, int len) {
RichString_writeFrom(this, attrs, data, this->chlen, len);
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);
}
void RichString_write(RichString* this, int attrs, const char* data) {
RichString_writeFrom(this, attrs, data, 0, strlen(data));
void RichString_setAttr(RichString *this, int attrs) {
for (int i = 0; i < this->len; i++) {
char c = this->chstr[i];
this->chstr[i] = c | attrs;
}
}
void RichString_applyAttr(RichString *this, int attrs) {
for (int i = 0; i < this->len - 1; i++) {
this->chstr[i] |= attrs;
}
}
RichString RichString_quickString(int attrs, char* data) {
RichString str = RichString_new();
RichString_write(&str, attrs, data);
return str;
}

View File

@ -1,88 +1,43 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_RichString
#define HEADER_RichString
/*
htop - RichString.h
(C) 2004,2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include <stdlib.h>
#include <string.h>
#include <curses.h>
#include <sys/param.h>
#include "debug.h"
#include <assert.h>
#define RICHSTRING_MAXLEN 300
#include "config.h"
#include <ctype.h>
#include <assert.h>
#ifdef HAVE_NCURSESW_CURSES_H
#include <ncursesw/curses.h>
#elif HAVE_NCURSES_NCURSES_H
#include <ncurses/ncurses.h>
#elif HAVE_NCURSES_CURSES_H
#include <ncurses/curses.h>
#elif HAVE_NCURSES_H
#include <ncurses.h>
#elif HAVE_CURSES_H
#include <curses.h>
#endif
#define RichString_size(this) ((this)->chlen)
#define RichString_sizeVal(this) ((this).chlen)
#define RichString_begin(this) RichString (this); (this).chlen = 0; (this).chptr = (this).chstr;
#define RichString_beginAllocated(this) (this).chlen = 0; (this).chptr = (this).chstr;
#define RichString_end(this) RichString_prune(&(this));
#ifdef HAVE_LIBNCURSESW
#define RichString_printVal(this, y, x) mvadd_wchstr(y, x, (this).chptr)
#define RichString_printoffnVal(this, y, x, off, n) mvadd_wchnstr(y, x, (this).chptr + off, n)
#define RichString_getCharVal(this, i) ((this).chptr[i].chars[0] & 255)
#define RichString_setChar(this, at, ch) do{ (this)->chptr[(at)].chars[0] = ch; } while(0)
#define CharType cchar_t
#else
#define RichString_printVal(this, y, x) mvaddchstr(y, x, (this).chptr)
#define RichString_printoffnVal(this, y, x, off, n) mvaddchnstr(y, x, (this).chptr + off, n)
#define RichString_getCharVal(this, i) ((this).chptr[i])
#define RichString_setChar(this, at, ch) do{ (this)->chptr[(at)] = ch; } while(0)
#define CharType chtype
#endif
typedef struct RichString_ {
int chlen;
CharType chstr[RICHSTRING_MAXLEN+1];
CharType* chptr;
int len;
chtype chstr[RICHSTRING_MAXLEN+1];
} RichString;
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
#define charBytes(n) (sizeof(CharType) * (n))
RichString RichString_new();
#ifdef HAVE_LIBNCURSESW
extern void RichString_setAttrn(RichString* this, int attrs, int start, int finish);
int RichString_findChar(RichString* this, char c, int start);
#else
void RichString_setAttrn(RichString* this, int attrs, int start, int finish);
int RichString_findChar(RichString* this, char c, int start);
#endif
void RichString_delete(RichString this);
void RichString_prune(RichString* this);
void RichString_setAttr(RichString* this, int attrs);
void RichString_write(RichString* this, int attrs, char* data);
void RichString_append(RichString* this, int attrs, const char* data);
inline void RichString_append(RichString* this, int attrs, char* data);
void RichString_appendn(RichString* this, int attrs, const char* data, int len);
inline void RichString_appendn(RichString* this, int attrs, char* data, int len);
void RichString_write(RichString* this, int attrs, const char* data);
void RichString_setAttr(RichString *this, int attrs);
void RichString_applyAttr(RichString *this, int attrs);
RichString RichString_quickString(int attrs, char* data);
#endif

View File

@ -1,24 +1,22 @@
/*
htop - ScreenManager.c
(C) 2004-2011 Hisham H. Muhammad
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 "ScreenManager.h"
#include "Panel.h"
#include "ListBox.h"
#include "Object.h"
#include "TypedVector.h"
#include "FunctionBar.h"
#include "debug.h"
#include <assert.h>
#include <time.h>
#include <stdlib.h>
#include <stdbool.h>
/*{
#include "FunctionBar.h"
#include "Vector.h"
#include "Header.h"
typedef enum Orientation_ {
VERTICAL,
@ -31,19 +29,16 @@ typedef struct ScreenManager_ {
int x2;
int y2;
Orientation orientation;
Vector* panels;
Vector* fuBars;
int panelCount;
const FunctionBar* fuBar;
const Header* header;
time_t lastScan;
TypedVector* items;
TypedVector* fuBars;
int itemCount;
FunctionBar* fuBar;
bool owner;
bool allowFocusChange;
} ScreenManager;
}*/
ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation orientation, const Header* header, bool owner) {
ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation orientation, bool owner) {
ScreenManager* this;
this = malloc(sizeof(ScreenManager));
this->x1 = x1;
@ -52,57 +47,61 @@ ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation ori
this->y2 = y2;
this->fuBar = NULL;
this->orientation = orientation;
this->panels = Vector_new(Class(Panel), owner, DEFAULT_SIZE);
this->fuBars = Vector_new(Class(FunctionBar), true, DEFAULT_SIZE);
this->panelCount = 0;
this->header = header;
this->items = TypedVector_new(LISTBOX_CLASS, owner, DEFAULT_SIZE);
this->fuBars = TypedVector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE);
this->itemCount = 0;
this->owner = owner;
this->allowFocusChange = true;
return this;
}
void ScreenManager_delete(ScreenManager* this) {
Vector_delete(this->panels);
Vector_delete(this->fuBars);
TypedVector_delete(this->items);
TypedVector_delete(this->fuBars);
free(this);
}
inline int ScreenManager_size(ScreenManager* this) {
return this->panelCount;
return this->itemCount;
}
void ScreenManager_add(ScreenManager* this, Panel* item, FunctionBar* fuBar, int size) {
void ScreenManager_add(ScreenManager* this, ListBox* item, FunctionBar* fuBar, int size) {
if (this->orientation == HORIZONTAL) {
int lastX = 0;
if (this->panelCount > 0) {
Panel* last = (Panel*) Vector_get(this->panels, this->panelCount - 1);
if (this->itemCount > 0) {
ListBox* last = (ListBox*) TypedVector_get(this->items, this->itemCount - 1);
lastX = last->x + last->w + 1;
}
if (size > 0) {
Panel_resize(item, size, LINES-this->y1+this->y2);
ListBox_resize(item, size, LINES-this->y1+this->y2);
} else {
Panel_resize(item, COLS-this->x1+this->x2-lastX, LINES-this->y1+this->y2);
ListBox_resize(item, COLS-this->x1+this->x2-lastX, LINES-this->y1+this->y2);
}
Panel_move(item, lastX, this->y1);
ListBox_move(item, lastX, this->y1);
}
// TODO: VERTICAL
Vector_add(this->panels, item);
TypedVector_add(this->items, item);
if (fuBar)
Vector_add(this->fuBars, fuBar);
TypedVector_add(this->fuBars, fuBar);
else
Vector_add(this->fuBars, FunctionBar_new(NULL, NULL, NULL));
TypedVector_add(this->fuBars, FunctionBar_new(0, NULL, NULL, NULL));
if (!this->fuBar && fuBar) this->fuBar = fuBar;
item->needsRedraw = true;
this->panelCount++;
this->itemCount++;
}
Panel* ScreenManager_remove(ScreenManager* this, int idx) {
assert(this->panelCount > idx);
Panel* panel = (Panel*) Vector_remove(this->panels, idx);
Vector_remove(this->fuBars, idx);
ListBox* ScreenManager_remove(ScreenManager* this, int index) {
assert(this->itemCount > index);
ListBox* lb = (ListBox*) TypedVector_remove(this->items, index);
TypedVector_remove(this->fuBars, index);
this->fuBar = NULL;
this->panelCount--;
return panel;
this->itemCount--;
return lb;
}
void ScreenManager_setFunctionBar(ScreenManager* this, FunctionBar* fuBar) {
if (this->owner && this->fuBar)
FunctionBar_delete((Object*)this->fuBar);
this->fuBar = fuBar;
}
void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2) {
@ -110,52 +109,40 @@ void ScreenManager_resize(ScreenManager* this, int x1, int y1, int x2, int y2) {
this->y1 = y1;
this->x2 = x2;
this->y2 = y2;
int panels = this->panelCount;
int items = this->itemCount;
int lastX = 0;
for (int i = 0; i < panels - 1; i++) {
Panel* panel = (Panel*) Vector_get(this->panels, i);
Panel_resize(panel, panel->w, LINES-y1+y2);
Panel_move(panel, lastX, y1);
lastX = panel->x + panel->w + 1;
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->panels, panels-1);
Panel_resize(panel, COLS-x1+x2-lastX, LINES-y1+y2);
Panel_move(panel, lastX, y1);
ListBox* lb = (ListBox*) TypedVector_get(this->items, items-1);
ListBox_resize(lb, COLS-x1+x2-lastX, LINES-y1+y2);
ListBox_move(lb, lastX, y1);
}
void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) {
bool quit = false;
int focus = 0;
Panel* panelFocus = (Panel*) Vector_get(this->panels, focus);
ListBox* lbFocus = (ListBox*) TypedVector_get(this->items, focus);
if (this->fuBar)
FunctionBar_draw(this->fuBar, NULL);
this->lastScan = 0;
int ch = 0;
int ch;
while (!quit) {
int panels = this->panelCount;
if (this->header) {
time_t now = time(NULL);
if (now > this->lastScan) {
ProcessList_scan(this->header->pl);
ProcessList_sort(this->header->pl);
this->lastScan = now;
}
Header_draw(this->header);
ProcessList_rebuildPanel(this->header->pl, false, false, false, false, NULL);
}
for (int i = 0; i < panels; i++) {
Panel* panel = (Panel*) Vector_get(this->panels, i);
Panel_draw(panel, i == focus);
if (i < panels) {
int items = this->itemCount;
for (int i = 0; i < items; i++) {
ListBox* lb = (ListBox*) TypedVector_get(this->items, i);
ListBox_draw(lb, i == focus);
if (i < items) {
if (this->orientation == HORIZONTAL) {
mvvline(panel->y, panel->x+panel->w, ' ', panel->h+1);
mvvline(lb->y, lb->x+lb->w, ' ', lb->h+1);
}
}
}
FunctionBar* bar = (FunctionBar*) Vector_get(this->fuBars, focus);
FunctionBar* bar = (FunctionBar*) TypedVector_get(this->fuBars, focus);
if (bar)
this->fuBar = bar;
if (this->fuBar)
@ -163,6 +150,7 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
ch = getch();
bool loop = false;
if (ch == KEY_MOUSE) {
MEVENT mevent;
int ok = getmouse(&mevent);
@ -170,23 +158,24 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
if (mevent.y == LINES - 1) {
ch = FunctionBar_synthesizeEvent(this->fuBar, mevent.x);
} else {
for (int i = 0; i < this->panelCount; i++) {
Panel* panel = (Panel*) Vector_get(this->panels, i);
if (mevent.x > panel->x && mevent.x <= panel->x+panel->w &&
mevent.y > panel->y && mevent.y <= panel->y+panel->h &&
(this->allowFocusChange || panelFocus == panel) ) {
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) {
focus = i;
panelFocus = panel;
Panel_setSelected(panel, mevent.y - panel->y + panel->scrollV - 1);
lbFocus = lb;
ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV - 1);
loop = true;
break;
}
}
}
}
}
if (loop) continue;
if (Panel_eventHandlerFn(panelFocus)) {
HandlerResult result = Panel_eventHandler(panelFocus, ch);
if (lbFocus->eventHandler) {
HandlerResult result = lbFocus->eventHandler(lbFocus, ch);
if (result == HANDLED) {
continue;
} else if (result == BREAK_LOOP) {
@ -204,26 +193,20 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
continue;
}
case KEY_LEFT:
case KEY_CTRLB:
if (!this->allowFocusChange)
break;
tryLeft:
if (focus > 0)
focus--;
panelFocus = (Panel*) Vector_get(this->panels, focus);
if (Panel_size(panelFocus) == 0 && focus > 0)
lbFocus = (ListBox*) TypedVector_get(this->items, focus);
if (ListBox_getSize(lbFocus) == 0 && focus > 0)
goto tryLeft;
break;
case KEY_RIGHT:
case KEY_CTRLF:
case 9:
if (!this->allowFocusChange)
break;
tryRight:
if (focus < this->panelCount - 1)
if (focus < this->itemCount - 1)
focus++;
panelFocus = (Panel*) Vector_get(this->panels, focus);
if (Panel_size(panelFocus) == 0 && focus < this->panelCount - 1)
lbFocus = (ListBox*) TypedVector_get(this->items, focus);
if (ListBox_getSize(lbFocus) == 0 && focus < this->itemCount - 1)
goto tryRight;
break;
case KEY_F(10):
@ -232,11 +215,11 @@ void ScreenManager_run(ScreenManager* this, Panel** lastFocus, int* lastKey) {
quit = true;
continue;
default:
Panel_onKey(panelFocus, ch);
ListBox_onKey(lbFocus, ch);
break;
}
}
*lastFocus = panelFocus;
*lastFocus = lbFocus;
*lastKey = ch;
}

View File

@ -1,17 +1,24 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_ScreenManager
#define HEADER_ScreenManager
/*
htop - ScreenManager.h
(C) 2004-2011 Hisham H. Muhammad
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 "ListBox.h"
#include "Object.h"
#include "TypedVector.h"
#include "FunctionBar.h"
#include "Vector.h"
#include "Header.h"
#include "debug.h"
#include <assert.h>
#include <stdbool.h>
typedef enum Orientation_ {
VERTICAL,
@ -24,29 +31,28 @@ typedef struct ScreenManager_ {
int x2;
int y2;
Orientation orientation;
Vector* panels;
Vector* fuBars;
int panelCount;
const FunctionBar* fuBar;
const Header* header;
time_t lastScan;
TypedVector* items;
int itemCount;
FunctionBar* fuBar;
TypedVector* fuBars;
bool owner;
bool allowFocusChange;
} ScreenManager;
ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation orientation, const Header* header, bool owner);
ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation orientation, bool owner);
void ScreenManager_delete(ScreenManager* this);
extern int ScreenManager_size(ScreenManager* this);
inline int ScreenManager_size(ScreenManager* this);
void ScreenManager_add(ScreenManager* this, Panel* item, FunctionBar* fuBar, int size);
void ScreenManager_add(ScreenManager* this, ListBox* item, FunctionBar* fuBar, int size);
Panel* ScreenManager_remove(ScreenManager* this, int idx);
ListBox* 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, Panel** lastFocus, int* lastKey);
void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey);
#endif

View File

@ -1,94 +1,120 @@
/*
htop - Settings.c
(C) 2004-2011 Hisham H. Muhammad
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Settings.h"
#include "String.h"
#include "Vector.h"
#include "ProcessList.h"
#include "Header.h"
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "debug.h"
#define DEFAULT_DELAY 15
/*{
#include "ProcessList.h"
#include "Header.h"
#include <stdbool.h>
typedef struct Settings_ {
char* userSettings;
ProcessList* pl;
Header* header;
int colorScheme;
int delay;
bool changed;
int delay;
} Settings;
}*/
Settings* Settings_new(ProcessList* pl, Header* header) {
Settings* this = malloc(sizeof(Settings));
this->pl = pl;
this->header = header;
char* home;
char* rcfile;
home = getenv("HOME_ETC");
if (!home) home = getenv("HOME");
if (!home) home = "";
rcfile = getenv("HOMERC");
if (!rcfile)
this->userSettings = String_cat(home, "/.htoprc");
else
this->userSettings = String_copy(rcfile);
this->colorScheme = 0;
this->changed = false;
this->delay = DEFAULT_DELAY;
bool ok = Settings_read(this, this->userSettings);
if (!ok) {
this->changed = true;
// TODO: how to get SYSCONFDIR correctly through Autoconf?
char* systemSettings = String_cat(SYSCONFDIR, "/htoprc");
ok = Settings_read(this, systemSettings);
free(systemSettings);
if (!ok) {
Header_defaultMeters(this->header);
pl->hideKernelThreads = true;
pl->highlightMegabytes = true;
}
}
return this;
}
void Settings_delete(Settings* this) {
free(this->userSettings);
free(this);
}
static void Settings_readMeters(Settings* this, char* line, HeaderSide side) {
/* private */
void Settings_readMeters(Settings* this, char* line, HeaderSide side) {
char* trim = String_trim(line);
int nIds;
char** ids = String_split(trim, ' ', &nIds);
char** ids = String_split(trim, ' ');
free(trim);
for (int i = 0; ids[i]; i++) {
int i;
for (i = 0; ids[i] != NULL; i++) {
Header_createMeter(this->header, ids[i], side);
}
String_freeArray(ids);
}
static void Settings_readMeterModes(Settings* this, char* line, HeaderSide side) {
/* private */
void Settings_readMeterModes(Settings* this, char* line, HeaderSide side) {
char* trim = String_trim(line);
int nIds;
char** ids = String_split(trim, ' ', &nIds);
char** ids = String_split(trim, ' ');
free(trim);
for (int i = 0; ids[i]; i++) {
int i;
for (i = 0; ids[i] != NULL; i++) {
int mode = atoi(ids[i]);
Header_setMode(this->header, i, mode, side);
}
String_freeArray(ids);
}
static bool Settings_read(Settings* this, const char* fileName, int cpuCount) {
FILE* fd = fopen(fileName, "r");
if (!fd)
bool Settings_read(Settings* this, char* fileName) {
// TODO: implement File object and make
// file I/O object-oriented.
FILE* fd;
fd = fopen(fileName, "r");
if (fd == NULL) {
return false;
const int maxLine = 2048;
}
const int maxLine = 512;
char buffer[maxLine];
bool readMeters = false;
while (fgets(buffer, maxLine, fd)) {
int nOptions;
char** option = String_split(buffer, '=', &nOptions);
if (nOptions < 2) {
String_freeArray(option);
continue;
}
while (!feof(fd)) {
buffer[0] = '\0';
fgets(buffer, maxLine, fd);
char** option = String_split(buffer, '=');
if (String_eq(option[0], "fields")) {
char* trim = String_trim(option[1]);
int nIds;
char** ids = String_split(trim, ' ', &nIds);
char** ids = String_split(trim, ' ');
free(trim);
int i, j;
this->pl->flags = 0;
for (j = 0, i = 0; i < LAST_PROCESSFIELD && ids[i]; i++) {
for (j = 0, i = 0; i < LAST_PROCESSFIELD && ids[i] != NULL; i++) {
// This "+1" is for compatibility with the older enum format.
int id = atoi(ids[i]) + 1;
if (id > 0 && id < LAST_PROCESSFIELD) {
this->pl->fields[j] = id;
this->pl->flags |= Process_fieldFlags[id];
j++;
}
}
@ -109,27 +135,12 @@ static bool Settings_read(Settings* this, const char* fileName, int cpuCount) {
this->pl->hideUserlandThreads = atoi(option[1]);
} else if (String_eq(option[0], "shadow_other_users")) {
this->pl->shadowOtherUsers = atoi(option[1]);
} else if (String_eq(option[0], "show_thread_names")) {
this->pl->showThreadNames = atoi(option[1]);
} else if (String_eq(option[0], "highlight_base_name")) {
this->pl->highlightBaseName = atoi(option[1]);
} else if (String_eq(option[0], "highlight_megabytes")) {
this->pl->highlightMegabytes = atoi(option[1]);
} else if (String_eq(option[0], "highlight_threads")) {
this->pl->highlightThreads = 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")) {
// Compatibility option.
this->pl->detailedCPUTime = atoi(option[1]);
} else if (String_eq(option[0], "detailed_cpu_time")) {
this->pl->detailedCPUTime = atoi(option[1]);
} else if (String_eq(option[0], "cpu_count_from_zero")) {
this->pl->countCPUsFromZero = atoi(option[1]);
} else if (String_eq(option[0], "update_process_names")) {
this->pl->updateProcessNames = atoi(option[1]);
} else if (String_eq(option[0], "account_guest_in_cpu_meter")) {
this->pl->accountGuestInCPUMeter = atoi(option[1]);
} else if (String_eq(option[0], "delay")) {
this->delay = atoi(option[1]);
} else if (String_eq(option[0], "color_scheme")) {
@ -153,7 +164,7 @@ static bool Settings_read(Settings* this, const char* fileName, int cpuCount) {
}
fclose(fd);
if (!readMeters) {
Header_defaultMeters(this->header, cpuCount);
Header_defaultMeters(this->header);
}
return true;
}
@ -166,8 +177,9 @@ bool Settings_write(Settings* this) {
if (fd == NULL) {
return false;
}
fprintf(fd, "# Beware! This file is rewritten by htop when settings are changed in the interface.\n");
fprintf(fd, "# Beware! This file is rewritten every time htop exits.\n");
fprintf(fd, "# The parser is also very primitive, and not human-friendly.\n");
fprintf(fd, "# (I know, it's in the todo list).\n");
fprintf(fd, "fields=");
for (int i = 0; this->pl->fields[i]; i++) {
// This "-1" is for compatibility with the older enum format.
@ -181,16 +193,10 @@ bool Settings_write(Settings* this) {
fprintf(fd, "hide_kernel_threads=%d\n", (int) this->pl->hideKernelThreads);
fprintf(fd, "hide_userland_threads=%d\n", (int) this->pl->hideUserlandThreads);
fprintf(fd, "shadow_other_users=%d\n", (int) this->pl->shadowOtherUsers);
fprintf(fd, "show_thread_names=%d\n", (int) this->pl->showThreadNames);
fprintf(fd, "highlight_base_name=%d\n", (int) this->pl->highlightBaseName);
fprintf(fd, "highlight_megabytes=%d\n", (int) this->pl->highlightMegabytes);
fprintf(fd, "highlight_threads=%d\n", (int) this->pl->highlightThreads);
fprintf(fd, "tree_view=%d\n", (int) this->pl->treeView);
fprintf(fd, "header_margin=%d\n", (int) this->header->margin);
fprintf(fd, "detailed_cpu_time=%d\n", (int) this->pl->detailedCPUTime);
fprintf(fd, "cpu_count_from_zero=%d\n", (int) this->pl->countCPUsFromZero);
fprintf(fd, "update_process_names=%d\n", (int) this->pl->updateProcessNames);
fprintf(fd, "account_guest_in_cpu_meter=%d\n", (int) this->pl->accountGuestInCPUMeter);
fprintf(fd, "color_scheme=%d\n", (int) this->colorScheme);
fprintf(fd, "delay=%d\n", (int) this->delay);
fprintf(fd, "left_meters=");
@ -214,71 +220,6 @@ bool Settings_write(Settings* this) {
fprintf(fd, "right_meter_modes=");
for (int i = 0; i < Header_size(this->header, RIGHT_HEADER); i++)
fprintf(fd, "%d ", Header_readMeterMode(this->header, i, RIGHT_HEADER));
fprintf(fd, "\n");
fclose(fd);
return true;
}
Settings* Settings_new(ProcessList* pl, Header* header, int cpuCount) {
Settings* this = malloc(sizeof(Settings));
this->pl = pl;
this->header = header;
char* legacyDotfile = NULL;
char* rcfile = getenv("HTOPRC");
if (rcfile) {
this->userSettings = strdup(rcfile);
} else {
const char* home = getenv("HOME");
if (!home) home = "";
const char* xdgConfigHome = getenv("XDG_CONFIG_HOME");
char* configDir = NULL;
char* htopDir = NULL;
if (xdgConfigHome) {
this->userSettings = String_cat(xdgConfigHome, "/htop/htoprc");
configDir = strdup(xdgConfigHome);
htopDir = String_cat(xdgConfigHome, "/htop");
} else {
this->userSettings = String_cat(home, "/.config/htop/htoprc");
configDir = String_cat(home, "/.config");
htopDir = String_cat(home, "/.config/htop");
}
legacyDotfile = String_cat(home, "/.htoprc");
(void) mkdir(configDir, 0700);
(void) mkdir(htopDir, 0700);
free(htopDir);
free(configDir);
struct stat st;
if (lstat(legacyDotfile, &st) != 0) {
st.st_mode = 0;
}
if (access(legacyDotfile, R_OK) != 0 || S_ISLNK(st.st_mode)) {
free(legacyDotfile);
legacyDotfile = NULL;
}
}
this->colorScheme = 0;
this->changed = false;
this->delay = DEFAULT_DELAY;
bool ok = Settings_read(this, legacyDotfile ? legacyDotfile : this->userSettings, cpuCount);
if (ok) {
if (legacyDotfile) {
// Transition to new location and delete old configuration file
if (Settings_write(this))
unlink(legacyDotfile);
}
} else {
this->changed = true;
// TODO: how to get SYSCONFDIR correctly through Autoconf?
char* systemSettings = String_cat(SYSCONFDIR, "/htoprc");
ok = Settings_read(this, systemSettings, cpuCount);
free(systemSettings);
if (!ok) {
Header_defaultMeters(this->header, cpuCount);
pl->hideKernelThreads = true;
pl->highlightMegabytes = true;
pl->highlightThreads = false;
}
}
free(legacyDotfile);
return this;
}

View File

@ -3,32 +3,39 @@
#ifndef HEADER_Settings
#define HEADER_Settings
/*
htop - Settings.h
(C) 2004-2011 Hisham H. Muhammad
htop - Settings.c
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define DEFAULT_DELAY 15
#include "String.h"
#include "ProcessList.h"
#include "Header.h"
#include <stdbool.h>
#include "debug.h"
#define DEFAULT_DELAY 15
typedef struct Settings_ {
char* userSettings;
ProcessList* pl;
Header* header;
int colorScheme;
int delay;
bool changed;
int delay;
} Settings;
Settings* Settings_new(ProcessList* pl, Header* header);
void Settings_delete(Settings* this);
bool Settings_read(Settings* this, char* fileName);
bool Settings_write(Settings* this);
Settings* Settings_new(ProcessList* pl, Header* header, int cpuCount);
#endif

99
SignalItem.c Normal file
View File

@ -0,0 +1,99 @@
/*
htop - SignalItem.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 "SignalItem.h"
#include "String.h"
#include "Object.h"
#include "RichString.h"
#include <string.h>
#include "debug.h"
#define SIGNAL_COUNT 34
/*{
typedef struct Signal_ {
Object super;
char* name;
int number;
} Signal;
extern char* SIGNAL_CLASS;
}*/
/* private property */
char* SIGNAL_CLASS = "Signal";
Signal* Signal_new(char* name, int number) {
Signal* this = malloc(sizeof(Signal));
((Object*)this)->class = SIGNAL_CLASS;
((Object*)this)->display = Signal_display;
((Object*)this)->delete = Signal_delete;
this->name = name;
this->number = number;
return this;
}
void Signal_delete(Object* cast) {
Signal* this = (Signal*)cast;
assert (this != NULL);
// names are string constants, so we're not deleting them.
free(this);
}
void Signal_display(Object* cast, RichString* out) {
Signal* this = (Signal*)cast;
assert (this != NULL);
char buffer[31];
snprintf(buffer, 30, "%2d %s", this->number, this->name);
RichString_write(out, CRT_colors[DEFAULT_COLOR], buffer);
}
int Signal_getSignalCount() {
return SIGNAL_COUNT;
}
Signal** Signal_getSignalTable() {
Signal** signals = malloc(sizeof(Signal*) * SIGNAL_COUNT);
signals[0] = Signal_new("Cancel", 0);
signals[1] = Signal_new("SIGHUP", 1);
signals[2] = Signal_new("SIGINT", 2);
signals[3] = Signal_new("SIGQUIT", 3);
signals[4] = Signal_new("SIGILL", 4);
signals[5] = Signal_new("SIGTRAP", 5);
signals[6] = Signal_new("SIGABRT", 6);
signals[7] = Signal_new("SIGIOT", 6);
signals[8] = Signal_new("SIGBUS", 7);
signals[9] = Signal_new("SIGFPE", 8);
signals[10] = Signal_new("SIGKILL", 9);
signals[11] = Signal_new("SIGUSR1", 10);
signals[12] = Signal_new("SIGSEGV", 11);
signals[13] = Signal_new("SIGUSR2", 12);
signals[14] = Signal_new("SIGPIPE", 13);
signals[15] = Signal_new("SIGALRM", 14);
signals[16] = Signal_new("SIGTERM", 15);
signals[17] = Signal_new("SIGSTKFLT", 16);
signals[18] = Signal_new("SIGCHLD", 17);
signals[19] = Signal_new("SIGCONT", 18);
signals[20] = Signal_new("SIGSTOP", 19);
signals[21] = Signal_new("SIGTSTP", 20);
signals[22] = Signal_new("SIGTTIN", 21);
signals[23] = Signal_new("SIGTTOU", 22);
signals[24] = Signal_new("SIGURG", 23);
signals[25] = Signal_new("SIGXCPU", 24);
signals[26] = Signal_new("SIGXFSZ", 25);
signals[27] = Signal_new("SIGVTALRM", 26);
signals[28] = Signal_new("SIGPROF", 27);
signals[29] = Signal_new("SIGWINCH", 28);
signals[30] = Signal_new("SIGIO", 29);
signals[31] = Signal_new("SIGPOLL", 29);
signals[32] = Signal_new("SIGPWR", 30);
signals[33] = Signal_new("SIGSYS", 31);
return signals;
}

41
SignalItem.h Normal file
View File

@ -0,0 +1,41 @@
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_Signal
#define HEADER_Signal
/*
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 "String.h"
#include "Object.h"
#include "RichString.h"
#include <string.h>
#include "debug.h"
#define SIGNAL_COUNT 34
typedef struct Signal_ {
Object super;
char* name;
int number;
} Signal;
extern char* SIGNAL_CLASS;
Signal* Signal_new(char* name, int number);
void Signal_delete(Object* cast);
void Signal_display(Object* cast, RichString* out);
int Signal_getSignalCount();
Signal** Signal_getSignalTable();
#endif

77
SignalsListBox.c Normal file
View File

@ -0,0 +1,77 @@
#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;
}

32
SignalsListBox.h Normal file
View File

@ -0,0 +1,32 @@
/* 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

View File

@ -1,72 +0,0 @@
/*
htop - SignalsPanel.c
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "Panel.h"
#include "SignalsPanel.h"
#include "ListItem.h"
#include "RichString.h"
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
/*{
typedef struct SignalItem_ {
const char* name;
int number;
} SignalItem;
}*/
static SignalItem signals[] = {
{ .name = " 0 Cancel", .number = 0 },
{ .name = " 1 SIGHUP", .number = 1 },
{ .name = " 2 SIGINT", .number = 2 },
{ .name = " 3 SIGQUIT", .number = 3 },
{ .name = " 4 SIGILL", .number = 4 },
{ .name = " 5 SIGTRAP", .number = 5 },
{ .name = " 6 SIGABRT", .number = 6 },
{ .name = " 6 SIGIOT", .number = 6 },
{ .name = " 7 SIGBUS", .number = 7 },
{ .name = " 8 SIGFPE", .number = 8 },
{ .name = " 9 SIGKILL", .number = 9 },
{ .name = "10 SIGUSR1", .number = 10 },
{ .name = "11 SIGSEGV", .number = 11 },
{ .name = "12 SIGUSR2", .number = 12 },
{ .name = "13 SIGPIPE", .number = 13 },
{ .name = "14 SIGALRM", .number = 14 },
{ .name = "15 SIGTERM", .number = 15 },
{ .name = "16 SIGSTKFLT", .number = 16 },
{ .name = "17 SIGCHLD", .number = 17 },
{ .name = "18 SIGCONT", .number = 18 },
{ .name = "19 SIGSTOP", .number = 19 },
{ .name = "20 SIGTSTP", .number = 20 },
{ .name = "21 SIGTTIN", .number = 21 },
{ .name = "22 SIGTTOU", .number = 22 },
{ .name = "23 SIGURG", .number = 23 },
{ .name = "24 SIGXCPU", .number = 24 },
{ .name = "25 SIGXFSZ", .number = 25 },
{ .name = "26 SIGVTALRM", .number = 26 },
{ .name = "27 SIGPROF", .number = 27 },
{ .name = "28 SIGWINCH", .number = 28 },
{ .name = "29 SIGIO", .number = 29 },
{ .name = "29 SIGPOLL", .number = 29 },
{ .name = "30 SIGPWR", .number = 30 },
{ .name = "31 SIGSYS", .number = 31 },
};
Panel* SignalsPanel_new() {
Panel* this = Panel_new(1, 1, 1, 1, true, Class(ListItem));
for(unsigned int i = 0; i < sizeof(signals)/sizeof(SignalItem); i++)
Panel_set(this, i, (Object*) ListItem_new(signals[i].name, signals[i].number));
Panel_setHeader(this, "Send signal:");
Panel_setSelected(this, 16); // 16th item is SIGTERM
return this;
}

View File

@ -1,21 +0,0 @@
/* Do not edit this file. It was automatically generated. */
#ifndef HEADER_SignalsPanel
#define HEADER_SignalsPanel
/*
htop - SignalsPanel.h
(C) 2004-2011 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
typedef struct SignalItem_ {
const char* name;
int number;
} SignalItem;
Panel* SignalsPanel_new();
#endif

133
String.c
View File

@ -1,25 +1,28 @@
/*
htop - String.c
(C) 2004-2011 Hisham H. Muhammad
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define _GNU_SOURCE
#include "String.h"
#include "config.h"
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
/*{
#define String_startsWith(s, match) (strstr((s), (match)) == (s))
#define String_contains_i(s1, s2) (strcasestr(s1, s2) != NULL)
}*/
#include "debug.h"
char* String_cat(const char* s1, const char* s2) {
inline void String_delete(char* s) {
free(s);
}
inline char* String_copy(char* orig) {
return strdup(orig);
}
char* String_cat(char* s1, char* s2) {
int l1 = strlen(s1);
int l2 = strlen(s2);
char* out = malloc(l1 + l2 + 1);
@ -28,7 +31,7 @@ char* String_cat(const char* s1, const char* s2) {
return out;
}
char* String_trim(const char* in) {
char* String_trim(char* in) {
while (in[0] == ' ' || in[0] == '\t' || in[0] == '\n') {
in++;
}
@ -42,7 +45,54 @@ char* String_trim(const char* in) {
return out;
}
inline int String_eq(const char* s1, const char* s2) {
char* String_copyUpTo(char* orig, char upTo) {
int len;
int origLen = strlen(orig);
char* at = strchr(orig, upTo);
if (at != NULL)
len = at - orig;
else
len = origLen;
char* copy = (char*) malloc(len+1);
strncpy(copy, orig, len);
copy[len] = '\0';
return copy;
}
char* String_sub(char* orig, int from, int to) {
char* copy;
int len;
len = strlen(orig);
if (to > len)
to = len;
if (from > len)
to = len;
len = to-from+1;
copy = (char*) malloc(len+1);
strncpy(copy, orig+from, len);
copy[len] = '\0';
return copy;
}
void String_println(char* s) {
printf("%s\n", s);
}
void String_print(char* s) {
printf("%s", s);
}
void String_printInt(int i) {
printf("%i", i);
}
void String_printPointer(void* p) {
printf("%p", p);
}
inline int String_eq(char* s1, char* s2) {
if (s1 == NULL || s2 == NULL) {
if (s1 == NULL && s2 == NULL)
return 1;
@ -52,8 +102,11 @@ inline int String_eq(const char* s1, const char* s2) {
return (strcmp(s1, s2) == 0);
}
char** String_split(const char* s, char sep, int* n) {
*n = 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);
int ctr = 0;
@ -68,13 +121,7 @@ char** String_split(const char* s, char sep, int* n) {
ctr++;
if (ctr == blocks) {
blocks += rate;
char** newOut = (char**) realloc(out, sizeof(char*) * blocks);
if (newOut) {
out = newOut;
} else {
blocks -= rate;
break;
}
out = (char**) realloc(out, sizeof(char*) * blocks);
}
s += size + 1;
}
@ -85,12 +132,8 @@ char** String_split(const char* s, char sep, int* n) {
out[ctr] = token;
ctr++;
}
char** newOut = realloc(out, sizeof(char*) * (ctr + 1));
if (newOut) {
out = newOut;
}
out = realloc(out, sizeof(char*) * (ctr + 1));
out[ctr] = NULL;
*n = ctr;
return out;
}
@ -101,29 +144,17 @@ void String_freeArray(char** s) {
free(s);
}
char* String_getToken(const char* line, const unsigned short int numMatch) {
const unsigned short int len = strlen(line);
char inWord = 0;
unsigned short int count = 0;
char match[50];
unsigned short int foundCount = 0;
for (unsigned short int i = 0; i < len; i++) {
char lastState = inWord;
inWord = line[i] == ' ' ? 0:1;
if (lastState == 0 && inWord == 1)
count++;
if(inWord == 1){
if (count == numMatch && line[i] != ' ' && line[i] != '\0' && line[i] != '\n' && line[i] != (char)EOF) {
match[foundCount] = line[i];
foundCount++;
}
}
}
match[foundCount] = '\0';
return((char*)strdup(match));
int String_startsWith_i(char* s, char* match) {
return (strncasecmp(s, match, strlen(match)) == 0);
}
int String_contains_i(char* s, char* match) {
int lens = strlen(s);
int lenmatch = strlen(match);
for (int i = 0; i < lens-lenmatch; i++) {
if (strncasecmp(s, match, strlen(match)) == 0)
return 1;
s++;
}
return 0;
}

View File

@ -1,27 +1,52 @@
/* Do not edit this file. It was automatically generated. */
/* Do not edit this file. It was automatically genarated. */
#ifndef HEADER_String
#define HEADER_String
/*
htop - String.h
(C) 2004-2011 Hisham H. Muhammad
htop
(C) 2004-2006 Hisham H. Muhammad
Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#define String_startsWith(s, match) (strstr((s), (match)) == (s))
#define String_contains_i(s1, s2) (strcasestr(s1, s2) != NULL)
#define _GNU_SOURCE
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
char* String_cat(const char* s1, const char* s2);
#include "debug.h"
char* String_trim(const char* in);
inline void String_delete(char* s);
extern int String_eq(const char* s1, const char* s2);
inline char* String_copy(char* orig);
char** String_split(const char* s, char sep, int* n);
char* String_cat(char* s1, char* s2);
char* String_trim(char* in);
char* String_copyUpTo(char* orig, char upTo);
char* String_sub(char* orig, int from, int to);
void String_println(char* s);
void String_print(char* s);
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);
char** String_split(char* s, char sep);
void String_freeArray(char** s);
char* String_getToken(const char* line, const unsigned short int numMatch);
int String_startsWith_i(char* s, char* match);
int String_contains_i(char* s, char* match);
#endif

Some files were not shown because too many files have changed in this diff Show More