From 266ab52b3a741a58fb17c48b0f7939d7c5d266de Mon Sep 17 00:00:00 2001 From: Daniel Lange Date: Mon, 11 Apr 2016 13:00:19 +0200 Subject: Imported Upstream version 0.6 --- AUTHORS | 2 +- AvailableColumnsListBox.c | 72 ++++++ AvailableColumnsListBox.h | 31 +++ AvailableMetersListBox.c | 27 +-- AvailableMetersListBox.h | 2 +- CPUMeter.c | 12 +- CRT.c | 15 +- CRT.h | 4 + CategoriesListBox.c | 50 +++-- CategoriesListBox.h | 2 + ChangeLog | 14 ++ CheckItem.c | 1 - ClockMeter.c | 4 +- ColorsListBox.c | 6 +- ColorsListBox.h | 2 +- ColumnsListBox.c | 104 +++++++++ ColumnsListBox.h | 32 +++ DisplayOptionsListBox.c | 7 +- DisplayOptionsListBox.h | 2 +- FunctionBar.c | 58 ++++- FunctionBar.h | 10 +- Hashtable.c | 10 +- Hashtable.h | 8 +- Header.c | 5 +- ListBox.c | 21 +- ListBox.h | 12 +- ListItem.c | 44 +++- ListItem.h | 17 +- LoadAverageMeter.c | 10 +- LoadMeter.c | 9 +- Makefile.am | 4 +- Makefile.in | 69 ++++-- MemoryMeter.c | 24 +- Meter.c | 28 ++- Meter.h | 10 +- MetersListBox.c | 8 +- MetersListBox.h | 2 +- NEWS | 1 + Object.c | 18 +- Object.h | 14 +- Process.c | 45 ++-- Process.h | 6 +- ProcessList.c | 46 ++-- ProcessList.h | 3 - README | 26 +-- ScreenManager.c | 31 ++- ScreenManager.h | 3 +- Settings.c | 29 ++- Settings.h | 2 + SignalsListBox.c | 6 +- SignalsListBox.h | 2 +- String.c | 2 +- SwapMeter.c | 2 +- TODO | 3 - TasksMeter.c | 2 +- TraceScreen.c | 164 ++++++++++++++ TraceScreen.h | 37 ++++ TypedVector.c | 21 +- TypedVector.h | 8 - UptimeMeter.c | 2 +- UsersTable.c | 6 +- UsersTable.h | 4 +- aclocal.m4 | 516 ++++++++++++++++++++++++------------------- config.h | 6 +- configure | 86 ++++---- configure.ac | 2 +- htop.1 | 36 +-- htop.c | 546 +++++++++++++++++----------------------------- 68 files changed, 1448 insertions(+), 965 deletions(-) create mode 100644 AvailableColumnsListBox.c create mode 100644 AvailableColumnsListBox.h create mode 100644 ColumnsListBox.c create mode 100644 ColumnsListBox.h create mode 100644 TraceScreen.c create mode 100644 TraceScreen.h diff --git a/AUTHORS b/AUTHORS index f4f0816..de8bf3f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1 @@ -Hisham H. Muhammad \ No newline at end of file +Hisham H. Muhammad diff --git a/AvailableColumnsListBox.c b/AvailableColumnsListBox.c new file mode 100644 index 0000000..f4f9137 --- /dev/null +++ b/AvailableColumnsListBox.c @@ -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 + +/*{ + +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; +} diff --git a/AvailableColumnsListBox.h b/AvailableColumnsListBox.h new file mode 100644 index 0000000..d771e20 --- /dev/null +++ b/AvailableColumnsListBox.h @@ -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 + + +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 diff --git a/AvailableMetersListBox.c b/AvailableMetersListBox.c index 3fce899..757cd59 100644 --- a/AvailableMetersListBox.c +++ b/AvailableMetersListBox.c @@ -32,22 +32,22 @@ AvailableMetersListBox* AvailableMetersListBox_new(Settings* settings, ListBox* this->leftBox = leftMeters; this->rightBox = rightMeters; this->scr = scr; - super->eventHandler = AvailableMetersListBox_eventHandler; + super->eventHandler = AvailableMetersListBox_EventHandler; - ListBox_setHeader(super, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], "Available meters")); - ListBox_add(super, (Object*) ListItem_new(String_copy("Swap"))); - ListBox_add(super, (Object*) ListItem_new(String_copy("Memory"))); - ListBox_add(super, (Object*) ListItem_new(String_copy("Clock"))); - ListBox_add(super, (Object*) ListItem_new(String_copy("Load"))); - ListBox_add(super, (Object*) ListItem_new(String_copy("LoadAverage"))); - ListBox_add(super, (Object*) ListItem_new(String_copy("Uptime"))); - ListBox_add(super, (Object*) ListItem_new(String_copy("Tasks"))); + ListBox_setHeader(super, "Available meters"); + ListBox_add(super, (Object*) ListItem_new("Swap", 0)); + ListBox_add(super, (Object*) ListItem_new("Memory", 0)); + ListBox_add(super, (Object*) ListItem_new("Clock", 0)); + ListBox_add(super, (Object*) ListItem_new("Load", 0)); + ListBox_add(super, (Object*) ListItem_new("LoadAverage", 0)); + ListBox_add(super, (Object*) ListItem_new("Uptime", 0)); + ListBox_add(super, (Object*) ListItem_new("Tasks", 0)); if (settings->pl->processorCount > 1) - ListBox_add(super, (Object*) ListItem_new(String_copy("CPUAverage"))); + ListBox_add(super, (Object*) ListItem_new("CPUAverage", 0)); for (int i = 1; i <= settings->pl->processorCount; i++) { char buffer[50]; sprintf(buffer, "CPU(%d)", i); - ListBox_add(super, (Object*) ListItem_new(String_copy(buffer))); + ListBox_add(super, (Object*) ListItem_new(buffer, 0)); } return this; } @@ -67,12 +67,12 @@ inline void AvailableMetersListBox_addHeader(Header* header, ListBox* lb, char* ListBox_add(lb, (Object*) Meter_toListItem(meter)); } -HandlerResult AvailableMetersListBox_eventHandler(ListBox* super, int ch) { +HandlerResult AvailableMetersListBox_EventHandler(ListBox* super, int ch) { AvailableMetersListBox* this = (AvailableMetersListBox*) super; Header* header = this->settings->header; ListItem* selected = (ListItem*) ListBox_getSelected(super); - char* name = selected->text; + char* name = selected->value; HandlerResult result = IGNORED; switch(ch) { @@ -94,6 +94,7 @@ HandlerResult AvailableMetersListBox_eventHandler(ListBox* super, int ch) { } } 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); diff --git a/AvailableMetersListBox.h b/AvailableMetersListBox.h index 000a795..be6da95 100644 --- a/AvailableMetersListBox.h +++ b/AvailableMetersListBox.h @@ -28,6 +28,6 @@ AvailableMetersListBox* AvailableMetersListBox_new(Settings* settings, ListBox* void AvailableMetersListBox_delete(Object* object); -HandlerResult AvailableMetersListBox_eventHandler(ListBox* super, int ch); +HandlerResult AvailableMetersListBox_EventHandler(ListBox* super, int ch); #endif diff --git a/CPUMeter.c b/CPUMeter.c index 8e9918b..c59c2c4 100644 --- a/CPUMeter.c +++ b/CPUMeter.c @@ -49,9 +49,9 @@ CPUMeter* CPUMeter_new(ProcessList* pl, int processor) { Meter_init((Meter*)this, NULL, caption, 3); ((Meter*)this)->name = malloc(20); sprintf(((Meter*)this)->name, "CPU(%d)", processor); - ((Meter*)this)->attributes[0] = &(CRT_colors[CPU_NICE]); - ((Meter*)this)->attributes[1] = &(CRT_colors[CPU_NORMAL]); - ((Meter*)this)->attributes[2] = &(CRT_colors[CPU_KERNEL]); + ((Meter*)this)->attributes[0] = CPU_NICE; + ((Meter*)this)->attributes[1] = CPU_NORMAL; + ((Meter*)this)->attributes[2] = CPU_KERNEL; ((Meter*)this)->setValues = CPUMeter_setValues; ((Object*)this)->display = CPUMeter_display; ((Meter*)this)->total = 1.0; @@ -76,11 +76,11 @@ void CPUMeter_display(Object* cast, RichString* out) { RichString_prune(out); sprintf(buffer, "%5.1f%% ", this->values[1] * 100.0); RichString_append(out, CRT_colors[METER_TEXT], ":"); - RichString_append(out, *(this->attributes[1]), buffer); + RichString_append(out, CRT_colors[CPU_NORMAL], buffer); sprintf(buffer, "%5.1f%% ", this->values[2] * 100.0); RichString_append(out, CRT_colors[METER_TEXT], "sys:"); - RichString_append(out, *(this->attributes[2]), buffer); + RichString_append(out, CRT_colors[CPU_KERNEL], buffer); sprintf(buffer, "%5.1f%% ", this->values[0] * 100.0); RichString_append(out, CRT_colors[METER_TEXT], "low:"); - RichString_append(out, *(this->attributes[0]), buffer); + RichString_append(out, CRT_colors[CPU_NICE], buffer); } diff --git a/CRT.c b/CRT.c index fa14811..910485e 100644 --- a/CRT.c +++ b/CRT.c @@ -126,6 +126,8 @@ void CRT_init(int delay, int colorScheme) { } 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("\033OP", KEY_F(1)); define_key("\033OQ", KEY_F(2)); define_key("\033OR", KEY_F(3)); @@ -134,6 +136,7 @@ void CRT_init(int delay, int colorScheme) { define_key("\033[12~", KEY_F(2)); define_key("\033[13~", KEY_F(3)); define_key("\033[14~", KEY_F(4)); + define_key("\033[17;2~", KEY_F(18)); } #ifndef DEBUG signal(11, CRT_handleSIGSEGV); @@ -144,7 +147,7 @@ void CRT_init(int delay, int colorScheme) { CRT_colorScheme = 1; CRT_setColors(CRT_colorScheme); - mousemask(BUTTON1_PRESSED, NULL); + mousemask(BUTTON1_CLICKED, NULL); } void CRT_done() { @@ -160,6 +163,16 @@ int CRT_readKey() { return ret; } +void CRT_disableDelay() { + nocbreak(); + cbreak(); + nodelay(stdscr, TRUE); +} + +void CRT_enableDelay() { + halfdelay(CRT_delay); +} + void CRT_handleSIGSEGV(int signal) { CRT_done(); fprintf(stderr, "Aborted. Please report bug at http://htop.sf.net"); diff --git a/CRT.h b/CRT.h index 2bdcd9d..0cf2518 100644 --- a/CRT.h +++ b/CRT.h @@ -105,4 +105,8 @@ void CRT_handleSIGTERM(int signal); void CRT_setColors(int colorScheme); +void CRT_enableDelay(); + +void CRT_disableDelay(); + #endif diff --git a/CategoriesListBox.c b/CategoriesListBox.c index 249f75c..e846a57 100644 --- a/CategoriesListBox.c +++ b/CategoriesListBox.c @@ -3,7 +3,9 @@ #include "AvailableMetersListBox.h" #include "MetersListBox.h" #include "DisplayOptionsListBox.h" +#include "ColumnsListBox.h" #include "ColorsListBox.h" +#include "AvailableColumnsListBox.h" #include "ListBox.h" @@ -22,14 +24,23 @@ typedef struct CategoriesListBox_ { }*/ /* private property */ -char* MetersFunctions[10] = {" ", " ", " ", "Type ", "Add L ", "Add R ", "MoveUp", "MoveDn", "Remove", "Done "}; +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; @@ -39,10 +50,11 @@ CategoriesListBox* CategoriesListBox_new(Settings* settings, ScreenManager* scr) this->settings = settings; this->scr = scr; super->eventHandler = CategoriesListBox_eventHandler; - ListBox_setHeader(super, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], "Setup")); - ListBox_add(super, (Object*) ListItem_new(String_copy("Meters"))); - ListBox_add(super, (Object*) ListItem_new(String_copy("Display options"))); - ListBox_add(super, (Object*) ListItem_new(String_copy("Colors"))); + 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; } @@ -83,6 +95,9 @@ HandlerResult CategoriesListBox_eventHandler(ListBox* super, int ch) { case 2: CategoriesListBox_makeColorsPage(this); break; + case 3: + CategoriesListBox_makeColumnsPage(this); + break; } } result = HANDLED; @@ -92,29 +107,28 @@ HandlerResult CategoriesListBox_eventHandler(ListBox* super, int ch) { return result; } -// TODO: factor out common code from these functions into a generic makePage - void CategoriesListBox_makeMetersPage(CategoriesListBox* this) { - FunctionBar* fuBar = FunctionBar_new(10, MetersFunctions, NULL, NULL); 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, 20); - ScreenManager_add(this->scr, lbRightMeters, 20); - ScreenManager_add(this->scr, lbAvailableMeters, -1); - ScreenManager_setFunctionBar(this->scr, fuBar); + 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) { - FunctionBar* fuBar = FunctionBar_new(10, DisplayOptionsFunctions, NULL, NULL); ListBox* lbDisplayOptions = (ListBox*) DisplayOptionsListBox_new(this->settings, this->scr); - ScreenManager_add(this->scr, lbDisplayOptions, -1); - ScreenManager_setFunctionBar(this->scr, fuBar); + ScreenManager_add(this->scr, lbDisplayOptions, FunctionBar_new(10, DisplayOptionsFunctions, NULL, NULL), -1); } void CategoriesListBox_makeColorsPage(CategoriesListBox* this) { - FunctionBar* fuBar = FunctionBar_new(10, ColorsFunctions, NULL, NULL); ListBox* lbColors = (ListBox*) ColorsListBox_new(this->settings, this->scr); - ScreenManager_add(this->scr, lbColors, -1); - ScreenManager_setFunctionBar(this->scr, fuBar); + 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); } diff --git a/CategoriesListBox.h b/CategoriesListBox.h index fa68d4b..60b13b4 100644 --- a/CategoriesListBox.h +++ b/CategoriesListBox.h @@ -35,4 +35,6 @@ void CategoriesListBox_makeDisplayOptionsPage(CategoriesListBox* this); void CategoriesListBox_makeColorsPage(CategoriesListBox* this); +void CategoriesListBox_makeColumnsPage(CategoriesListBox* this); + #endif diff --git a/ChangeLog b/ChangeLog index f2eb9b9..8e82693 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,18 @@ +What's new in version 0.6 + +* Configuration of columns merged into the Setup screen +* Integrated strace (press 's') + (thanks to Marinho Barcellos for the help) +* BUGFIX: some fixes, aided by Valgrind + (thanks to Wolfram Schlich for the report) +* BUGFIX: fixed bug when switching meter modes + (thanks to Eduardo Righes for the report) +* Show processes of a single user +* "SortBy" function now menu-based +* Improved mouse handling +* ...and on top of that reduced memory consumption! + What's new in version 0.5.4 * Color schemes diff --git a/CheckItem.c b/CheckItem.c index de7c30b..0c42867 100644 --- a/CheckItem.c +++ b/CheckItem.c @@ -17,7 +17,6 @@ typedef struct CheckItem_ { Object super; char* text; bool* value; - bool radio; } CheckItem; extern char* CHECKITEM_CLASS; diff --git a/ClockMeter.c b/ClockMeter.c index 9469a35..2a27906 100644 --- a/ClockMeter.c +++ b/ClockMeter.c @@ -30,7 +30,7 @@ struct ClockMeter_ { ClockMeter* ClockMeter_new() { ClockMeter* this = malloc(sizeof(ClockMeter)); Meter_init((Meter*)this, String_copy("Clock"), String_copy("Time: "), 1); - ((Meter*)this)->attributes[0] = &(CRT_colors[CLOCK]); + ((Meter*)this)->attributes[0] = CLOCK; ((Meter*)this)->setValues = ClockMeter_setValues; ((Object*)this)->display = ClockMeter_display; ((Meter*)this)->total = 24 * 60; @@ -50,5 +50,5 @@ void ClockMeter_setValues(Meter* cast) { void ClockMeter_display(Object* cast, RichString* out) { Meter* super = (Meter*) cast; ClockMeter* this = (ClockMeter*) cast; - RichString_write(out, *(super->attributes[0]), this->clock); + RichString_write(out, CRT_colors[super->attributes[0]], this->clock); } diff --git a/ColorsListBox.c b/ColorsListBox.c index 37593bb..31cfc63 100644 --- a/ColorsListBox.c +++ b/ColorsListBox.c @@ -47,9 +47,9 @@ ColorsListBox* ColorsListBox_new(Settings* settings, ScreenManager* scr) { this->settings = settings; this->scr = scr; - super->eventHandler = ColorsListBox_eventHandler; + super->eventHandler = ColorsListBox_EventHandler; - ListBox_setHeader(super, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], "Colors")); + 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; @@ -65,7 +65,7 @@ void ColorsListBox_delete(Object* object) { free(this); } -HandlerResult ColorsListBox_eventHandler(ListBox* super, int ch) { +HandlerResult ColorsListBox_EventHandler(ListBox* super, int ch) { ColorsListBox* this = (ColorsListBox*) super; HandlerResult result = IGNORED; diff --git a/ColorsListBox.h b/ColorsListBox.h index df3b635..25b5653 100644 --- a/ColorsListBox.h +++ b/ColorsListBox.h @@ -26,7 +26,7 @@ ColorsListBox* ColorsListBox_new(Settings* settings, ScreenManager* scr); void ColorsListBox_delete(Object* object); -HandlerResult ColorsListBox_eventHandler(ListBox* super, int ch); +HandlerResult ColorsListBox_EventHandler(ListBox* super, int ch); #endif diff --git a/ColumnsListBox.c b/ColumnsListBox.c new file mode 100644 index 0000000..d3d02ee --- /dev/null +++ b/ColumnsListBox.c @@ -0,0 +1,104 @@ + +#include "ColumnsListBox.h" + +#include "ListBox.h" +#include "Settings.h" +#include "ScreenManager.h" + +#include "debug.h" +#include + +/*{ + +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; +} diff --git a/ColumnsListBox.h b/ColumnsListBox.h new file mode 100644 index 0000000..f9e455e --- /dev/null +++ b/ColumnsListBox.h @@ -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 + + +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 diff --git a/DisplayOptionsListBox.c b/DisplayOptionsListBox.c index 37541f2..dcf0a8a 100644 --- a/DisplayOptionsListBox.c +++ b/DisplayOptionsListBox.c @@ -28,9 +28,9 @@ DisplayOptionsListBox* DisplayOptionsListBox_new(Settings* settings, ScreenManag this->settings = settings; this->scr = scr; - super->eventHandler = DisplayOptionsListBox_eventHandler; + super->eventHandler = DisplayOptionsListBox_EventHandler; - ListBox_setHeader(super, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], "Display options")); + 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))); @@ -48,7 +48,7 @@ void DisplayOptionsListBox_delete(Object* object) { free(this); } -HandlerResult DisplayOptionsListBox_eventHandler(ListBox* super, int ch) { +HandlerResult DisplayOptionsListBox_EventHandler(ListBox* super, int ch) { DisplayOptionsListBox* this = (DisplayOptionsListBox*) super; HandlerResult result = IGNORED; @@ -64,6 +64,7 @@ HandlerResult DisplayOptionsListBox_eventHandler(ListBox* super, int ch) { } if (result == HANDLED) { + this->settings->changed = true; Header* header = this->settings->header; Header_calculateHeight(header); Header_draw(header); diff --git a/DisplayOptionsListBox.h b/DisplayOptionsListBox.h index f78e996..13f5fd3 100644 --- a/DisplayOptionsListBox.h +++ b/DisplayOptionsListBox.h @@ -25,7 +25,7 @@ DisplayOptionsListBox* DisplayOptionsListBox_new(Settings* settings, ScreenManag void DisplayOptionsListBox_delete(Object* object); -HandlerResult DisplayOptionsListBox_eventHandler(ListBox* super, int ch); +HandlerResult DisplayOptionsListBox_EventHandler(ListBox* super, int ch); #endif diff --git a/FunctionBar.c b/FunctionBar.c index ecbef80..02f3e0b 100644 --- a/FunctionBar.c +++ b/FunctionBar.c @@ -5,6 +5,7 @@ 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" @@ -19,42 +20,81 @@ in the source distribution for its full text. /*{ typedef struct FunctionBar_ { + Object super; int size; char** functions; char** keys; int* events; + bool staticData; } FunctionBar; +extern char* FUNCTIONBAR_CLASS; + }*/ /* private property */ -char* FunctionBar_FKeys[10] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"}; +char* FUNCTIONBAR_CLASS = "FunctionBar"; + +/* private property */ +static char* FunctionBar_FKeys[10] = {"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10"}; /* private property */ -int FunctionBar_FEvents[10] = {KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10)}; +static char* FunctionBar_FLabels[10] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", " "}; + +/* private property */ +static int FunctionBar_FEvents[10] = {KEY_F(1), KEY_F(2), KEY_F(3), KEY_F(4), KEY_F(5), KEY_F(6), KEY_F(7), KEY_F(8), KEY_F(9), KEY_F(10)}; FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events) { FunctionBar* this = malloc(sizeof(FunctionBar)); + ((Object*) this)->class = FUNCTIONBAR_CLASS; + ((Object*) this)->delete = FunctionBar_delete; this->functions = functions; this->size = size; if (keys && events) { - this->keys = keys; - this->events = events; + this->staticData = false; + 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]; + } } else { + this->staticData = true; + this->functions = functions ? functions : FunctionBar_FLabels; this->keys = FunctionBar_FKeys; this->events = FunctionBar_FEvents; - assert(this->size == 10); + assert((!functions) || this->size == 10); } return this; } -void FunctionBar_delete(FunctionBar* this) { - // These are always static data, RIGHT? >;) - // free(this->functions); - // free(this->keys); +void FunctionBar_delete(Object* cast) { + FunctionBar* this = (FunctionBar*) cast; + 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, 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] = String_copy(text); + break; + } + } +} + void FunctionBar_draw(FunctionBar* this, char* buffer) { FunctionBar_drawAttr(this, buffer, CRT_colors[FUNCTION_BAR]); } diff --git a/FunctionBar.h b/FunctionBar.h index 3e08f8e..5bb2161 100644 --- a/FunctionBar.h +++ b/FunctionBar.h @@ -9,6 +9,7 @@ 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" @@ -21,21 +22,24 @@ in the source distribution for its full text. typedef struct FunctionBar_ { + Object super; int size; char** functions; char** keys; int* events; + bool staticData; } FunctionBar; - - +extern char* FUNCTIONBAR_CLASS; FunctionBar* FunctionBar_new(int size, char** functions, char** keys, int* events); -void FunctionBar_delete(FunctionBar* this); +void FunctionBar_delete(Object* this); void FunctionBar_draw(FunctionBar* this, char* buffer); +void FunctionBar_setLabel(FunctionBar* this, int event, char* text); + void FunctionBar_drawAttr(FunctionBar* this, char* buffer, int attr); int FunctionBar_synthesizeEvent(FunctionBar* this, int pos); diff --git a/Hashtable.c b/Hashtable.c index 3ecc0f2..617a5be 100644 --- a/Hashtable.c +++ b/Hashtable.c @@ -15,8 +15,8 @@ in the source distribution for its full text. /*{ typedef struct Hashtable_ Hashtable; -typedef void(*HashtablePairFunction)(int, void*); -typedef int(*HashtableHashAlgorithm)(Hashtable*, int); +typedef void(*Hashtable_PairFunction)(int, void*, void*); +typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int); typedef struct HashtableItem { int key; @@ -28,7 +28,7 @@ struct Hashtable_ { int size; HashtableItem** buckets; int items; - HashtableHashAlgorithm hashAlgorithm; + Hashtable_HashAlgorithm hashAlgorithm; bool owner; }; }*/ @@ -129,11 +129,11 @@ inline void* Hashtable_get(Hashtable* this, int key) { bucketPtr = bucketPtr->next; } -void Hashtable_foreach(Hashtable* this, HashtablePairFunction f) { +void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData) { for (int i = 0; i < this->size; i++) { HashtableItem* walk = this->buckets[i]; while (walk != NULL) { - f(walk->key, walk->value); + f(walk->key, walk->value, userData); walk = walk->next; } } diff --git a/Hashtable.h b/Hashtable.h index e031cbe..2f52831 100644 --- a/Hashtable.h +++ b/Hashtable.h @@ -17,8 +17,8 @@ in the source distribution for its full text. typedef struct Hashtable_ Hashtable; -typedef void(*HashtablePairFunction)(int, void*); -typedef int(*HashtableHashAlgorithm)(Hashtable*, int); +typedef void(*Hashtable_PairFunction)(int, void*, void*); +typedef int(*Hashtable_HashAlgorithm)(Hashtable*, int); typedef struct HashtableItem { int key; @@ -30,7 +30,7 @@ struct Hashtable_ { int size; HashtableItem** buckets; int items; - HashtableHashAlgorithm hashAlgorithm; + Hashtable_HashAlgorithm hashAlgorithm; bool owner; }; @@ -50,6 +50,6 @@ void* Hashtable_remove(Hashtable* this, int key); inline void* Hashtable_get(Hashtable* this, int key); -void Hashtable_foreach(Hashtable* this, HashtablePairFunction f); +void Hashtable_foreach(Hashtable* this, Hashtable_PairFunction f, void* userData); #endif diff --git a/Header.c b/Header.c index a101821..c20066d 100644 --- a/Header.c +++ b/Header.c @@ -78,8 +78,9 @@ void Header_createMeter(Header* this, char* name, HeaderSide side) { TypedVector_add(meters, CPUMeter_new(this->pl, 0)); } else if (String_startsWith(name, "CPU")) { int num; - sscanf(name, "CPU(%d)", &num); - TypedVector_add(meters, CPUMeter_new(this->pl, num)); + int ok = sscanf(name, "CPU(%d)", &num); + if (ok) + TypedVector_add(meters, CPUMeter_new(this->pl, num)); } } diff --git a/ListBox.c b/ListBox.c index 3d5352b..6076236 100644 --- a/ListBox.c +++ b/ListBox.c @@ -30,7 +30,7 @@ typedef enum HandlerResult_ { BREAK_LOOP } HandlerResult; -typedef HandlerResult(*ListBox_eventHandler)(ListBox*, int); +typedef HandlerResult(*ListBox_EventHandler)(ListBox*, int); struct ListBox_ { Object super; @@ -42,7 +42,7 @@ struct ListBox_ { int oldSelected; bool needsRedraw; RichString header; - ListBox_eventHandler eventHandler; + ListBox_EventHandler eventHandler; }; extern char* LISTBOX_CLASS; @@ -96,7 +96,7 @@ void ListBox_done(ListBox* this) { TypedVector_delete(this->items); } -void ListBox_setHeader(ListBox* this, RichString header) { +inline void ListBox_setRichHeader(ListBox* this, RichString header) { assert (this != NULL); if (this->header.len > 0) { @@ -106,6 +106,14 @@ void ListBox_setHeader(ListBox* this, RichString 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); @@ -141,6 +149,13 @@ void ListBox_add(ListBox* this, Object* 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); diff --git a/ListBox.h b/ListBox.h index 3843abe..750bcfd 100644 --- a/ListBox.h +++ b/ListBox.h @@ -33,7 +33,7 @@ typedef enum HandlerResult_ { BREAK_LOOP } HandlerResult; -typedef HandlerResult(*ListBox_eventHandler)(ListBox*, int); +typedef HandlerResult(*ListBox_EventHandler)(ListBox*, int); struct ListBox_ { Object super; @@ -45,7 +45,7 @@ struct ListBox_ { int oldSelected; bool needsRedraw; RichString header; - ListBox_eventHandler eventHandler; + ListBox_EventHandler eventHandler; }; extern char* LISTBOX_CLASS; @@ -60,7 +60,11 @@ void ListBox_init(ListBox* this, int x, int y, int w, int h, char* type, bool ow void ListBox_done(ListBox* this); -void ListBox_setHeader(ListBox* this, RichString header); +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); @@ -70,6 +74,8 @@ 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); diff --git a/ListItem.c b/ListItem.c index 840ca98..95b5677 100644 --- a/ListItem.c +++ b/ListItem.c @@ -1,13 +1,15 @@ /* -htop -(C) 2004 Hisham H. Muhammad +htop - ListItem.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 "ListItem.h" +#include "String.h" #include "Object.h" -#include "CRT.h" +#include "RichString.h" +#include #include "debug.h" @@ -15,7 +17,8 @@ in the source distribution for its full text. typedef struct ListItem_ { Object super; - char* text; + char* value; + int key; } ListItem; extern char* LISTITEM_CLASS; @@ -24,25 +27,46 @@ extern char* LISTITEM_CLASS; /* private property */ char* LISTITEM_CLASS = "ListItem"; -ListItem* ListItem_new(char* text) { +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; - this->text = text; + ((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; - assert (this != NULL); - - free(this->text); + free(this->value); free(this); } void ListItem_display(Object* cast, RichString* out) { ListItem* this = (ListItem*)cast; assert (this != NULL); - RichString_write(out, CRT_colors[DEFAULT_COLOR], this->text); + int len = strlen(this->value)+1; + char buffer[len+1]; + snprintf(buffer, len, "%s", this->value); + RichString_write(out, CRT_colors[DEFAULT_COLOR], buffer); } + +const char* ListItem_getRef(ListItem* this) { + return this->value; +} + +int ListItem_compare(const Object* cast1, const Object* cast2) { + ListItem* obj1 = (ListItem*) cast1; + ListItem* obj2 = (ListItem*) cast2; + return strcmp(obj1->value, obj2->value); +} + diff --git a/ListItem.h b/ListItem.h index 9f1584b..580cbc8 100644 --- a/ListItem.h +++ b/ListItem.h @@ -9,24 +9,31 @@ Released under the GNU GPL, see the COPYING file in the source distribution for its full text. */ +#include "String.h" #include "Object.h" -#include "CRT.h" +#include "RichString.h" +#include #include "debug.h" - typedef struct ListItem_ { Object super; - char* text; + char* value; + int key; } ListItem; extern char* LISTITEM_CLASS; - -ListItem* ListItem_new(char* text); +ListItem* ListItem_new(char* value, int key); void ListItem_delete(Object* cast); void ListItem_display(Object* cast, RichString* out); +void ListItem_append(ListItem* this, char* text); + +const char* ListItem_getRef(ListItem* this); + +int ListItem_compare(const Object*, const Object*); + #endif diff --git a/LoadAverageMeter.c b/LoadAverageMeter.c index 3ef03cb..824e71c 100644 --- a/LoadAverageMeter.c +++ b/LoadAverageMeter.c @@ -31,9 +31,9 @@ void LoadAverageMeter_scan(double* one, double* five, double* fifteen); LoadAverageMeter* LoadAverageMeter_new() { LoadAverageMeter* this = malloc(sizeof(LoadAverageMeter)); Meter_init((Meter*)this, String_copy("LoadAverage"), String_copy("Load average: "), 3); - ((Meter*)this)->attributes[0] = &(CRT_colors[LOAD_AVERAGE_FIFTEEN]); - ((Meter*)this)->attributes[1] = &(CRT_colors[LOAD_AVERAGE_FIVE]); - ((Meter*)this)->attributes[2] = &(CRT_colors[LOAD_AVERAGE_ONE]); + ((Meter*)this)->attributes[0] = LOAD_AVERAGE_FIFTEEN; + ((Meter*)this)->attributes[1] = LOAD_AVERAGE_FIVE; + ((Meter*)this)->attributes[2] = LOAD_AVERAGE_ONE; ((Object*)this)->display = LoadAverageMeter_display; ((Meter*)this)->setValues = LoadAverageMeter_setValues; Meter_setMode((Meter*)this, TEXT); @@ -46,8 +46,10 @@ LoadAverageMeter* LoadAverageMeter_new() { void LoadAverageMeter_scan(double* one, double* five, double* fifteen) { int activeProcs, totalProcs, lastProc; FILE *fd = fopen(PROCDIR "/loadavg", "r"); - fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen, + int read = fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen, &activeProcs, &totalProcs, &lastProc); + (void) read; + assert(read == 6); fclose(fd); } diff --git a/LoadMeter.c b/LoadMeter.c index c2b2af7..b93f305 100644 --- a/LoadMeter.c +++ b/LoadMeter.c @@ -26,7 +26,7 @@ struct LoadMeter_ { LoadMeter* LoadMeter_new() { LoadMeter* this = malloc(sizeof(LoadMeter)); Meter_init((Meter*)this, String_copy("Load"), String_copy("Load: "), 1); - ((Meter*)this)->attributes[0] = &(CRT_colors[LOAD]); + ((Meter*)this)->attributes[0] = LOAD; ((Meter*)this)->setValues = LoadMeter_setValues; ((Object*)this)->display = LoadMeter_display; Meter_setMode((Meter*)this, GRAPH); @@ -38,8 +38,10 @@ LoadMeter* LoadMeter_new() { void LoadMeter_scan(double* one, double* five, double* fifteen) { int activeProcs, totalProcs, lastProc; FILE *fd = fopen(PROCDIR "/loadavg", "r"); - fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen, + int read = fscanf(fd, "%lf %lf %lf %d/%d %d", one, five, fifteen, &activeProcs, &totalProcs, &lastProc); + (void) read; + assert(read == 6); fclose(fd); } @@ -53,10 +55,9 @@ void LoadMeter_setValues(Meter* cast) { } void LoadMeter_display(Object* cast, RichString* out) { - Meter* super = (Meter*)cast; LoadMeter* this = (LoadMeter*)cast; char buffer[20]; RichString_prune(out); sprintf(buffer, "%.2f ", ((Meter*)this)->values[0]); - RichString_append(out, *(super->attributes[0]), buffer); + RichString_append(out, CRT_colors[LOAD], buffer); } diff --git a/Makefile.am b/Makefile.am index d1734a6..ede3484 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,4 +19,6 @@ ListItem.h LoadAverageMeter.h LoadMeter.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 +ColorsListBox.c ColorsListBox.h TraceScreen.c TraceScreen.h \ +AvailableColumnsListBox.c AvailableColumnsListBox.h ColumnsListBox.c \ +ColumnsListBox.h diff --git a/Makefile.in b/Makefile.in index 14f7672..6af6ff9 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.9.6 from Makefile.am. +# Makefile.in generated by automake 1.8.4 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005 Free Software Foundation, Inc. +# 2003, 2004 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -14,6 +14,8 @@ @SET_MAKE@ +SOURCES = $(htop_SOURCES) + srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ @@ -67,12 +69,40 @@ am_htop_OBJECTS = AvailableMetersListBox.$(OBJEXT) \ SignalsListBox.$(OBJEXT) String.$(OBJEXT) SwapMeter.$(OBJEXT) \ TasksMeter.$(OBJEXT) TypedVector.$(OBJEXT) \ UptimeMeter.$(OBJEXT) UsersTable.$(OBJEXT) CheckItem.$(OBJEXT) \ - ColorsListBox.$(OBJEXT) + ColorsListBox.$(OBJEXT) TraceScreen.$(OBJEXT) \ + AvailableColumnsListBox.$(OBJEXT) ColumnsListBox.$(OBJEXT) htop_OBJECTS = $(am_htop_OBJECTS) htop_LDADD = $(LDADD) DEFAULT_INCLUDES = -I. -I$(srcdir) -I. depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles +@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/AvailableColumnsListBox.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/AvailableMetersListBox.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/CPUMeter.Po ./$(DEPDIR)/CRT.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/CategoriesListBox.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/CheckItem.Po ./$(DEPDIR)/ClockMeter.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ColorsListBox.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ColumnsListBox.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/DebugMemory.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/DisplayOptionsListBox.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/FunctionBar.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/Hashtable.Po ./$(DEPDIR)/Header.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ListBox.Po ./$(DEPDIR)/ListItem.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/LoadAverageMeter.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/LoadMeter.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/MemoryMeter.Po ./$(DEPDIR)/Meter.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/MetersListBox.Po ./$(DEPDIR)/Object.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/Process.Po ./$(DEPDIR)/ProcessList.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/RichString.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/ScreenManager.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/Settings.Po ./$(DEPDIR)/SignalItem.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/SignalsListBox.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/String.Po ./$(DEPDIR)/SwapMeter.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/TasksMeter.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/TraceScreen.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/TypedVector.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/UptimeMeter.Po \ +@AMDEP_TRUE@ ./$(DEPDIR)/UsersTable.Po ./$(DEPDIR)/htop.Po COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) @@ -144,8 +174,6 @@ am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ bindir = @bindir@ build_alias = @build_alias@ datadir = @datadir@ @@ -183,7 +211,9 @@ ListItem.h LoadAverageMeter.h LoadMeter.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 +ColorsListBox.c ColorsListBox.h TraceScreen.c TraceScreen.h \ +AvailableColumnsListBox.c AvailableColumnsListBox.h ColumnsListBox.c \ +ColumnsListBox.h all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am @@ -273,6 +303,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AvailableColumnsListBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AvailableMetersListBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CPUMeter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CRT.Po@am__quote@ @@ -280,6 +311,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CheckItem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClockMeter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ColorsListBox.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ColumnsListBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DebugMemory.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DisplayOptionsListBox.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FunctionBar.Po@am__quote@ @@ -303,6 +335,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/String.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SwapMeter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TasksMeter.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TraceScreen.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TypedVector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UptimeMeter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UsersTable.Po@am__quote@ @@ -312,14 +345,16 @@ distclean-compile: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: @am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ @am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` uninstall-info-am: install-man1: $(man1_MANS) $(man_MANS) @@ -389,7 +424,7 @@ TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ - test -n "$$unique" || unique=$$empty_fix; \ + test -z "$$unique" && unique=$$empty_fix; \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$tags $$unique; \ fi @@ -451,15 +486,15 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r $(distdir) dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir - tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-tarZ: distdir - tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(AMTAR) chof - $(distdir) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir @@ -472,7 +507,7 @@ dist-zip: distdir $(am__remove_distdir) dist dist-all: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then @@ -481,11 +516,11 @@ dist dist-all: distdir distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\ *.tar.bz2*) \ - bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\ *.tar.Z*) \ - uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ *.zip*) \ @@ -568,7 +603,7 @@ mostlyclean-generic: clean-generic: distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" diff --git a/MemoryMeter.c b/MemoryMeter.c index 43029ff..5efa5b7 100644 --- a/MemoryMeter.c +++ b/MemoryMeter.c @@ -35,23 +35,15 @@ struct MemoryMeter_ { MemoryMeter* MemoryMeter_new(ProcessList* pl) { MemoryMeter* this = malloc(sizeof(MemoryMeter)); Meter_init((Meter*)this, String_copy("Memory"), String_copy("Mem"), 3); - ((Meter*)this)->attributes[0] = &(CRT_colors[MEMORY_USED]); - ((Meter*)this)->attributes[1] = &(CRT_colors[MEMORY_BUFFERS]); - ((Meter*)this)->attributes[2] = &(CRT_colors[MEMORY_CACHE]); + ((Meter*)this)->attributes[0] = MEMORY_USED; + ((Meter*)this)->attributes[1] = MEMORY_BUFFERS; + ((Meter*)this)->attributes[2] = MEMORY_CACHE; ((Meter*)this)->setValues = MemoryMeter_setValues; ((Object*)this)->display = MemoryMeter_display; this->pl = pl; Meter_setMode((Meter*)this, BAR); - if (this->pl->totalMem > 1000000) { - this->wideFormat = "%7ldk "; - this->wideLimit = 22 + 9 * 4; - } else if (this->pl->totalMem > 100000) { - this->wideFormat = "%6ldk "; - this->wideLimit = 22 + 8 * 4; - } else { - this->wideFormat = "%5ldk "; - this->wideLimit = 22 + 7 * 4; - } + this->wideFormat = "%6ldk "; + this->wideLimit = 22 + 8 * 4; return this; } @@ -88,11 +80,11 @@ void MemoryMeter_display(Object* cast, RichString* out) { RichString_append(out, CRT_colors[METER_VALUE], buffer); sprintf(buffer, format, usedMem); RichString_append(out, CRT_colors[METER_TEXT], "used:"); - RichString_append(out, *(meter->attributes[0]), buffer); + RichString_append(out, CRT_colors[MEMORY_USED], buffer); sprintf(buffer, format, buffersMem); RichString_append(out, CRT_colors[METER_TEXT], "buffers:"); - RichString_append(out, *(meter->attributes[1]), buffer); + RichString_append(out, CRT_colors[MEMORY_BUFFERS], buffer); sprintf(buffer, format, cachedMem); RichString_append(out, CRT_colors[METER_TEXT], "cache:"); - RichString_append(out, *(meter->attributes[2]), buffer); + RichString_append(out, CRT_colors[MEMORY_CACHE], buffer); } diff --git a/Meter.c b/Meter.c index 2e436e5..c35b6a9 100644 --- a/Meter.c +++ b/Meter.c @@ -26,8 +26,8 @@ in the source distribution for its full text. typedef struct Meter_ Meter; -typedef void(*Method_Meter_setValues)(Meter*); -typedef void(*Method_Meter_draw)(Meter*, int, int, int); +typedef void(*Meter_SetValues)(Meter*); +typedef void(*Meter_Draw)(Meter*, int, int, int); typedef enum MeterMode_ { UNSET, @@ -43,10 +43,10 @@ struct Meter_ { int h; int w; - Method_Meter_draw draw; - Method_Meter_setValues setValues; + Meter_Draw draw; + Meter_SetValues setValues; int items; - int** attributes; + int* attributes; double* values; double total; char* caption; @@ -80,6 +80,9 @@ char* Meter_ledDigits[3][10] = { /* private property */ char Meter_barCharacters[] = "|#*@$%&"; +/* private property */ +static RichString Meter_stringBuffer; + Meter* Meter_new(char* name, char* caption, int items) { Meter* this = malloc(sizeof(Meter)); Meter_init(this, name, caption, items); @@ -92,7 +95,7 @@ void Meter_init(Meter* this, char* name, char* caption, int items) { this->items = items; this->name = name; this->caption = caption; - this->attributes = malloc(sizeof(int*) * items); + this->attributes = malloc(sizeof(int) * items); this->values = malloc(sizeof(double) * items); this->displayBuffer.c = NULL; this->mode = UNSET; @@ -113,11 +116,6 @@ void Meter_freeBuffer(Meter* this) { free(this->displayBuffer.c); break; } - case LED: - case TEXT: { - free(this->displayBuffer.rs); - break; - } case GRAPH: { free(this->displayBuffer.graph); break; @@ -192,7 +190,7 @@ void Meter_drawBar(Meter* this, int x, int y, int w) { // ...then print the buffer. offset = 0; for (int i = 0; i < this->items; i++) { - attrset(*(this->attributes[i])); + attrset(CRT_colors[this->attributes[i]]); mvaddnstr(y, x + offset, bar + offset, blockSizes[i]); offset += blockSizes[i]; offset = MAX(offset, 0); @@ -307,13 +305,13 @@ void Meter_setMode(Meter* this, MeterMode mode) { } case TEXT: { this->draw = Meter_drawText; - this->displayBuffer.rs = malloc(sizeof(RichString)); + this->displayBuffer.rs = & Meter_stringBuffer; this->h = 1; break; } case LED: { this->draw = Meter_drawLed; - this->displayBuffer.rs = malloc(sizeof(RichString)); + this->displayBuffer.rs = & Meter_stringBuffer; this->h = 3; break; } @@ -348,5 +346,5 @@ ListItem* Meter_toListItem(Meter* this) { } } sprintf(buffer, "%s [%s]", this->name, mode); - return ListItem_new(String_copy(buffer)); + return ListItem_new(buffer, 0); } diff --git a/Meter.h b/Meter.h index fff0e93..4e0e5fa 100644 --- a/Meter.h +++ b/Meter.h @@ -29,8 +29,8 @@ in the source distribution for its full text. typedef struct Meter_ Meter; -typedef void(*Method_Meter_setValues)(Meter*); -typedef void(*Method_Meter_draw)(Meter*, int, int, int); +typedef void(*Meter_SetValues)(Meter*); +typedef void(*Meter_Draw)(Meter*, int, int, int); typedef enum MeterMode_ { UNSET, @@ -46,10 +46,10 @@ struct Meter_ { int h; int w; - Method_Meter_draw draw; - Method_Meter_setValues setValues; + Meter_Draw draw; + Meter_SetValues setValues; int items; - int** attributes; + int* attributes; double* values; double total; char* caption; diff --git a/MetersListBox.c b/MetersListBox.c index 5f09c2b..dc756ca 100644 --- a/MetersListBox.c +++ b/MetersListBox.c @@ -29,8 +29,8 @@ MetersListBox* MetersListBox_new(Settings* settings, char* header, TypedVector* this->settings = settings; this->meters = meters; this->scr = scr; - super->eventHandler = MetersListBox_eventHandler; - ListBox_setHeader(super, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], header)); + 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)); @@ -45,7 +45,7 @@ void MetersListBox_delete(Object* object) { free(this); } -HandlerResult MetersListBox_eventHandler(ListBox* super, int ch) { +HandlerResult MetersListBox_EventHandler(ListBox* super, int ch) { MetersListBox* this = (MetersListBox*) super; int selected = ListBox_getSelectedIndex(super); @@ -59,7 +59,7 @@ HandlerResult MetersListBox_eventHandler(ListBox* super, int ch) { case 't': { Meter* meter = (Meter*) TypedVector_get(this->meters, selected); - MeterMode mode = ++(meter->mode); + MeterMode mode = meter->mode + 1; if (mode == LAST_METERMODE) mode = 1; // skip mode 0, "unset" Meter_setMode(meter, mode); diff --git a/MetersListBox.h b/MetersListBox.h index c4653f3..92f96f9 100644 --- a/MetersListBox.h +++ b/MetersListBox.h @@ -25,6 +25,6 @@ MetersListBox* MetersListBox_new(Settings* settings, char* header, TypedVector* void MetersListBox_delete(Object* object); -HandlerResult MetersListBox_eventHandler(ListBox* super, int ch); +HandlerResult MetersListBox_EventHandler(ListBox* super, int ch); #endif diff --git a/NEWS b/NEWS index af87e86..52c40f1 100644 --- a/NEWS +++ b/NEWS @@ -2,3 +2,4 @@ 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. + diff --git a/Object.c b/Object.c index 3a8c628..dfa5e09 100644 --- a/Object.c +++ b/Object.c @@ -17,15 +17,15 @@ in the source distribution for its full text. /*{ typedef struct Object_ Object; -typedef void(*Method_Object_display)(Object*, RichString*); -typedef bool(*Method_Object_equals)(const Object*, const Object*); -typedef void(*Method_Object_delete)(Object*); +typedef void(*Object_Display)(Object*, RichString*); +typedef int(*Object_Compare)(const Object*, const Object*); +typedef void(*Object_Delete)(Object*); struct Object_ { char* class; - Method_Object_display display; - Method_Object_equals equals; - Method_Object_delete delete; + Object_Display display; + Object_Compare compare; + Object_Delete delete; }; }*/ @@ -37,7 +37,7 @@ void Object_new() { this = malloc(sizeof(Object)); this->class = OBJECT_CLASS; this->display = Object_display; - this->equals = Object_equals; + this->compare = Object_compare; this->delete = Object_delete; } @@ -55,6 +55,6 @@ void Object_display(Object* this, RichString* out) { RichString_write(out, CRT_colors[DEFAULT_COLOR], objAddress); } -bool Object_equals(const Object* this, const Object* o) { - return (this == o); +int Object_compare(const Object* this, const Object* o) { + return (this - o); } diff --git a/Object.h b/Object.h index b7497ea..b69c902 100644 --- a/Object.h +++ b/Object.h @@ -19,15 +19,15 @@ in the source distribution for its full text. typedef struct Object_ Object; -typedef void(*Method_Object_display)(Object*, RichString*); -typedef bool(*Method_Object_equals)(const Object*, const Object*); -typedef void(*Method_Object_delete)(Object*); +typedef void(*Object_Display)(Object*, RichString*); +typedef int(*Object_Compare)(const Object*, const Object*); +typedef void(*Object_Delete)(Object*); struct Object_ { char* class; - Method_Object_display display; - Method_Object_equals equals; - Method_Object_delete delete; + Object_Display display; + Object_Compare compare; + Object_Delete delete; }; @@ -39,6 +39,6 @@ void Object_delete(Object* this); void Object_display(Object* this, RichString* out); -bool Object_equals(const Object* this, const Object* o); +int Object_compare(const Object* this, const Object* o); #endif diff --git a/Process.c b/Process.c index 8333a17..fae1ed4 100644 --- a/Process.c +++ b/Process.c @@ -5,6 +5,7 @@ Released under the GNU GPL, see the COPYING file in the source distribution for its full text. */ +#define _GNU_SOURCE #include "ProcessList.h" #include "Object.h" #include "CRT.h" @@ -25,9 +26,6 @@ in the source distribution for its full text. #include #include -// TODO: wtf!? -int kill(pid_t pid, int signal); - // This works only with glibc 2.1+. On earlier versions // the behavior is similar to have a hardcoded page size. #define PAGE_SIZE ( sysconf(_SC_PAGESIZE) / 1024 ) @@ -38,7 +36,7 @@ int kill(pid_t pid, int signal); /*{ typedef enum ProcessField_ { - PID, COMM, STATE, PPID, PGRP, SESSION, TTY_NR, TPGID, FLAGS, MINFLT, CMINFLT, MAJFLT, CMAJFLT, UTIME, + 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, @@ -54,7 +52,7 @@ typedef struct Process_ { bool updated; int pid; - char comm[PROCESS_COMM_LEN + 2]; + char* comm; int indent; char state; bool tag; @@ -116,19 +114,20 @@ extern char* Process_fieldNames[]; char* PROCESS_CLASS = "Process"; /* private property */ -char *Process_fieldNames[] = { "PID", "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", "SIGIGNORE", "SIGCATCH", "WCHAN", "NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE", "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM", "USER", "TIME", "LAST_PROCESSFIELD"}; +char *Process_fieldNames[] = { "", "PID", "Command", "STATE", "PPID", "PGRP", "SESSION", "TTY_NR", "TPGID", "FLAGS", "MINFLT", "CMINFLT", "MAJFLT", "CMAJFLT", "UTIME", "STIME", "CUTIME", "CSTIME", "PRIORITY", "NICE", "ITREALVALUE", "STARTTIME", "VSIZE", "RSS", "RLIM", "STARTCODE", "ENDCODE", "STARTSTACK", "KSTKESP", "KSTKEIP", "SIGNAL", "BLOCKED", "SIGIGNORE", "SIGCATCH", "WCHAN", "NSWAP", "CNSWAP", "EXIT_SIGNAL", "PROCESSOR", "M_SIZE", "M_RESIDENT", "M_SHARE", "M_TRS", "M_DRS", "M_LRS", "M_DT", "ST_UID", "PERCENT_CPU", "PERCENT_MEM", "USER", "TIME", "*** report bug! ***"}; Process* Process_new(struct ProcessList_ *pl) { Process* this = malloc(sizeof(Process)); ((Object*)this)->class = PROCESS_CLASS; ((Object*)this)->display = Process_display; - ((Object*)this)->equals = Process_equals; + ((Object*)this)->compare = Process_compare; ((Object*)this)->delete = Process_delete; this->pl = pl; this->tag = false; this->updated = false; this->utime = 0; this->stime = 0; + this->comm = NULL; return this; } @@ -140,6 +139,7 @@ Process* Process_clone(Process* this) { void Process_delete(Object* cast) { Process* this = (Process*) cast; + if (this->comm) free(this->comm); assert (this != NULL); free(this); } @@ -148,7 +148,7 @@ void Process_display(Object* cast, RichString* out) { Process* this = (Process*) cast; ProcessField* fields = this->pl->fields; RichString_prune(out); - for (int i = 0; fields[i] != LAST_PROCESSFIELD; i++) + for (int i = 0; fields[i]; i++) Process_writeField(this, out, fields[i]); if (this->pl->shadowOtherUsers && this->st_uid != getuid()) RichString_setAttr(out, CRT_colors[PROCESS_SHADOW]); @@ -161,14 +161,6 @@ void Process_toggleTag(Process* this) { this->tag = this->tag == true ? false : true; } -bool Process_equals(const Object* o1, const Object* o2) { - Process* p1 = (Process*) o1; - Process* p2 = (Process*) o2; - if (p1 == NULL || p2 == NULL) - return false; - return (p1->pid == p2->pid); -} - void Process_setPriority(Process* this, int priority) { int old_prio = getpriority(PRIO_PROCESS, this->pid); int err = setpriority(PRIO_PROCESS, this->pid, priority); @@ -188,24 +180,25 @@ void Process_sendSignal(Process* this, int signal) { /* private */ void Process_printLargeNumber(Process* this, RichString *str, unsigned int number) { char buffer[10]; + int len; if(number >= (1000 * ONE_M)) { - snprintf(buffer, 10, "%4.2fG ", (float)number / ONE_M); - RichString_append(str, CRT_colors[LARGE_NUMBER], buffer); + len = snprintf(buffer, 10, "%4.2fG ", (float)number / ONE_M); + RichString_appendn(str, CRT_colors[LARGE_NUMBER], buffer, len); } else if(number >= (100000)) { - snprintf(buffer, 10, "%4dM ", number / ONE_K); + len = snprintf(buffer, 10, "%4dM ", number / ONE_K); int attr = this->pl->highlightMegabytes ? CRT_colors[PROCESS_MEGABYTES] : CRT_colors[PROCESS]; - RichString_append(str, attr, buffer); + RichString_appendn(str, attr, buffer, len); } else if (this->pl->highlightMegabytes && number >= 1000) { - snprintf(buffer, 10, "%2d", number/1000); - RichString_append(str, CRT_colors[PROCESS_MEGABYTES], buffer); + len = snprintf(buffer, 10, "%2d", number/1000); + RichString_appendn(str, CRT_colors[PROCESS_MEGABYTES], buffer, len); number %= 1000; - snprintf(buffer, 10, "%03d ", number); - RichString_append(str, CRT_colors[PROCESS], buffer); + len = snprintf(buffer, 10, "%03d ", number); + RichString_appendn(str, CRT_colors[PROCESS], buffer, len); } else { - snprintf(buffer, 10, "%5d ", number); - RichString_append(str, CRT_colors[PROCESS], buffer); + len = snprintf(buffer, 10, "%5d ", number); + RichString_appendn(str, CRT_colors[PROCESS], buffer, len); } } diff --git a/Process.h b/Process.h index 2b3b755..5cf127e 100644 --- a/Process.h +++ b/Process.h @@ -40,7 +40,7 @@ int kill(pid_t pid, int signal); typedef enum ProcessField_ { - PID, COMM, STATE, PPID, PGRP, SESSION, TTY_NR, TPGID, FLAGS, MINFLT, CMINFLT, MAJFLT, CMAJFLT, UTIME, + 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, @@ -56,7 +56,7 @@ typedef struct Process_ { bool updated; int pid; - char comm[PROCESS_COMM_LEN + 2]; + char* comm; int indent; char state; bool tag; @@ -125,8 +125,6 @@ void Process_display(Object* cast, RichString* out); void Process_toggleTag(Process* this); -bool Process_equals(const Object* o1, const Object* o2); - void Process_setPriority(Process* this, int priority); void Process_sendSignal(Process* this, int signal); diff --git a/ProcessList.c b/ProcessList.c index d5d4ddc..3d87ec0 100644 --- a/ProcessList.c +++ b/ProcessList.c @@ -92,20 +92,18 @@ typedef struct ProcessList_ { }*/ /* private property */ -ProcessField defaultHeaders[LAST_PROCESSFIELD] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, LAST_PROCESSFIELD }; +ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, LAST_PROCESSFIELD, 0 }; ProcessList* ProcessList_new(UsersTable* usersTable) { ProcessList* this; this = malloc(sizeof(ProcessList)); this->processes = TypedVector_new(PROCESS_CLASS, true, DEFAULT_SIZE); this->processTable = Hashtable_new(20, false); - TypedVector_setCompareFunction(this->processes, Process_compare); this->prototype = Process_new(this); this->usersTable = usersTable; /* tree-view auxiliary buffers */ this->processes2 = TypedVector_new(PROCESS_CLASS, true, DEFAULT_SIZE); - TypedVector_setCompareFunction(this->processes2, Process_compare); FILE* status = fopen(PROCSTATFILE, "r"); assert(status != NULL); @@ -132,10 +130,10 @@ ProcessList* ProcessList_new(UsersTable* usersTable) { this->totalPeriod[i] = 1; } - this->fields = malloc(sizeof(ProcessField) * LAST_PROCESSFIELD); + this->fields = calloc(sizeof(ProcessField), LAST_PROCESSFIELD+1); // TODO: turn 'fields' into a TypedVector, // (and ProcessFields into proper objects). - for (int i = 0; i < LAST_PROCESSFIELD; i++) { + for (int i = 0; defaultHeaders[i]; i++) { this->fields[i] = defaultHeaders[i]; } this->sortKey = PERCENT_CPU; @@ -179,28 +177,10 @@ void ProcessList_invertSortOrder(ProcessList* this) { this->direction = 1; } -void ProcessList_sortKey(ProcessList* this, int delta) { - assert(delta == 1 || delta == -1); - int i = 0; - while (this->fields[i] != this->sortKey) - i++; - i += delta; - if (i < 0) { - i = 0; - while (this->fields[i] != LAST_PROCESSFIELD) - i++; - i--; - } else if (this->fields[i] == LAST_PROCESSFIELD) - i = 0; - this->sortKey = this->fields[i]; - this->direction = 1; - // Weird code... -} - RichString ProcessList_printHeader(ProcessList* this) { RichString out = RichString_new(); ProcessField* fields = this->fields; - for (int i = 0; fields[i] != LAST_PROCESSFIELD; i++) { + for (int i = 0; fields[i]; i++) { char* field = Process_printField(fields[i]); if (this->sortKey == fields[i]) RichString_append(&out, CRT_colors[PANEL_HIGHLIGHT_FOCUS], field); @@ -222,8 +202,11 @@ void ProcessList_add(ProcessList* this, Process* p) { void ProcessList_remove(ProcessList* this, Process* p) { Hashtable_remove(this->processTable, p->pid); + ProcessField pf = this->sortKey; + this->sortKey = PID; int index = TypedVector_indexOf(this->processes, p); TypedVector_remove(this->processes, index); + this->sortKey = pf; } Process* ProcessList_get(ProcessList* this, int index) { @@ -447,18 +430,15 @@ void ProcessList_processEntries(ProcessList* this, char* dirname, int parent, fl goto errorReadingProcess; } - char* cmdline = process->comm; - int amtRead = fread(cmdline, 1, PROCESS_COMM_LEN - 1, status); + int amtRead = fread(command, 1, PROCESS_COMM_LEN - 1, status); if (amtRead > 0) { for (int i = 0; i < amtRead; i++) - if (cmdline[i] == '\0' || cmdline[i] == '\n') - cmdline[i] = ' '; - cmdline[amtRead] = '\0'; - } - else { - strncpy(process->comm, command, PROCESS_COMM_LEN); - cmdline[PROCESS_COMM_LEN] = '\0'; + if (command[i] == '\0' || command[i] == '\n') + command[i] = ' '; + command[amtRead] = '\0'; } + command[PROCESS_COMM_LEN] = '\0'; + process->comm = String_copy(command); fclose(status); } diff --git a/ProcessList.h b/ProcessList.h index 5817bad..530af6f 100644 --- a/ProcessList.h +++ b/ProcessList.h @@ -101,11 +101,8 @@ void ProcessList_delete(ProcessList* this); void ProcessList_invertSortOrder(ProcessList* this); -void ProcessList_sortKey(ProcessList* this, int delta); - RichString ProcessList_printHeader(ProcessList* this); - void ProcessList_prune(ProcessList* this); void ProcessList_add(ProcessList* this, Process* p); diff --git a/README b/README index fde7f8a..39db6ae 100644 --- a/README +++ b/README @@ -2,7 +2,7 @@ htop by Hisham Muhammad -May, 2004 - September, 2005 +May, 2004 - December, 2005 Introduction ~~~~~~~~~~~~ @@ -42,27 +42,7 @@ 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. -Keys -~~~~ - -Arrows, -[PgUp], [PgDn], -[Home], [End] - scroll process list -[F1], [h] - help screen -[F2], [S] - setup: configure header meters -[F3], [/] - incremental process search: type process name -[F4], [I] - invert sort order -[F5], [<] - select sorting by previous field -[F6], [>] - select sorting by next field -[F7], []] - increase process priority (superuser only) -[F8], [[] - decrease process priority -[F9], [k] - kill process (all tagged ones, or the current, if none is tagged) -[F10],[q] - quit -[F] - highlight follows process -[M] - sort by memory usage -[P] - sort by processor usage -[C] - select columns -[space] -[Ctrl+L] - refresh screen +See the manual page (man htop) or the on-line help ('F1' or 'h' +inside htop) for a list of supported key commands. if not all keys work check your curses configuration. diff --git a/ScreenManager.c b/ScreenManager.c index 72d77db..3d0c1d9 100644 --- a/ScreenManager.c +++ b/ScreenManager.c @@ -30,6 +30,7 @@ typedef struct ScreenManager_ { int y2; Orientation orientation; TypedVector* items; + TypedVector* fuBars; int itemCount; FunctionBar* fuBar; bool owner; @@ -47,6 +48,7 @@ ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation ori this->fuBar = NULL; this->orientation = orientation; this->items = TypedVector_new(LISTBOX_CLASS, owner, DEFAULT_SIZE); + this->fuBars = TypedVector_new(FUNCTIONBAR_CLASS, true, DEFAULT_SIZE); this->itemCount = 0; this->owner = owner; return this; @@ -54,8 +56,7 @@ ScreenManager* ScreenManager_new(int x1, int y1, int x2, int y2, Orientation ori void ScreenManager_delete(ScreenManager* this) { TypedVector_delete(this->items); - if (this->owner) - FunctionBar_delete(this->fuBar); + TypedVector_delete(this->fuBars); free(this); } @@ -63,7 +64,7 @@ inline int ScreenManager_size(ScreenManager* this) { return this->itemCount; } -void ScreenManager_add(ScreenManager* this, ListBox* item, int size) { +void ScreenManager_add(ScreenManager* this, ListBox* item, FunctionBar* fuBar, int size) { if (this->orientation == HORIZONTAL) { int lastX = 0; if (this->itemCount > 0) { @@ -79,6 +80,11 @@ void ScreenManager_add(ScreenManager* this, ListBox* item, int size) { } // TODO: VERTICAL TypedVector_add(this->items, item); + if (fuBar) + TypedVector_add(this->fuBars, fuBar); + else + TypedVector_add(this->fuBars, FunctionBar_new(0, NULL, NULL, NULL)); + if (!this->fuBar && fuBar) this->fuBar = fuBar; item->needsRedraw = true; this->itemCount++; } @@ -86,13 +92,15 @@ void ScreenManager_add(ScreenManager* this, ListBox* item, int size) { 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->itemCount--; return lb; } void ScreenManager_setFunctionBar(ScreenManager* this, FunctionBar* fuBar) { if (this->owner && this->fuBar) - FunctionBar_delete(this->fuBar); + FunctionBar_delete((Object*)this->fuBar); this->fuBar = fuBar; } @@ -134,6 +142,9 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) { } } } + FunctionBar* bar = (FunctionBar*) TypedVector_get(this->fuBars, focus); + if (bar) + this->fuBar = bar; if (this->fuBar) FunctionBar_draw(this->fuBar, NULL); @@ -183,10 +194,8 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) { } case KEY_LEFT: tryLeft: - focus--; - if (focus == -1) { - focus = this->itemCount - 1; - } + if (focus > 0) + focus--; lbFocus = (ListBox*) TypedVector_get(this->items, focus); if (ListBox_getSize(lbFocus) == 0 && focus > 0) goto tryLeft; @@ -194,10 +203,8 @@ void ScreenManager_run(ScreenManager* this, ListBox** lastFocus, int* lastKey) { case KEY_RIGHT: case 9: tryRight: - focus++; - if (focus == this->itemCount) { - focus = 0; - } + if (focus < this->itemCount - 1) + focus++; lbFocus = (ListBox*) TypedVector_get(this->items, focus); if (ListBox_getSize(lbFocus) == 0 && focus < this->itemCount - 1) goto tryRight; diff --git a/ScreenManager.h b/ScreenManager.h index 20e8000..1eb685f 100644 --- a/ScreenManager.h +++ b/ScreenManager.h @@ -34,6 +34,7 @@ typedef struct ScreenManager_ { TypedVector* items; int itemCount; FunctionBar* fuBar; + TypedVector* fuBars; bool owner; } ScreenManager; @@ -44,7 +45,7 @@ void ScreenManager_delete(ScreenManager* this); inline int ScreenManager_size(ScreenManager* this); -void ScreenManager_add(ScreenManager* this, ListBox* item, int size); +void ScreenManager_add(ScreenManager* this, ListBox* item, FunctionBar* fuBar, int size); ListBox* ScreenManager_remove(ScreenManager* this, int index); diff --git a/Settings.c b/Settings.c index 0e01999..30b5c54 100644 --- a/Settings.c +++ b/Settings.c @@ -21,6 +21,7 @@ typedef struct Settings_ { ProcessList* pl; Header* header; int colorScheme; + bool changed; int delay; } Settings; @@ -35,15 +36,19 @@ Settings* Settings_new(ProcessList* pl, Header* header) { if (!home) home = getenv("HOME"); this->userSettings = String_cat(home, "/.htoprc"); 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; @@ -98,14 +103,20 @@ bool Settings_read(Settings* this, char* fileName) { char* trim = String_trim(option[1]); char** ids = String_split(trim, ' '); free(trim); - int i; - for (i = 0; ids[i] != NULL; i++) { - this->pl->fields[i] = atoi(ids[i]); + int i, j; + 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; + j++; + } } - this->pl->fields[i] = LAST_PROCESSFIELD; + this->pl->fields[j] = (ProcessField) NULL; String_freeArray(ids); } else if (String_eq(option[0], "sort_key")) { - this->pl->sortKey = atoi(option[1]); + // This "+1" is for compatibility with the older enum format. + this->pl->sortKey = atoi(option[1]) + 1; } else if (String_eq(option[0], "sort_direction")) { this->pl->direction = atoi(option[1]); } else if (String_eq(option[0], "tree_view")) { @@ -164,11 +175,13 @@ bool Settings_write(Settings* this) { 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] != LAST_PROCESSFIELD; i++) { - fprintf(fd, "%d ", (int) this->pl->fields[i]); + for (int i = 0; this->pl->fields[i]; i++) { + // This "-1" is for compatibility with the older enum format. + fprintf(fd, "%d ", (int) this->pl->fields[i]-1); } fprintf(fd, "\n"); - fprintf(fd, "sort_key=%d\n", (int) this->pl->sortKey); + // This "-1" is for compatibility with the older enum format. + fprintf(fd, "sort_key=%d\n", (int) this->pl->sortKey-1); fprintf(fd, "sort_direction=%d\n", (int) this->pl->direction); fprintf(fd, "hide_threads=%d\n", (int) this->pl->hideThreads); fprintf(fd, "hide_kernel_threads=%d\n", (int) this->pl->hideKernelThreads); diff --git a/Settings.h b/Settings.h index 74f9c71..91be193 100644 --- a/Settings.h +++ b/Settings.h @@ -15,12 +15,14 @@ in the source distribution for its full text. #include "debug.h" + typedef struct Settings_ { char* userSettings; ProcessList* pl; Header* header; int colorScheme; int delay; + bool changed; } Settings; diff --git a/SignalsListBox.c b/SignalsListBox.c index e626994..94442be 100644 --- a/SignalsListBox.c +++ b/SignalsListBox.c @@ -27,7 +27,7 @@ SignalsListBox* SignalsListBox_new(int x, int y, int w, int h) { ((Object*)this)->delete = SignalsListBox_delete; this->signals = Signal_getSignalTable(); - super->eventHandler = SignalsListBox_eventHandler; + super->eventHandler = SignalsListBox_EventHandler; int sigCount = Signal_getSignalCount(); for(int i = 0; i < sigCount; i++) ListBox_set(super, i, (Object*) this->signals[i]); @@ -46,12 +46,12 @@ void SignalsListBox_delete(Object* object) { void SignalsListBox_reset(SignalsListBox* this) { ListBox* super = (ListBox*) this; - ListBox_setHeader(super, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], "Send signal:")); + ListBox_setHeader(super, "Send signal:"); ListBox_setSelected(super, 16); // 16th item is SIGTERM this->state = 0; } -HandlerResult SignalsListBox_eventHandler(ListBox* super, int ch) { +HandlerResult SignalsListBox_EventHandler(ListBox* super, int ch) { SignalsListBox* this = (SignalsListBox*) super; int size = ListBox_getSize(super); diff --git a/SignalsListBox.h b/SignalsListBox.h index af2fbf7..f7f0b0c 100644 --- a/SignalsListBox.h +++ b/SignalsListBox.h @@ -27,6 +27,6 @@ void SignalsListBox_delete(Object* object); void SignalsListBox_reset(SignalsListBox* this); -HandlerResult SignalsListBox_eventHandler(ListBox* super, int ch); +HandlerResult SignalsListBox_EventHandler(ListBox* super, int ch); #endif diff --git a/String.c b/String.c index 8290351..20ec7d1 100644 --- a/String.c +++ b/String.c @@ -132,7 +132,7 @@ char** String_split(char* s, char sep) { out[ctr] = token; ctr++; } - out = realloc(out, sizeof(char*) * ctr + 1); + out = realloc(out, sizeof(char*) * (ctr + 1)); out[ctr] = NULL; return out; } diff --git a/SwapMeter.c b/SwapMeter.c index b22f56a..55a531f 100644 --- a/SwapMeter.c +++ b/SwapMeter.c @@ -33,7 +33,7 @@ struct SwapMeter_ { SwapMeter* SwapMeter_new(ProcessList* pl) { SwapMeter* this = malloc(sizeof(SwapMeter)); Meter_init((Meter*)this, String_copy("Swap"), String_copy("Swp"), 1); - ((Meter*)this)->attributes[0] = &(CRT_colors[SWAP]); + ((Meter*)this)->attributes[0] = SWAP; ((Meter*)this)->setValues = SwapMeter_setValues; ((Object*)this)->display = SwapMeter_display; this->pl = pl; diff --git a/TODO b/TODO index b98017c..ffe15df 100644 --- a/TODO +++ b/TODO @@ -2,9 +2,6 @@ FEATURES: * read SYSCONFDIR/htoprc (help, autoconf gurus!) - * integrate columns configuration in the setup screen - * handle saving of .htoprc more elegantly - * option to display only processes of a single user * make bars display refresh independent from list refresh * auto-calibrate delay * add some more 'top' features diff --git a/TasksMeter.c b/TasksMeter.c index 75291c8..86bda9b 100644 --- a/TasksMeter.c +++ b/TasksMeter.c @@ -28,7 +28,7 @@ struct TasksMeter_ { TasksMeter* TasksMeter_new(ProcessList* pl) { TasksMeter* this = malloc(sizeof(TasksMeter)); Meter_init((Meter*)this, String_copy("Tasks"), String_copy("Tasks: "), 1); - ((Meter*)this)->attributes[0] = &(CRT_colors[TASKS_RUNNING]); + ((Meter*)this)->attributes[0] = TASKS_RUNNING; ((Object*)this)->display = TasksMeter_display; ((Meter*)this)->setValues = TasksMeter_setValues; this->pl = pl; diff --git a/TraceScreen.c b/TraceScreen.c new file mode 100644 index 0000000..9628290 --- /dev/null +++ b/TraceScreen.c @@ -0,0 +1,164 @@ +/* +htop - TraceScreen.c +(C) 2005 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include "TraceScreen.h" +#include "ProcessList.h" +#include "Process.h" +#include "ListItem.h" + +/*{ + +typedef struct TraceScreen_ { + Process* process; + ListBox* display; + FunctionBar* bar; + bool tracing; +} TraceScreen; + +}*/ + +/* private property */ +static char* tbFunctions[3] = {"AutoScroll ", "Stop Tracing ", "Done "}; + +/* private property */ +static char* tbKeys[3] = {"F4", "F5", "Esc"}; + +/* private property */ +static int tbEvents[3] = {KEY_F(4), KEY_F(5), 27}; + +TraceScreen* TraceScreen_new(Process* process) { + TraceScreen* this = (TraceScreen*) malloc(sizeof(TraceScreen)); + this->process = process; + this->display = ListBox_new(0, 1, COLS, LINES-2, LISTITEM_CLASS, true); + this->bar = FunctionBar_new(3, tbFunctions, tbKeys, tbEvents); + this->tracing = true; + return this; +} + +void TraceScreen_delete(TraceScreen* this) { + ListBox_delete((Object*)this->display); + FunctionBar_delete((Object*)this->bar); + free(this); +} + +void TraceScreen_draw(TraceScreen* this) { + attrset(CRT_colors[PANEL_HEADER_FOCUS]); + mvhline(0, 0, ' ', COLS); + mvprintw(0, 0, "Trace of process %d - %s", this->process->pid, this->process->comm); + attrset(CRT_colors[DEFAULT_COLOR]); + FunctionBar_draw(this->bar, NULL); +} + +void TraceScreen_run(TraceScreen* this) { +// if (this->process->pid == getpid()) return; + char buffer[1001]; + int fdpair[2]; + int err = pipe(fdpair); + if (err == -1) return; + int child = fork(); + if (child == -1) return; + if (child == 0) { + dup2(fdpair[1], STDERR_FILENO); + fcntl(fdpair[1], F_SETFL, O_NONBLOCK); + sprintf(buffer, "%d", this->process->pid); + execlp("strace", "strace", "-p", buffer, NULL); + exit(1); + } + fcntl(fdpair[0], F_SETFL, O_NONBLOCK); + FILE* strace = fdopen(fdpair[0], "r"); + ListBox* lb = this->display; + int fd_strace = fileno(strace); + TraceScreen_draw(this); + CRT_disableDelay(); + bool contLine = false; + bool follow = false; + bool looping = true; + while (looping) { + fd_set fds; + FD_ZERO(&fds); + FD_SET(fd_strace, &fds); + struct timeval tv; + tv.tv_sec = 0; tv.tv_usec = 500; + int ready = select(fd_strace+1, &fds, NULL, NULL, &tv); + int nread = 0; + if (ready > 0) + nread = fread(buffer, 1, 1000, strace); + if (nread && this->tracing) { + char* line = buffer; + buffer[nread] = '\0'; + for (int i = 0; i < nread; i++) { + if (buffer[i] == '\n') { + buffer[i] = '\0'; + if (contLine) { + ListItem_append((ListItem*)ListBox_get(lb, + ListBox_getSize(lb)-1), line); + contLine = false; + } else { + ListBox_add(lb, (Object*) ListItem_new(line, 0)); + } + line = buffer+i+1; + } + } + if (line < buffer+nread) { + ListBox_add(lb, (Object*) ListItem_new(line, 0)); + buffer[nread] = '\0'; + contLine = true; + } + if (follow) + ListBox_setSelected(lb, ListBox_getSize(lb)-1); + ListBox_draw(lb, true); + } + int ch = getch(); + if (ch == KEY_MOUSE) { + MEVENT mevent; + int ok = getmouse(&mevent); + if (ok == OK) + if (mevent.y >= lb->y && mevent.y < LINES - 1) { + ListBox_setSelected(lb, mevent.y - lb->y + lb->scrollV); + follow = false; + ch = 0; + } if (mevent.y == LINES - 1) + ch = FunctionBar_synthesizeEvent(this->bar, mevent.x); + } + switch(ch) { + case ERR: + continue; + case KEY_F(5): + this->tracing = !this->tracing; + FunctionBar_setLabel(this->bar, KEY_F(5), this->tracing?"Stop Tracing ":"Resume Tracing "); + TraceScreen_draw(this); + break; + case 'f': + case KEY_F(4): + follow = !follow; + if (follow) + ListBox_setSelected(lb, ListBox_getSize(lb)-1); + break; + case 'q': + case 27: + looping = false; + break; + case KEY_RESIZE: + ListBox_resize(lb, COLS, LINES-2); + TraceScreen_draw(this); + break; + default: + follow = false; + ListBox_onKey(lb, ch); + } + ListBox_draw(lb, true); + } + kill(child, SIGTERM); + fclose(strace); +} diff --git a/TraceScreen.h b/TraceScreen.h new file mode 100644 index 0000000..e26737c --- /dev/null +++ b/TraceScreen.h @@ -0,0 +1,37 @@ +/* +htop - TraceScreen.h +(C) 2005 Hisham H. Muhammad +Released under the GNU GPL, see the COPYING file +in the source distribution for its full text. +*/ +#ifndef HEADER_TraceScreen +#define HEADER_TraceScreen + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include "ProcessList.h" +#include "ListBox.h" +#include "FunctionBar.h" + +typedef struct TraceScreen_ { + Process* process; + ListBox* display; + FunctionBar* bar; + bool tracing; +} TraceScreen; + +TraceScreen* TraceScreen_new(Process* process); + +void TraceScreen_delete(TraceScreen* this); + +void TraceScreen_draw(TraceScreen* this); + +void TraceScreen_run(TraceScreen* this); + +#endif + diff --git a/TypedVector.c b/TypedVector.c index fe62c86..0fd5e91 100644 --- a/TypedVector.c +++ b/TypedVector.c @@ -21,14 +21,12 @@ in the source distribution for its full text. #endif typedef void(*TypedVector_procedure)(void*); -typedef int(*TypedVector_booleanFunction)(const Object*,const Object*); typedef struct TypedVector_ { Object **array; int arraySize; int growthRate; int items; - TypedVector_booleanFunction compareFunction; char* vectorType; bool owner; } TypedVector; @@ -44,7 +42,6 @@ TypedVector* TypedVector_new(char* vectorType_, bool owner, int size) { this->growthRate = size; this->array = (Object**) calloc(size, sizeof(Object*)); this->arraySize = size; - this->compareFunction = TypedVector_compareFunction; this->items = 0; this->vectorType = vectorType_; this->owner = owner; @@ -65,7 +62,7 @@ void TypedVector_delete(TypedVector* this) { bool TypedVector_isConsistent(TypedVector* this) { if (this->owner) { for (int i = 0; i < this->items; i++) - if (this->array[i]->class != this->vectorType) + if (this->array[i] && this->array[i]->class != this->vectorType) return false; return true; } else { @@ -86,20 +83,12 @@ void TypedVector_prune(TypedVector* this) { this->items = 0; } -int TypedVector_compareFunction(const Object* v1, const Object* v2) { - return !(v1->equals(v1, v2)); -} - -void TypedVector_setCompareFunction(TypedVector* this, TypedVector_booleanFunction f) { - this->compareFunction = f; -} - void TypedVector_sort(TypedVector* this) { assert(TypedVector_isConsistent(this)); int i, j; for (i = 1; i < this->items; i++) { void* t = this->array[i]; - for (j = i-1; j >= 0 && this->compareFunction(this->array[j], t) < 0; j--) + for (j = i-1; j >= 0 && this->array[j]->compare(this->array[j], t) < 0; j--) this->array[j+1] = this->array[j]; this->array[j+1] = t; } @@ -108,7 +97,7 @@ void TypedVector_sort(TypedVector* this) { /* for (int i = 0; i < this->items; i++) { for (int j = i+1; j < this->items; j++) { - if (this->compareFunction(this->array[i], this->array[j]) < 0) { + if (this->array[j]->compare(this->array[j], t) < 0) { void* tmp = this->array[i]; this->array[i] = this->array[j]; this->array[j] = tmp; @@ -235,7 +224,7 @@ void TypedVector_merge(TypedVector* this, TypedVector* v2) { } void TypedVector_add(TypedVector* this, void* data_) { - assert(((Object*)data_)->class == this->vectorType); + assert(data_ && ((Object*)data_)->class == this->vectorType); Object* data = data_; assert(TypedVector_isConsistent(this)); @@ -252,7 +241,7 @@ inline int TypedVector_indexOf(TypedVector* this, void* search_) { for (i = 0; i < this->items; i++) { Object* o = (Object*)this->array[i]; - if (o->equals(o, search)) + if (o && o->compare(o, search) == 0) return i; } return -1; diff --git a/TypedVector.h b/TypedVector.h index 42c16b5..3a9da4d 100644 --- a/TypedVector.h +++ b/TypedVector.h @@ -23,14 +23,12 @@ in the source distribution for its full text. #endif typedef void(*TypedVector_procedure)(void*); -typedef int(*TypedVector_booleanFunction)(const Object*,const Object*); typedef struct TypedVector_ { Object **array; int arraySize; int growthRate; int items; - TypedVector_booleanFunction compareFunction; char* vectorType; bool owner; } TypedVector; @@ -40,16 +38,10 @@ TypedVector* TypedVector_new(char* vectorType_, bool owner, int size); void TypedVector_delete(TypedVector* this); - void TypedVector_prune(TypedVector* this); -int TypedVector_compareFunction(const Object* v1, const Object* v2); - -void TypedVector_setCompareFunction(TypedVector* this, TypedVector_booleanFunction f); - void TypedVector_sort(TypedVector* this); - void TypedVector_insert(TypedVector* this, int index, void* data_); Object* TypedVector_take(TypedVector* this, int index); diff --git a/UptimeMeter.c b/UptimeMeter.c index 3b27a98..ced1e1a 100644 --- a/UptimeMeter.c +++ b/UptimeMeter.c @@ -32,7 +32,7 @@ struct UptimeMeter_ { UptimeMeter* UptimeMeter_new() { UptimeMeter* this = malloc(sizeof(UptimeMeter)); Meter_init((Meter*)this, String_copy("Uptime"), String_copy("Uptime: "), 1); - ((Meter*)this)->attributes[0] = &(CRT_colors[UPTIME]); + ((Meter*)this)->attributes[0] = UPTIME; ((Object*)this)->display = UptimeMeter_display; ((Meter*)this)->setValues = UptimeMeter_setValues; Meter_setMode((Meter*)this, TEXT); diff --git a/UsersTable.c b/UsersTable.c index e063a4c..d3b84e9 100644 --- a/UsersTable.c +++ b/UsersTable.c @@ -47,6 +47,10 @@ char* UsersTable_getRef(UsersTable* this, int uid) { return name; } -int UsersTable_size(UsersTable* this) { +inline int UsersTable_size(UsersTable* this) { return (Hashtable_size(this->users)); } + +inline void UsersTable_foreach(UsersTable* this, Hashtable_PairFunction f, void* userData) { + Hashtable_foreach(this->users, f, userData); +} diff --git a/UsersTable.h b/UsersTable.h index 3007ce7..4e8e665 100644 --- a/UsersTable.h +++ b/UsersTable.h @@ -34,6 +34,8 @@ void UsersTable_delete(UsersTable* this); char* UsersTable_getRef(UsersTable* this, int uid); -int UsersTable_size(UsersTable* this); +inline int UsersTable_size(UsersTable* this); + +void UsersTable_foreach(UsersTable*, Hashtable_PairFunction, void*); #endif diff --git a/aclocal.m4 b/aclocal.m4 index aef181a..1b5a5f1 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,7 +1,7 @@ -# generated automatically by aclocal 1.9.6 -*- Autoconf -*- +# generated automatically by aclocal 1.8.4 -*- Autoconf -*- -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, -# 2005 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -11,32 +11,55 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. +# -*- Autoconf -*- +# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Generated from amversion.in; do not edit by hand. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. -AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"]) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION so it can be traced. # This function is AC_REQUIREd by AC_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.9.6])]) + [AM_AUTOMAKE_VERSION([1.8.4])]) -# AM_AUX_DIR_EXPAND -*- Autoconf -*- +# AM_AUX_DIR_EXPAND -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to @@ -83,16 +106,26 @@ AC_PREREQ([2.50])dnl am_aux_dir=`cd $ac_aux_dir && pwd` ]) -# AM_CONDITIONAL -*- Autoconf -*- +# AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. +# Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. -# serial 7 +# serial 6 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- @@ -112,19 +145,30 @@ else fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then - AC_MSG_ERROR([[conditional "$1" was never defined. -Usually this means the macro was only invoked conditionally.]]) + AC_MSG_ERROR([conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]) fi])]) +# serial 7 -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 # Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# serial 8 +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, @@ -133,6 +177,7 @@ fi])]) # CC etc. in the Makefile, will ask for an AC_PROG_CC use... + # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. @@ -272,16 +317,26 @@ AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH]) ]) -# Generate code to set up dependency tracking. -*- Autoconf -*- +# Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. -#serial 3 +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ @@ -300,21 +355,27 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], else continue fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue @@ -340,19 +401,30 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) -# Do all the work for Automake. -*- Autoconf -*- +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 # Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# serial 12 +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. -# This macro actually does too much. Some checks are only needed if -# your package does certain things. But this isn't really a big deal. +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 11 # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) @@ -410,6 +482,7 @@ AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG(AMTAR, tar) AM_PROG_INSTALL_SH AM_PROG_INSTALL_STRIP AC_REQUIRE([AM_PROG_MKDIR_P])dnl @@ -418,9 +491,7 @@ AC_REQUIRE([AM_PROG_MKDIR_P])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl -_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], - [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], - [_AM_PROG_TAR([v7])])]) + _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], @@ -454,27 +525,51 @@ for _am_header in $config_headers :; do done echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl install_sh=${install_sh-"$am_aux_dir/install-sh"} AC_SUBST(install_sh)]) -# Copyright (C) 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. +# -*- Autoconf -*- +# Copyright (C) 2003 Free Software Foundation, Inc. -# serial 2 +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. @@ -489,15 +584,26 @@ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) -# Check to see how 'make' treats includes. -*- Autoconf -*- +# Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. -# serial 3 +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 # AM_MAKE_INCLUDE() # ----------------- @@ -541,16 +647,27 @@ AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) -# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- +# -*- Autoconf -*- -# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. -# serial 4 +# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ @@ -576,16 +693,27 @@ else fi ]) -# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - # AM_PROG_MKDIR_P # --------------- # Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. -# + +# Copyright (C) 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + # Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories # created by `make install' are always world readable, even if the # installer happens to have an overly restrictive umask (e.g. 077). @@ -606,21 +734,13 @@ fi # this.) AC_DEFUN([AM_PROG_MKDIR_P], [if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # We used to keeping the `.' as first argument, in order to - # allow $(mkdir_p) to be used without argument. As in + # Keeping the `.' argument allows $(mkdir_p) to be used without + # argument. Indeed, we sometimes output rules like # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. However this is wrong - # for two reasons: - # 1. if the package is installed by a user who cannot write `.' - # make install will fail, - # 2. the above comment should most certainly read - # $(mkdir_p) $(DESTDIR)$(somedir) - # so it does not work when $(somedir) is undefined and - # $(DESTDIR) is not. - # To support the latter case, we have to write - # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), - # so the `.' trick is pointless. - mkdir_p='mkdir -p --' + # where $(somedir) is conditionally defined. + # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more + # expensive solution, as it forces Make to start a sub-shell.) + mkdir_p='mkdir -p -- .' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as @@ -639,15 +759,26 @@ else fi AC_SUBST([mkdir_p])]) -# Helper functions for option handling. -*- Autoconf -*- +# Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. -# serial 3 +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 # _AM_MANGLE_OPTION(NAME) # ----------------------- @@ -672,16 +803,28 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Check to make sure that the build environment is sane. -*- Autoconf -*- - -# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 -# Free Software Foundation, Inc. # -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. +# Check to make sure that the build environment is sane. +# + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. -# serial 4 +# serial 3 # AM_SANITY_CHECK # --------------- @@ -724,14 +867,25 @@ Check your system clock]) fi AC_MSG_RESULT(yes)]) -# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - # AM_PROG_INSTALL_STRIP -# --------------------- + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip @@ -752,99 +906,3 @@ fi INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Check how to create a tarball. -*- Autoconf -*- - -# Copyright (C) 2004, 2005 Free Software Foundation, Inc. -# -# This file is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# serial 2 - -# _AM_PROG_TAR(FORMAT) -# -------------------- -# Check how to create a tarball in format FORMAT. -# FORMAT should be one of `v7', `ustar', or `pax'. -# -# Substitute a variable $(am__tar) that is a command -# writing to stdout a FORMAT-tarball containing the directory -# $tardir. -# tardir=directory && $(am__tar) > result.tar -# -# Substitute a variable $(am__untar) that extract such -# a tarball read from stdin. -# $(am__untar) < result.tar -AC_DEFUN([_AM_PROG_TAR], -[# Always define AMTAR for backward compatibility. -AM_MISSING_PROG([AMTAR], [tar]) -m4_if([$1], [v7], - [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], - [m4_case([$1], [ustar],, [pax],, - [m4_fatal([Unknown tar format])]) -AC_MSG_CHECKING([how to create a $1 tar archive]) -# Loop over all known methods to create a tar archive until one works. -_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' -_am_tools=${am_cv_prog_tar_$1-$_am_tools} -# Do not fold the above two line into one, because Tru64 sh and -# Solaris sh will not grok spaces in the rhs of `-'. -for _am_tool in $_am_tools -do - case $_am_tool in - gnutar) - for _am_tar in tar gnutar gtar; - do - AM_RUN_LOG([$_am_tar --version]) && break - done - am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' - am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' - am__untar="$_am_tar -xf -" - ;; - plaintar) - # Must skip GNU tar: if it does not support --format= it doesn't create - # ustar tarball either. - (tar --version) >/dev/null 2>&1 && continue - am__tar='tar chf - "$$tardir"' - am__tar_='tar chf - "$tardir"' - am__untar='tar xf -' - ;; - pax) - am__tar='pax -L -x $1 -w "$$tardir"' - am__tar_='pax -L -x $1 -w "$tardir"' - am__untar='pax -r' - ;; - cpio) - am__tar='find "$$tardir" -print | cpio -o -H $1 -L' - am__tar_='find "$tardir" -print | cpio -o -H $1 -L' - am__untar='cpio -i -H $1 -d' - ;; - none) - am__tar=false - am__tar_=false - am__untar=false - ;; - esac - - # If the value was cached, stop now. We just wanted to have am__tar - # and am__untar set. - test -n "${am_cv_prog_tar_$1}" && break - - # tar/untar a dummy directory, and stop if the command works - rm -rf conftest.dir - mkdir conftest.dir - echo GrepMe > conftest.dir/file - AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) - rm -rf conftest.dir - if test -s conftest.tar; then - AM_RUN_LOG([$am__untar /dev/null 2>&1 && break - fi -done -rm -rf conftest.dir - -AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) -AC_MSG_RESULT([$am_cv_prog_tar_$1])]) -AC_SUBST([am__tar]) -AC_SUBST([am__untar]) -]) # _AM_PROG_TAR - diff --git a/config.h b/config.h index e028286..1fb8f16 100644 --- a/config.h +++ b/config.h @@ -105,13 +105,13 @@ #define PACKAGE_NAME "htop" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "htop 0.5.4" +#define PACKAGE_STRING "htop 0.6" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "htop" /* Define to the version of this package. */ -#define PACKAGE_VERSION "0.5.4" +#define PACKAGE_VERSION "0.6" /* Define as the return type of signal handlers (`int' or `void'). */ #define RETSIGTYPE void @@ -120,7 +120,7 @@ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "0.5.4" +#define VERSION "0.6" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ diff --git a/configure b/configure index fae2fc3..f5b3b10 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.59 for htop 0.5.4. +# Generated by GNU Autoconf 2.59 for htop 0.6. # # Report bugs to . # @@ -269,8 +269,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='htop' PACKAGE_TARNAME='htop' -PACKAGE_VERSION='0.5.4' -PACKAGE_STRING='htop 0.5.4' +PACKAGE_VERSION='0.6' +PACKAGE_STRING='htop 0.6' PACKAGE_BUGREPORT='loderunner@users.sourceforge.net' ac_unique_file="htop.c" @@ -311,7 +311,7 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP LIBOBJS LTLIBOBJS' +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO AMTAR install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CPP EGREP LIBOBJS LTLIBOBJS' ac_subst_files='' # Initialize some variables set by options. @@ -780,7 +780,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures htop 0.5.4 to adapt to many kinds of systems. +\`configure' configures htop 0.6 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -842,7 +842,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of htop 0.5.4:";; + short | recursive ) echo "Configuration of htop 0.6:";; esac cat <<\_ACEOF @@ -960,7 +960,7 @@ fi test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -htop configure 0.5.4 +htop configure 0.6 generated by GNU Autoconf 2.59 Copyright (C) 2003 Free Software Foundation, Inc. @@ -974,7 +974,7 @@ cat >&5 <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by htop $as_me 0.5.4, which was +It was created by htop $as_me 0.6, which was generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1310,7 +1310,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -am__api_version="1.9" +am__api_version="1.8" ac_aux_dir= for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do if test -f $ac_dir/install-sh; then @@ -1487,21 +1487,13 @@ echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - # We used to keeping the `.' as first argument, in order to - # allow $(mkdir_p) to be used without argument. As in + # Keeping the `.' argument allows $(mkdir_p) to be used without + # argument. Indeed, we sometimes output rules like # $(mkdir_p) $(somedir) - # where $(somedir) is conditionally defined. However this is wrong - # for two reasons: - # 1. if the package is installed by a user who cannot write `.' - # make install will fail, - # 2. the above comment should most certainly read - # $(mkdir_p) $(DESTDIR)$(somedir) - # so it does not work when $(somedir) is undefined and - # $(DESTDIR) is not. - # To support the latter case, we have to write - # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), - # so the `.' trick is pointless. - mkdir_p='mkdir -p --' + # where $(somedir) is conditionally defined. + # (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more + # expensive solution, as it forces Make to start a sub-shell.) + mkdir_p='mkdir -p -- .' else # On NextStep and OpenStep, the `mkdir' command does not # recognize any option. It will interpret all options as @@ -1617,7 +1609,7 @@ fi # Define the identity of the package. PACKAGE='htop' - VERSION='0.5.4' + VERSION='0.6' cat >>confdefs.h <<_ACEOF @@ -1645,6 +1637,9 @@ AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +AMTAR=${AMTAR-"${am_missing_run}tar"} + install_sh=${install_sh-"$am_aux_dir/install-sh"} # Installed binaries are usually stripped using `strip' when the user @@ -1737,13 +1732,6 @@ INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" # We need awk for the "check" target. The system "awk" is bad on # some platforms. -# Always define AMTAR for backward compatibility. - -AMTAR=${AMTAR-"${am_missing_run}tar"} - -am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' - - @@ -5629,7 +5617,7 @@ _ASBOX } >&5 cat >&5 <<_CSEOF -This file was extended by htop $as_me 0.5.4, which was +This file was extended by htop $as_me 0.6, which was generated by GNU Autoconf 2.59. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5692,7 +5680,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -htop config.status 0.5.4 +htop config.status 0.6 configured by $0, generated by GNU Autoconf 2.59, with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" @@ -5901,6 +5889,7 @@ s,@AUTOCONF@,$AUTOCONF,;t t s,@AUTOMAKE@,$AUTOMAKE,;t t s,@AUTOHEADER@,$AUTOHEADER,;t t s,@MAKEINFO@,$MAKEINFO,;t t +s,@AMTAR@,$AMTAR,;t t s,@install_sh@,$install_sh,;t t s,@STRIP@,$STRIP,;t t s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t @@ -5909,9 +5898,6 @@ s,@mkdir_p@,$mkdir_p,;t t s,@AWK@,$AWK,;t t s,@SET_MAKE@,$SET_MAKE,;t t s,@am__leading_dot@,$am__leading_dot,;t t -s,@AMTAR@,$AMTAR,;t t -s,@am__tar@,$am__tar,;t t -s,@am__untar@,$am__untar,;t t s,@CC@,$CC,;t t s,@CFLAGS@,$CFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t @@ -6554,21 +6540,27 @@ echo X"$mf" | else continue fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running `make'. + grep '^DEP_FILES *= *[^ #]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue diff --git a/configure.ac b/configure.ac index 64a5acf..f68a38f 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) -AC_INIT([htop],[0.5.4],[loderunner@users.sourceforge.net]) +AC_INIT([htop],[0.6],[loderunner@users.sourceforge.net]) AM_INIT_AUTOMAKE AC_CONFIG_SRCDIR([htop.c]) AC_CONFIG_HEADER([config.h]) diff --git a/htop.1 b/htop.1 index dcb5689..ddca7bb 100644 --- a/htop.1 +++ b/htop.1 @@ -1,4 +1,4 @@ -.TH "htop" "1" "0.5" "Bartosz Fenski " "Utils" +.TH "htop" "1" "0.6" "Bartosz Fenski " "Utils" .SH "NAME" htop \- interactive process viewer .SH "SYNTAX" @@ -27,12 +27,21 @@ Scroll process list. like "kill", will then apply over the list of tagged processes, instead of the currently highlighted one. .TP +.B U +"Untag" all processes (remove all tags added with the Space key). +.TP +.B s +Trace process system calls: if strace(1) is installed, pressing this key +will attach it to the currently selected process, presenting a live +update of system calls issued by the process. +.TP .B F1, h Help screen .TP .B F2, S Setup screen. There you can configure meters displayed on the top side -of the screen, as well as setting various display options. +of the screen, as well as set various display options, choose among +color schemes and select the layout of the displayed columns. .TP .B F3, / Incremental process search: type in part of a process command line and @@ -49,12 +58,8 @@ between them as a tree. Toggling the key will switch between tree and your previously selected sort view. Selecting a sort view will exit tree view. .TP -.B Shift-F6 (F18), < -Select sorting by previous field. The sort field is indicated by a -highlight in the header. -.TP .B F6, > -Select sorting by next field. The sort field is indicated by a +Select field for sorting. The sort field is indicated by a highlight in the header. .TP .B F7, ], - @@ -72,6 +77,9 @@ If none is tagged, sends to the currently selected process. .B F10, q Quit .TP +.B u +Show only processes owned by a specified user. +.TP .B M Sort by memory usage (top compatibility key). .TP @@ -81,22 +89,20 @@ Sort by processor usage (top compatibility key). .B T Sort by time (top compatibility key). .TP -.B C -Select displayed columns. -.TP .B F "Follow" process: if the sort order causes the currently selected process to move in the list, make the selection bar follow it. This is useful for monitoring a process: this way, you can keep a process always visible on screen. When a movement key is used, "follow" loses effect. .TP -.B U -Shadow other users: processes belonging to other users are displayed in -dim color (requires a capable terminal). -.TP .B K Hide kernel threads: prevent the threads belonging the kernel to be -displayed in the process list. +displayed in the process list. (This is a toggle key.) +.TP +.B H +Hide user threads: on systems that represent them differently than ordinary +processes (such as recent NPTL-based systems), this can hide threads from +userspace processes in the process list. (This is a toggle key.) .TP .B Ctrl-L Refresh: redraw screen and recalculate values. diff --git a/htop.c b/htop.c index b851a70..a1bd7ee 100644 --- a/htop.c +++ b/htop.c @@ -5,6 +5,13 @@ Released under the GNU GPL, see the COPYING file in the source distribution for its full text. */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + #include "ProcessList.h" #include "CRT.h" #include "ListBox.h" @@ -17,18 +24,11 @@ in the source distribution for its full text. #include "ListItem.h" #include "CategoriesListBox.h" #include "SignalsListBox.h" +#include "TraceScreen.h" #include "config.h" #include "debug.h" -#include -#include -#include -#include -#include - -int usleep(int usec); - //#link m #define INCSEARCH_MAX 40 @@ -47,20 +47,19 @@ void printHelpFlag() { clear(); printf("htop " VERSION " - (C) 2004,2005 Hisham Muhammad.\n"); printf("Released under the GNU GPL.\n\n"); - printf("-d DELAY Delay between updates, in tenths of seconds\n\n"); + printf("-d DELAY Delay between updates, in tenths of seconds\n\n"); + printf("-u USERNAME Show only processes of a given user\n\n"); printf("Press F1 inside htop for online help.\n"); - printf("See the man page for full info.\n\n"); + printf("See the man page for full information.\n\n"); exit(0); } void showHelp() { clear(); attrset(CRT_colors[HELP_BOLD]); - for (int i = 0; i < LINES; i++) { - move(i, 0); hline(' ', COLS); - } mvaddstr(0, 0, "htop " VERSION " - (C) 2004 Hisham Muhammad."); - mvaddstr(1, 0, "Released under the GNU GPL. See man page for more info."); + mvaddstr(1, 0, "Released under the GNU GPL. See 'man' page for more info."); + attrset(CRT_colors[DEFAULT_COLOR]); mvaddstr(3, 0, "CPU usage bar: "); #define addattrstr(a,s) attrset(a);addstr(s) @@ -85,293 +84,119 @@ void showHelp() { addattrstr(CRT_colors[BAR_SHADOW], " used/total"); addattrstr(CRT_colors[BAR_BORDER], "]"); attrset(CRT_colors[DEFAULT_COLOR]); + mvaddstr(6,0, "Type and layout of header meters is configurable in the setup screen."); + + mvaddstr( 8, 0, " Arrows: scroll process list F5 t: tree view"); + mvaddstr( 9, 0, " Digits: incremental PID search u: show processes of a single user"); + mvaddstr(10, 0, " F3 /: incremental name search H: hide/show user threads"); + mvaddstr(11, 0, " K: hide/show kernel threads"); + mvaddstr(12, 0, " Space: tag processes F: cursor follows process"); + mvaddstr(13, 0, " U: untag all processes"); + mvaddstr(14, 0, " F9 k: kill process/tagged processes P: sort by CPU%"); + mvaddstr(15, 0, " + [ F7: lower priority (+ nice) M: sort by MEM%"); + mvaddstr(16, 0, " - ] F8: higher priority (root only) T: sort by TIME"); + mvaddstr(17, 0, " F4 I: invert sort order"); + mvaddstr(18, 0, " F2 S: setup F6 >: select sort column"); + mvaddstr(19, 0, " F1 h: show this help screen"); + mvaddstr(20, 0, " F10 q: quit s: trace syscalls with strace"); attrset(CRT_colors[HELP_BOLD]); - mvaddstr(7, 0, "Keyboard shortcuts"); + mvaddstr( 8, 0, " Arrows"); mvaddstr( 8,40, " F5 t"); + mvaddstr( 9, 0, " Digits"); mvaddstr( 9,40, " u"); + mvaddstr(10, 0, " F3 /"); mvaddstr(10,40, " H"); + mvaddstr(11,40, " K"); + mvaddstr(12, 0, " Space"); mvaddstr(12,40, " F"); + mvaddstr(13, 0, " U"); + mvaddstr(14, 0, " F9 k"); mvaddstr(14,40, " P"); + mvaddstr(15, 0, " + [ F7"); mvaddstr(15,40, " M"); + mvaddstr(16, 0, " - ] F8"); mvaddstr(16,40, " T"); + mvaddstr(17,40, " F4 I"); + mvaddstr(18, 0, " F2 S"); mvaddstr(18,40, " F6 >"); + mvaddstr(19, 0, " F1 h"); + mvaddstr(20, 0, " F10 q"); mvaddstr(20,40, " s"); attrset(CRT_colors[DEFAULT_COLOR]); - mvaddstr(8, 0, " Arrows - scroll process list Digits - incremental PID search"); - mvaddstr(9, 0, " Space - tag process / - incremental name search"); - mvaddstr(10, 0, " k - kill process/tagged processes U - shadow other users"); - mvaddstr(11, 0, " I - invert sort order t - tree view"); - mvaddstr(12, 0, " P - sort by CPU% K - hide kernel threads"); - mvaddstr(13, 0, " M - sort by MEM% F - cursor follows process"); - mvaddstr(14, 0, " T - sort by TIME Ctrl-L - refresh"); - mvaddstr(15, 0, " [ - decrease priority ] - increase priority (superuser)"); - mvaddstr(16, 0, " C - configure columns S - setup"); - mvaddstr(17, 0, " h - shows this help screen q - quit"); + attrset(CRT_colors[HELP_BOLD]); - mvaddstr(19,0, "Press any key to return."); + mvaddstr(23,0, "Press any key to return."); attrset(CRT_colors[DEFAULT_COLOR]); refresh(); CRT_readKey(); clear(); } -void showColumnConfig(ProcessList* pl) { - - int i; - int startSelected = 0; - int startAvailable = 0; - int currRow = 0; - int currCol = 0; - bool configure = true; - bool save = false; - - ProcessField avail[LAST_PROCESSFIELD + 1] = { 0 }; - ProcessField select[LAST_PROCESSFIELD + 1] = { 0 }; - ProcessField original[LAST_PROCESSFIELD + 1] = { 0 }; - int countAvail = 0; - int countSelect = 0; - int countOriginal = 0; - - for(i = 0; i < LAST_PROCESSFIELD && pl->fields[i] != LAST_PROCESSFIELD; i++) { - select[i] = pl->fields[i]; - original[i] = pl->fields[i]; - countSelect++; - } - countOriginal = countSelect; - select[countSelect] = LAST_PROCESSFIELD; - original[i] = pl->fields[i]; - for(i = 0; i < LAST_PROCESSFIELD; i++) { - bool found = false; - for(int j = 0; j < LAST_PROCESSFIELD && pl->fields[j] != LAST_PROCESSFIELD; j++) - if(i == pl->fields[j]) found = true; - if(!found) { - avail[countAvail] = i; - countAvail++; - } - } - avail[countAvail] = LAST_PROCESSFIELD; - - clear(); - mvaddstr(0, 0, "Column configuration"); - attron(CRT_colors[HELP_BOLD]); - mvaddstr(4, 1, "Selected Columns"); - attroff(CRT_colors[HELP_BOLD]); - attron(CRT_colors[HELP_BOLD]); - mvaddstr(4, (COLS / 2) + 1, "Available Columns"); - attroff(CRT_colors[HELP_BOLD]); - char* functions[5] = { "Move Up", "Move Down", "Move <->", "Apply ", "Cancel" }; - char* keys[5] = { "- ", "+ ", "Enter", "w ", "Esc" }; - int events[5] = { '-', '+', 13, 'w', 27 }; - FunctionBar* fuBar = FunctionBar_new(5, functions, keys, events); - FunctionBar_draw(fuBar, NULL); - - while(configure) { - - for(i = 0; i < LAST_PROCESSFIELD; i++) - pl->fields[i] = select[i]; - - for(i = 0; i < LAST_PROCESSFIELD; i++) { - int field = select[i + startSelected]; - if(field == LAST_PROCESSFIELD) break; - if(i == (LINES - 8)) break; - mvhline(5 + i, 1, ' ', COLS / 2); - mvaddstr(5 + i, 1, Process_fieldNames[field]); - } - for (; i < LINES - 8; i++) - mvhline(5 + i, 1, ' ', COLS / 2); - - RichString str = ProcessList_printHeader(pl); - if (str.len > 0) { - int attr = CRT_colors[PANEL_HEADER_FOCUS]; - attron(attr); - RichString_applyAttr(&str, attr); - move(2, 0); - hline(' ', 512); - mvaddchstr(2, 0, str.chstr); - attroff(attr); - } - - for(i = 0; i < LAST_PROCESSFIELD; i++) { - int field = avail[i + startAvailable]; - if(field == LAST_PROCESSFIELD) break; - if(i == (LINES - 8)) break; - mvhline(5 + i, (COLS / 2) + 1, ' ', COLS / 2); - mvaddstr(5 + i, (COLS / 2) + 1, Process_fieldNames[field]); - } - for (; i < LINES - 8; i++) - mvhline(5 + i, (COLS / 2) + 1, ' ', COLS / 2); - mvchgat(5 + currRow, (currCol) ? (COLS / 2) + 1 : 1, (COLS / 2) - 2, - A_REVERSE, CRT_colors[PANEL_HIGHLIGHT_FOCUS], NULL); - - refresh(); - - int *numEntries = (currCol) ? &countAvail : &countSelect; - int *notEntries = (currCol) ? &countSelect : &countAvail; - int *start = (currCol) ? &startAvailable : &startSelected; - int pos = currRow + *start; - - int c = getch(); - - mvchgat(5 + currRow, (currCol) ? (COLS / 2) + 1 : 1, (COLS / 2) - 2, - A_NORMAL, 0, NULL); - - switch(c) { - case KEY_DOWN: - if(currRow + *start == *numEntries - 1) break; - if(currRow < LINES - 9) currRow++; - else { - if((*numEntries - *start) > (LINES - 8)) - (*start)++; - } - break; - - case KEY_NPAGE: - // TODO: quick and dirty hack. Better improve. - for (int i = 0; i < LINES - 9; i++) { - if(currRow + *start == *numEntries - 1) break; - if(currRow < LINES - 9) currRow++; - else { - if((*numEntries - *start) > (LINES - 8)) - (*start)++; - } - } - break; - - case KEY_PPAGE: - // TODO: quick and dirty hack. Better improve. - for (int i = 0; i < LINES - 9; i++) { - if(currRow > 0) currRow--; - else { - if(*start > 0) - (*start)--; - } - } - break; - - case KEY_UP: - if(currRow > 0) currRow--; - else { - if(*start > 0) - (*start)--; - } - break; - - case KEY_LEFT: - currCol = 0; - if(currRow > *notEntries - 1) currRow = *notEntries - 1; - break; - - case KEY_RIGHT: - if(countAvail == 0) break; - currCol = 1; - if(currRow > *notEntries - 1) currRow = *notEntries - 1; - break; - - case '}': - case ']': - case '+': - case '.': - case '=': { - if(currRow + *start == *numEntries - 1) break; - ProcessField *array = (currCol) ? avail : select; - ProcessField inv = array[pos]; - array[pos] = array[pos + 1]; - array[pos + 1] = inv; - if(currRow < LINES - 9) currRow++; //From Key Down - else { - if((*numEntries - *start) > (LINES - 8)) - (*start)++; - } - break; - } - - case '{': - case '[': - case '_': - case ',': - case '-': { - if(currRow + *start == 0) break; - ProcessField *array = (currCol) ? avail : select; - ProcessField inv = array[pos]; - array[pos] = array[pos - 1]; - array[pos - 1] = inv; - if(currRow > 0) currRow--; //From Key up - else { - if(*start > 0) - (*start)--; - } - break; - } - - case 0x0a: - case 0x0d: - case KEY_ENTER: - if(*numEntries == 0) break; - if(!currCol && *numEntries == 1) break; - ProcessField *array = (currCol) ? avail : select; - ProcessField *notarray = (currCol) ? select : avail; - for(i = *notEntries + 2; i >=1; i--) { - notarray[i] = notarray[i-1]; - } - notarray[0] = array[pos]; - (*notEntries)++; - - for(i = pos; pos < LAST_PROCESSFIELD; i++) { - if(array[i] == LAST_PROCESSFIELD) break; - array[i] = array[i + 1]; - } - (*numEntries)--; - array[*numEntries] = LAST_PROCESSFIELD; - if(*start > 0) (*start)--; - else - if(pos > *numEntries - 1) currRow--; - - currCol = currCol == 0 ? 1 : 0; - currRow = 0; - - if(*numEntries == 0) { - currCol = 0; - currRow = 0; - } - break; - - case 27: - case 'q': - configure = false; - break; - - case 'w': - save = true; - configure = false; - break; +static void Setup_run(Settings* settings, int headerHeight) { + ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true); + CategoriesListBox* lbCategories = CategoriesListBox_new(settings, scr); + ScreenManager_add(scr, (ListBox*) lbCategories, NULL, 16); + CategoriesListBox_makeMetersPage(lbCategories); + ListBox* lbFocus; + int ch; + ScreenManager_run(scr, &lbFocus, &ch); + ScreenManager_delete(scr); +} - default: - break; +static bool changePriority(ListBox* lb, int delta) { + bool anyTagged = false; + for (int i = 0; i < ListBox_getSize(lb); i++) { + Process* p = (Process*) ListBox_get(lb, i); + if (p->tag) { + Process_setPriority(p, p->nice + delta); + anyTagged = true; } } - - if(save) { - for(i = 0; i < LAST_PROCESSFIELD && select[i] != LAST_PROCESSFIELD; i++) - pl->fields[i] = select[i]; - pl->fields[countSelect] = LAST_PROCESSFIELD; + if (!anyTagged) { + Process* p = (Process*) ListBox_getSelected(lb); + Process_setPriority(p, p->nice + delta); } - else { - for(i = 0; i < LAST_PROCESSFIELD && original[i] != LAST_PROCESSFIELD; i++) - pl->fields[i] = original[i]; - pl->fields[countOriginal] = LAST_PROCESSFIELD; - } - FunctionBar_delete(fuBar); - - clear(); + return anyTagged; +} +static HandlerResult pickWithEnter(ListBox* lb, int ch) { + if (ch == 13) + return BREAK_LOOP; + return IGNORED; } -void Setup_run(Settings* settings, int headerHeight) { - ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, true); - CategoriesListBox* lbCategories = CategoriesListBox_new(settings, scr); - ScreenManager_add(scr, (ListBox*) lbCategories, 16); - CategoriesListBox_makeMetersPage(lbCategories); +static Object* pickFromList(ListBox* lb, ListBox* list, int x, int y, char** keyLabels, FunctionBar* prevBar) { + char* fuKeys[2] = {"Enter", "Esc"}; + int fuEvents[2] = {13, 27}; + if (!lb->eventHandler) + ListBox_setEventHandler(list, pickWithEnter); + ScreenManager* scr = ScreenManager_new(0, y, 0, -1, HORIZONTAL, false); + ScreenManager_add(scr, list, FunctionBar_new(2, keyLabels, fuKeys, fuEvents), x - 1); + ScreenManager_add(scr, lb, NULL, -1); ListBox* lbFocus; int ch; ScreenManager_run(scr, &lbFocus, &ch); ScreenManager_delete(scr); + ListBox_move(lb, 0, y); + ListBox_resize(lb, COLS, LINES-y-1); + FunctionBar_draw(prevBar, NULL); + if (lbFocus == list && ch == 13) { + return ListBox_getSelected(list); + } + return NULL; +} + +void addUserToList(int key, void* userCast, void* lbCast) { + char* user = (char*) userCast; + ListBox* lb = (ListBox*) lbCast; + ListBox_add(lb, (Object*) ListItem_new(user, key)); +} + +void setUserOnly(const char* userName, bool* userOnly, uid_t* userId) { + struct passwd* user = getpwnam(userName); + if (user) { + *userOnly = true; + *userId = user->pw_uid; + } } int main(int argc, char** argv) { int delay = -1; + bool userOnly = false; + uid_t userId = 0; if (argc > 0) { if (String_eq(argv[1], "--help")) { @@ -383,6 +208,9 @@ int main(int argc, char** argv) { sscanf(argv[2], "%d", &delay); if (delay < 1) delay = 1; if (delay > 100) delay = 100; + } else if (String_eq(argv[1], "-u")) { + if (argc < 2) printHelpFlag(); + setUserOnly(argv[2], &userOnly, &userId); } } @@ -416,7 +244,7 @@ int main(int argc, char** argv) { CRT_init(settings->delay, settings->colorScheme); lb = ListBox_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false); - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); char* searchFunctions[3] = {"Next ", "Exit ", " Search: "}; char* searchKeys[3] = {"F3", "Esc", " "}; @@ -436,16 +264,17 @@ int main(int argc, char** argv) { bool follow = false; struct timeval tv; - double time = 0.0; + double newTime = 0.0; double oldTime = 0.0; bool recalculate; + while (!quit) { gettimeofday(&tv, NULL); - time = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000); - recalculate = (time - oldTime > CRT_delay); + newTime = ((double)tv.tv_sec * 10) + ((double)tv.tv_usec / 100000); + recalculate = (newTime - oldTime > CRT_delay); if (recalculate) - oldTime = time; + oldTime = newTime; if (doRefresh) { incSearchIndex = 0; incSearchBuffer[0] = 0; @@ -462,12 +291,16 @@ int main(int argc, char** argv) { } ListBox_prune(lb); int size = ProcessList_size(pl); + int lbi = 0; for (int i = 0; i < size; i++) { Process* p = ProcessList_get(pl, i); - ListBox_set(lb, i, (Object*)p); - if ((!follow && i == currPos) || (follow && p->pid == currPid)) { - ListBox_setSelected(lb, i); - lb->scrollV = currScrollV; + if (!userOnly || (p->st_uid == userId)) { + ListBox_set(lb, lbi, (Object*)p); + if ((!follow && lbi == currPos) || (follow && p->pid == currPid)) { + ListBox_setSelected(lb, lbi); + lb->scrollV = currScrollV; + } + lbi++; } } } @@ -575,7 +408,8 @@ int main(int argc, char** argv) { refreshTimeout = 0; pl->sortKey = PERCENT_MEM; pl->treeView = false; - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + settings->changed = true; + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); break; } case 'T': @@ -583,7 +417,17 @@ int main(int argc, char** argv) { refreshTimeout = 0; pl->sortKey = TIME; pl->treeView = false; - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + settings->changed = true; + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); + break; + } + case 'U': + { + for (int i = 0; i < ListBox_getSize(lb); i++) { + Process* p = (Process*) ListBox_get(lb, i); + p->tag = false; + } + doRefresh = true; break; } case 'P': @@ -591,7 +435,8 @@ int main(int argc, char** argv) { refreshTimeout = 0; pl->sortKey = PERCENT_CPU; pl->treeView = false; - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + settings->changed = true; + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); break; } case KEY_F(1): @@ -602,7 +447,6 @@ int main(int argc, char** argv) { refreshTimeout = 0; break; } - case '\012': // Enter case '\014': // Ctrl+L { clear(); @@ -617,12 +461,24 @@ int main(int argc, char** argv) { ListBox_onKey(lb, KEY_DOWN); break; } + case 's': + { + TraceScreen* ts = TraceScreen_new((Process*) ListBox_getSelected(lb)); + TraceScreen_run(ts); + TraceScreen_delete(ts); + clear(); + FunctionBar_draw(defaultBar, NULL); + refreshTimeout = 0; + CRT_enableDelay(); + break; + } case 'S': + case 'C': case KEY_F(2): { Setup_run(settings, headerHeight); // TODO: shouldn't need this, colors should be dynamic - ListBox_setHeader(lb, ProcessList_printHeader(pl)); + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); headerHeight = Header_calculateHeight(header); ListBox_move(lb, 0, headerHeight); ListBox_resize(lb, COLS, LINES-headerHeight-1); @@ -635,33 +491,39 @@ int main(int argc, char** argv) { follow = true; continue; } + case 'u': + { + ListBox* lbu = ListBox_new(0, 0, 0, 0, LISTITEM_CLASS, true); + ListBox_setHeader(lbu, "Show processes of:"); + UsersTable_foreach(ut, addUserToList, lbu); + TypedVector_sort(lbu->items); + ListItem* allUsers = ListItem_new("All users", -1); + ListBox_insert(lbu, 0, (Object*) allUsers); + char* fuFunctions[2] = {"Show ", "Cancel "}; + ListItem* picked = (ListItem*) pickFromList(lb, lbu, 20, headerHeight, fuFunctions, defaultBar); + if (picked) { + if (picked == allUsers) { + userOnly = false; + break; + } else { + setUserOnly(ListItem_getRef(picked), &userOnly, &userId); + } + } + break; + } case KEY_F(9): case 'k': { - const int lbkWidth = 15; if (!lbk) { - lbk = (ListBox*) SignalsListBox_new(0, headerHeight, lbkWidth-1, LINES - headerHeight - 2); + lbk = (ListBox*) SignalsListBox_new(0, 0, 0, 0); } SignalsListBox_reset((SignalsListBox*) lbk); - char* fuFunctions[2] = {"Send ", "Cancel "}; - char* fuKeys[2] = {"Enter", "Esc"}; - int fuEvents[2] = {13, 27}; - FunctionBar* fuBar = FunctionBar_new(2, fuFunctions, fuKeys, fuEvents); - - ScreenManager* scr = ScreenManager_new(0, headerHeight, 0, -1, HORIZONTAL, false); - ScreenManager_add(scr, lbk, lbkWidth - 1); - ScreenManager_add(scr, lb, -1); - ScreenManager_setFunctionBar(scr, fuBar); - ListBox* lbFocus; - int ch; - ScreenManager_run(scr, &lbFocus, &ch); - - if (lbFocus == lbk && ch == 13) { - Signal* signal = (Signal*) ListBox_getSelected(lbk); + Signal* signal = (Signal*) pickFromList(lb, lbk, 15, headerHeight, fuFunctions, defaultBar); + if (signal) { if (signal->number != 0) { - ListBox_setHeader(lbk, RichString_quickString(CRT_colors[PANEL_HEADER_FOCUS], "Sending...")); - ListBox_draw(lbk, true); + ListBox_setHeader(lb, "Sending..."); + ListBox_draw(lb, true); refresh(); bool anyTagged = false; for (int i = 0; i < ListBox_getSize(lb); i++) { @@ -679,14 +541,8 @@ int main(int argc, char** argv) { napms(500); } } - - FunctionBar_delete(fuBar); - ScreenManager_delete(scr); - - ListBox_move(lb, 0, headerHeight); - ListBox_resize(lb, COLS, LINES-headerHeight-1); - FunctionBar_draw(defaultBar, NULL); - + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); + refreshTimeout = 0; break; } case KEY_F(10): @@ -696,27 +552,37 @@ int main(int argc, char** argv) { case '<': case ',': case KEY_F(18): - { - refreshTimeout = 0; - pl->treeView = false; - ProcessList_sortKey(pl, -1); - ListBox_setHeader(lb, ProcessList_printHeader(pl)); - break; - } case '>': case '.': case KEY_F(6): { + ListBox* lbf = ListBox_new(0,0,0,0,LISTITEM_CLASS,true); + ListBox_setHeader(lbf, "Sort by"); + char* fuFunctions[2] = {"Sort ", "Cancel "}; + ProcessField* fields = pl->fields; + for (int i = 0; fields[i]; i++) { + char* name = String_trim(Process_printField(fields[i])); + ListBox_add(lbf, (Object*) ListItem_new(name, fields[i])); + if (fields[i] == pl->sortKey) + ListBox_setSelected(lbf, i); + free(name); + } + ListItem* field = (ListItem*) pickFromList(lb, lbf, 15, headerHeight, fuFunctions, defaultBar); + if (field) { + pl->treeView = false; + settings->changed = true; + pl->sortKey = field->key; + } + ((Object*)lbf)->delete((Object*)lbf); + ListBox_setRichHeader(lb, ProcessList_printHeader(pl)); refreshTimeout = 0; - pl->treeView = false; - ProcessList_sortKey(pl, 1); - ListBox_setHeader(lb, ProcessList_printHeader(pl)); break; } case 'I': case KEY_F(4): { refreshTimeout = 0; + settings->changed = true; ProcessList_invertSortOrder(pl); break; } @@ -725,18 +591,14 @@ int main(int argc, char** argv) { case '=': case '+': { - Process* p = (Process*) ListBox_getSelected(lb);; - Process_setPriority(p, p->nice + 1); - doRefresh = false; + doRefresh = changePriority(lb, 1); break; } case KEY_F(7): case ']': case '-': { - Process* p = (Process*) ListBox_getSelected(lb);; - Process_setPriority(p, p->nice - 1); - doRefresh = false; + doRefresh = changePriority(lb, -1); break; } case KEY_F(3): @@ -744,28 +606,21 @@ int main(int argc, char** argv) { FunctionBar_draw(searchBar, incSearchBuffer); incSearchMode = true; break; - case 'C': - showColumnConfig(pl); - FunctionBar_draw(defaultBar, NULL); - ListBox_setHeader(lb, ProcessList_printHeader(pl)); - refreshTimeout = 0; - break; case 't': case KEY_F(5): refreshTimeout = 0; pl->treeView = !pl->treeView; + settings->changed = true; break; case 'H': refreshTimeout = 0; pl->hideThreads = !pl->hideThreads; - break; - case 'U': - refreshTimeout = 0; - pl->shadowOtherUsers = !pl->shadowOtherUsers; + settings->changed = true; break; case 'K': refreshTimeout = 0; pl->hideKernelThreads = !pl->hideKernelThreads; + settings->changed = true; break; default: doRefresh = false; @@ -781,11 +636,12 @@ int main(int argc, char** argv) { refresh(); CRT_done(); - Settings_write(settings); + if (settings->changed) + Settings_write(settings); Header_delete(header); ProcessList_delete(pl); - FunctionBar_delete(searchBar); - FunctionBar_delete(defaultBar); + FunctionBar_delete((Object*)searchBar); + FunctionBar_delete((Object*)defaultBar); ((Object*)lb)->delete((Object*)lb); if (lbk) ((Object*)lbk)->delete((Object*)lbk); -- cgit v1.2.3