Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
adam.huang
htop
Commits
187a035a
Commit
187a035a
authored
Jan 28, 2018
by
Hisham Muhammad
Browse files
Add support for multiple screens, switchable using Tab
parent
ece89b8d
Changes
19
Hide whitespace changes
Inline
Side-by-side
Action.c
View file @
187a035a
...
...
@@ -156,9 +156,10 @@ static bool expandCollapse(Panel* panel) {
}
Htop_Reaction
Action_setSortKey
(
Settings
*
settings
,
ProcessField
sortKey
)
{
settings
->
sortKey
=
sortKey
;
settings
->
direction
=
1
;
settings
->
treeView
=
false
;
ScreenSettings
*
ss
=
settings
->
ss
;
ss
->
sortKey
=
sortKey
;
ss
->
direction
=
1
;
ss
->
treeView
=
false
;
return
HTOP_REFRESH
|
HTOP_SAVE_SETTINGS
|
HTOP_UPDATE_PANELHDR
|
HTOP_KEEP_FOLLOWING
;
}
...
...
@@ -166,11 +167,12 @@ static Htop_Reaction sortBy(State* st) {
Htop_Reaction
reaction
=
HTOP_OK
;
Panel
*
sortPanel
=
Panel_new
(
0
,
0
,
0
,
0
,
true
,
Class
(
ListItem
),
FunctionBar_newEnterEsc
(
"Sort "
,
"Cancel "
));
Panel_setHeader
(
sortPanel
,
"Sort by"
);
ProcessField
*
fields
=
st
->
settings
->
fields
;
ScreenSettings
*
ss
=
st
->
settings
->
ss
;
ProcessField
*
fields
=
ss
->
fields
;
for
(
int
i
=
0
;
fields
[
i
];
i
++
)
{
char
*
name
=
String_trim
(
Process_fields
[
fields
[
i
]].
name
);
Panel_add
(
sortPanel
,
(
Object
*
)
ListItem_new
(
name
,
fields
[
i
]));
if
(
fields
[
i
]
==
s
t
->
setting
s
->
sortKey
)
if
(
fields
[
i
]
==
ss
->
sortKey
)
Panel_setSelected
(
sortPanel
,
i
);
free
(
name
);
}
...
...
@@ -218,8 +220,9 @@ static Htop_Reaction actionToggleProgramPath(State* st) {
}
static
Htop_Reaction
actionToggleTreeView
(
State
*
st
)
{
st
->
settings
->
treeView
=
!
st
->
settings
->
treeView
;
if
(
st
->
settings
->
treeView
)
st
->
settings
->
direction
=
1
;
ScreenSettings
*
ss
=
st
->
settings
->
ss
;
ss
->
treeView
=
!
ss
->
treeView
;
if
(
ss
->
treeView
)
ss
->
direction
=
1
;
ProcessList_expandTree
(
st
->
pl
);
return
HTOP_REFRESH
|
HTOP_SAVE_SETTINGS
|
HTOP_KEEP_FOLLOWING
|
HTOP_REDRAW_BAR
|
HTOP_UPDATE_PANELHDR
;
}
...
...
@@ -247,7 +250,7 @@ static Htop_Reaction actionLowerPriority(State* st) {
}
static
Htop_Reaction
actionInvertSortOrder
(
State
*
st
)
{
Settings_invertSortOrder
(
st
->
settings
);
Screen
Settings_invertSortOrder
(
st
->
settings
->
ss
);
return
HTOP_REFRESH
|
HTOP_SAVE_SETTINGS
;
}
...
...
@@ -261,13 +264,23 @@ static Htop_Reaction actionExpandOrCollapse(State* st) {
}
static
Htop_Reaction
actionExpandCollapseOrSortColumn
(
State
*
st
)
{
return
st
->
settings
->
treeView
?
actionExpandOrCollapse
(
st
)
:
actionSetSortColumn
(
st
);
return
st
->
settings
->
ss
->
treeView
?
actionExpandOrCollapse
(
st
)
:
actionSetSortColumn
(
st
);
}
static
Htop_Reaction
actionQuit
()
{
return
HTOP_QUIT
;
}
static
Htop_Reaction
actionNextScreen
(
State
*
st
)
{
Settings
*
settings
=
st
->
settings
;
settings
->
ssIndex
++
;
if
(
settings
->
ssIndex
==
settings
->
nScreens
)
{
settings
->
ssIndex
=
0
;
}
settings
->
ss
=
settings
->
screens
[
settings
->
ssIndex
];
return
HTOP_REFRESH
;
}
static
Htop_Reaction
actionSetAffinity
(
State
*
st
)
{
if
(
st
->
pl
->
cpuCount
==
1
)
return
HTOP_OK
;
...
...
@@ -571,5 +584,6 @@ void Action_setBindings(Htop_Action* keys) {
keys
[
'U'
]
=
actionUntagAll
;
keys
[
'c'
]
=
actionTagAllChildren
;
keys
[
'e'
]
=
actionShowEnvScreen
;
keys
[
'\t'
]
=
actionNextScreen
;
}
CategoriesPanel.c
View file @
187a035a
...
...
@@ -10,7 +10,6 @@ in the source distribution for its full text.
#include "AvailableMetersPanel.h"
#include "MetersPanel.h"
#include "DisplayOptionsPanel.h"
#include "ColumnsPanel.h"
#include "ScreensPanel.h"
#include "ColorsPanel.h"
#include "AvailableColumnsPanel.h"
...
...
@@ -67,7 +66,7 @@ static void CategoriesPanel_makeColorsPage(CategoriesPanel* this) {
static
void
CategoriesPanel_makeScreensPage
(
CategoriesPanel
*
this
)
{
Panel
*
screens
=
(
Panel
*
)
ScreensPanel_new
(
this
->
settings
);
Panel
*
columns
=
(
Panel
*
)
ColumnsPanel_new
(
this
->
settings
)
;
Panel
*
columns
=
(
Panel
*
)
((
ScreensPanel
*
)
screens
)
->
columns
;
Panel
*
availableColumns
=
(
Panel
*
)
AvailableColumnsPanel_new
(
columns
);
ScreenManager_add
(
this
->
scr
,
screens
,
20
);
ScreenManager_add
(
this
->
scr
,
columns
,
20
);
...
...
ColumnsPanel.c
View file @
187a035a
...
...
@@ -22,8 +22,9 @@ in the source distribution for its full text.
typedef struct ColumnsPanel_ {
Panel super;
ScreenSettings* ss;
bool* changed;
Settings* settings;
bool moving;
} ColumnsPanel;
...
...
@@ -123,22 +124,31 @@ PanelClass ColumnsPanel_class = {
.
eventHandler
=
ColumnsPanel_eventHandler
};
ColumnsPanel
*
ColumnsPanel_new
(
Settings
*
settings
)
{
void
ColumnsPanel_fill
(
ColumnsPanel
*
this
,
ScreenSettings
*
ss
)
{
Panel
*
super
=
(
Panel
*
)
this
;
Panel_prune
(
super
);
ProcessField
*
fields
=
ss
->
fields
;
for
(;
*
fields
;
fields
++
)
{
if
(
Process_fields
[
*
fields
].
name
)
{
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
Process_fields
[
*
fields
].
name
,
*
fields
));
}
}
this
->
ss
=
ss
;
}
ColumnsPanel
*
ColumnsPanel_new
(
ScreenSettings
*
ss
,
bool
*
changed
)
{
ColumnsPanel
*
this
=
AllocThis
(
ColumnsPanel
);
Panel
*
super
=
(
Panel
*
)
this
;
FunctionBar
*
fuBar
=
FunctionBar_new
(
ColumnsFunctions
,
NULL
,
NULL
);
Panel_init
(
super
,
1
,
1
,
1
,
1
,
Class
(
ListItem
),
true
,
fuBar
);
this
->
settings
=
settings
;
this
->
ss
=
ss
;
this
->
changed
=
changed
;
this
->
moving
=
false
;
Panel_setHeader
(
super
,
"Active Columns"
);
ColumnsPanel_fill
(
this
,
ss
);
ProcessField
*
fields
=
this
->
settings
->
fields
;
for
(;
*
fields
;
fields
++
)
{
if
(
Process_fields
[
*
fields
].
name
)
{
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
Process_fields
[
*
fields
].
name
,
*
fields
));
}
}
return
this
;
}
...
...
@@ -154,14 +164,14 @@ int ColumnsPanel_fieldNameToIndex(const char* name) {
void
ColumnsPanel_update
(
Panel
*
super
)
{
ColumnsPanel
*
this
=
(
ColumnsPanel
*
)
super
;
int
size
=
Panel_size
(
super
);
this
->
settings
->
changed
=
true
;
this
->
s
etting
s
->
fields
=
xRealloc
(
this
->
s
etting
s
->
fields
,
sizeof
(
ProcessField
)
*
(
size
+
1
));
this
->
s
etting
s
->
flags
=
0
;
*
(
this
->
changed
)
=
true
;
this
->
ss
->
fields
=
xRealloc
(
this
->
ss
->
fields
,
sizeof
(
ProcessField
)
*
(
size
+
1
));
this
->
ss
->
flags
=
0
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
int
key
=
((
ListItem
*
)
Panel_get
(
super
,
i
))
->
key
;
this
->
s
etting
s
->
fields
[
i
]
=
key
;
this
->
s
etting
s
->
flags
|=
Process_fields
[
key
].
flags
;
this
->
ss
->
fields
[
i
]
=
key
;
this
->
ss
->
flags
|=
key
<
1000
?
Process_fields
[
key
].
flags
:
0
;
}
this
->
s
etting
s
->
fields
[
size
]
=
0
;
this
->
ss
->
fields
[
size
]
=
0
;
}
ColumnsPanel.h
View file @
187a035a
...
...
@@ -14,15 +14,18 @@ in the source distribution for its full text.
typedef
struct
ColumnsPanel_
{
Panel
super
;
ScreenSettings
*
ss
;
bool
*
changed
;
Settings
*
settings
;
bool
moving
;
}
ColumnsPanel
;
extern
PanelClass
ColumnsPanel_class
;
ColumnsPanel
*
ColumnsPanel_new
(
Settings
*
settings
);
void
ColumnsPanel_fill
(
ColumnsPanel
*
this
,
ScreenSettings
*
ss
);
ColumnsPanel
*
ColumnsPanel_new
(
ScreenSettings
*
ss
,
bool
*
changed
);
int
ColumnsPanel_fieldNameToIndex
(
const
char
*
name
);
...
...
DisplayOptionsPanel.c
View file @
187a035a
...
...
@@ -83,7 +83,6 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
this
->
scr
=
scr
;
Panel_setHeader
(
super
,
"Display options"
);
Panel_add
(
super
,
(
Object
*
)
CheckItem_newByRef
(
xStrdup
(
"Tree view"
),
&
(
settings
->
treeView
)));
Panel_add
(
super
,
(
Object
*
)
CheckItem_newByRef
(
xStrdup
(
"Shadow other users' processes"
),
&
(
settings
->
shadowOtherUsers
)));
Panel_add
(
super
,
(
Object
*
)
CheckItem_newByRef
(
xStrdup
(
"Hide kernel threads"
),
&
(
settings
->
hideKernelThreads
)));
Panel_add
(
super
,
(
Object
*
)
CheckItem_newByRef
(
xStrdup
(
"Hide userland process threads"
),
&
(
settings
->
hideUserlandThreads
)));
...
...
Header.c
View file @
187a035a
...
...
@@ -62,7 +62,7 @@ void Header_delete(Header* this) {
void
Header_populateFromSettings
(
Header
*
this
)
{
Header_forEachColumn
(
this
,
col
)
{
MeterColumnSettings
*
colSettings
=
&
this
->
settings
->
c
olumns
[
col
];
MeterColumnSettings
*
colSettings
=
&
this
->
settings
->
meterC
olumns
[
col
];
for
(
int
i
=
0
;
i
<
colSettings
->
len
;
i
++
)
{
Header_addMeterByName
(
this
,
colSettings
->
names
[
i
],
col
);
if
(
colSettings
->
modes
[
i
]
!=
0
)
{
...
...
@@ -75,7 +75,7 @@ void Header_populateFromSettings(Header* this) {
void
Header_writeBackToSettings
(
const
Header
*
this
)
{
Header_forEachColumn
(
this
,
col
)
{
MeterColumnSettings
*
colSettings
=
&
this
->
settings
->
c
olumns
[
col
];
MeterColumnSettings
*
colSettings
=
&
this
->
settings
->
meterC
olumns
[
col
];
String_freeArray
(
colSettings
->
names
);
free
(
colSettings
->
modes
);
...
...
ListItem.c
View file @
187a035a
...
...
@@ -27,13 +27,13 @@ typedef struct ListItem_ {
}*/
static
void
ListItem_delete
(
Object
*
cast
)
{
void
ListItem_delete
(
Object
*
cast
)
{
ListItem
*
this
=
(
ListItem
*
)
cast
;
free
(
this
->
value
);
free
(
this
);
}
static
void
ListItem_display
(
Object
*
cast
,
RichString
*
out
)
{
void
ListItem_display
(
Object
*
cast
,
RichString
*
out
)
{
ListItem
*
const
this
=
(
ListItem
*
)
cast
;
assert
(
this
!=
NULL
);
/*
...
...
@@ -59,11 +59,15 @@ ObjectClass ListItem_class = {
.
compare
=
ListItem_compare
};
ListItem
*
ListItem_new
(
const
char
*
value
,
int
key
)
{
ListItem
*
this
=
AllocThis
(
ListItem
);
void
ListItem_init
(
ListItem
*
this
,
const
char
*
value
,
int
key
)
{
this
->
value
=
xStrdup
(
value
);
this
->
key
=
key
;
this
->
moving
=
false
;
}
ListItem
*
ListItem_new
(
const
char
*
value
,
int
key
)
{
ListItem
*
this
=
AllocThis
(
ListItem
);
ListItem_init
(
this
,
value
,
key
);
return
this
;
}
...
...
ListItem.h
View file @
187a035a
...
...
@@ -19,8 +19,14 @@ typedef struct ListItem_ {
}
ListItem
;
void
ListItem_delete
(
Object
*
cast
);
void
ListItem_display
(
Object
*
cast
,
RichString
*
out
);
extern
ObjectClass
ListItem_class
;
void
ListItem_init
(
ListItem
*
this
,
const
char
*
value
,
int
key
);
ListItem
*
ListItem_new
(
const
char
*
value
,
int
key
);
void
ListItem_append
(
ListItem
*
this
,
const
char
*
text
);
...
...
MainPanel.c
View file @
187a035a
...
...
@@ -67,15 +67,17 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) {
Htop_Reaction
reaction
=
HTOP_OK
;
Settings
*
settings
=
this
->
state
->
settings
;
ScreenSettings
*
ss
=
settings
->
ss
;
if
(
EVENT_IS_HEADER_CLICK
(
ch
))
{
int
x
=
EVENT_HEADER_CLICK_GET_X
(
ch
);
ProcessList
*
pl
=
this
->
state
->
pl
;
Settings
*
settings
=
this
->
state
->
settings
;
int
hx
=
super
->
scrollH
+
x
+
1
;
ProcessField
field
=
ProcessList_keyAt
(
pl
,
hx
);
if
(
field
==
s
etting
s
->
sortKey
)
{
Settings_invertSortOrder
(
s
etting
s
);
s
etting
s
->
treeView
=
false
;
if
(
field
==
ss
->
sortKey
)
{
Screen
Settings_invertSortOrder
(
ss
);
ss
->
treeView
=
false
;
}
else
{
reaction
|=
Action_setSortKey
(
settings
,
field
);
}
...
...
@@ -108,8 +110,8 @@ static HandlerResult MainPanel_eventHandler(Panel* super, int ch) {
}
if
(
reaction
&
HTOP_REDRAW_BAR
)
{
MainPanel_updateTreeFunctions
(
this
,
this
->
state
->
settings
->
treeView
);
IncSet_drawBar
(
this
->
inc
);
MainPanel_updateTreeFunctions
(
this
,
settings
->
ss
->
treeView
);
IncSet_drawBar
(
this
->
inc
,
CRT_colors
[
FUNCTION_BAR
]
);
}
if
(
reaction
&
HTOP_UPDATE_PANELHDR
)
{
ProcessList_printHeader
(
this
->
state
->
pl
,
Panel_getHeader
(
super
));
...
...
Process.c
View file @
187a035a
...
...
@@ -393,7 +393,8 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
attr
=
CRT_colors
[
PROCESS_THREAD
];
baseattr
=
CRT_colors
[
PROCESS_THREAD_BASENAME
];
}
if
(
!
this
->
settings
->
treeView
||
this
->
indent
==
0
)
{
ScreenSettings
*
ss
=
this
->
settings
->
ss
;
if
(
!
ss
->
treeView
||
this
->
indent
==
0
)
{
Process_writeCommand
(
this
,
attr
,
baseattr
,
str
);
return
;
}
else
{
...
...
@@ -414,7 +415,7 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
buf
+=
written
;
n
-=
written
;
}
const
char
*
draw
=
CRT_treeStr
[
lastItem
?
(
this
->
setting
s
->
direction
==
1
?
TREE_STR_BEND
:
TREE_STR_TEND
)
:
TREE_STR_RTEE
];
const
char
*
draw
=
CRT_treeStr
[
lastItem
?
(
s
s
->
direction
==
1
?
TREE_STR_BEND
:
TREE_STR_TEND
)
:
TREE_STR_RTEE
];
xSnprintf
(
buf
,
n
,
"%s%s "
,
draw
,
this
->
showChildren
?
CRT_treeStr
[
TREE_STR_SHUT
]
:
CRT_treeStr
[
TREE_STR_OPEN
]
);
RichString_append
(
str
,
CRT_colors
[
PROCESS_TREE
],
buffer
);
Process_writeCommand
(
this
,
attr
,
baseattr
,
str
);
...
...
@@ -485,7 +486,7 @@ void Process_writeField(Process* this, RichString* str, ProcessField field) {
void
Process_display
(
Object
*
cast
,
RichString
*
out
)
{
Process
*
this
=
(
Process
*
)
cast
;
ProcessField
*
fields
=
this
->
settings
->
fields
;
ProcessField
*
fields
=
this
->
settings
->
ss
->
fields
;
RichString_prune
(
out
);
for
(
int
i
=
0
;
fields
[
i
];
i
++
)
As_Process
(
this
)
->
writeField
(
this
,
out
,
fields
[
i
]);
...
...
@@ -555,14 +556,15 @@ long Process_pidCompare(const void* v1, const void* v2) {
long
Process_compare
(
const
void
*
v1
,
const
void
*
v2
)
{
Process
*
p1
,
*
p2
;
Settings
*
settings
=
((
Process
*
)
v1
)
->
settings
;
if
(
settings
->
direction
==
1
)
{
ScreenSettings
*
ss
=
settings
->
ss
;
if
(
ss
->
direction
==
1
)
{
p1
=
(
Process
*
)
v1
;
p2
=
(
Process
*
)
v2
;
}
else
{
p2
=
(
Process
*
)
v1
;
p1
=
(
Process
*
)
v2
;
}
switch
(
s
etting
s
->
sortKey
)
{
switch
(
ss
->
sortKey
)
{
case
PERCENT_CPU
:
return
(
p2
->
percent_cpu
>
p1
->
percent_cpu
?
1
:
-
1
);
case
PERCENT_MEM
:
...
...
ProcessList.c
View file @
187a035a
...
...
@@ -124,14 +124,15 @@ void ProcessList_setPanel(ProcessList* this, Panel* panel) {
void
ProcessList_printHeader
(
ProcessList
*
this
,
RichString
*
header
)
{
RichString_prune
(
header
);
ProcessField
*
fields
=
this
->
settings
->
fields
;
ProcessField
*
fields
=
this
->
settings
->
ss
->
fields
;
for
(
int
i
=
0
;
fields
[
i
];
i
++
)
{
const
char
*
field
=
Process_fields
[
fields
[
i
]].
title
;
unsigned
int
key
=
fields
[
i
];
const
char
*
field
=
Process_fields
[
key
].
title
;
if
(
!
field
)
field
=
"- "
;
i
f
(
!
this
->
settings
->
treeView
&&
this
->
settings
->
sortKey
==
fields
[
i
]
)
RichString_append
(
header
,
CRT_colors
[
PANEL_SELECTION_FOCUS
]
,
field
);
else
RichString_append
(
header
,
CRT_
color
s
[
PANEL_HEADER_FOCUS
]
,
field
);
i
nt
color
=
(
!
this
->
settings
->
ss
->
treeView
&&
this
->
settings
->
ss
->
sortKey
==
key
)
?
CRT_colors
[
PANEL_SELECTION_FOCUS
]
:
CRT_colors
[
PANEL_HEADER_FOCUS
];
RichString_append
(
header
,
color
,
field
);
}
}
...
...
@@ -200,19 +201,19 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i
}
void
ProcessList_sort
(
ProcessList
*
this
)
{
if
(
!
this
->
settings
->
treeView
)
{
if
(
!
this
->
settings
->
ss
->
treeView
)
{
Vector_insertionSort
(
this
->
processes
);
}
else
{
// Save settings
int
direction
=
this
->
settings
->
direction
;
int
sortKey
=
this
->
settings
->
sortKey
;
int
direction
=
this
->
settings
->
ss
->
direction
;
int
sortKey
=
this
->
settings
->
ss
->
sortKey
;
// Sort by PID
this
->
settings
->
sortKey
=
PID
;
this
->
settings
->
direction
=
1
;
this
->
settings
->
ss
->
sortKey
=
PID
;
this
->
settings
->
ss
->
direction
=
1
;
Vector_quickSort
(
this
->
processes
);
// Restore settings
this
->
settings
->
sortKey
=
sortKey
;
this
->
settings
->
direction
=
direction
;
this
->
settings
->
ss
->
sortKey
=
sortKey
;
this
->
settings
->
ss
->
direction
=
direction
;
int
vsize
=
Vector_size
(
this
->
processes
);
// Find all processes whose parent is not visible
int
size
;
...
...
@@ -271,7 +272,7 @@ void ProcessList_sort(ProcessList* this) {
ProcessField
ProcessList_keyAt
(
ProcessList
*
this
,
int
at
)
{
int
x
=
0
;
ProcessField
*
fields
=
this
->
settings
->
fields
;
ProcessField
*
fields
=
this
->
settings
->
ss
->
fields
;
ProcessField
field
;
for
(
int
i
=
0
;
(
field
=
fields
[
i
]);
i
++
)
{
const
char
*
title
=
Process_fields
[
field
].
title
;
...
...
ScreenManager.c
View file @
187a035a
...
...
@@ -71,30 +71,46 @@ inline int ScreenManager_size(ScreenManager* this) {
}
void
ScreenManager_add
(
ScreenManager
*
this
,
Panel
*
item
,
int
size
)
{
ScreenManager_insert
(
this
,
item
,
size
,
Vector_size
(
this
->
panels
));
}
void
ScreenManager_insert
(
ScreenManager
*
this
,
Panel
*
item
,
int
size
,
int
idx
)
{
if
(
this
->
orientation
==
HORIZONTAL
)
{
int
lastX
=
0
;
if
(
this
->
panelCount
>
0
)
{
Panel
*
last
=
(
Panel
*
)
Vector_get
(
this
->
panels
,
this
->
panelCount
-
1
);
if
(
idx
>
0
)
{
Panel
*
last
=
(
Panel
*
)
Vector_get
(
this
->
panels
,
idx
-
1
);
lastX
=
last
->
x
+
last
->
w
+
1
;
}
int
height
=
LINES
-
this
->
y1
+
this
->
y2
;
if
(
size
>
0
)
{
Panel_resize
(
item
,
size
,
height
);
}
else
{
Panel_resize
(
item
,
COLS
-
this
->
x1
+
this
->
x2
-
lastX
,
height
);
if
(
size
<=
0
)
{
size
=
COLS
-
this
->
x1
+
this
->
x2
-
lastX
;
}
Panel_resize
(
item
,
size
,
height
);
Panel_move
(
item
,
lastX
,
this
->
y1
);
if
(
idx
<
this
->
panelCount
)
{
for
(
int
i
=
idx
+
1
;
i
<=
this
->
panelCount
;
i
++
)
{
Panel
*
p
=
(
Panel
*
)
Vector_get
(
this
->
panels
,
i
);
Panel_move
(
p
,
p
->
x
+
size
,
p
->
y
);
}
}
}
// TODO: VERTICAL
Vector_
add
(
this
->
panels
,
item
);
Vector_
insert
(
this
->
panels
,
idx
,
item
);
item
->
needsRedraw
=
true
;
this
->
panelCount
++
;
}
Panel
*
ScreenManager_remove
(
ScreenManager
*
this
,
int
idx
)
{
assert
(
this
->
panelCount
>
idx
);
int
w
=
((
Panel
*
)
Vector_get
(
this
->
panels
,
idx
))
->
w
;
Panel
*
panel
=
(
Panel
*
)
Vector_remove
(
this
->
panels
,
idx
);
this
->
panelCount
--
;
if
(
idx
<
this
->
panelCount
)
{
for
(
int
i
=
idx
;
i
<
this
->
panelCount
;
i
++
)
{
Panel
*
p
=
(
Panel
*
)
Vector_get
(
this
->
panels
,
i
);
Panel_move
(
p
,
p
->
x
-
w
,
p
->
y
);
}
}
return
panel
;
}
...
...
@@ -131,7 +147,7 @@ static void checkRecalculation(ScreenManager* this, double* oldTime, int* sortTi
if
(
*
rescan
)
{
*
oldTime
=
newTime
;
ProcessList_scan
(
pl
);
if
(
*
sortTimeout
==
0
||
this
->
settings
->
treeView
)
{
if
(
*
sortTimeout
==
0
||
this
->
settings
->
ss
->
treeView
)
{
ProcessList_sort
(
pl
);
*
sortTimeout
=
1
;
}
...
...
ScreenManager.h
View file @
187a035a
...
...
@@ -43,6 +43,8 @@ extern int ScreenManager_size(ScreenManager* this);
void
ScreenManager_add
(
ScreenManager
*
this
,
Panel
*
item
,
int
size
);
void
ScreenManager_insert
(
ScreenManager
*
this
,
Panel
*
item
,
int
size
,
int
idx
);
Panel
*
ScreenManager_remove
(
ScreenManager
*
this
,
int
idx
);
void
ScreenManager_resize
(
ScreenManager
*
this
,
int
x1
,
int
y1
,
int
x2
,
int
y2
);
...
...
ScreensPanel.c
View file @
187a035a
...
...
@@ -9,7 +9,6 @@ in the source distribution for its full text.
#include "Platform.h"
#include "StringUtils.h"
#include "ListItem.h"
#include "CRT.h"
#include <assert.h>
...
...
@@ -19,7 +18,10 @@ in the source distribution for its full text.
/*{
#include "Panel.h"
#include "ScreenManager.h"
#include "ColumnsPanel.h"
#include "Settings.h"
#include "ListItem.h"
#ifndef SCREEN_NAME_LEN
#define SCREEN_NAME_LEN 20
...
...
@@ -27,8 +29,10 @@ in the source distribution for its full text.
typedef struct ScreensPanel_ {
Panel super;
ScreenManager* scr;
Settings* settings;
ColumnsPanel* columns;
char buffer[SCREEN_NAME_LEN + 1];
char* saved;
int cursor;
...
...
@@ -36,9 +40,27 @@ typedef struct ScreensPanel_ {
bool renaming;
} ScreensPanel;
typedef struct ScreenListItem_ {
ListItem super;
ScreenSettings* ss;
} ScreenListItem;
}*/
static
const
char
*
const
ScreensFunctions
[]
=
{
" "
,
"Rename"
,
" "
,
" "
,
" "
,
" "
,
"MoveUp"
,
"MoveDn"
,
"Remove"
,
"Done "
,
NULL
};
ObjectClass
ScreenListItem_class
=
{
.
display
=
ListItem_display
,
.
delete
=
ListItem_delete
,
.
compare
=
ListItem_compare
};
ScreenListItem
*
ScreenListItem_new
(
const
char
*
value
,
int
key
,
ScreenSettings
*
ss
)
{
ScreenListItem
*
this
=
AllocThis
(
ScreenListItem
);
ListItem_init
((
ListItem
*
)
this
,
value
,
key
);
this
->
ss
=
ss
;
return
this
;
}
static
const
char
*
const
ScreensFunctions
[]
=
{
" "
,
"Rename"
,
" "
,
" "
,
"New "
,
" "
,
"MoveUp"
,
"MoveDn"
,
"Remove"
,
"Done "
,
NULL
};
static
void
ScreensPanel_delete
(
Object
*
object
)
{
Panel
*
super
=
(
Panel
*
)
object
;
...
...
@@ -81,6 +103,7 @@ static HandlerResult ScreensPanel_eventHandlerRenaming(Panel* super, int ch) {
this
->
renaming
=
false
;
super
->
cursorOn
=
false
;
Panel_setSelectionColor
(
super
,
CRT_colors
[
PANEL_SELECTION_FOCUS
]);
ScreensPanel_update
(
super
);
break
;
}
case
27
:
// Esc
...
...
@@ -94,11 +117,10 @@ static HandlerResult ScreensPanel_eventHandlerRenaming(Panel* super, int ch) {
}
}
}
ScreensPanel_update
(
super
);
return
HANDLED
;
}
void
startRenaming
(
Panel
*
super
)
{
static
void
startRenaming
(
Panel
*
super
)
{
ScreensPanel
*
const
this
=
(
ScreensPanel
*
)
super
;
ListItem
*
item
=
(
ListItem
*
)
Panel_getSelected
(
super
);
...
...
@@ -115,10 +137,25 @@ void startRenaming(Panel* super) {
Panel_setCursorToSelection
(
super
);
}
static
void
rebuildSettingsArray
(
Panel
*
super
)
{
ScreensPanel
*
const
this
=
(
ScreensPanel
*
)
super
;
int
n
=
Panel_size
(
super
);
free
(
this
->
settings
->
screens
);
this
->
settings
->
screens
=
xMalloc
(
sizeof
(
ScreenSettings
*
)
*
(
n
+
1
));
this
->
settings
->
screens
[
n
]
=
NULL
;
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
ScreenListItem
*
item
=
(
ScreenListItem
*
)
Panel_get
(
super
,
i
);
this
->
settings
->
screens
[
i
]
=
item
->
ss
;
}
}
static
HandlerResult
ScreensPanel_eventHandlerNormal
(
Panel
*
super
,
int
ch
)
{
ScreensPanel
*
const
this
=
(
ScreensPanel
*
)
super
;
int
selected
=
Panel_getSelectedIndex
(
super
);
ScreenListItem
*
oldFocus
=
(
ScreenListItem
*
)
Panel_getSelected
(
super
);
bool
shouldRebuildArray
=
false
;
HandlerResult
result
=
IGNORED
;
switch
(
ch
)
{
case
0x0a
:
...
...
@@ -133,27 +170,39 @@ static HandlerResult ScreensPanel_eventHandlerNormal(Panel* super, int ch) {
result
=
HANDLED
;
break
;
}
case
EVENT_SET_SELECTED
:
result
=
HANDLED
;
break
;
case
KEY_NPAGE
:
case
KEY_PPAGE
:
case
KEY_HOME
:
case
KEY_END
:
{
Panel_onKey
(
super
,
ch
);
break
;
}
case
KEY_F
(
2
):
case
0x12
:
/* Ctrl+R */
case
KEY_CTRL
(
'R'
):
{
startRenaming
(
super
);
result
=
HANDLED
;
break
;
}
case
KEY_F
(
5
):
case
0x0e
:
/* Ctrl+N */
case
KEY_CTRL
(
'N'
):
{
ListItem
*
item
=
ListItem_new
(
""
,
0
);
int
idx
=
Panel_getSelectedIndex
(
super
);
Panel_insert
(
super
,
idx
+
1
,
(
Object
*
)
item
);
Panel_setSelected
(
super
,
idx
+
1
);
startRenaming
(
super
);
shouldRebuildArray
=
true
;
result
=
HANDLED
;
break
;
}
case
KEY_UP
:
{
if
(
!
this
->
moving
)
{
Panel_onKey
(
super
,
ch
);
break
;
}
/* else fallthrough */
...
...
@@ -163,12 +212,14 @@ static HandlerResult ScreensPanel_eventHandlerNormal(Panel* super, int ch) {
case
'-'
:
{
Panel_moveSelectedUp
(
super
);
shouldRebuildArray
=
true
;
result
=
HANDLED
;
break
;
}
case
KEY_DOWN
:
{
if
(
!
this
->
moving
)
{
Panel_onKey
(
super
,
ch
);
break
;
}
/* else fallthrough */
...
...
@@ -178,13 +229,17 @@ static HandlerResult ScreensPanel_eventHandlerNormal(Panel* super, int ch) {
case
'+'
:
{
Panel_moveSelectedDown
(
super
);
shouldRebuildArray
=
true
;
result
=
HANDLED
;
break
;
}
case
KEY_F
(
9
):
//case KEY_DC:
{
Panel_remove
(
super
,
selected
);
if
(
Panel_size
(
super
)
>
1
)
{
Panel_remove
(
super
,
selected
);
}
shouldRebuildArray
=
true
;
result
=
HANDLED
;
break
;
}
...
...
@@ -197,6 +252,14 @@ static HandlerResult ScreensPanel_eventHandlerNormal(Panel* super, int ch) {
break
;
}
}
ScreenListItem
*
newFocus
=
(
ScreenListItem
*
)
Panel_getSelected
(
super
);
if
(
oldFocus
!=
newFocus
)
{
ColumnsPanel_fill
(
this
->
columns
,
newFocus
->
ss
);
result
=
HANDLED
;
}
if
(
shouldRebuildArray
)
{
rebuildSettingsArray
(
super
);
}
if
(
result
==
HANDLED
)
ScreensPanel_update
(
super
);
return
result
;
...
...
@@ -227,16 +290,17 @@ ScreensPanel* ScreensPanel_new(Settings* settings) {
Panel_init
(
super
,
1
,
1
,
1
,
1
,
Class
(
ListItem
),
true
,
fuBar
);
this
->
settings
=
settings
;
this
->
columns
=
ColumnsPanel_new
(
settings
->
screens
[
0
],
&
(
settings
->
changed
));
this
->
moving
=
false
;
this
->
renaming
=
false
;
super
->
cursorOn
=
false
;
this
->
cursor
=
0
;
Panel_setHeader
(
super
,
"Screens"
);
char
**
screens
=
this
->
settings
->
s
creens
;
for
(;
*
screens
;
screens
++
)
{
char
*
name
=
*
screens
;
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
name
,
0
));
for
(
unsigned
int
i
=
0
;
i
<
settings
->
nS
creens
;
i
++
)
{
ScreenSettings
*
ss
=
settings
->
screens
[
i
];
char
*
name
=
ss
->
name
;
Panel_add
(
super
,
(
Object
*
)
Screen
ListItem_new
(
name
,
i
,
ss
));
}
return
this
;
}
...
...
@@ -248,7 +312,7 @@ void ScreensPanel_update(Panel* super) {
this
->
settings
->
screens
=
xRealloc
(
this
->
settings
->
screens
,
sizeof
(
char
*
)
*
(
size
+
1
));
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
char
*
name
=
((
ListItem
*
)
Panel_get
(
super
,
i
))
->
value
;
this
->
settings
->
screens
[
i
]
=
xStrdup
(
name
);
this
->
settings
->
screens
[
i
]
->
name
=
xStrdup
(
name
);
}
this
->
settings
->
screens
[
size
]
=
NULL
;
}
ScreensPanel.h
View file @
187a035a
...
...
@@ -10,7 +10,10 @@ in the source distribution for its full text.
*/
#include "Panel.h"
#include "ScreenManager.h"
#include "ColumnsPanel.h"
#include "Settings.h"
#include "ListItem.h"
#ifndef SCREEN_NAME_LEN
#define SCREEN_NAME_LEN 20
...
...
@@ -18,8 +21,10 @@ in the source distribution for its full text.
typedef
struct
ScreensPanel_
{
Panel
super
;
ScreenManager
*
scr
;
Settings
*
settings
;
ColumnsPanel
*
columns
;
char
buffer
[
SCREEN_NAME_LEN
+
1
];
char
*
saved
;
int
cursor
;
...
...
@@ -27,8 +32,15 @@ typedef struct ScreensPanel_ {
bool
renaming
;
}
ScreensPanel
;
typedef
struct
ScreenListItem_
{
ListItem
super
;
ScreenSettings
*
ss
;
}
ScreenListItem
;
extern
ObjectClass
ScreenListItem_class
;
void
startRenaming
(
Panel
*
super
);
ScreenListItem
*
ScreenListItem_new
(
const
char
*
value
,
int
key
,
ScreenSettings
*
ss
);
extern
PanelClass
ScreensPanel_class
;
...
...
Settings.c
View file @
187a035a
...
...
@@ -29,26 +29,33 @@ typedef struct {
int* modes;
} MeterColumnSettings;
typedef struct {
char* name;
ProcessField* fields;
int flags;
int direction;
ProcessField sortKey;
bool treeView;
} ScreenSettings;
typedef struct Settings_ {
char* filename;
MeterColumnSettings
c
olumns[2];
MeterColumnSettings
meterC
olumns[2];
char** screens;
int nScreens;
ScreenSettings** screens;
unsigned int nScreens;
unsigned int ssIndex;
ScreenSettings* ss;
ProcessField* fields;
int flags;
int colorScheme;
int delay;
int cpuCount;
int direction;
ProcessField sortKey;
bool countCPUsFromZero;
bool detailedCPUTime;
bool treeView;
bool showProgramPath;
bool hideThreads;
bool shadowOtherUsers;
...
...
@@ -80,8 +87,10 @@ static void writeList(FILE* fd, char** list, int len) {
fprintf
(
fd
,
"
\n
"
);
}
static
char
**
readQuotedList
(
char
*
line
,
int
*
size
)
{
*
size
=
0
;
/*
static char** readQuotedList(char* line) {
int n = 0;
char** list = xCalloc(sizeof(char*), 1);
int start = 0;
for (;;) {
...
...
@@ -100,50 +109,51 @@ static char** readQuotedList(char* line, int* size) {
char* item = xMalloc(len + 1);
strncpy(item, line + start, len);
item[len] = '\0';
list
[
*
size
]
=
item
;
(
*
size
)
++
;
list
=
xRealloc
(
list
,
sizeof
(
char
*
)
*
(
*
size
+
1
));
list[
n
] = item;
n
++;
list = xRealloc(list, sizeof(char*) * (
n
+ 1));
start = close + 1;
}
list
[
*
size
]
=
NULL
;
list[
n
] = NULL;
return list;
}
static
void
writeQuotedList
(
FILE
*
fd
,
char
**
list
,
int
len
)
{
static void writeQuotedList(FILE* fd, char** list) {
const char* sep = "";
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
for (int i = 0;
list[i]
; i++) {
fprintf(fd, "%s\"%s\"", sep, list[i]);
sep = " ";
}
fprintf(fd, "\n");
}
*/
void
Settings_delete
(
Settings
*
this
)
{
free
(
this
->
filename
);
free
(
this
->
fields
);
for
(
unsigned
int
i
=
0
;
i
<
(
sizeof
(
this
->
columns
)
/
sizeof
(
MeterColumnSettings
));
i
++
)
{
String_freeArray
(
this
->
columns
[
i
].
names
);
free
(
this
->
columns
[
i
].
modes
);
for
(
unsigned
int
i
=
0
;
i
<
(
sizeof
(
this
->
meterColumns
)
/
sizeof
(
MeterColumnSettings
));
i
++
)
{
String_freeArray
(
this
->
meterColumns
[
i
].
names
);
free
(
this
->
meterColumns
[
i
].
modes
);
}
if
(
this
->
screens
)
{
for
(
unsigned
int
i
=
0
;
this
->
screens
[
i
];
i
++
)
{
free
(
this
->
screens
[
i
]
->
name
);
free
(
this
->
screens
[
i
]
->
fields
);
}
free
(
this
->
screens
);
}
String_freeArray
(
this
->
screens
);
free
(
this
);
}
static
void
Settings_readMeters
(
Settings
*
this
,
char
*
line
,
int
column
)
{
static
void
Settings_readMeters
(
Settings
*
this
,
char
*
line
,
int
side
)
{
char
*
trim
=
String_trim
(
line
);
int
nIds
;
char
**
ids
=
String_split
(
trim
,
' '
,
&
nIds
);
free
(
trim
);
this
->
c
olumns
[
column
].
names
=
ids
;
this
->
meterC
olumns
[
side
].
names
=
ids
;
}
static
void
Settings_readScreens
(
Settings
*
this
,
char
*
line
)
{
char
*
trim
=
String_trim
(
line
);
this
->
screens
=
readQuotedList
(
trim
,
&
(
this
->
nScreens
));
free
(
trim
);
}
static
void
Settings_readMeterModes
(
Settings
*
this
,
char
*
line
,
int
column
)
{
static
void
Settings_readMeterModes
(
Settings
*
this
,
char
*
line
,
int
side
)
{
char
*
trim
=
String_trim
(
line
);
int
nIds
;
char
**
ids
=
String_split
(
trim
,
' '
,
&
nIds
);
...
...
@@ -152,13 +162,13 @@ static void Settings_readMeterModes(Settings* this, char* line, int column) {
for
(
int
i
=
0
;
ids
[
i
];
i
++
)
{
len
++
;
}
this
->
c
olumns
[
column
].
len
=
len
;
this
->
meterC
olumns
[
side
].
len
=
len
;
int
*
modes
=
xCalloc
(
len
,
sizeof
(
int
));
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
modes
[
i
]
=
atoi
(
ids
[
i
]);
}
String_freeArray
(
ids
);
this
->
c
olumns
[
column
].
modes
=
modes
;
this
->
meterC
olumns
[
side
].
modes
=
modes
;
}
static
void
Settings_defaultMeters
(
Settings
*
this
)
{
...
...
@@ -167,44 +177,54 @@ static void Settings_defaultMeters(Settings* this) {
sizes
[
1
]
++
;
}
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
this
->
c
olumns
[
i
].
names
=
xCalloc
(
sizes
[
i
]
+
1
,
sizeof
(
char
*
));
this
->
c
olumns
[
i
].
modes
=
xCalloc
(
sizes
[
i
],
sizeof
(
int
));
this
->
c
olumns
[
i
].
len
=
sizes
[
i
];
this
->
meterC
olumns
[
i
].
names
=
xCalloc
(
sizes
[
i
]
+
1
,
sizeof
(
char
*
));
this
->
meterC
olumns
[
i
].
modes
=
xCalloc
(
sizes
[
i
],
sizeof
(
int
));
this
->
meterC
olumns
[
i
].
len
=
sizes
[
i
];
}
int
r
=
0
;
if
(
this
->
cpuCount
>
8
)
{
this
->
c
olumns
[
0
].
names
[
0
]
=
xStrdup
(
"LeftCPUs2"
);
this
->
c
olumns
[
0
].
modes
[
0
]
=
BAR_METERMODE
;
this
->
c
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"RightCPUs2"
);
this
->
c
olumns
[
1
].
modes
[
r
++
]
=
BAR_METERMODE
;
this
->
meterC
olumns
[
0
].
names
[
0
]
=
xStrdup
(
"LeftCPUs2"
);
this
->
meterC
olumns
[
0
].
modes
[
0
]
=
BAR_METERMODE
;
this
->
meterC
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"RightCPUs2"
);
this
->
meterC
olumns
[
1
].
modes
[
r
++
]
=
BAR_METERMODE
;
}
else
if
(
this
->
cpuCount
>
4
)
{
this
->
c
olumns
[
0
].
names
[
0
]
=
xStrdup
(
"LeftCPUs"
);
this
->
c
olumns
[
0
].
modes
[
0
]
=
BAR_METERMODE
;
this
->
c
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"RightCPUs"
);
this
->
c
olumns
[
1
].
modes
[
r
++
]
=
BAR_METERMODE
;
this
->
meterC
olumns
[
0
].
names
[
0
]
=
xStrdup
(
"LeftCPUs"
);
this
->
meterC
olumns
[
0
].
modes
[
0
]
=
BAR_METERMODE
;
this
->
meterC
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"RightCPUs"
);
this
->
meterC
olumns
[
1
].
modes
[
r
++
]
=
BAR_METERMODE
;
}
else
{
this
->
c
olumns
[
0
].
names
[
0
]
=
xStrdup
(
"AllCPUs"
);
this
->
c
olumns
[
0
].
modes
[
0
]
=
BAR_METERMODE
;
this
->
meterC
olumns
[
0
].
names
[
0
]
=
xStrdup
(
"AllCPUs"
);
this
->
meterC
olumns
[
0
].
modes
[
0
]
=
BAR_METERMODE
;
}
this
->
c
olumns
[
0
].
names
[
1
]
=
xStrdup
(
"Memory"
);
this
->
c
olumns
[
0
].
modes
[
1
]
=
BAR_METERMODE
;
this
->
c
olumns
[
0
].
names
[
2
]
=
xStrdup
(
"Swap"
);
this
->
c
olumns
[
0
].
modes
[
2
]
=
BAR_METERMODE
;
this
->
meterC
olumns
[
0
].
names
[
1
]
=
xStrdup
(
"Memory"
);
this
->
meterC
olumns
[
0
].
modes
[
1
]
=
BAR_METERMODE
;
this
->
meterC
olumns
[
0
].
names
[
2
]
=
xStrdup
(
"Swap"
);
this
->
meterC
olumns
[
0
].
modes
[
2
]
=
BAR_METERMODE
;
this
->
c
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"Tasks"
);
this
->
c
olumns
[
1
].
modes
[
r
++
]
=
TEXT_METERMODE
;
this
->
c
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"LoadAverage"
);
this
->
c
olumns
[
1
].
modes
[
r
++
]
=
TEXT_METERMODE
;
this
->
c
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"Uptime"
);
this
->
c
olumns
[
1
].
modes
[
r
++
]
=
TEXT_METERMODE
;
this
->
meterC
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"Tasks"
);
this
->
meterC
olumns
[
1
].
modes
[
r
++
]
=
TEXT_METERMODE
;
this
->
meterC
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"LoadAverage"
);
this
->
meterC
olumns
[
1
].
modes
[
r
++
]
=
TEXT_METERMODE
;
this
->
meterC
olumns
[
1
].
names
[
r
]
=
xStrdup
(
"Uptime"
);
this
->
meterC
olumns
[
1
].
modes
[
r
++
]
=
TEXT_METERMODE
;
}
static
void
Settings_defaultScreens
(
Settings
*
this
)
{
this
->
screens
=
xMalloc
(
sizeof
(
char
*
)
*
3
);
this
->
screens
[
0
]
=
xStrdup
(
"Overview"
);
this
->
screens
[
1
]
=
xStrdup
(
"I/O"
);
this
->
screens
[
2
]
=
NULL
;
static
int
toFieldIndex
(
const
char
*
str
)
{
if
(
isdigit
(
str
[
0
]))
{
// This "+1" is for compatibility with the older enum format.
int
id
=
atoi
(
str
)
+
1
;
if
(
Process_fields
[
id
].
name
&&
id
<
Platform_numberOfFields
)
{
return
id
;
}
}
else
{
for
(
int
p
=
1
;
p
<
LAST_PROCESSFIELD
;
p
++
)
{
if
(
Process_fields
[
p
].
name
&&
strcmp
(
Process_fields
[
p
].
name
,
str
)
==
0
)
{
return
p
;
}
}
}
return
-
1
;
}
static
void
readFields
(
ProcessField
*
fields
,
int
*
flags
,
const
char
*
line
)
{
...
...
@@ -215,11 +235,10 @@ static void readFields(ProcessField* fields, int* flags, const char* line) {
int
i
,
j
;
*
flags
=
0
;
for
(
j
=
0
,
i
=
0
;
i
<
Platform_numberOfFields
&&
ids
[
i
];
i
++
)
{
// This "+1" is for compatibility with the older enum format.
int
id
=
atoi
(
ids
[
i
])
+
1
;
if
(
id
>
0
&&
Process_fields
[
id
].
name
&&
id
<
Platform_numberOfFields
)
{
fields
[
j
]
=
id
;
*
flags
|=
Process_fields
[
id
].
flags
;
int
idx
=
toFieldIndex
(
ids
[
i
]);
if
(
idx
!=
-
1
)
{
fields
[
j
]
=
idx
;
*
flags
|=
Process_fields
[
idx
].
flags
;
j
++
;
}
}
...
...
@@ -227,6 +246,25 @@ static void readFields(ProcessField* fields, int* flags, const char* line) {
String_freeArray
(
ids
);
}
static
void
Settings_readScreen
(
Settings
*
this
,
const
char
*
name
,
const
char
*
line
)
{
ScreenSettings
*
ss
=
xCalloc
(
sizeof
(
ScreenSettings
),
1
);
ss
->
name
=
xStrdup
(
name
);
ss
->
fields
=
xCalloc
(
Platform_numberOfFields
+
1
,
sizeof
(
ProcessField
));
ss
->
flags
=
0
;
ss
->
direction
=
1
;
ss
->
treeView
=
0
;
readFields
(
ss
->
fields
,
&
(
ss
->
flags
),
line
);
this
->
screens
[
this
->
nScreens
]
=
ss
;
this
->
nScreens
++
;
this
->
screens
=
xRealloc
(
this
->
screens
,
sizeof
(
ScreenSettings
*
)
*
(
this
->
nScreens
+
1
));
this
->
screens
[
this
->
nScreens
]
=
NULL
;
}
static
void
Settings_defaultScreens
(
Settings
*
this
)
{
Settings_readScreen
(
this
,
"Default"
,
"PID USER PRIORITY NICE M_SIZE M_RESIDENT M_SHARE STATE PERCENT_CPU PERCENT_MEM TIME Command"
);
Settings_readScreen
(
this
,
"I/O"
,
"PID IO_PRIORITY USER IO_READ_RATE IO_WRITE_RATE Command"
);
}
static
bool
Settings_read
(
Settings
*
this
,
const
char
*
fileName
)
{
FILE
*
fd
;
...
...
@@ -237,6 +275,9 @@ static bool Settings_read(Settings* this, const char* fileName) {
return
false
;
bool
readMeters
=
false
;
ProcessField
*
legacyFields
=
xCalloc
(
Platform_numberOfFields
+
1
,
sizeof
(
ProcessField
));
int
legacyFlags
;
bool
legacyFieldsRead
=
false
;
for
(;;)
{
char
*
line
=
String_readLine
(
fd
);
if
(
!
line
)
{
...
...
@@ -250,14 +291,8 @@ static bool Settings_read(Settings* this, const char* fileName) {
continue
;
}
if
(
String_eq
(
option
[
0
],
"fields"
))
{
readFields
(
this
->
fields
,
&
(
this
->
flags
),
option
[
1
]);
}
else
if
(
String_eq
(
option
[
0
],
"sort_key"
))
{
// This "+1" is for compatibility with the older enum format.
this
->
sortKey
=
atoi
(
option
[
1
])
+
1
;
}
else
if
(
String_eq
(
option
[
0
],
"sort_direction"
))
{
this
->
direction
=
atoi
(
option
[
1
]);
}
else
if
(
String_eq
(
option
[
0
],
"tree_view"
))
{
this
->
treeView
=
atoi
(
option
[
1
]);
readFields
(
legacyFields
,
&
legacyFlags
,
option
[
1
]);
legacyFieldsRead
=
true
;
}
else
if
(
String_eq
(
option
[
0
],
"hide_threads"
))
{
this
->
hideThreads
=
atoi
(
option
[
1
]);
}
else
if
(
String_eq
(
option
[
0
],
"hide_kernel_threads"
))
{
...
...
@@ -306,14 +341,31 @@ static bool Settings_read(Settings* this, const char* fileName) {
}
else
if
(
String_eq
(
option
[
0
],
"right_meter_modes"
))
{
Settings_readMeterModes
(
this
,
option
[
1
],
1
);
readMeters
=
true
;
}
else
if
(
String_eq
(
option
[
0
],
"screens"
))
{
Settings_readScreens
(
this
,
option
[
1
]);
}
else
if
(
strncmp
(
option
[
0
],
"screen:"
,
7
)
==
0
)
{
Settings_readScreen
(
this
,
option
[
0
]
+
7
,
option
[
1
]);
}
else
if
(
String_eq
(
option
[
0
],
".tree_view"
))
{
if
(
this
->
nScreens
>
0
)
{
this
->
screens
[
this
->
nScreens
-
1
]
->
treeView
=
atoi
(
option
[
1
]);
}
}
else
if
(
String_eq
(
option
[
0
],
".sort_direction"
))
{
if
(
this
->
nScreens
>
0
)
{
this
->
screens
[
this
->
nScreens
-
1
]
->
direction
=
atoi
(
option
[
1
]);
}
}
else
if
(
String_eq
(
option
[
0
],
".sort_key"
))
{
if
(
this
->
nScreens
>
0
)
{
this
->
screens
[
this
->
nScreens
-
1
]
->
sortKey
=
toFieldIndex
(
option
[
1
]);
}
}
String_freeArray
(
option
);
}
fclose
(
fd
);
if
(
!
this
->
s
creens
)
{
if
(
this
->
nS
creens
==
0
)
{
Settings_defaultScreens
(
this
);
if
(
legacyFieldsRead
)
{
free
(
this
->
screens
[
0
]
->
fields
);
this
->
screens
[
0
]
->
fields
=
legacyFields
;
this
->
screens
[
0
]
->
flags
=
legacyFlags
;
}
}
if
(
!
readMeters
)
{
Settings_defaultMeters
(
this
);
...
...
@@ -321,25 +373,28 @@ static bool Settings_read(Settings* this, const char* fileName) {
return
true
;
}
static
void
writeFields
(
FILE
*
fd
,
ProcessField
*
fields
,
const
char
*
name
)
{
fprintf
(
fd
,
"%s="
,
name
);
static
void
writeFields
(
FILE
*
fd
,
ProcessField
*
fields
,
bool
byName
)
{
const
char
*
sep
=
""
;
for
(
int
i
=
0
;
fields
[
i
];
i
++
)
{
// This "-1" is for compatibility with the older enum format.
fprintf
(
fd
,
"%s%d"
,
sep
,
(
int
)
fields
[
i
]
-
1
);
if
(
byName
)
{
fprintf
(
fd
,
"%s%s"
,
sep
,
Process_fields
[
fields
[
i
]].
name
);
}
else
{
// This " - 1" is for compatibility with the older enum format.
fprintf
(
fd
,
"%s%d"
,
sep
,
(
int
)
fields
[
i
]
-
1
);
}
sep
=
" "
;
}
fprintf
(
fd
,
"
\n
"
);
}
static
void
writeMeters
(
Settings
*
this
,
FILE
*
fd
,
int
column
)
{
writeList
(
fd
,
this
->
c
olumns
[
column
].
names
,
this
->
c
olumns
[
column
].
len
);
static
void
writeMeters
(
Settings
*
this
,
FILE
*
fd
,
int
side
)
{
writeList
(
fd
,
this
->
meterC
olumns
[
side
].
names
,
this
->
meterC
olumns
[
side
].
len
);
}
static
void
writeMeterModes
(
Settings
*
this
,
FILE
*
fd
,
int
column
)
{
static
void
writeMeterModes
(
Settings
*
this
,
FILE
*
fd
,
int
side
)
{
const
char
*
sep
=
""
;
for
(
int
i
=
0
;
i
<
this
->
c
olumns
[
column
].
len
;
i
++
)
{
fprintf
(
fd
,
"%s%d"
,
sep
,
this
->
c
olumns
[
column
].
modes
[
i
]);
for
(
int
i
=
0
;
i
<
this
->
meterC
olumns
[
side
].
len
;
i
++
)
{
fprintf
(
fd
,
"%s%d"
,
sep
,
this
->
meterC
olumns
[
side
].
modes
[
i
]);
sep
=
" "
;
}
fprintf
(
fd
,
"
\n
"
);
...
...
@@ -357,10 +412,7 @@ bool Settings_write(Settings* this) {
}
fprintf
(
fd
,
"# Beware! This file is rewritten by htop when settings are changed in the interface.
\n
"
);
fprintf
(
fd
,
"# The parser is also very primitive, and not human-friendly.
\n
"
);
writeFields
(
fd
,
this
->
fields
,
"fields"
);
// This "-1" is for compatibility with the older enum format.
fprintf
(
fd
,
"sort_key=%d
\n
"
,
(
int
)
this
->
sortKey
-
1
);
fprintf
(
fd
,
"sort_direction=%d
\n
"
,
(
int
)
this
->
direction
);
fprintf
(
fd
,
"fields="
);
writeFields
(
fd
,
this
->
screens
[
0
]
->
fields
,
false
);
fprintf
(
fd
,
"hide_threads=%d
\n
"
,
(
int
)
this
->
hideThreads
);
fprintf
(
fd
,
"hide_kernel_threads=%d
\n
"
,
(
int
)
this
->
hideKernelThreads
);
fprintf
(
fd
,
"hide_userland_threads=%d
\n
"
,
(
int
)
this
->
hideUserlandThreads
);
...
...
@@ -370,7 +422,6 @@ bool Settings_write(Settings* this) {
fprintf
(
fd
,
"highlight_base_name=%d
\n
"
,
(
int
)
this
->
highlightBaseName
);
fprintf
(
fd
,
"highlight_megabytes=%d
\n
"
,
(
int
)
this
->
highlightMegabytes
);
fprintf
(
fd
,
"highlight_threads=%d
\n
"
,
(
int
)
this
->
highlightThreads
);
fprintf
(
fd
,
"tree_view=%d
\n
"
,
(
int
)
this
->
treeView
);
fprintf
(
fd
,
"header_margin=%d
\n
"
,
(
int
)
this
->
headerMargin
);
fprintf
(
fd
,
"detailed_cpu_time=%d
\n
"
,
(
int
)
this
->
detailedCPUTime
);
fprintf
(
fd
,
"cpu_count_from_zero=%d
\n
"
,
(
int
)
this
->
countCPUsFromZero
);
...
...
@@ -382,8 +433,16 @@ bool Settings_write(Settings* this) {
fprintf
(
fd
,
"left_meter_modes="
);
writeMeterModes
(
this
,
fd
,
0
);
fprintf
(
fd
,
"right_meters="
);
writeMeters
(
this
,
fd
,
1
);
fprintf
(
fd
,
"right_meter_modes="
);
writeMeterModes
(
this
,
fd
,
1
);
if
(
this
->
nScreens
>
0
)
{
fprintf
(
fd
,
"screens="
);
writeQuotedList
(
fd
,
this
->
screens
,
this
->
nScreens
);
if
(
this
->
screens
&&
this
->
screens
[
0
])
{
for
(
unsigned
int
i
=
0
;
i
<
this
->
nScreens
;
i
++
)
{
ScreenSettings
*
ss
=
this
->
screens
[
i
];
fprintf
(
fd
,
"screen:%s="
,
ss
->
name
);
writeFields
(
fd
,
ss
->
fields
,
true
);
fprintf
(
fd
,
".tree_view=%d
\n
"
,
(
int
)
ss
->
treeView
);
// This "-1" is for compatibility with the older enum format.
fprintf
(
fd
,
".sort_key=%d
\n
"
,
(
int
)
ss
->
sortKey
-
1
);
fprintf
(
fd
,
".sort_direction=%d
\n
"
,
(
int
)
ss
->
direction
);
}
}
fclose
(
fd
);
return
true
;
...
...
@@ -393,14 +452,11 @@ Settings* Settings_new(int cpuCount) {
Settings
*
this
=
xCalloc
(
1
,
sizeof
(
Settings
));
this
->
sortKey
=
PERCENT_CPU
;
this
->
direction
=
1
;
this
->
hideThreads
=
false
;
this
->
shadowOtherUsers
=
false
;
this
->
showThreadNames
=
false
;
this
->
hideKernelThreads
=
false
;
this
->
hideUserlandThreads
=
false
;
this
->
treeView
=
false
;
this
->
highlightBaseName
=
false
;
this
->
highlightMegabytes
=
false
;
this
->
detailedCPUTime
=
false
;
...
...
@@ -410,15 +466,8 @@ Settings* Settings_new(int cpuCount) {
this
->
showProgramPath
=
true
;
this
->
highlightThreads
=
true
;
this
->
fields
=
xCalloc
(
Platform_numberOfFields
+
1
,
sizeof
(
ProcessField
));
// TODO: turn 'fields' into a Vector,
// (and ProcessFields into proper objects).
this
->
flags
=
0
;
ProcessField
*
defaults
=
Platform_defaultFields
;
for
(
int
i
=
0
;
defaults
[
i
];
i
++
)
{
this
->
fields
[
i
]
=
defaults
[
i
];
this
->
flags
|=
Process_fields
[
defaults
[
i
]].
flags
;
}
this
->
screens
=
xCalloc
(
sizeof
(
ScreenSettings
*
),
1
);
this
->
nScreens
=
0
;
char
*
legacyDotfile
=
NULL
;
char
*
rcfile
=
getenv
(
"HTOPRC"
);
...
...
@@ -481,11 +530,15 @@ Settings* Settings_new(int cpuCount) {
this
->
headerMargin
=
true
;
}
}
this
->
ssIndex
=
0
;
this
->
ss
=
this
->
screens
[
this
->
ssIndex
];
free
(
legacyDotfile
);
return
this
;
}
void
Settings_invertSortOrder
(
Settings
*
this
)
{
void
Screen
Settings_invertSortOrder
(
Screen
Settings
*
this
)
{
if
(
this
->
direction
==
1
)
this
->
direction
=
-
1
;
else
...
...
Settings.h
View file @
187a035a
...
...
@@ -20,26 +20,33 @@ typedef struct {
int
*
modes
;
}
MeterColumnSettings
;
typedef
struct
{
char
*
name
;
ProcessField
*
fields
;
int
flags
;
int
direction
;
ProcessField
sortKey
;
bool
treeView
;
}
ScreenSettings
;
typedef
struct
Settings_
{
char
*
filename
;
MeterColumnSettings
c
olumns
[
2
];
MeterColumnSettings
meterC
olumns
[
2
];
char
**
screens
;
int
nScreens
;
ScreenSettings
**
screens
;
unsigned
int
nScreens
;
unsigned
int
ssIndex
;
ScreenSettings
*
ss
;
ProcessField
*
fields
;
int
flags
;
int
colorScheme
;
int
delay
;
int
cpuCount
;
int
direction
;
ProcessField
sortKey
;
bool
countCPUsFromZero
;
bool
detailedCPUTime
;
bool
treeView
;
bool
showProgramPath
;
bool
hideThreads
;
bool
shadowOtherUsers
;
...
...
@@ -61,12 +68,16 @@ typedef struct Settings_ {
#endif
/*
*/
void
Settings_delete
(
Settings
*
this
);
bool
Settings_write
(
Settings
*
this
);
Settings
*
Settings_new
(
int
cpuCount
);
void
Settings_invertSortOrder
(
Settings
*
this
);
void
Screen
Settings_invertSortOrder
(
Screen
Settings
*
this
);
#endif
htop.c
View file @
187a035a
...
...
@@ -203,12 +203,12 @@ int main(int argc, char** argv) {
MainPanel
*
panel
=
MainPanel_new
();
ProcessList_setPanel
(
pl
,
(
Panel
*
)
panel
);
MainPanel_updateTreeFunctions
(
panel
,
settings
->
treeView
);
MainPanel_updateTreeFunctions
(
panel
,
settings
->
screens
[
0
]
->
treeView
);
if
(
flags
.
sortKey
>
0
)
{
settings
->
sortKey
=
flags
.
sortKey
;
settings
->
treeView
=
false
;
settings
->
direction
=
1
;
settings
->
screens
[
0
]
->
sortKey
=
flags
.
sortKey
;
settings
->
screens
[
0
]
->
treeView
=
false
;
settings
->
screens
[
0
]
->
direction
=
1
;
}
ProcessList_printHeader
(
pl
,
Panel_getHeader
((
Panel
*
)
panel
));
...
...
linux/LinuxProcess.c
View file @
187a035a
...
...
@@ -404,7 +404,7 @@ void LinuxProcess_writeField(Process* this, RichString* str, ProcessField field)
long
LinuxProcess_compare
(
const
void
*
v1
,
const
void
*
v2
)
{
LinuxProcess
*
p1
,
*
p2
;
Settings
*
settings
=
((
Process
*
)
v1
)
->
settings
;
if
(
settings
->
direction
==
1
)
{
if
(
settings
->
ss
->
direction
==
1
)
{
p1
=
(
LinuxProcess
*
)
v1
;
p2
=
(
LinuxProcess
*
)
v2
;
}
else
{
...
...
@@ -412,7 +412,7 @@ long LinuxProcess_compare(const void* v1, const void* v2) {
p1
=
(
LinuxProcess
*
)
v2
;
}
long
long
diff
;
switch
((
int
)
settings
->
sortKey
)
{
switch
((
int
)
settings
->
ss
->
sortKey
)
{
case
M_DRS
:
return
(
p2
->
m_drs
-
p1
->
m_drs
);
case
M_DT
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment