mirror of https://github.com/xzeldon/htop.git
Merge branch 'header_fmt' of cgzones/htop
This commit is contained in:
commit
ec2307688e
8
Action.c
8
Action.c
|
@ -84,12 +84,8 @@ Object* Action_pickFromVector(State* st, Panel* list, int x, bool followProcess)
|
||||||
|
|
||||||
static void Action_runSetup(State* st) {
|
static void Action_runSetup(State* st) {
|
||||||
ScreenManager* scr = ScreenManager_new(st->header, st->settings, st, true);
|
ScreenManager* scr = ScreenManager_new(st->header, st->settings, st, true);
|
||||||
CategoriesPanel* panelCategories = CategoriesPanel_new(scr, st->settings, st->header, st->pl);
|
CategoriesPanel_new(scr, st->settings, st->header, st->pl);
|
||||||
ScreenManager_add(scr, (Panel*) panelCategories, 16);
|
ScreenManager_run(scr, NULL, NULL);
|
||||||
CategoriesPanel_makeMetersPage(panelCategories);
|
|
||||||
Panel* panelFocus;
|
|
||||||
int ch;
|
|
||||||
ScreenManager_run(scr, &panelFocus, &ch);
|
|
||||||
ScreenManager_delete(scr);
|
ScreenManager_delete(scr);
|
||||||
if (st->settings->changed) {
|
if (st->settings->changed) {
|
||||||
Header_writeBackToSettings(st->header);
|
Header_writeBackToSettings(st->header);
|
||||||
|
|
|
@ -30,14 +30,15 @@ static void AvailableMetersPanel_delete(Object* object) {
|
||||||
Panel* super = (Panel*) object;
|
Panel* super = (Panel*) object;
|
||||||
AvailableMetersPanel* this = (AvailableMetersPanel*) object;
|
AvailableMetersPanel* this = (AvailableMetersPanel*) object;
|
||||||
Panel_done(super);
|
Panel_done(super);
|
||||||
|
free(this->meterPanels);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void AvailableMetersPanel_addMeter(Header* header, Panel* panel, const MeterClass* type, unsigned int param, int column) {
|
static inline void AvailableMetersPanel_addMeter(Header* header, MetersPanel* panel, const MeterClass* type, unsigned int param, size_t column) {
|
||||||
const Meter* meter = Header_addMeterByClass(header, type, param, column);
|
const Meter* meter = Header_addMeterByClass(header, type, param, column);
|
||||||
Panel_add(panel, (Object*) Meter_toListItem(meter, false));
|
Panel_add((Panel*)panel, (Object*) Meter_toListItem(meter, false));
|
||||||
Panel_setSelected(panel, Panel_size(panel) - 1);
|
Panel_setSelected((Panel*)panel, Panel_size((Panel*)panel) - 1);
|
||||||
MetersPanel_setMoving((MetersPanel*)panel, true);
|
MetersPanel_setMoving(panel, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) {
|
static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) {
|
||||||
|
@ -58,7 +59,7 @@ static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) {
|
||||||
case 'l':
|
case 'l':
|
||||||
case 'L':
|
case 'L':
|
||||||
{
|
{
|
||||||
AvailableMetersPanel_addMeter(header, this->leftPanel, Platform_meterTypes[type], param, 0);
|
AvailableMetersPanel_addMeter(header, this->meterPanels[0], Platform_meterTypes[type], param, 0);
|
||||||
result = HANDLED;
|
result = HANDLED;
|
||||||
update = true;
|
update = true;
|
||||||
break;
|
break;
|
||||||
|
@ -70,7 +71,7 @@ static HandlerResult AvailableMetersPanel_eventHandler(Panel* super, int ch) {
|
||||||
case 'r':
|
case 'r':
|
||||||
case 'R':
|
case 'R':
|
||||||
{
|
{
|
||||||
AvailableMetersPanel_addMeter(header, this->rightPanel, Platform_meterTypes[type], param, 1);
|
AvailableMetersPanel_addMeter(header, this->meterPanels[this->columns - 1], Platform_meterTypes[type], param, this->columns - 1);
|
||||||
result = (KEY_LEFT << 16) | SYNTH_KEY;
|
result = (KEY_LEFT << 16) | SYNTH_KEY;
|
||||||
update = true;
|
update = true;
|
||||||
break;
|
break;
|
||||||
|
@ -138,7 +139,7 @@ static void AvailableMetersPanel_addPlatformMeter(Panel* super, const MeterClass
|
||||||
Panel_add(super, (Object*) ListItem_new(label, offset << 16));
|
Panel_add(super, (Object*) ListItem_new(label, offset << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* header, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr, const ProcessList* pl) {
|
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* header, size_t columns, MetersPanel** meterPanels, ScreenManager* scr, const ProcessList* pl) {
|
||||||
AvailableMetersPanel* this = AllocThis(AvailableMetersPanel);
|
AvailableMetersPanel* this = AllocThis(AvailableMetersPanel);
|
||||||
Panel* super = (Panel*) this;
|
Panel* super = (Panel*) this;
|
||||||
FunctionBar* fuBar = FunctionBar_newEnterEsc("Add ", "Done ");
|
FunctionBar* fuBar = FunctionBar_newEnterEsc("Add ", "Done ");
|
||||||
|
@ -146,8 +147,8 @@ AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* heade
|
||||||
|
|
||||||
this->settings = settings;
|
this->settings = settings;
|
||||||
this->header = header;
|
this->header = header;
|
||||||
this->leftPanel = leftMeters;
|
this->columns = columns;
|
||||||
this->rightPanel = rightMeters;
|
this->meterPanels = meterPanels;
|
||||||
this->scr = scr;
|
this->scr = scr;
|
||||||
|
|
||||||
Panel_setHeader(super, "Available meters");
|
Panel_setHeader(super, "Available meters");
|
||||||
|
|
|
@ -8,6 +8,7 @@ in the source distribution for its full text.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Header.h"
|
#include "Header.h"
|
||||||
|
#include "MetersPanel.h"
|
||||||
#include "Panel.h"
|
#include "Panel.h"
|
||||||
#include "ProcessList.h"
|
#include "ProcessList.h"
|
||||||
#include "ScreenManager.h"
|
#include "ScreenManager.h"
|
||||||
|
@ -20,12 +21,12 @@ typedef struct AvailableMetersPanel_ {
|
||||||
|
|
||||||
Settings* settings;
|
Settings* settings;
|
||||||
Header* header;
|
Header* header;
|
||||||
Panel* leftPanel;
|
size_t columns;
|
||||||
Panel* rightPanel;
|
MetersPanel** meterPanels;
|
||||||
} AvailableMetersPanel;
|
} AvailableMetersPanel;
|
||||||
|
|
||||||
extern const PanelClass AvailableMetersPanel_class;
|
extern const PanelClass AvailableMetersPanel_class;
|
||||||
|
|
||||||
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* header, Panel* leftMeters, Panel* rightMeters, ScreenManager* scr, const ProcessList* pl);
|
AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Header* header, size_t columns, MetersPanel **meterPanels, ScreenManager* scr, const ProcessList* pl);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -17,6 +17,8 @@ in the source distribution for its full text.
|
||||||
#include "ColumnsPanel.h"
|
#include "ColumnsPanel.h"
|
||||||
#include "DisplayOptionsPanel.h"
|
#include "DisplayOptionsPanel.h"
|
||||||
#include "FunctionBar.h"
|
#include "FunctionBar.h"
|
||||||
|
#include "Header.h"
|
||||||
|
#include "HeaderOptionsPanel.h"
|
||||||
#include "ListItem.h"
|
#include "ListItem.h"
|
||||||
#include "MetersPanel.h"
|
#include "MetersPanel.h"
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
@ -33,14 +35,24 @@ static void CategoriesPanel_delete(Object* object) {
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CategoriesPanel_makeMetersPage(CategoriesPanel* this) {
|
static void CategoriesPanel_makeMetersPage(CategoriesPanel* this) {
|
||||||
MetersPanel* leftMeters = MetersPanel_new(this->settings, "Left column", this->header->columns[0], this->scr);
|
size_t columns = HeaderLayout_getColumns(this->scr->header->headerLayout);
|
||||||
MetersPanel* rightMeters = MetersPanel_new(this->settings, "Right column", this->header->columns[1], this->scr);
|
MetersPanel** meterPanels = xMallocArray(columns, sizeof(MetersPanel));
|
||||||
leftMeters->rightNeighbor = rightMeters;
|
|
||||||
rightMeters->leftNeighbor = leftMeters;
|
for (size_t i = 0; i < columns; i++) {
|
||||||
Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->settings, this->header, (Panel*) leftMeters, (Panel*) rightMeters, this->scr, this->pl);
|
char titleBuffer[32];
|
||||||
ScreenManager_add(this->scr, (Panel*) leftMeters, 20);
|
xSnprintf(titleBuffer, sizeof(titleBuffer), "Column %zu", i + 1);
|
||||||
ScreenManager_add(this->scr, (Panel*) rightMeters, 20);
|
meterPanels[i] = MetersPanel_new(this->settings, titleBuffer, this->header->columns[i], this->scr);
|
||||||
|
|
||||||
|
if (i != 0) {
|
||||||
|
meterPanels[i]->leftNeighbor = meterPanels[i - 1];
|
||||||
|
meterPanels[i - 1]->rightNeighbor = meterPanels[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ScreenManager_add(this->scr, (Panel*) meterPanels[i], 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
Panel* availableMeters = (Panel*) AvailableMetersPanel_new(this->settings, this->header, columns, meterPanels, this->scr, this->pl);
|
||||||
ScreenManager_add(this->scr, availableMeters, -1);
|
ScreenManager_add(this->scr, availableMeters, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +73,25 @@ static void CategoriesPanel_makeColumnsPage(CategoriesPanel* this) {
|
||||||
ScreenManager_add(this->scr, availableColumns, -1);
|
ScreenManager_add(this->scr, availableColumns, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CategoriesPanel_makeHeaderOptionsPage(CategoriesPanel* this) {
|
||||||
|
Panel* colors = (Panel*) HeaderOptionsPanel_new(this->settings, this->scr);
|
||||||
|
ScreenManager_add(this->scr, colors, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (* CategoriesPanel_makePageFunc)(CategoriesPanel* ref);
|
||||||
|
typedef struct CategoriesPanelPage_ {
|
||||||
|
const char* name;
|
||||||
|
CategoriesPanel_makePageFunc ctor;
|
||||||
|
} CategoriesPanelPage;
|
||||||
|
|
||||||
|
static const CategoriesPanelPage categoriesPanelPages[] = {
|
||||||
|
{ .name = "Display options", .ctor = CategoriesPanel_makeDisplayOptionsPage },
|
||||||
|
{ .name = "Header layout", .ctor = CategoriesPanel_makeHeaderOptionsPage },
|
||||||
|
{ .name = "Meters", .ctor = CategoriesPanel_makeMetersPage },
|
||||||
|
{ .name = "Columns", .ctor = CategoriesPanel_makeColumnsPage },
|
||||||
|
{ .name = "Colors", .ctor = CategoriesPanel_makeColorsPage },
|
||||||
|
};
|
||||||
|
|
||||||
static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
|
static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
|
||||||
CategoriesPanel* this = (CategoriesPanel*) super;
|
CategoriesPanel* this = (CategoriesPanel*) super;
|
||||||
|
|
||||||
|
@ -98,19 +129,8 @@ static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
|
||||||
for (int i = 1; i < size; i++)
|
for (int i = 1; i < size; i++)
|
||||||
ScreenManager_remove(this->scr, 1);
|
ScreenManager_remove(this->scr, 1);
|
||||||
|
|
||||||
switch (selected) {
|
if (selected >= 0 && (size_t)selected < ARRAYSIZE(categoriesPanelPages)) {
|
||||||
case 0:
|
categoriesPanelPages[selected].ctor(this);
|
||||||
CategoriesPanel_makeMetersPage(this);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
CategoriesPanel_makeDisplayOptionsPage(this);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
CategoriesPanel_makeColorsPage(this);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
CategoriesPanel_makeColumnsPage(this);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -135,9 +155,10 @@ CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Settings* settings, Hea
|
||||||
this->header = header;
|
this->header = header;
|
||||||
this->pl = pl;
|
this->pl = pl;
|
||||||
Panel_setHeader(super, "Setup");
|
Panel_setHeader(super, "Setup");
|
||||||
Panel_add(super, (Object*) ListItem_new("Meters", 0));
|
for (size_t i = 0; i < ARRAYSIZE(categoriesPanelPages); i++)
|
||||||
Panel_add(super, (Object*) ListItem_new("Display options", 0));
|
Panel_add(super, (Object*) ListItem_new(categoriesPanelPages[i].name, 0));
|
||||||
Panel_add(super, (Object*) ListItem_new("Colors", 0));
|
|
||||||
Panel_add(super, (Object*) ListItem_new("Columns", 0));
|
ScreenManager_add(scr, super, 16);
|
||||||
|
categoriesPanelPages[0].ctor(this);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,6 @@ typedef struct CategoriesPanel_ {
|
||||||
ProcessList* pl;
|
ProcessList* pl;
|
||||||
} CategoriesPanel;
|
} CategoriesPanel;
|
||||||
|
|
||||||
void CategoriesPanel_makeMetersPage(CategoriesPanel* this);
|
|
||||||
|
|
||||||
extern const PanelClass CategoriesPanel_class;
|
extern const PanelClass CategoriesPanel_class;
|
||||||
|
|
||||||
CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Settings* settings, Header* header, ProcessList* pl);
|
CategoriesPanel* CategoriesPanel_new(ScreenManager* scr, Settings* settings, Header* header, ProcessList* pl);
|
||||||
|
|
197
Header.c
197
Header.c
|
@ -7,6 +7,7 @@ in the source distribution for its full text.
|
||||||
|
|
||||||
#include "Header.h"
|
#include "Header.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -22,15 +23,17 @@ in the source distribution for its full text.
|
||||||
#include "XUtils.h"
|
#include "XUtils.h"
|
||||||
|
|
||||||
|
|
||||||
Header* Header_new(ProcessList* pl, Settings* settings, int nrColumns) {
|
Header* Header_new(ProcessList* pl, Settings* settings, HeaderLayout hLayout) {
|
||||||
Header* this = xCalloc(1, sizeof(Header));
|
Header* this = xCalloc(1, sizeof(Header));
|
||||||
this->columns = xCalloc(nrColumns, sizeof(Vector*));
|
this->columns = xMallocArray(HeaderLayout_getColumns(hLayout), sizeof(Vector*));
|
||||||
this->settings = settings;
|
this->settings = settings;
|
||||||
this->pl = pl;
|
this->pl = pl;
|
||||||
this->nrColumns = nrColumns;
|
this->headerLayout = hLayout;
|
||||||
|
|
||||||
Header_forEachColumn(this, i) {
|
Header_forEachColumn(this, i) {
|
||||||
this->columns[i] = Vector_new(Class(Meter), true, DEFAULT_SIZE);
|
this->columns[i] = Vector_new(Class(Meter), true, DEFAULT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,37 +41,109 @@ void Header_delete(Header* this) {
|
||||||
Header_forEachColumn(this, i) {
|
Header_forEachColumn(this, i) {
|
||||||
Vector_delete(this->columns[i]);
|
Vector_delete(this->columns[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(this->columns);
|
free(this->columns);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Header_setLayout(Header* this, HeaderLayout hLayout) {
|
||||||
|
size_t oldColumns = HeaderLayout_getColumns(this->headerLayout);
|
||||||
|
size_t newColumns = HeaderLayout_getColumns(hLayout);
|
||||||
|
|
||||||
|
this->headerLayout = hLayout;
|
||||||
|
|
||||||
|
if (newColumns == oldColumns)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (newColumns > oldColumns) {
|
||||||
|
this->columns = xReallocArray(this->columns, newColumns, sizeof(Vector*));
|
||||||
|
for (size_t i = oldColumns; i < newColumns; i++)
|
||||||
|
this->columns[i] = Vector_new(Class(Meter), true, DEFAULT_SIZE);
|
||||||
|
} else {
|
||||||
|
// move meters from to-be-deleted columns into last one
|
||||||
|
for (size_t i = newColumns; i < oldColumns; i++) {
|
||||||
|
for (int j = this->columns[i]->items - 1; j >= 0; j--) {
|
||||||
|
Vector_add(this->columns[newColumns - 1], Vector_take(this->columns[i], j));
|
||||||
|
}
|
||||||
|
Vector_delete(this->columns[i]);
|
||||||
|
}
|
||||||
|
this->columns = xReallocArray(this->columns, newColumns, sizeof(Vector*));
|
||||||
|
}
|
||||||
|
|
||||||
|
Header_calculateHeight(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Header_addMeterByName(Header* this, const char* name, MeterModeId mode, unsigned int column) {
|
||||||
|
assert(column < HeaderLayout_getColumns(this->headerLayout));
|
||||||
|
|
||||||
|
Vector* meters = this->columns[column];
|
||||||
|
|
||||||
|
const char* paren = strchr(name, '(');
|
||||||
|
unsigned int param = 0;
|
||||||
|
size_t nameLen;
|
||||||
|
if (paren) {
|
||||||
|
int ok = sscanf(paren, "(%10u)", ¶m); // CPUMeter
|
||||||
|
if (!ok) {
|
||||||
|
char* end, dynamic[32] = {0};
|
||||||
|
if (sscanf(paren, "(%30s)", dynamic)) { // DynamicMeter
|
||||||
|
if ((end = strrchr(dynamic, ')')) == NULL)
|
||||||
|
return; // htoprc parse failure
|
||||||
|
*end = '\0';
|
||||||
|
if (!DynamicMeter_search(this->pl->dynamicMeters, dynamic, ¶m))
|
||||||
|
return; // name lookup failure
|
||||||
|
} else {
|
||||||
|
param = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nameLen = paren - name;
|
||||||
|
} else {
|
||||||
|
nameLen = strlen(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const MeterClass* const* type = Platform_meterTypes; *type; type++) {
|
||||||
|
if (0 == strncmp(name, (*type)->name, nameLen) && (*type)->name[nameLen] == '\0') {
|
||||||
|
Meter* meter = Meter_new(this->pl, param, *type);
|
||||||
|
if (mode != 0) {
|
||||||
|
Meter_setMode(meter, mode);
|
||||||
|
}
|
||||||
|
Vector_add(meters, meter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Header_populateFromSettings(Header* this) {
|
void Header_populateFromSettings(Header* this) {
|
||||||
|
Header_setLayout(this, this->settings->hLayout);
|
||||||
|
|
||||||
Header_forEachColumn(this, col) {
|
Header_forEachColumn(this, col) {
|
||||||
const MeterColumnSettings* colSettings = &this->settings->columns[col];
|
const MeterColumnSetting* colSettings = &this->settings->hColumns[col];
|
||||||
for (int i = 0; i < colSettings->len; i++) {
|
Vector_prune(this->columns[col]);
|
||||||
if (!Header_addMeterByName(this, colSettings->names[i], col)) {
|
for (size_t i = 0; i < colSettings->len; i++) {
|
||||||
continue;
|
Header_addMeterByName(this, colSettings->names[i], colSettings->modes[i], col);
|
||||||
}
|
|
||||||
if (colSettings->modes[i] != 0) {
|
|
||||||
Header_setMode(this, i, colSettings->modes[i], col);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Header_calculateHeight(this);
|
Header_calculateHeight(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Header_writeBackToSettings(const Header* this) {
|
void Header_writeBackToSettings(const Header* this) {
|
||||||
Header_forEachColumn(this, col) {
|
Settings_setHeaderLayout(this->settings, this->headerLayout);
|
||||||
MeterColumnSettings* colSettings = &this->settings->columns[col];
|
|
||||||
|
|
||||||
String_freeArray(colSettings->names);
|
Header_forEachColumn(this, col) {
|
||||||
|
MeterColumnSetting* colSettings = &this->settings->hColumns[col];
|
||||||
|
|
||||||
|
if (colSettings->names) {
|
||||||
|
for (size_t j = 0; j < colSettings->len; j++)
|
||||||
|
free(colSettings->names[j]);
|
||||||
|
free(colSettings->names);
|
||||||
|
}
|
||||||
free(colSettings->modes);
|
free(colSettings->modes);
|
||||||
|
|
||||||
const Vector* vec = this->columns[col];
|
const Vector* vec = this->columns[col];
|
||||||
int len = Vector_size(vec);
|
int len = Vector_size(vec);
|
||||||
|
|
||||||
colSettings->names = xCalloc(len + 1, sizeof(char*));
|
colSettings->names = len ? xCalloc(len, sizeof(char*)) : NULL;
|
||||||
colSettings->modes = xCalloc(len, sizeof(int));
|
colSettings->modes = len ? xCalloc(len, sizeof(int)) : NULL;
|
||||||
colSettings->len = len;
|
colSettings->len = len;
|
||||||
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
|
@ -88,50 +163,9 @@ void Header_writeBackToSettings(const Header* this) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Header_addMeterByName(Header* this, const char* name, int column) {
|
Meter* Header_addMeterByClass(Header* this, const MeterClass* type, unsigned int param, unsigned int column) {
|
||||||
Vector* meters = this->columns[column];
|
assert(column < HeaderLayout_getColumns(this->headerLayout));
|
||||||
|
|
||||||
char* paren = strchr(name, '(');
|
|
||||||
unsigned int param = 0;
|
|
||||||
if (paren) {
|
|
||||||
char* end, dynamic[32] = {0};
|
|
||||||
int ok = sscanf(paren, "(%10u)", ¶m); // CPUMeter
|
|
||||||
if (!ok) {
|
|
||||||
if (sscanf(paren, "(%30s)", dynamic)) { // DynamicMeter
|
|
||||||
if ((end = strrchr(dynamic, ')')) == NULL)
|
|
||||||
return false; // indicate htoprc parse failure
|
|
||||||
*end = '\0';
|
|
||||||
if (!DynamicMeter_search(this->pl->dynamicMeters, dynamic, ¶m))
|
|
||||||
return false; // indicates name lookup failure
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*paren = '\0';
|
|
||||||
}
|
|
||||||
for (const MeterClass* const* type = Platform_meterTypes; *type; type++) {
|
|
||||||
if (String_eq(name, (*type)->name)) {
|
|
||||||
Meter* meter = Meter_new(this->pl, param, *type);
|
|
||||||
Vector_add(meters, meter);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (paren)
|
|
||||||
*paren = '(';
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Header_setMode(Header* this, int i, MeterModeId mode, int column) {
|
|
||||||
Vector* meters = this->columns[column];
|
|
||||||
|
|
||||||
if (i >= Vector_size(meters))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Meter* meter = (Meter*) Vector_get(meters, i);
|
|
||||||
Meter_setMode(meter, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
Meter* Header_addMeterByClass(Header* this, const MeterClass* type, unsigned int param, int column) {
|
|
||||||
Vector* meters = this->columns[column];
|
Vector* meters = this->columns[column];
|
||||||
|
|
||||||
Meter* meter = Meter_new(this->pl, param, type);
|
Meter* meter = Meter_new(this->pl, param, type);
|
||||||
|
@ -139,18 +173,6 @@ Meter* Header_addMeterByClass(Header* this, const MeterClass* type, unsigned int
|
||||||
return meter;
|
return meter;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Header_size(const Header* this, int column) {
|
|
||||||
const Vector* meters = this->columns[column];
|
|
||||||
return Vector_size(meters);
|
|
||||||
}
|
|
||||||
|
|
||||||
MeterModeId Header_readMeterMode(const Header* this, int i, int column) {
|
|
||||||
const Vector* meters = this->columns[column];
|
|
||||||
|
|
||||||
const Meter* meter = (const Meter*) Vector_get(meters, i);
|
|
||||||
return meter->mode;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Header_reinit(Header* this) {
|
void Header_reinit(Header* this) {
|
||||||
Header_forEachColumn(this, col) {
|
Header_forEachColumn(this, col) {
|
||||||
for (int i = 0; i < Vector_size(this->columns[col]); i++) {
|
for (int i = 0; i < Vector_size(this->columns[col]); i++) {
|
||||||
|
@ -169,25 +191,36 @@ void Header_draw(const Header* this) {
|
||||||
for (int y = 0; y < height; y++) {
|
for (int y = 0; y < height; y++) {
|
||||||
mvhline(y, 0, ' ', COLS);
|
mvhline(y, 0, ' ', COLS);
|
||||||
}
|
}
|
||||||
const int width = COLS / this->nrColumns - pad;
|
const int width = COLS - pad;
|
||||||
int x = pad;
|
int x = pad;
|
||||||
|
float roundingLoss = 0.0f;
|
||||||
|
|
||||||
Header_forEachColumn(this, col) {
|
Header_forEachColumn(this, col) {
|
||||||
Vector* meters = this->columns[col];
|
Vector* meters = this->columns[col];
|
||||||
|
float colWidth = (float)width * HeaderLayout_layouts[this->headerLayout].widths[col] / 100.0f;
|
||||||
|
|
||||||
|
roundingLoss += colWidth - floorf(colWidth);
|
||||||
|
if (roundingLoss >= 1.0f) {
|
||||||
|
colWidth += 1.0f;
|
||||||
|
roundingLoss -= 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
for (int y = (pad / 2), i = 0; i < Vector_size(meters); i++) {
|
for (int y = (pad / 2), i = 0; i < Vector_size(meters); i++) {
|
||||||
Meter* meter = (Meter*) Vector_get(meters, i);
|
Meter* meter = (Meter*) Vector_get(meters, i);
|
||||||
|
|
||||||
int actualWidth;
|
float actualWidth = colWidth;
|
||||||
if (meter->mode == TEXT_METERMODE)
|
if (meter->mode == TEXT_METERMODE) {
|
||||||
actualWidth = meter->columnWidthCount * width + (meter->columnWidthCount - 1) * (2 * pad + 1);
|
for (int j = 1; j < meter->columnWidthCount; j++) {
|
||||||
else
|
actualWidth += (float)width * HeaderLayout_layouts[this->headerLayout].widths[col + j] / 100.0f;
|
||||||
actualWidth = width;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
assert(meter->draw);
|
assert(meter->draw);
|
||||||
meter->draw(meter, x, y, actualWidth);
|
meter->draw(meter, x, y, floorf(actualWidth));
|
||||||
y += meter->h;
|
y += meter->h;
|
||||||
}
|
}
|
||||||
x += width + pad;
|
|
||||||
|
x += floorf(colWidth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,8 +240,8 @@ void Header_updateData(Header* this) {
|
||||||
* by counting how many columns to the right are empty or contain a BlankMeter.
|
* by counting how many columns to the right are empty or contain a BlankMeter.
|
||||||
* Returns the number of columns to span, i.e. if the direct neighbor is occupied 1.
|
* Returns the number of columns to span, i.e. if the direct neighbor is occupied 1.
|
||||||
*/
|
*/
|
||||||
static int calcColumnWidthCount(const Header* this, const Meter* curMeter, const int pad, const int curColumn, const int curHeight) {
|
static int calcColumnWidthCount(const Header* this, const Meter* curMeter, const int pad, const unsigned int curColumn, const int curHeight) {
|
||||||
for (int i = curColumn + 1; i < this->nrColumns; i++) {
|
for (size_t i = curColumn + 1; i < HeaderLayout_getColumns(this->headerLayout); i++) {
|
||||||
const Vector* meters = this->columns[i];
|
const Vector* meters = this->columns[i];
|
||||||
|
|
||||||
int height = pad;
|
int height = pad;
|
||||||
|
@ -227,7 +260,7 @@ static int calcColumnWidthCount(const Header* this, const Meter* curMeter, const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this->nrColumns - curColumn;
|
return HeaderLayout_getColumns(this->headerLayout) - curColumn;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Header_calculateHeight(Header* this) {
|
int Header_calculateHeight(Header* this) {
|
||||||
|
|
18
Header.h
18
Header.h
|
@ -17,30 +17,24 @@ typedef struct Header_ {
|
||||||
Vector** columns;
|
Vector** columns;
|
||||||
Settings* settings;
|
Settings* settings;
|
||||||
ProcessList* pl;
|
ProcessList* pl;
|
||||||
int nrColumns;
|
HeaderLayout headerLayout;
|
||||||
int pad;
|
int pad;
|
||||||
int height;
|
int height;
|
||||||
} Header;
|
} Header;
|
||||||
|
|
||||||
#define Header_forEachColumn(this_, i_) for (int (i_)=0; (i_) < (this_)->nrColumns; ++(i_))
|
#define Header_forEachColumn(this_, i_) for (size_t (i_)=0; (i_) < HeaderLayout_getColumns((this_)->headerLayout); ++(i_))
|
||||||
|
|
||||||
Header* Header_new(ProcessList* pl, Settings* settings, int nrColumns);
|
Header* Header_new(ProcessList* pl, Settings* settings, HeaderLayout hLayout);
|
||||||
|
|
||||||
void Header_delete(Header* this);
|
void Header_delete(Header* this);
|
||||||
|
|
||||||
|
void Header_setLayout(Header* this, HeaderLayout hLayout);
|
||||||
|
|
||||||
void Header_populateFromSettings(Header* this);
|
void Header_populateFromSettings(Header* this);
|
||||||
|
|
||||||
void Header_writeBackToSettings(const Header* this);
|
void Header_writeBackToSettings(const Header* this);
|
||||||
|
|
||||||
bool Header_addMeterByName(Header* this, const char* name, int column);
|
Meter* Header_addMeterByClass(Header* this, const MeterClass* type, unsigned int param, unsigned int column);
|
||||||
|
|
||||||
void Header_setMode(Header* this, int i, MeterModeId mode, int column);
|
|
||||||
|
|
||||||
Meter* Header_addMeterByClass(Header* this, const MeterClass* type, unsigned int param, int column);
|
|
||||||
|
|
||||||
int Header_size(const Header* this, int column);
|
|
||||||
|
|
||||||
MeterModeId Header_readMeterMode(const Header* this, int i, int column);
|
|
||||||
|
|
||||||
void Header_reinit(Header* this);
|
void Header_reinit(Header* this);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef HEADER_HeaderLayout
|
||||||
|
#define HEADER_HeaderLayout
|
||||||
|
/*
|
||||||
|
htop - HeaderLayout.h
|
||||||
|
(C) 2021 htop dev team
|
||||||
|
Released under the GNU GPLv2, see the COPYING file
|
||||||
|
in the source distribution for its full text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "Macros.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum HeaderLayout_ {
|
||||||
|
HF_TWO_50_50,
|
||||||
|
HF_TWO_33_67,
|
||||||
|
HF_TWO_67_33,
|
||||||
|
HF_THREE_33_34_33,
|
||||||
|
HF_THREE_25_25_50,
|
||||||
|
HF_THREE_25_50_25,
|
||||||
|
HF_THREE_50_25_25,
|
||||||
|
HF_THREE_40_20_40,
|
||||||
|
HF_FOUR_25_25_25_25,
|
||||||
|
LAST_HEADER_LAYOUT
|
||||||
|
} HeaderLayout;
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
uint8_t columns;
|
||||||
|
const uint8_t widths[4];
|
||||||
|
const char* description;
|
||||||
|
} HeaderLayout_layouts[LAST_HEADER_LAYOUT] = {
|
||||||
|
[HF_TWO_50_50] = { 2, { 50, 50, 0, 0 }, "2 columns - 50/50 (default)", },
|
||||||
|
[HF_TWO_33_67] = { 2, { 33, 67, 0, 0 }, "2 columns - 33/67", },
|
||||||
|
[HF_TWO_67_33] = { 2, { 67, 33, 0, 0 }, "2 columns - 67/33", },
|
||||||
|
[HF_THREE_33_34_33] = { 3, { 33, 34, 33, 0 }, "3 columns - 33/34/33", },
|
||||||
|
[HF_THREE_25_25_50] = { 3, { 25, 25, 50, 0 }, "3 columns - 25/25/50", },
|
||||||
|
[HF_THREE_25_50_25] = { 3, { 25, 50, 25, 0 }, "3 columns - 25/50/25", },
|
||||||
|
[HF_THREE_50_25_25] = { 3, { 50, 25, 25, 0 }, "3 columns - 50/25/25", },
|
||||||
|
[HF_THREE_40_20_40] = { 3, { 40, 20, 40, 0 }, "3 columns - 40/20/40", },
|
||||||
|
[HF_FOUR_25_25_25_25] = { 4, { 25, 25, 25, 25 }, "4 columns - 25/25/25/25", },
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline size_t HeaderLayout_getColumns(HeaderLayout hLayout) {
|
||||||
|
/* assert the layout is initialized */
|
||||||
|
assert(0 <= hLayout);
|
||||||
|
assert(hLayout < LAST_HEADER_LAYOUT);
|
||||||
|
assert(HeaderLayout_layouts[hLayout].description[0]);
|
||||||
|
return HeaderLayout_layouts[hLayout].columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HEADER_HeaderLayout */
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
htop - HeaderOptionsPanel.c
|
||||||
|
(C) 2021 htop dev team
|
||||||
|
Released under the GNU GPLv2, see the COPYING file
|
||||||
|
in the source distribution for its full text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "HeaderOptionsPanel.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "CRT.h"
|
||||||
|
#include "FunctionBar.h"
|
||||||
|
#include "Header.h"
|
||||||
|
#include "Object.h"
|
||||||
|
#include "OptionItem.h"
|
||||||
|
#include "ProvideCurses.h"
|
||||||
|
#include "RichString.h"
|
||||||
|
#include "Vector.h"
|
||||||
|
|
||||||
|
|
||||||
|
static const char* const HeaderOptionsFunctions[] = {" ", " ", " ", " ", " ", " ", " ", " ", " ", "Done ", NULL};
|
||||||
|
|
||||||
|
static void HeaderOptionsPanel_delete(Object* object) {
|
||||||
|
Panel* super = (Panel*) object;
|
||||||
|
HeaderOptionsPanel* this = (HeaderOptionsPanel*) object;
|
||||||
|
Panel_done(super);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HandlerResult HeaderOptionsPanel_eventHandler(Panel* super, int ch) {
|
||||||
|
HeaderOptionsPanel* this = (HeaderOptionsPanel*) super;
|
||||||
|
|
||||||
|
HandlerResult result = IGNORED;
|
||||||
|
int mark;
|
||||||
|
|
||||||
|
switch(ch) {
|
||||||
|
case 0x0a:
|
||||||
|
case 0x0d:
|
||||||
|
case KEY_ENTER:
|
||||||
|
case KEY_MOUSE:
|
||||||
|
case KEY_RECLICK:
|
||||||
|
case ' ':
|
||||||
|
mark = Panel_getSelectedIndex(super);
|
||||||
|
assert(mark >= 0);
|
||||||
|
assert(mark < LAST_HEADER_LAYOUT);
|
||||||
|
|
||||||
|
for (int i = 0; i < LAST_HEADER_LAYOUT; i++)
|
||||||
|
CheckItem_set((CheckItem*)Panel_get(super, i), false);
|
||||||
|
CheckItem_set((CheckItem*)Panel_get(super, mark), true);
|
||||||
|
|
||||||
|
Header_setLayout(this->scr->header, mark);
|
||||||
|
this->settings->changed = true;
|
||||||
|
|
||||||
|
ScreenManager_resize(this->scr);
|
||||||
|
|
||||||
|
result = HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PanelClass HeaderOptionsPanel_class = {
|
||||||
|
.super = {
|
||||||
|
.extends = Class(Panel),
|
||||||
|
.delete = HeaderOptionsPanel_delete
|
||||||
|
},
|
||||||
|
.eventHandler = HeaderOptionsPanel_eventHandler
|
||||||
|
};
|
||||||
|
|
||||||
|
HeaderOptionsPanel* HeaderOptionsPanel_new(Settings* settings, ScreenManager* scr) {
|
||||||
|
HeaderOptionsPanel* this = AllocThis(HeaderOptionsPanel);
|
||||||
|
Panel* super = (Panel*) this;
|
||||||
|
FunctionBar* fuBar = FunctionBar_new(HeaderOptionsFunctions, NULL, NULL);
|
||||||
|
Panel_init(super, 1, 1, 1, 1, Class(CheckItem), true, fuBar);
|
||||||
|
|
||||||
|
this->scr = scr;
|
||||||
|
this->settings = settings;
|
||||||
|
|
||||||
|
Panel_setHeader(super, "Header Layout");
|
||||||
|
for (int i = 0; i < LAST_HEADER_LAYOUT; i++) {
|
||||||
|
Panel_add(super, (Object*) CheckItem_newByVal(HeaderLayout_layouts[i].description, false));
|
||||||
|
}
|
||||||
|
CheckItem_set((CheckItem*)Panel_get(super, settings->hLayout), true);
|
||||||
|
return this;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef HEADER_HeaderOptionsPanel
|
||||||
|
#define HEADER_HeaderOptionsPanel
|
||||||
|
/*
|
||||||
|
htop - ColorsPanel.h
|
||||||
|
(C) 2021 htop dev team
|
||||||
|
Released under the GNU GPLv2, see the COPYING file
|
||||||
|
in the source distribution for its full text.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Panel.h"
|
||||||
|
#include "ScreenManager.h"
|
||||||
|
#include "Settings.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct HeaderOptionsPanel_ {
|
||||||
|
Panel super;
|
||||||
|
|
||||||
|
ScreenManager* scr;
|
||||||
|
Settings* settings;
|
||||||
|
} HeaderOptionsPanel;
|
||||||
|
|
||||||
|
extern const PanelClass HeaderOptionsPanel_class;
|
||||||
|
|
||||||
|
HeaderOptionsPanel* HeaderOptionsPanel_new(Settings* settings, ScreenManager* scr);
|
||||||
|
|
||||||
|
#endif /* HEADER_HeaderOptionsPanel */
|
|
@ -45,6 +45,7 @@ myhtopsources = \
|
||||||
FunctionBar.c \
|
FunctionBar.c \
|
||||||
Hashtable.c \
|
Hashtable.c \
|
||||||
Header.c \
|
Header.c \
|
||||||
|
HeaderOptionsPanel.c \
|
||||||
HostnameMeter.c \
|
HostnameMeter.c \
|
||||||
IncSet.c \
|
IncSet.c \
|
||||||
InfoScreen.c \
|
InfoScreen.c \
|
||||||
|
@ -102,6 +103,8 @@ myhtopheaders = \
|
||||||
FunctionBar.h \
|
FunctionBar.h \
|
||||||
Hashtable.h \
|
Hashtable.h \
|
||||||
Header.h \
|
Header.h \
|
||||||
|
HeaderLayout.h \
|
||||||
|
HeaderOptionsPanel.h \
|
||||||
HostnameMeter.h \
|
HostnameMeter.h \
|
||||||
IncSet.h \
|
IncSet.h \
|
||||||
InfoScreen.h \
|
InfoScreen.h \
|
||||||
|
|
|
@ -185,7 +185,6 @@ static HandlerResult MetersPanel_eventHandler(Panel* super, int ch) {
|
||||||
Header* header = this->scr->header;
|
Header* header = this->scr->header;
|
||||||
this->settings->changed = true;
|
this->settings->changed = true;
|
||||||
Header_calculateHeight(header);
|
Header_calculateHeight(header);
|
||||||
Header_draw(header);
|
|
||||||
ScreenManager_resize(this->scr);
|
ScreenManager_resize(this->scr);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
149
Settings.c
149
Settings.c
|
@ -25,21 +25,27 @@ in the source distribution for its full text.
|
||||||
void Settings_delete(Settings* this) {
|
void Settings_delete(Settings* this) {
|
||||||
free(this->filename);
|
free(this->filename);
|
||||||
free(this->fields);
|
free(this->fields);
|
||||||
for (unsigned int i = 0; i < ARRAYSIZE(this->columns); i++) {
|
for (unsigned int i = 0; i < HeaderLayout_getColumns(this->hLayout); i++) {
|
||||||
String_freeArray(this->columns[i].names);
|
if (this->hColumns[i].names) {
|
||||||
free(this->columns[i].modes);
|
for (uint8_t j = 0; j < this->hColumns[i].len; j++)
|
||||||
|
free(this->hColumns[i].names[j]);
|
||||||
|
free(this->hColumns[i].names);
|
||||||
}
|
}
|
||||||
|
free(this->hColumns[i].modes);
|
||||||
|
}
|
||||||
|
free(this->hColumns);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Settings_readMeters(Settings* this, const char* line, int column) {
|
static void Settings_readMeters(Settings* this, const char* line, unsigned int column) {
|
||||||
char* trim = String_trim(line);
|
char* trim = String_trim(line);
|
||||||
char** ids = String_split(trim, ' ', NULL);
|
char** ids = String_split(trim, ' ', NULL);
|
||||||
free(trim);
|
free(trim);
|
||||||
this->columns[column].names = ids;
|
column = MINIMUM(column, HeaderLayout_getColumns(this->hLayout) - 1);
|
||||||
|
this->hColumns[column].names = ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Settings_readMeterModes(Settings* this, const char* line, int column) {
|
static void Settings_readMeterModes(Settings* this, const char* line, unsigned int column) {
|
||||||
char* trim = String_trim(line);
|
char* trim = String_trim(line);
|
||||||
char** ids = String_split(trim, ' ', NULL);
|
char** ids = String_split(trim, ' ', NULL);
|
||||||
free(trim);
|
free(trim);
|
||||||
|
@ -47,13 +53,14 @@ static void Settings_readMeterModes(Settings* this, const char* line, int column
|
||||||
for (int i = 0; ids[i]; i++) {
|
for (int i = 0; ids[i]; i++) {
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
this->columns[column].len = len;
|
column = MINIMUM(column, HeaderLayout_getColumns(this->hLayout) - 1);
|
||||||
|
this->hColumns[column].len = len;
|
||||||
int* modes = len ? xCalloc(len, sizeof(int)) : NULL;
|
int* modes = len ? xCalloc(len, sizeof(int)) : NULL;
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
modes[i] = atoi(ids[i]);
|
modes[i] = atoi(ids[i]);
|
||||||
}
|
}
|
||||||
String_freeArray(ids);
|
String_freeArray(ids);
|
||||||
this->columns[column].modes = modes;
|
this->hColumns[column].modes = modes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Settings_defaultMeters(Settings* this, unsigned int initialCpuCount) {
|
static void Settings_defaultMeters(Settings* this, unsigned int initialCpuCount) {
|
||||||
|
@ -62,50 +69,50 @@ static void Settings_defaultMeters(Settings* this, unsigned int initialCpuCount)
|
||||||
sizes[1]++;
|
sizes[1]++;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
this->columns[i].names = xCalloc(sizes[i] + 1, sizeof(char*));
|
this->hColumns[i].names = xCalloc(sizes[i] + 1, sizeof(char*));
|
||||||
this->columns[i].modes = xCalloc(sizes[i], sizeof(int));
|
this->hColumns[i].modes = xCalloc(sizes[i], sizeof(int));
|
||||||
this->columns[i].len = sizes[i];
|
this->hColumns[i].len = sizes[i];
|
||||||
}
|
}
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
if (initialCpuCount > 128) {
|
if (initialCpuCount > 128) {
|
||||||
// Just show the average, ricers need to config for impressive screenshots
|
// Just show the average, ricers need to config for impressive screenshots
|
||||||
this->columns[0].names[0] = xStrdup("CPU");
|
this->hColumns[0].names[0] = xStrdup("CPU");
|
||||||
this->columns[0].modes[0] = BAR_METERMODE;
|
this->hColumns[0].modes[0] = BAR_METERMODE;
|
||||||
} else if (initialCpuCount > 32) {
|
} else if (initialCpuCount > 32) {
|
||||||
this->columns[0].names[0] = xStrdup("LeftCPUs8");
|
this->hColumns[0].names[0] = xStrdup("LeftCPUs8");
|
||||||
this->columns[0].modes[0] = BAR_METERMODE;
|
this->hColumns[0].modes[0] = BAR_METERMODE;
|
||||||
this->columns[1].names[r] = xStrdup("RightCPUs8");
|
this->hColumns[1].names[r] = xStrdup("RightCPUs8");
|
||||||
this->columns[1].modes[r++] = BAR_METERMODE;
|
this->hColumns[1].modes[r++] = BAR_METERMODE;
|
||||||
} else if (initialCpuCount > 16) {
|
} else if (initialCpuCount > 16) {
|
||||||
this->columns[0].names[0] = xStrdup("LeftCPUs4");
|
this->hColumns[0].names[0] = xStrdup("LeftCPUs4");
|
||||||
this->columns[0].modes[0] = BAR_METERMODE;
|
this->hColumns[0].modes[0] = BAR_METERMODE;
|
||||||
this->columns[1].names[r] = xStrdup("RightCPUs4");
|
this->hColumns[1].names[r] = xStrdup("RightCPUs4");
|
||||||
this->columns[1].modes[r++] = BAR_METERMODE;
|
this->hColumns[1].modes[r++] = BAR_METERMODE;
|
||||||
} else if (initialCpuCount > 8) {
|
} else if (initialCpuCount > 8) {
|
||||||
this->columns[0].names[0] = xStrdup("LeftCPUs2");
|
this->hColumns[0].names[0] = xStrdup("LeftCPUs2");
|
||||||
this->columns[0].modes[0] = BAR_METERMODE;
|
this->hColumns[0].modes[0] = BAR_METERMODE;
|
||||||
this->columns[1].names[r] = xStrdup("RightCPUs2");
|
this->hColumns[1].names[r] = xStrdup("RightCPUs2");
|
||||||
this->columns[1].modes[r++] = BAR_METERMODE;
|
this->hColumns[1].modes[r++] = BAR_METERMODE;
|
||||||
} else if (initialCpuCount > 4) {
|
} else if (initialCpuCount > 4) {
|
||||||
this->columns[0].names[0] = xStrdup("LeftCPUs");
|
this->hColumns[0].names[0] = xStrdup("LeftCPUs");
|
||||||
this->columns[0].modes[0] = BAR_METERMODE;
|
this->hColumns[0].modes[0] = BAR_METERMODE;
|
||||||
this->columns[1].names[r] = xStrdup("RightCPUs");
|
this->hColumns[1].names[r] = xStrdup("RightCPUs");
|
||||||
this->columns[1].modes[r++] = BAR_METERMODE;
|
this->hColumns[1].modes[r++] = BAR_METERMODE;
|
||||||
} else {
|
} else {
|
||||||
this->columns[0].names[0] = xStrdup("AllCPUs");
|
this->hColumns[0].names[0] = xStrdup("AllCPUs");
|
||||||
this->columns[0].modes[0] = BAR_METERMODE;
|
this->hColumns[0].modes[0] = BAR_METERMODE;
|
||||||
}
|
}
|
||||||
this->columns[0].names[1] = xStrdup("Memory");
|
this->hColumns[0].names[1] = xStrdup("Memory");
|
||||||
this->columns[0].modes[1] = BAR_METERMODE;
|
this->hColumns[0].modes[1] = BAR_METERMODE;
|
||||||
this->columns[0].names[2] = xStrdup("Swap");
|
this->hColumns[0].names[2] = xStrdup("Swap");
|
||||||
this->columns[0].modes[2] = BAR_METERMODE;
|
this->hColumns[0].modes[2] = BAR_METERMODE;
|
||||||
this->columns[1].names[r] = xStrdup("Tasks");
|
this->hColumns[1].names[r] = xStrdup("Tasks");
|
||||||
this->columns[1].modes[r++] = TEXT_METERMODE;
|
this->hColumns[1].modes[r++] = TEXT_METERMODE;
|
||||||
this->columns[1].names[r] = xStrdup("LoadAverage");
|
this->hColumns[1].names[r] = xStrdup("LoadAverage");
|
||||||
this->columns[1].modes[r++] = TEXT_METERMODE;
|
this->hColumns[1].modes[r++] = TEXT_METERMODE;
|
||||||
this->columns[1].names[r] = xStrdup("Uptime");
|
this->hColumns[1].names[r] = xStrdup("Uptime");
|
||||||
this->columns[1].modes[r++] = TEXT_METERMODE;
|
this->hColumns[1].modes[r++] = TEXT_METERMODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Settings_readFields(Settings* settings, const char* line) {
|
static void Settings_readFields(Settings* settings, const char* line) {
|
||||||
|
@ -258,6 +265,12 @@ static bool Settings_read(Settings* this, const char* fileName, unsigned int ini
|
||||||
} else if (String_eq(option[0], "enable_mouse")) {
|
} else if (String_eq(option[0], "enable_mouse")) {
|
||||||
this->enableMouse = atoi(option[1]);
|
this->enableMouse = atoi(option[1]);
|
||||||
#endif
|
#endif
|
||||||
|
} else if (String_eq(option[0], "header_layout")) {
|
||||||
|
this->hLayout = atoi(option[1]);
|
||||||
|
if (this->hLayout < 0 || this->hLayout >= LAST_HEADER_LAYOUT)
|
||||||
|
this->hLayout = HF_TWO_50_50;
|
||||||
|
free(this->hColumns);
|
||||||
|
this->hColumns = xCalloc(HeaderLayout_getColumns(this->hLayout), sizeof(MeterColumnSetting));
|
||||||
} else if (String_eq(option[0], "left_meters")) {
|
} else if (String_eq(option[0], "left_meters")) {
|
||||||
Settings_readMeters(this, option[1], 0);
|
Settings_readMeters(this, option[1], 0);
|
||||||
didReadMeters = true;
|
didReadMeters = true;
|
||||||
|
@ -270,6 +283,12 @@ static bool Settings_read(Settings* this, const char* fileName, unsigned int ini
|
||||||
} else if (String_eq(option[0], "right_meter_modes")) {
|
} else if (String_eq(option[0], "right_meter_modes")) {
|
||||||
Settings_readMeterModes(this, option[1], 1);
|
Settings_readMeterModes(this, option[1], 1);
|
||||||
didReadMeters = true;
|
didReadMeters = true;
|
||||||
|
} else if (String_startsWith(option[0], "column_meters_")) {
|
||||||
|
Settings_readMeters(this, option[1], atoi(option[0] + strlen("column_meters_")));
|
||||||
|
didReadMeters = true;
|
||||||
|
} else if (String_startsWith(option[0], "column_meter_modes_")) {
|
||||||
|
Settings_readMeterModes(this, option[1], atoi(option[0] + strlen("column_meter_modes_")));
|
||||||
|
didReadMeters = true;
|
||||||
} else if (String_eq(option[0], "hide_function_bar")) {
|
} else if (String_eq(option[0], "hide_function_bar")) {
|
||||||
this->hideFunctionBar = atoi(option[1]);
|
this->hideFunctionBar = atoi(option[1]);
|
||||||
#ifdef HAVE_LIBHWLOC
|
#ifdef HAVE_LIBHWLOC
|
||||||
|
@ -302,19 +321,19 @@ static void writeFields(FILE* fd, const ProcessField* fields, Hashtable* columns
|
||||||
fprintf(fd, "\n");
|
fprintf(fd, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeMeters(const Settings* this, FILE* fd, int column) {
|
static void writeMeters(const Settings* this, FILE* fd, unsigned int column) {
|
||||||
const char* sep = "";
|
const char* sep = "";
|
||||||
for (int i = 0; i < this->columns[column].len; i++) {
|
for (uint8_t i = 0; i < this->hColumns[column].len; i++) {
|
||||||
fprintf(fd, "%s%s", sep, this->columns[column].names[i]);
|
fprintf(fd, "%s%s", sep, this->hColumns[column].names[i]);
|
||||||
sep = " ";
|
sep = " ";
|
||||||
}
|
}
|
||||||
fprintf(fd, "\n");
|
fprintf(fd, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void writeMeterModes(const Settings* this, FILE* fd, int column) {
|
static void writeMeterModes(const Settings* this, FILE* fd, unsigned int column) {
|
||||||
const char* sep = "";
|
const char* sep = "";
|
||||||
for (int i = 0; i < this->columns[column].len; i++) {
|
for (uint8_t i = 0; i < this->hColumns[column].len; i++) {
|
||||||
fprintf(fd, "%s%d", sep, this->columns[column].modes[i]);
|
fprintf(fd, "%s%d", sep, this->hColumns[column].modes[i]);
|
||||||
sep = " ";
|
sep = " ";
|
||||||
}
|
}
|
||||||
fprintf(fd, "\n");
|
fprintf(fd, "\n");
|
||||||
|
@ -375,10 +394,13 @@ int Settings_write(const Settings* this, bool onCrash) {
|
||||||
fprintf(fd, "enable_mouse=%d\n", (int) this->enableMouse);
|
fprintf(fd, "enable_mouse=%d\n", (int) this->enableMouse);
|
||||||
#endif
|
#endif
|
||||||
fprintf(fd, "delay=%d\n", (int) this->delay);
|
fprintf(fd, "delay=%d\n", (int) this->delay);
|
||||||
fprintf(fd, "left_meters="); writeMeters(this, fd, 0);
|
fprintf(fd, "header_layout=%d\n", (int) this->hLayout);
|
||||||
fprintf(fd, "left_meter_modes="); writeMeterModes(this, fd, 0);
|
for (unsigned int i = 0; i < HeaderLayout_getColumns(this->hLayout); i++) {
|
||||||
fprintf(fd, "right_meters="); writeMeters(this, fd, 1);
|
fprintf(fd, "column_meters_%u=", i);
|
||||||
fprintf(fd, "right_meter_modes="); writeMeterModes(this, fd, 1);
|
writeMeters(this, fd, i);
|
||||||
|
fprintf(fd, "column_meter_modes_%u=", i);
|
||||||
|
writeMeterModes(this, fd, i);
|
||||||
|
}
|
||||||
fprintf(fd, "hide_function_bar=%d\n", (int) this->hideFunctionBar);
|
fprintf(fd, "hide_function_bar=%d\n", (int) this->hideFunctionBar);
|
||||||
#ifdef HAVE_LIBHWLOC
|
#ifdef HAVE_LIBHWLOC
|
||||||
fprintf(fd, "topology_affinity=%d\n", (int) this->topologyAffinity);
|
fprintf(fd, "topology_affinity=%d\n", (int) this->topologyAffinity);
|
||||||
|
@ -402,6 +424,8 @@ Settings* Settings_new(unsigned int initialCpuCount, Hashtable* dynamicColumns)
|
||||||
Settings* this = xCalloc(1, sizeof(Settings));
|
Settings* this = xCalloc(1, sizeof(Settings));
|
||||||
|
|
||||||
this->dynamicColumns = dynamicColumns;
|
this->dynamicColumns = dynamicColumns;
|
||||||
|
this->hLayout = HF_TWO_50_50;
|
||||||
|
this->hColumns = xCalloc(HeaderLayout_getColumns(this->hLayout), sizeof(MeterColumnSetting));
|
||||||
this->sortKey = PERCENT_CPU;
|
this->sortKey = PERCENT_CPU;
|
||||||
this->treeSortKey = PID;
|
this->treeSortKey = PID;
|
||||||
this->direction = -1;
|
this->direction = -1;
|
||||||
|
@ -531,3 +555,26 @@ void Settings_enableReadonly(void) {
|
||||||
bool Settings_isReadonly(void) {
|
bool Settings_isReadonly(void) {
|
||||||
return readonly;
|
return readonly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Settings_setHeaderLayout(Settings* this, HeaderLayout hLayout) {
|
||||||
|
unsigned int oldColumns = HeaderLayout_getColumns(this->hLayout);
|
||||||
|
unsigned int newColumns = HeaderLayout_getColumns(hLayout);
|
||||||
|
|
||||||
|
if (newColumns > oldColumns) {
|
||||||
|
this->hColumns = xReallocArray(this->hColumns, newColumns, sizeof(MeterColumnSetting));
|
||||||
|
memset(this->hColumns + oldColumns, 0, (newColumns - oldColumns) * sizeof(MeterColumnSetting));
|
||||||
|
} else if (newColumns < oldColumns) {
|
||||||
|
for (unsigned int i = newColumns; i < oldColumns; i++) {
|
||||||
|
if (this->hColumns[i].names) {
|
||||||
|
for (uint8_t j = 0; j < this->hColumns[i].len; j++)
|
||||||
|
free(this->hColumns[i].names[j]);
|
||||||
|
free(this->hColumns[i].names);
|
||||||
|
}
|
||||||
|
free(this->hColumns[i].modes);
|
||||||
|
}
|
||||||
|
this->hColumns = xReallocArray(this->hColumns, newColumns, sizeof(MeterColumnSetting));
|
||||||
|
}
|
||||||
|
|
||||||
|
this->hLayout = hLayout;
|
||||||
|
this->changed = true;
|
||||||
|
}
|
||||||
|
|
10
Settings.h
10
Settings.h
|
@ -13,6 +13,7 @@ in the source distribution for its full text.
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "Hashtable.h"
|
#include "Hashtable.h"
|
||||||
|
#include "HeaderLayout.h"
|
||||||
#include "Process.h"
|
#include "Process.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,15 +22,16 @@ in the source distribution for its full text.
|
||||||
#define CONFIG_READER_MIN_VERSION 2
|
#define CONFIG_READER_MIN_VERSION 2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int len;
|
uint8_t len;
|
||||||
char** names;
|
char** names;
|
||||||
int* modes;
|
int* modes;
|
||||||
} MeterColumnSettings;
|
} MeterColumnSetting;
|
||||||
|
|
||||||
typedef struct Settings_ {
|
typedef struct Settings_ {
|
||||||
char* filename;
|
char* filename;
|
||||||
int config_version;
|
int config_version;
|
||||||
MeterColumnSettings columns[2];
|
HeaderLayout hLayout;
|
||||||
|
MeterColumnSetting* hColumns;
|
||||||
Hashtable* dynamicColumns;
|
Hashtable* dynamicColumns;
|
||||||
|
|
||||||
ProcessField* fields;
|
ProcessField* fields;
|
||||||
|
@ -107,4 +109,6 @@ void Settings_enableReadonly(void);
|
||||||
|
|
||||||
bool Settings_isReadonly(void);
|
bool Settings_isReadonly(void);
|
||||||
|
|
||||||
|
void Settings_setHeaderLayout(Settings* this, HeaderLayout hLayout);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue