Skip to content

Commit 5f02fd8

Browse files
committed
PCP: DynamicScreens
Signed-off-by: Sohaib Mohamed <sohaib.amhmd@gmail.com>
1 parent 4eeabc3 commit 5f02fd8

53 files changed

Lines changed: 1889 additions & 18 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Action.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ in the source distribution for its full text.
1717
#include "Panel.h"
1818
#include "Process.h"
1919
#include "ProcessList.h"
20+
#include "GenericDataList.h"
2021
#include "Settings.h"
2122
#include "UsersTable.h"
2223

@@ -39,6 +40,7 @@ typedef struct State_ {
3940
Settings* settings;
4041
UsersTable* ut;
4142
ProcessList* pl;
43+
GenericDataList* gl;
4244
struct MainPanel_* mainPanel;
4345
Header* header;
4446
bool pauseUpdate;

AvailableColumnsPanel.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@ in the source distribution for its full text.
2323
#include "XUtils.h"
2424

2525

26+
Panel* activeAvailableColumns;
27+
2628
static const char* const AvailableColumnsFunctions[] = {" ", " ", " ", " ", "Add ", " ", " ", " ", " ", "Done ", NULL};
2729

2830
static void AvailableColumnsPanel_delete(Object* object) {
2931
Panel* super = (Panel*) object;
3032
AvailableColumnsPanel* this = (AvailableColumnsPanel*) object;
33+
if (activeAvailableColumns == super)
34+
activeAvailableColumns = NULL;
3135
Panel_done(super);
3236
free(this);
3337
}
@@ -81,6 +85,9 @@ const PanelClass AvailableColumnsPanel_class = {
8185

8286
static void AvailableColumnsPanel_addDynamicColumn(ht_key_t key, void* value, void* data) {
8387
const DynamicColumn* column = (const DynamicColumn*) value;
88+
if (column->belongToDynamicScreen)
89+
return;
90+
8491
Panel* super = (Panel*) data;
8592
const char* title = column->caption ? column->caption : column->heading;
8693
if (!title)
@@ -91,13 +98,13 @@ static void AvailableColumnsPanel_addDynamicColumn(ht_key_t key, void* value, vo
9198
}
9299

93100
// Handle DynamicColumns entries in the AvailableColumnsPanel
94-
static void AvailableColumnsPanel_addDynamicColumns(Panel* super, Hashtable* dynamicColumns) {
101+
void AvailableColumnsPanel_addDynamicColumns(Panel* super, Hashtable* dynamicColumns) {
95102
assert(dynamicColumns);
96103
Hashtable_foreach(dynamicColumns, AvailableColumnsPanel_addDynamicColumn, super);
97104
}
98105

99106
// Handle remaining Platform Meter entries in the AvailableColumnsPanel
100-
static void AvailableColumnsPanel_addPlatformColumn(Panel* super) {
107+
void AvailableColumnsPanel_addPlatformColumn(Panel* super) {
101108
for (int i = 1; i < LAST_PROCESSFIELD; i++) {
102109
if (i != COMM && Process_fields[i].description) {
103110
char description[256];
@@ -117,6 +124,11 @@ AvailableColumnsPanel* AvailableColumnsPanel_new(Panel* columns, Hashtable* dyna
117124
AvailableColumnsPanel_addPlatformColumn(super);
118125
AvailableColumnsPanel_addDynamicColumns(super, dynamicColumns);
119126

127+
activeAvailableColumns = super;
120128
this->columns = columns;
121129
return this;
122130
}
131+
132+
Panel* AvailableColumnsPanel_get(void) {
133+
return activeAvailableColumns;
134+
}

AvailableColumnsPanel.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,10 @@ extern const PanelClass AvailableColumnsPanel_class;
2020

2121
AvailableColumnsPanel* AvailableColumnsPanel_new(Panel* columns, Hashtable* dynamicColumns);
2222

23+
void AvailableColumnsPanel_addPlatformColumn(Panel* super);
24+
25+
void AvailableColumnsPanel_addDynamicColumns(Panel* super, Hashtable* dynamicColumns);
26+
27+
Panel* AvailableColumnsPanel_get(void);
28+
2329
#endif

CommandLine.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ in the source distribution for its full text.
2525
#include "CRT.h"
2626
#include "DynamicColumn.h"
2727
#include "DynamicMeter.h"
28+
#include "DynamicScreen.h"
29+
#include "GenericDataList.h"
2830
#include "Hashtable.h"
2931
#include "Header.h"
3032
#include "IncSet.h"
@@ -328,11 +330,16 @@ int CommandLine_run(const char* name, int argc, char** argv) {
328330
dc = Hashtable_new(0, true);
329331

330332
ProcessList* pl = ProcessList_new(ut, dm, dc, flags.pidMatchList, flags.userId);
331-
332333
Settings* settings = Settings_new(pl->activeCPUs, dc);
334+
335+
Hashtable* dt = DynamicScreens_new(settings);
336+
GenericDataList* gl = GenericDataList_new();
337+
333338
pl->settings = settings;
339+
if (gl)
340+
gl->settings = settings;
334341

335-
Header* header = Header_new(pl, settings, 2);
342+
Header* header = Header_new(pl, gl, settings, 2);
336343

337344
Header_populateFromSettings(header);
338345

@@ -362,7 +369,7 @@ int CommandLine_run(const char* name, int argc, char** argv) {
362369
CRT_init(settings, flags.allowUnicode);
363370

364371
MainPanel* panel = MainPanel_new();
365-
ProcessList_setPanel(pl, (Panel*) panel);
372+
MainPanel* genericDataPanel = MainPanel_new();
366373

367374
MainPanel_updateLabels(panel, settings->ss->treeView, flags.commFilter);
368375

@@ -377,7 +384,13 @@ int CommandLine_run(const char* name, int argc, char** argv) {
377384
.hideMeters = false,
378385
};
379386

380-
MainPanel_setState(panel, &state);
387+
panel->state = &state;
388+
genericDataPanel->state = &state;
389+
390+
ProcessList_setPanel(pl, (Panel*) panel);
391+
if (gl)
392+
GenericDataList_setPanel(gl, (Panel*) genericDataPanel);
393+
381394
if (flags.commFilter)
382395
setCommFilter(&state, &(flags.commFilter));
383396

@@ -405,6 +418,7 @@ int CommandLine_run(const char* name, int argc, char** argv) {
405418

406419
Header_delete(header);
407420
ProcessList_delete(pl);
421+
GenericDataList_delete(gl);
408422

409423
ScreenManager_delete(scr);
410424
MetersPanel_cleanup();
@@ -420,6 +434,7 @@ int CommandLine_run(const char* name, int argc, char** argv) {
420434
Settings_delete(settings);
421435
DynamicColumns_delete(dc);
422436
DynamicMeters_delete(dm);
437+
DynamicScreens_delete(dt);
423438

424439
return 0;
425440
}

DynamicColumn.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
#define DYNAMIC_DEFAULT_COLUMN_WIDTH -5
1313

1414
typedef struct DynamicColumn_ {
15-
char name[32]; /* unique, internal-only name */
16-
char* heading; /* displayed in main screen */
17-
char* caption; /* displayed in setup menu (short name) */
18-
char* description; /* displayed in setup menu (detail) */
19-
int width; /* display width +/- for value alignment */
15+
char name[32]; /* unique, internal-only name */
16+
char* heading; /* displayed in main screen */
17+
char* caption; /* displayed in setup menu (short name) */
18+
char* description; /* displayed in setup menu (detail) */
19+
int width; /* display width +/- for value alignment */
20+
bool belongToDynamicScreen; /* belong to DynamicScreen or ProcessList screen? */
21+
bool enabled; /* false == ignore this column */
2022
} DynamicColumn;
2123

2224
Hashtable* DynamicColumns_new(void);

DynamicScreen.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
htop - DynamicScreen.c
3+
(C) 2022 Sohaib Mohammed
4+
(C) 2022 htop dev team
5+
(C) 2022 Red Hat, Inc. All Rights Reserved.
6+
Released under the GNU GPLv2+, see the COPYING file
7+
in the source distribution for its full text.
8+
*/
9+
10+
#include "DynamicScreen.h"
11+
12+
#include <stdbool.h>
13+
#include <stddef.h>
14+
15+
#include "Hashtable.h"
16+
#include "Platform.h"
17+
#include "XUtils.h"
18+
19+
20+
Hashtable* DynamicScreens_new(Settings* settings) {
21+
return Platform_dynamicScreens(settings);
22+
}
23+
24+
void DynamicScreens_delete(Hashtable* dynamics) {
25+
if (dynamics) {
26+
Platform_dynamicScreensDone(dynamics);
27+
Hashtable_delete(dynamics);
28+
}
29+
}
30+
31+
typedef struct {
32+
ht_key_t key;
33+
const char* name;
34+
bool found;
35+
} DynamicIterator;
36+
37+
static void DynamicScreen_compare(ht_key_t key, void* value, void* data) {
38+
const DynamicScreen* screen = (const DynamicScreen*)value;
39+
DynamicIterator* iter = (DynamicIterator*)data;
40+
if (String_eq(iter->name, screen->name)) {
41+
iter->found = true;
42+
iter->key = key;
43+
}
44+
}
45+
46+
bool DynamicScreen_search(Hashtable* dynamics, const char* name, ht_key_t* key) {
47+
DynamicIterator iter = { .key = 0, .name = name, .found = false };
48+
if (dynamics)
49+
Hashtable_foreach(dynamics, DynamicScreen_compare, &iter);
50+
if (key)
51+
*key = iter.key;
52+
return iter.found;
53+
}
54+
55+
const char* DynamicScreen_lookup(Hashtable* dynamics, ht_key_t key) {
56+
const DynamicScreen* screen = Hashtable_get(dynamics, key);
57+
return screen ? screen->name : NULL;
58+
}
59+
60+
void DynamicScreen_availableColumns(char* currentScreen) {
61+
Platform_dynamicScreenAvailableColumns(currentScreen);
62+
}

DynamicScreen.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef HEADER_DynamicScreen
2+
#define HEADER_DynamicScreen
3+
4+
#include <stdbool.h>
5+
6+
#include "Hashtable.h"
7+
#include "Settings.h"
8+
9+
10+
typedef struct DynamicScreen_ {
11+
char name[32]; /* unique name, cannot contain spaces */
12+
char* caption;
13+
char* fields;
14+
char* sortKey;
15+
int direction;
16+
} DynamicScreen;
17+
18+
Hashtable* DynamicScreens_new(Settings* settings);
19+
20+
void DynamicScreens_delete(Hashtable* dynamics);
21+
22+
const char* DynamicScreen_lookup(Hashtable* dynamics, unsigned int key);
23+
24+
bool DynamicScreen_search(Hashtable* dynamics, const char* name, unsigned int* key);
25+
26+
void DynamicScreen_availableColumns(char* currentScreen);
27+
28+
#endif

GenericData.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
htop - GenericData.c
3+
(C) 2022 Sohaib Mohammed
4+
(C) 2022 htop dev team
5+
(C) 2022 Red Hat, Inc.
6+
Released under the GNU GPLv2+, see the COPYING file
7+
in the source distribution for its full text.
8+
*/
9+
10+
#include "GenericData.h"
11+
12+
#include <assert.h>
13+
14+
#include "CRT.h"
15+
#include "Macros.h"
16+
#include "Process.h"
17+
#include "RichString.h"
18+
#include "Settings.h"
19+
20+
21+
void GenericData_init(GenericData* this, const Settings* settings) {
22+
this->settings = settings;
23+
}
24+
25+
void GenericData_done(ATTR_UNUSED GenericData* this) {
26+
assert (this != NULL);
27+
}
28+
29+
void GenericData_writeField(ATTR_UNUSED const GenericData* this, ATTR_UNUSED RichString* str, ATTR_UNUSED int field) {
30+
return;
31+
}
32+
33+
void GenericData_display(const Object* cast, RichString* out) {
34+
const GenericData* this = (const GenericData*) cast;
35+
const ProcessField* fields = this->settings->ss->fields;
36+
for (int i = 0; fields[i]; i++)
37+
As_GenericData(this)->writeField(this, out, i);
38+
}
39+
40+
int GenericData_compare(const void* v1, const void* v2) {
41+
const GenericData* g1 = (const GenericData*)v1;
42+
const GenericData* g2 = (const GenericData*)v2;
43+
44+
const Settings* settings = g1->settings;
45+
const ScreenSettings* ss = settings->ss;
46+
47+
ProcessField key = ScreenSettings_getActiveSortKey(ss);
48+
49+
int result = GenericData_compareByKey(g1, g2, key);
50+
51+
return (ScreenSettings_getActiveDirection(ss) == 1) ? result : -result;
52+
}
53+
54+
int GenericData_compareByKey_Base(const GenericData* g1, const GenericData* g2, ATTR_UNUSED ProcessField key) {
55+
// TODO
56+
(void) g1;
57+
(void) g2;
58+
59+
return 0;
60+
}
61+
62+
const GenericDataClass GenericData_class = {
63+
.super = {
64+
.extends = Class(Object),
65+
.display = GenericData_display,
66+
.compare = GenericData_compare,
67+
},
68+
.writeField = GenericData_writeField,
69+
};

GenericData.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#ifndef HEADER_GenericData
2+
#define HEADER_GenericData
3+
/*
4+
htop - GenericData.h
5+
(C) 2022 Sohaib Mohammed
6+
(C) 2022 htop dev team
7+
(C) 2022 Red Hat, Inc.
8+
Released under the GNU GPLv2+, see the COPYING file
9+
in the source distribution for its full text.
10+
*/
11+
12+
#include "Object.h"
13+
#include "ProcessField.h"
14+
#include "RichString.h"
15+
#include "Settings.h"
16+
17+
18+
typedef struct GenericData_ {
19+
/* Super object for emulated OOP */
20+
Object super;
21+
22+
/* Pointer to quasi-global data structures */
23+
const Settings* settings;
24+
25+
} GenericData;
26+
27+
28+
// Implemented in platform-specific code:
29+
void GenericData_writeField(const GenericData* this, RichString* str, int field);
30+
int GenericData_compare(const void* v1, const void* v2);
31+
void GenericData_delete(Object* cast);
32+
33+
typedef GenericData* (*GenericData_New)(const Settings* settings);
34+
typedef void (*GenericData_WriteField)(const GenericData*, RichString*, int field);
35+
typedef int (*GenericData_CompareByKey)(const GenericData*, const GenericData*, int key);
36+
37+
typedef struct GenericDataClass_ {
38+
const ObjectClass super;
39+
const GenericData_WriteField writeField;
40+
const GenericData_CompareByKey compareByKey;
41+
} GenericDataClass;
42+
43+
#define As_GenericData(this_) ((const GenericDataClass*)((this_)->super.klass))
44+
45+
#define GenericData_compareByKey(g1_, g2_, key_) (As_GenericData(g1_)->compareByKey ? (As_GenericData(g1_)->compareByKey(g1_, g2_, key_)) : GenericData_compareByKey_Base(g1_, g2_, key_))
46+
47+
int GenericData_compareByKey_Base(const GenericData* g1, const GenericData* g2, ProcessField key);
48+
49+
void GenericData_display(const Object* cast, RichString* out);
50+
extern const GenericDataClass GenericData_class;
51+
52+
void GenericData_init(GenericData* this, const Settings* settings);
53+
54+
void GenericData_done(GenericData* this);
55+
56+
void GenericData_addField(GenericData* this);
57+
58+
void GenericData_removeField(GenericData* this);
59+
60+
void GenericData_rebuildFields(GenericData* this);
61+
62+
#endif

0 commit comments

Comments
 (0)