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
d2acffa5
Commit
d2acffa5
authored
Mar 15, 2015
by
Hisham Muhammad
Browse files
Merge branch 'wip' of
https://github.com/hishamhm/htop
into freebsd
Conflicts: htop.c unsupported/Platform.h
parents
c29e53c5
50000d80
Changes
60
Expand all
Hide whitespace changes
Inline
Side-by-side
Action.c
View file @
d2acffa5
...
...
@@ -5,16 +5,37 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#include "
Process
.h"
#include "Panel.h"
#include "
config
.h"
#include "Action.h"
#include "Affinity.h"
#include "AffinityPanel.h"
#include "CategoriesPanel.h"
#include "CRT.h"
#include "MainPanel.h"
#include "OpenFilesScreen.h"
#include "Process.h"
#include "ScreenManager.h"
#include "SignalsPanel.h"
#include "String.h"
#include "TraceScreen.h"
#include <ctype.h>
#include <math.h>
#include <pwd.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/param.h>
#include <sys/time.h>
/*{
#include "IncSet.h"
#include "Settings.h"
#include "Header.h"
#include "UsersTable.h"
#include "ProcessList.h"
#include "Panel.h"
typedef enum {
HTOP_OK = 0x00,
...
...
@@ -33,51 +54,29 @@ typedef struct State_ {
IncSet* inc;
Settings* settings;
UsersTable* ut;
ProcessList* pl;
Panel* panel;
Header* header;
} State;
typedef bool(*Action_ForeachProcessFn)(Process*, size_t);
}*/
int
Action_selectedPid
(
Panel
*
panel
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
if
(
p
)
{
return
p
->
pid
;
}
return
-
1
;
}
bool
Action_foreachProcess
(
Panel
*
panel
,
Action_ForeachProcessFn
fn
,
int
arg
,
bool
*
wasAnyTagged
)
{
bool
ok
=
true
;
bool
anyTagged
=
false
;
for
(
int
i
=
0
;
i
<
Panel_size
(
panel
);
i
++
)
{
Process
*
p
=
(
Process
*
)
Panel_get
(
panel
,
i
);
if
(
p
->
tag
)
{
ok
=
fn
(
p
,
arg
)
&&
ok
;
anyTagged
=
true
;
}
}
if
(
!
anyTagged
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
if
(
p
)
ok
=
fn
(
p
,
arg
)
&&
ok
;
}
if
(
wasAnyTagged
)
*
wasAnyTagged
=
anyTagged
;
return
ok
;
}
Object
*
Action_pickFromVector
(
Panel
*
panel
,
Panel
*
list
,
int
x
,
const
char
**
keyLabels
,
Header
*
header
)
{
Object
*
Action_pickFromVector
(
State
*
st
,
Panel
*
list
,
int
x
,
const
char
**
keyLabels
)
{
Panel
*
panel
=
st
->
panel
;
Header
*
header
=
st
->
header
;
Settings
*
settings
=
st
->
settings
;
int
y
=
panel
->
y
;
const
char
*
fuKeys
[]
=
{
"Enter"
,
"Esc"
,
NULL
};
int
fuEvents
[]
=
{
13
,
27
};
ScreenManager
*
scr
=
ScreenManager_new
(
0
,
y
,
0
,
-
1
,
HORIZONTAL
,
header
,
false
);
ScreenManager
*
scr
=
ScreenManager_new
(
0
,
header
->
height
,
0
,
-
1
,
HORIZONTAL
,
header
,
settings
,
false
);
scr
->
allowFocusChange
=
false
;
ScreenManager_add
(
scr
,
list
,
FunctionBar_new
(
keyLabels
,
fuKeys
,
fuEvents
),
x
-
1
);
ScreenManager_add
(
scr
,
panel
,
NULL
,
-
1
);
Panel
*
panelFocus
;
int
ch
;
bool
unfollow
=
false
;
int
pid
=
Action
_selectedPid
(
panel
);
int
pid
=
MainPanel
_selectedPid
(
(
MainPanel
*
)
panel
);
if
(
header
->
pl
->
following
==
-
1
)
{
header
->
pl
->
following
=
pid
;
unfollow
=
true
;
...
...
@@ -98,3 +97,451 @@ Object* Action_pickFromVector(Panel* panel, Panel* list, int x, const char** key
}
return
NULL
;
}
// ----------------------------------------
static
const
char
*
CategoriesFunctions
[]
=
{
" "
,
" "
,
" "
,
" "
,
" "
,
" "
,
" "
,
" "
,
" "
,
"Done "
,
NULL
};
static
void
Setup_run
(
Settings
*
settings
,
const
Header
*
header
,
ProcessList
*
pl
)
{
ScreenManager
*
scr
=
ScreenManager_new
(
0
,
header
->
height
,
0
,
-
1
,
HORIZONTAL
,
header
,
settings
,
true
);
CategoriesPanel
*
panelCategories
=
CategoriesPanel_new
(
scr
,
settings
,
(
Header
*
)
header
,
pl
);
ScreenManager_add
(
scr
,
(
Panel
*
)
panelCategories
,
FunctionBar_new
(
CategoriesFunctions
,
NULL
,
NULL
),
16
);
CategoriesPanel_makeMetersPage
(
panelCategories
);
Panel
*
panelFocus
;
int
ch
;
ScreenManager_run
(
scr
,
&
panelFocus
,
&
ch
);
ScreenManager_delete
(
scr
);
}
static
bool
changePriority
(
MainPanel
*
panel
,
int
delta
)
{
bool
anyTagged
;
bool
ok
=
MainPanel_foreachProcess
(
panel
,
(
MainPanel_ForeachProcessFn
)
Process_changePriorityBy
,
delta
,
&
anyTagged
);
if
(
!
ok
)
beep
();
return
anyTagged
;
}
static
void
addUserToVector
(
int
key
,
void
*
userCast
,
void
*
panelCast
)
{
char
*
user
=
(
char
*
)
userCast
;
Panel
*
panel
=
(
Panel
*
)
panelCast
;
Panel_add
(
panel
,
(
Object
*
)
ListItem_new
(
user
,
key
));
}
bool
Action_setUserOnly
(
const
char
*
userName
,
uid_t
*
userId
)
{
struct
passwd
*
user
=
getpwnam
(
userName
);
if
(
user
)
{
*
userId
=
user
->
pw_uid
;
return
true
;
}
*
userId
=
-
1
;
return
false
;
}
static
void
tagAllChildren
(
Panel
*
panel
,
Process
*
parent
)
{
parent
->
tag
=
true
;
pid_t
ppid
=
parent
->
pid
;
for
(
int
i
=
0
;
i
<
Panel_size
(
panel
);
i
++
)
{
Process
*
p
=
(
Process
*
)
Panel_get
(
panel
,
i
);
if
(
!
p
->
tag
&&
p
->
ppid
==
ppid
)
{
tagAllChildren
(
panel
,
p
);
}
}
}
static
bool
expandCollapse
(
Panel
*
panel
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
if
(
!
p
)
return
false
;
p
->
showChildren
=
!
p
->
showChildren
;
return
true
;
}
static
inline
Htop_Reaction
setSortKey
(
Settings
*
settings
,
ProcessField
sortKey
)
{
settings
->
sortKey
=
sortKey
;
settings
->
direction
=
1
;
settings
->
treeView
=
false
;
return
HTOP_REFRESH
|
HTOP_SAVE_SETTINGS
|
HTOP_UPDATE_PANELHDR
;
}
static
Htop_Reaction
sortBy
(
State
*
st
)
{
Htop_Reaction
reaction
=
HTOP_OK
;
Panel
*
sortPanel
=
Panel_new
(
0
,
0
,
0
,
0
,
true
,
Class
(
ListItem
));
Panel_setHeader
(
sortPanel
,
"Sort by"
);
const
char
*
fuFunctions
[]
=
{
"Sort "
,
"Cancel "
,
NULL
};
ProcessField
*
fields
=
st
->
settings
->
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
]
==
st
->
settings
->
sortKey
)
Panel_setSelected
(
sortPanel
,
i
);
free
(
name
);
}
ListItem
*
field
=
(
ListItem
*
)
Action_pickFromVector
(
st
,
sortPanel
,
15
,
fuFunctions
);
if
(
field
)
{
reaction
|=
setSortKey
(
st
->
settings
,
field
->
key
);
}
Object_delete
(
sortPanel
);
return
reaction
|
HTOP_REFRESH
|
HTOP_REDRAW_BAR
|
HTOP_UPDATE_PANELHDR
;
}
// ----------------------------------------
static
Htop_Reaction
actionResize
(
State
*
st
)
{
Panel_resize
(
st
->
panel
,
COLS
,
LINES
-
(
st
->
panel
->
y
)
-
1
);
return
HTOP_REDRAW_BAR
;
}
static
Htop_Reaction
actionSortByMemory
(
State
*
st
)
{
return
setSortKey
(
st
->
settings
,
PERCENT_MEM
);
}
static
Htop_Reaction
actionSortByCPU
(
State
*
st
)
{
return
setSortKey
(
st
->
settings
,
PERCENT_CPU
);
}
static
Htop_Reaction
actionSortByTime
(
State
*
st
)
{
return
setSortKey
(
st
->
settings
,
TIME
);
}
static
Htop_Reaction
actionToggleKernelThreads
(
State
*
st
)
{
st
->
settings
->
hideKernelThreads
=
!
st
->
settings
->
hideKernelThreads
;
return
HTOP_RECALCULATE
|
HTOP_SAVE_SETTINGS
;
}
static
Htop_Reaction
actionToggleUserlandThreads
(
State
*
st
)
{
st
->
settings
->
hideUserlandThreads
=
!
st
->
settings
->
hideUserlandThreads
;
st
->
settings
->
hideThreads
=
st
->
settings
->
hideUserlandThreads
;
return
HTOP_RECALCULATE
|
HTOP_SAVE_SETTINGS
;
}
static
Htop_Reaction
actionToggleTreeView
(
State
*
st
)
{
st
->
settings
->
treeView
=
!
st
->
settings
->
treeView
;
if
(
st
->
settings
->
treeView
)
st
->
settings
->
direction
=
1
;
ProcessList_expandTree
(
st
->
pl
);
return
HTOP_REFRESH
|
HTOP_SAVE_SETTINGS
|
HTOP_KEEP_FOLLOWING
|
HTOP_REDRAW_BAR
|
HTOP_UPDATE_PANELHDR
;
}
static
Htop_Reaction
actionIncFilter
(
State
*
st
)
{
IncSet_activate
(
st
->
inc
,
INC_FILTER
);
return
HTOP_REFRESH
|
HTOP_KEEP_FOLLOWING
;
}
static
Htop_Reaction
actionIncSearch
(
State
*
st
)
{
IncSet_activate
(
st
->
inc
,
INC_SEARCH
);
return
HTOP_REFRESH
|
HTOP_KEEP_FOLLOWING
;
}
static
Htop_Reaction
actionHigherPriority
(
State
*
st
)
{
bool
changed
=
changePriority
((
MainPanel
*
)
st
->
panel
,
-
1
);
return
changed
?
HTOP_REFRESH
:
HTOP_OK
;
}
static
Htop_Reaction
actionLowerPriority
(
State
*
st
)
{
bool
changed
=
changePriority
((
MainPanel
*
)
st
->
panel
,
1
);
return
changed
?
HTOP_REFRESH
:
HTOP_OK
;
}
static
Htop_Reaction
actionInvertSortOrder
(
State
*
st
)
{
Settings_invertSortOrder
(
st
->
settings
);
return
HTOP_REFRESH
|
HTOP_SAVE_SETTINGS
;
}
static
Htop_Reaction
actionSetSortColumn
(
State
*
st
)
{
return
sortBy
(
st
);
}
static
Htop_Reaction
actionExpandOrCollapse
(
State
*
st
)
{
bool
changed
=
expandCollapse
(
st
->
panel
);
return
changed
?
HTOP_RECALCULATE
:
HTOP_OK
;
}
static
Htop_Reaction
actionExpandCollapseOrSortColumn
(
State
*
st
)
{
return
st
->
settings
->
treeView
?
actionExpandOrCollapse
(
st
)
:
actionSetSortColumn
(
st
);
}
static
Htop_Reaction
actionQuit
()
{
return
HTOP_QUIT
;
}
static
Htop_Reaction
actionSetAffinity
(
State
*
st
)
{
if
(
st
->
pl
->
cpuCount
==
1
)
return
HTOP_OK
;
#if (HAVE_LIBHWLOC || HAVE_NATIVE_AFFINITY)
Panel
*
panel
=
st
->
panel
;
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
panel
);
if
(
!
p
)
return
HTOP_OK
;
Affinity
*
affinity
=
Affinity_get
(
p
,
st
->
pl
);
if
(
!
affinity
)
return
HTOP_OK
;
Panel
*
affinityPanel
=
AffinityPanel_new
(
st
->
pl
,
affinity
);
Affinity_delete
(
affinity
);
const
char
*
fuFunctions
[]
=
{
"Set "
,
"Cancel "
,
NULL
};
void
*
set
=
Action_pickFromVector
(
st
,
affinityPanel
,
15
,
fuFunctions
);
if
(
set
)
{
Affinity
*
affinity
=
AffinityPanel_getAffinity
(
affinityPanel
,
st
->
pl
);
bool
ok
=
MainPanel_foreachProcess
((
MainPanel
*
)
panel
,
(
MainPanel_ForeachProcessFn
)
Affinity_set
,
(
size_t
)
affinity
,
NULL
);
if
(
!
ok
)
beep
();
Affinity_delete
(
affinity
);
}
Panel_delete
((
Object
*
)
affinityPanel
);
#endif
return
HTOP_REFRESH
|
HTOP_REDRAW_BAR
|
HTOP_UPDATE_PANELHDR
;
}
static
Htop_Reaction
actionKill
(
State
*
st
)
{
Panel
*
signalsPanel
=
(
Panel
*
)
SignalsPanel_new
();
const
char
*
fuFunctions
[]
=
{
"Send "
,
"Cancel "
,
NULL
};
ListItem
*
sgn
=
(
ListItem
*
)
Action_pickFromVector
(
st
,
signalsPanel
,
15
,
fuFunctions
);
if
(
sgn
)
{
if
(
sgn
->
key
!=
0
)
{
Panel_setHeader
(
st
->
panel
,
"Sending..."
);
Panel_draw
(
st
->
panel
,
true
);
refresh
();
MainPanel_foreachProcess
((
MainPanel
*
)
st
->
panel
,
(
MainPanel_ForeachProcessFn
)
Process_sendSignal
,
(
size_t
)
sgn
->
key
,
NULL
);
napms
(
500
);
}
}
Panel_delete
((
Object
*
)
signalsPanel
);
return
HTOP_REFRESH
|
HTOP_REDRAW_BAR
|
HTOP_UPDATE_PANELHDR
;
}
static
Htop_Reaction
actionFilterByUser
(
State
*
st
)
{
Panel
*
usersPanel
=
Panel_new
(
0
,
0
,
0
,
0
,
true
,
Class
(
ListItem
));
Panel_setHeader
(
usersPanel
,
"Show processes of:"
);
UsersTable_foreach
(
st
->
ut
,
addUserToVector
,
usersPanel
);
Vector_insertionSort
(
usersPanel
->
items
);
ListItem
*
allUsers
=
ListItem_new
(
"All users"
,
-
1
);
Panel_insert
(
usersPanel
,
0
,
(
Object
*
)
allUsers
);
const
char
*
fuFunctions
[]
=
{
"Show "
,
"Cancel "
,
NULL
};
ListItem
*
picked
=
(
ListItem
*
)
Action_pickFromVector
(
st
,
usersPanel
,
20
,
fuFunctions
);
if
(
picked
)
{
if
(
picked
==
allUsers
)
{
st
->
pl
->
userId
=
-
1
;
}
else
{
Action_setUserOnly
(
ListItem_getRef
(
picked
),
&
(
st
->
pl
->
userId
));
}
}
Panel_delete
((
Object
*
)
usersPanel
);
return
HTOP_REFRESH
|
HTOP_REDRAW_BAR
|
HTOP_UPDATE_PANELHDR
;
}
static
Htop_Reaction
actionFollow
(
State
*
st
)
{
st
->
pl
->
following
=
MainPanel_selectedPid
((
MainPanel
*
)
st
->
panel
);
return
HTOP_KEEP_FOLLOWING
;
}
static
Htop_Reaction
actionSetup
(
State
*
st
)
{
Setup_run
(
st
->
settings
,
st
->
header
,
st
->
pl
);
// TODO: shouldn't need this, colors should be dynamic
int
headerHeight
=
Header_calculateHeight
(
st
->
header
);
Panel_move
(
st
->
panel
,
0
,
headerHeight
);
Panel_resize
(
st
->
panel
,
COLS
,
LINES
-
headerHeight
-
1
);
return
HTOP_REFRESH
|
HTOP_REDRAW_BAR
|
HTOP_UPDATE_PANELHDR
;
}
static
Htop_Reaction
actionLsof
(
State
*
st
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
st
->
panel
);
if
(
!
p
)
return
HTOP_OK
;
OpenFilesScreen
*
ts
=
OpenFilesScreen_new
(
p
);
OpenFilesScreen_run
(
ts
);
OpenFilesScreen_delete
(
ts
);
clear
();
CRT_enableDelay
();
return
HTOP_REFRESH
|
HTOP_REDRAW_BAR
;
}
static
Htop_Reaction
actionStrace
(
State
*
st
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
st
->
panel
);
if
(
!
p
)
return
HTOP_OK
;
TraceScreen
*
ts
=
TraceScreen_new
(
p
);
TraceScreen_run
(
ts
);
TraceScreen_delete
(
ts
);
clear
();
CRT_enableDelay
();
return
HTOP_REFRESH
|
HTOP_REDRAW_BAR
;
}
static
Htop_Reaction
actionTag
(
State
*
st
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
st
->
panel
);
if
(
!
p
)
return
HTOP_OK
;
Process_toggleTag
(
p
);
Panel_onKey
(
st
->
panel
,
KEY_DOWN
);
return
HTOP_OK
;
}
static
Htop_Reaction
actionRedraw
()
{
clear
();
return
HTOP_REFRESH
|
HTOP_REDRAW_BAR
;
}
static
struct
{
const
char
*
key
;
const
char
*
info
;
}
helpLeft
[]
=
{
{
.
key
=
" Arrows: "
,
.
info
=
"scroll process list"
},
{
.
key
=
" Digits: "
,
.
info
=
"incremental PID search"
},
{
.
key
=
" F3 /: "
,
.
info
=
"incremental name search"
},
{
.
key
=
" F4
\\
: "
,.
info
=
"incremental name filtering"
},
{
.
key
=
" F5 t: "
,
.
info
=
"tree view"
},
{
.
key
=
" u: "
,
.
info
=
"show processes of a single user"
},
{
.
key
=
" H: "
,
.
info
=
"hide/show user threads"
},
{
.
key
=
" K: "
,
.
info
=
"hide/show kernel threads"
},
{
.
key
=
" F: "
,
.
info
=
"cursor follows process"
},
{
.
key
=
" F6 + -: "
,
.
info
=
"expand/collapse tree"
},
{
.
key
=
" P M T: "
,
.
info
=
"sort by CPU%, MEM% or TIME"
},
{
.
key
=
" I: "
,
.
info
=
"invert sort order"
},
{
.
key
=
" F6 >: "
,
.
info
=
"select sort column"
},
{
.
key
=
NULL
,
.
info
=
NULL
}
};
static
struct
{
const
char
*
key
;
const
char
*
info
;
}
helpRight
[]
=
{
{
.
key
=
" Space: "
,
.
info
=
"tag process"
},
{
.
key
=
" c: "
,
.
info
=
"tag process and its children"
},
{
.
key
=
" U: "
,
.
info
=
"untag all processes"
},
{
.
key
=
" F9 k: "
,
.
info
=
"kill process/tagged processes"
},
{
.
key
=
" F7 ]: "
,
.
info
=
"higher priority (root only)"
},
{
.
key
=
" F8 [: "
,
.
info
=
"lower priority (+ nice)"
},
#if (HAVE_LIBHWLOC || HAVE_NATIVE_AFFINITY)
{
.
key
=
" a: "
,
.
info
=
"set CPU affinity"
},
#endif
{
.
key
=
" i: "
,
.
info
=
"set IO prority"
},
{
.
key
=
" l: "
,
.
info
=
"list open files with lsof"
},
{
.
key
=
" s: "
,
.
info
=
"trace syscalls with strace"
},
{
.
key
=
" "
,
.
info
=
""
},
{
.
key
=
" F2 S: "
,
.
info
=
"setup"
},
{
.
key
=
" F1 h: "
,
.
info
=
"show this help screen"
},
{
.
key
=
" F10 q: "
,
.
info
=
"quit"
},
{
.
key
=
NULL
,
.
info
=
NULL
}
};
static
Htop_Reaction
actionHelp
(
State
*
st
)
{
Settings
*
settings
=
st
->
settings
;
clear
();
attrset
(
CRT_colors
[
HELP_BOLD
]);
for
(
int
i
=
0
;
i
<
LINES
-
1
;
i
++
)
mvhline
(
i
,
0
,
' '
,
COLS
);
mvaddstr
(
0
,
0
,
"htop "
VERSION
" - "
COPYRIGHT
);
mvaddstr
(
1
,
0
,
"Released under the GNU GPL. See 'man' page for more info."
);
attrset
(
CRT_colors
[
DEFAULT_COLOR
]);
mvaddstr
(
3
,
0
,
"CPU usage bar: "
);
#define addattrstr(a,s) attrset(a);addstr(s)
addattrstr
(
CRT_colors
[
BAR_BORDER
],
"["
);
if
(
settings
->
detailedCPUTime
)
{
addattrstr
(
CRT_colors
[
CPU_NICE_TEXT
],
"low"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_NORMAL
],
"normal"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_KERNEL
],
"kernel"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_IRQ
],
"irq"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_SOFTIRQ
],
"soft-irq"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_STEAL
],
"steal"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_GUEST
],
"guest"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_IOWAIT
],
"io-wait"
);
addattrstr
(
CRT_colors
[
BAR_SHADOW
],
" used%"
);
}
else
{
addattrstr
(
CRT_colors
[
CPU_NICE_TEXT
],
"low-priority"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_NORMAL
],
"normal"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_KERNEL
],
"kernel"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
CPU_STEAL
],
"virtualiz"
);
addattrstr
(
CRT_colors
[
BAR_SHADOW
],
" used%"
);
}
addattrstr
(
CRT_colors
[
BAR_BORDER
],
"]"
);
attrset
(
CRT_colors
[
DEFAULT_COLOR
]);
mvaddstr
(
4
,
0
,
"Memory bar: "
);
addattrstr
(
CRT_colors
[
BAR_BORDER
],
"["
);
addattrstr
(
CRT_colors
[
MEMORY_USED
],
"used"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
MEMORY_BUFFERS_TEXT
],
"buffers"
);
addstr
(
"/"
);
addattrstr
(
CRT_colors
[
MEMORY_CACHE
],
"cache"
);
addattrstr
(
CRT_colors
[
BAR_SHADOW
],
" used/total"
);
addattrstr
(
CRT_colors
[
BAR_BORDER
],
"]"
);
attrset
(
CRT_colors
[
DEFAULT_COLOR
]);
mvaddstr
(
5
,
0
,
"Swap bar: "
);
addattrstr
(
CRT_colors
[
BAR_BORDER
],
"["
);
addattrstr
(
CRT_colors
[
SWAP
],
"used"
);
addattrstr
(
CRT_colors
[
BAR_SHADOW
],
" used/total"
);
addattrstr
(
CRT_colors
[
BAR_BORDER
],
"]"
);
attrset
(
CRT_colors
[
DEFAULT_COLOR
]);
mvaddstr
(
6
,
0
,
"Type and layout of header meters are configurable in the setup screen."
);
if
(
CRT_colorScheme
==
COLORSCHEME_MONOCHROME
)
{
mvaddstr
(
7
,
0
,
"In monochrome, meters are displayed through different chars, in order: |#*@$%&"
);
}
mvaddstr
(
8
,
0
,
" Status: R: running; S: sleeping; T: traced/stopped; Z: zombie; D: disk sleep"
);
for
(
int
i
=
0
;
helpLeft
[
i
].
info
;
i
++
)
{
mvaddstr
(
9
+
i
,
9
,
helpLeft
[
i
].
info
);
}
for
(
int
i
=
0
;
helpRight
[
i
].
info
;
i
++
)
{
mvaddstr
(
9
+
i
,
49
,
helpRight
[
i
].
info
);
}
attrset
(
CRT_colors
[
HELP_BOLD
]);
for
(
int
i
=
0
;
helpLeft
[
i
].
key
;
i
++
)
{
mvaddstr
(
9
+
i
,
0
,
helpLeft
[
i
].
key
);
}
for
(
int
i
=
0
;
helpRight
[
i
].
key
;
i
++
)
{
mvaddstr
(
9
+
i
,
40
,
helpRight
[
i
].
key
);
}
attrset
(
CRT_colors
[
HELP_BOLD
]);
mvaddstr
(
23
,
0
,
"Press any key to return."
);
attrset
(
CRT_colors
[
DEFAULT_COLOR
]);
refresh
();
CRT_readKey
();
clear
();
return
HTOP_RECALCULATE
|
HTOP_REDRAW_BAR
;
}
static
Htop_Reaction
actionUntagAll
(
State
*
st
)
{
for
(
int
i
=
0
;
i
<
Panel_size
(
st
->
panel
);
i
++
)
{
Process
*
p
=
(
Process
*
)
Panel_get
(
st
->
panel
,
i
);
p
->
tag
=
false
;
}
return
HTOP_REFRESH
;
}
static
Htop_Reaction
actionTagAllChildren
(
State
*
st
)
{
Process
*
p
=
(
Process
*
)
Panel_getSelected
(
st
->
panel
);
if
(
!
p
)
return
HTOP_OK
;
tagAllChildren
(
st
->
panel
,
p
);
return
HTOP_OK
;
}
void
Action_setBindings
(
Htop_Action
*
keys
)
{
keys
[
KEY_RESIZE
]
=
actionResize
;
keys
[
'M'
]
=
actionSortByMemory
;
keys
[
'T'
]
=
actionSortByTime
;
keys
[
'P'
]
=
actionSortByCPU
;
keys
[
'H'
]
=
actionToggleUserlandThreads
;
keys
[
'K'
]
=
actionToggleKernelThreads
;
keys
[
't'
]
=
actionToggleTreeView
;
keys
[
KEY_F
(
5
)]
=
actionToggleTreeView
;
keys
[
KEY_F
(
4
)]
=
actionIncFilter
;
keys
[
'\\'
]
=
actionIncFilter
;
keys
[
KEY_F
(
3
)]
=
actionIncSearch
;
keys
[
'/'
]
=
actionIncSearch
;
keys
[
']'
]
=
actionHigherPriority
;
keys
[
KEY_F
(
7
)]
=
actionHigherPriority
;
keys
[
'['
]
=
actionLowerPriority
;
keys
[
KEY_F
(
8
)]
=
actionLowerPriority
;
keys
[
'I'
]
=
actionInvertSortOrder
;
keys
[
KEY_F
(
6
)]
=
actionExpandCollapseOrSortColumn
;
keys
[
KEY_F
(
18
)]
=
actionExpandCollapseOrSortColumn
;
keys
[
'<'
]
=
actionSetSortColumn
;
keys
[
','
]
=
actionSetSortColumn
;
keys
[
'>'
]
=
actionSetSortColumn
;
keys
[
'.'
]
=
actionSetSortColumn
;
keys
[
KEY_F
(
10
)]
=
actionQuit
;
keys
[
'q'
]
=
actionQuit
;
keys
[
'a'
]
=
actionSetAffinity
;
keys
[
KEY_F
(
9
)]
=
actionKill
;
keys
[
'k'
]
=
actionKill
;
keys
[
'+'
]
=
actionExpandOrCollapse
;
keys
[
'='
]
=
actionExpandOrCollapse
;
keys
[
'-'
]
=
actionExpandOrCollapse
;
keys
[
'u'
]
=
actionFilterByUser
;
keys
[
'F'
]
=
actionFollow
;
keys
[
'S'
]
=
actionSetup
;
keys
[
'C'
]
=
actionSetup
;
keys
[
KEY_F
(
2
)]
=
actionSetup
;
keys
[
'l'
]
=
actionLsof
;
keys
[
's'
]
=
actionStrace
;
keys
[
' '
]
=
actionTag
;
keys
[
'\014'
]
=
actionRedraw
;
// Ctrl+L
keys
[
KEY_F
(
1
)]
=
actionHelp
;
keys
[
'h'
]
=
actionHelp
;
keys
[
'?'
]
=
actionHelp
;
keys
[
'U'
]
=
actionUntagAll
;
keys
[
'c'
]
=
actionTagAllChildren
;
}
Action.h
View file @
d2acffa5
...
...
@@ -12,7 +12,10 @@ in the source distribution for its full text.
#include "IncSet.h"
#include "Settings.h"
#include "Header.h"
#include "UsersTable.h"
#include "ProcessList.h"
#include "Panel.h"
typedef
enum
{
HTOP_OK
=
0x00
,
...
...
@@ -31,15 +34,21 @@ typedef struct State_ {
IncSet
*
inc
;
Settings
*
settings
;
UsersTable
*
ut
;
ProcessList
*
pl
;
Panel
*
panel
;
Header
*
header
;
}
State
;
typedef
bool
(
*
Action_ForeachProcessFn
)(
Process
*
,
size_t
);
Object
*
Action_pickFromVector
(
State
*
st
,
Panel
*
list
,
int
x
,
const
char
**
keyLabels
);
int
Action_selectedPid
(
Panel
*
panel
);
// ----------------------------------------
bool
Action_foreachProcess
(
Panel
*
panel
,
Action_ForeachProcessFn
fn
,
int
arg
,
bool
*
wasAnyTagged
);
bool
Action_setUserOnly
(
const
char
*
userName
,
uid_t
*
userId
);
// ----------------------------------------
void
Action_setBindings
(
Htop_Action
*
keys
);
Object
*
Action_pickFromVector
(
Panel
*
panel
,
Panel
*
list
,
int
x
,
const
char
**
keyLabels
,
Header
*
header
);
#endif
Affinity.c
View file @
d2acffa5
...
...
@@ -9,9 +9,18 @@ in the source distribution for its full text.
#include <stdlib.h>
#ifdef HAVE_LIBHWLOC
#include <hwloc/linux.h>
#elif HAVE_NATIVE_AFFINITY
#include <sched.h>
#endif
/*{
#include "Process.h"
#include "ProcessList.h"
typedef struct Affinity_ {
ProcessList* pl;
int size;
int used;
int* cpus;
...
...
@@ -19,10 +28,11 @@ typedef struct Affinity_ {
}*/
Affinity
*
Affinity_new
()
{
Affinity
*
Affinity_new
(
ProcessList
*
pl
)
{
Affinity
*
this
=
calloc
(
1
,
sizeof
(
Affinity
));
this
->
size
=
8
;
this
->
cpus
=
calloc
(
this
->
size
,
sizeof
(
int
));
this
->
pl
=
pl
;
return
this
;
}
...
...
@@ -40,3 +50,62 @@ void Affinity_add(Affinity* this, int id) {
this
->
used
++
;
}
#ifdef HAVE_LIBHWLOC
Affinity
*
Affinity_get
(
Process
*
proc
,
ProcessList
*
pl
)
{
hwloc_cpuset_t
cpuset
=
hwloc_bitmap_alloc
();
bool
ok
=
(
hwloc_linux_get_tid_cpubind
(
pl
->
topology
,
proc
->
pid
,
cpuset
)
==
0
);
Affinity
*
affinity
=
NULL
;
if
(
ok
)
{
affinity
=
Affinity_new
(
pl
);
if
(
hwloc_bitmap_last
(
cpuset
)
==
-
1
)
{
for
(
int
i
=
0
;
i
<
pl
->
cpuCount
;
i
++
)
{
Affinity_add
(
affinity
,
i
);
}
}
else
{
unsigned
int
id
;
hwloc_bitmap_foreach_begin
(
id
,
cpuset
);
Affinity_add
(
affinity
,
id
);
hwloc_bitmap_foreach_end
();
}
}
hwloc_bitmap_free
(
cpuset
);
return
affinity
;
}
bool
Affinity_set
(
Process
*
proc
,
Affinity
*
this
)
{
hwloc_cpuset_t
cpuset
=
hwloc_bitmap_alloc
();
for
(
int
i
=
0
;
i
<
affinity
->
used
;
i
++
)
{
hwloc_bitmap_set
(
cpuset
,
affinity
->
cpus
[
i
]);
}
bool
ok
=
(
hwloc_linux_set_tid_cpubind
(
this
->
pl
->
topology
,
proc
->
pid
,
cpuset
)
==
0
);
hwloc_bitmap_free
(
cpuset
);
return
ok
;
}
#elif HAVE_NATIVE_AFFINITY
Affinity
*
Affinity_get
(
Process
*
proc
,
ProcessList
*
pl
)
{
cpu_set_t
cpuset
;
bool
ok
=
(
sched_getaffinity
(
proc
->
pid
,
sizeof
(
cpu_set_t
),
&
cpuset
)
==
0
);
if
(
!
ok
)
return
NULL
;
Affinity
*
affinity
=
Affinity_new
(
pl
);
for
(
int
i
=
0
;
i
<
pl
->
cpuCount
;
i
++
)
{
if
(
CPU_ISSET
(
i
,
&
cpuset
))
Affinity_add
(
affinity
,
i
);
}
return
affinity
;
}
bool
Affinity_set
(
Process
*
proc
,
Affinity
*
this
)
{
cpu_set_t
cpuset
;
CPU_ZERO
(
&
cpuset
);
for
(
int
i
=
0
;
i
<
this
->
used
;
i
++
)
{
CPU_SET
(
this
->
cpus
[
i
],
&
cpuset
);
}
bool
ok
=
(
sched_setaffinity
(
proc
->
pid
,
sizeof
(
unsigned
long
),
&
cpuset
)
==
0
);
return
ok
;
}
#endif
Affinity.h
View file @
d2acffa5
...
...
@@ -9,19 +9,39 @@ Released under the GNU GPL, see the COPYING file
in the source distribution for its full text.
*/
#ifdef HAVE_LIBHWLOC
#elif HAVE_NATIVE_AFFINITY
#endif
#include "Process.h"
#include "ProcessList.h"
typedef
struct
Affinity_
{
ProcessList
*
pl
;
int
size
;
int
used
;
int
*
cpus
;
}
Affinity
;
Affinity
*
Affinity_new
();
Affinity
*
Affinity_new
(
ProcessList
*
pl
);
void
Affinity_delete
(
Affinity
*
this
);
void
Affinity_add
(
Affinity
*
this
,
int
id
);
#ifdef HAVE_LIBHWLOC
Affinity
*
Affinity_get
(
Process
*
proc
,
ProcessList
*
pl
);
bool
Affinity_set
(
Process
*
proc
,
Affinity
*
this
);
#elif HAVE_NATIVE_AFFINITY
Affinity
*
Affinity_get
(
Process
*
proc
,
ProcessList
*
pl
);
bool
Affinity_set
(
Process
*
proc
,
Affinity
*
this
);
#endif
#endif
AffinityPanel.c
View file @
d2acffa5
...
...
@@ -50,7 +50,7 @@ Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) {
int
curCpu
=
0
;
for
(
int
i
=
0
;
i
<
pl
->
cpuCount
;
i
++
)
{
char
number
[
10
];
snprintf
(
number
,
9
,
"%d"
,
ProcessList_cpuId
(
pl
,
i
));
snprintf
(
number
,
9
,
"%d"
,
Settings_cpuId
(
pl
->
settings
,
i
));
bool
mode
;
if
(
curCpu
<
affinity
->
used
&&
affinity
->
cpus
[
curCpu
]
==
i
)
{
mode
=
true
;
...
...
@@ -63,8 +63,8 @@ Panel* AffinityPanel_new(ProcessList* pl, Affinity* affinity) {
return
this
;
}
Affinity
*
AffinityPanel_getAffinity
(
Panel
*
this
)
{
Affinity
*
affinity
=
Affinity_new
();
Affinity
*
AffinityPanel_getAffinity
(
Panel
*
this
,
ProcessList
*
pl
)
{
Affinity
*
affinity
=
Affinity_new
(
pl
);
int
size
=
Panel_size
(
this
);
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
if
(
CheckItem_get
((
CheckItem
*
)
Panel_get
(
this
,
i
)))
...
...
AffinityPanel.h
View file @
d2acffa5
...
...
@@ -18,6 +18,6 @@ extern PanelClass AffinityPanel_class;
Panel
*
AffinityPanel_new
(
ProcessList
*
pl
,
Affinity
*
affinity
);
Affinity
*
AffinityPanel_getAffinity
(
Panel
*
this
);
Affinity
*
AffinityPanel_getAffinity
(
Panel
*
this
,
ProcessList
*
pl
);
#endif
AvailableColumnsPanel.c
View file @
d2acffa5
...
...
@@ -13,18 +13,14 @@ in the source distribution for its full text.
#include <assert.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
/*{
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct AvailableColumnsPanel_ {
Panel super;
Panel* columns;
Settings* settings;
ScreenManager* scr;
} AvailableColumnsPanel;
}*/
...
...
@@ -38,7 +34,7 @@ static void AvailableColumnsPanel_delete(Object* object) {
static
HandlerResult
AvailableColumnsPanel_eventHandler
(
Panel
*
super
,
int
ch
)
{
AvailableColumnsPanel
*
this
=
(
AvailableColumnsPanel
*
)
super
;
char
*
text
=
((
ListItem
*
)
Panel_getSelected
(
super
))
->
value
;
int
key
=
((
ListItem
*
)
Panel_getSelected
(
super
))
->
key
;
HandlerResult
result
=
IGNORED
;
switch
(
ch
)
{
...
...
@@ -47,7 +43,7 @@ static HandlerResult AvailableColumnsPanel_eventHandler(Panel* super, int ch) {
case
KEY_F
(
5
):
{
int
at
=
Panel_getSelectedIndex
(
this
->
columns
);
Panel_insert
(
this
->
columns
,
at
,
(
Object
*
)
ListItem_new
(
text
,
0
));
Panel_insert
(
this
->
columns
,
at
,
(
Object
*
)
ListItem_new
(
Process_fields
[
key
].
name
,
key
));
Panel_setSelected
(
this
->
columns
,
at
+
1
);
ColumnsPanel_update
(
this
->
columns
);
result
=
HANDLED
;
...
...
@@ -71,19 +67,19 @@ PanelClass AvailableColumnsPanel_class = {
.
eventHandler
=
AvailableColumnsPanel_eventHandler
};
AvailableColumnsPanel
*
AvailableColumnsPanel_new
(
Settings
*
settings
,
Panel
*
columns
,
ScreenManager
*
scr
)
{
AvailableColumnsPanel
*
AvailableColumnsPanel_new
(
Panel
*
columns
)
{
AvailableColumnsPanel
*
this
=
AllocThis
(
AvailableColumnsPanel
);
Panel
*
super
=
(
Panel
*
)
this
;
Panel_init
(
super
,
1
,
1
,
1
,
1
,
Class
(
ListItem
),
true
);
this
->
settings
=
settings
;
this
->
scr
=
scr
;
Panel_setHeader
(
super
,
"Available Columns"
);
for
(
int
i
=
1
;
i
<
LAST_PROCESSFIELD
;
i
++
)
{
if
(
i
!=
COMM
)
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
Process_fieldNames
[
i
],
0
));
if
(
i
!=
COMM
&&
Process_fields
[
i
].
description
)
{
char
description
[
256
];
snprintf
(
description
,
sizeof
(
description
),
"%s - %s"
,
Process_fields
[
i
].
name
,
Process_fields
[
i
].
description
);
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
description
,
i
));
}
}
this
->
columns
=
columns
;
return
this
;
...
...
AvailableColumnsPanel.h
View file @
d2acffa5
...
...
@@ -10,20 +10,15 @@ in the source distribution for its full text.
*/
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef
struct
AvailableColumnsPanel_
{
Panel
super
;
Panel
*
columns
;
Settings
*
settings
;
ScreenManager
*
scr
;
}
AvailableColumnsPanel
;
extern
PanelClass
AvailableColumnsPanel_class
;
AvailableColumnsPanel
*
AvailableColumnsPanel_new
(
Settings
*
settings
,
Panel
*
columns
,
ScreenManager
*
scr
);
AvailableColumnsPanel
*
AvailableColumnsPanel_new
(
Panel
*
columns
);
#endif
AvailableMetersPanel.c
View file @
d2acffa5
...
...
@@ -6,6 +6,7 @@ in the source distribution for its full text.
*/
#include "AvailableMetersPanel.h"
#include "MetersPanel.h"
#include "CPUMeter.h"
#include "Header.h"
...
...
@@ -19,14 +20,16 @@ in the source distribution for its full text.
#include "Settings.h"
#include "Panel.h"
#include "ScreenManager.h"
#include "ProcessList.h"
typedef struct AvailableMetersPanel_ {
Panel super;
ScreenManager* scr;
Settings* settings;
Header* header;
Panel* leftPanel;
Panel* rightPanel;
ScreenManager* scr;
} AvailableMetersPanel;
}*/
...
...
@@ -38,39 +41,48 @@ static void AvailableMetersPanel_delete(Object* object) {
free
(
this
);
}
static
inline
void
AvailableMetersPanel_add
Head
er
(
Header
*
header
,
Panel
*
panel
,
MeterClass
*
type
,
int
param
,
HeaderSide
side
)
{
Meter
*
meter
=
(
Meter
*
)
Header_addMeter
(
header
,
type
,
param
,
side
);
static
inline
void
AvailableMetersPanel_add
Met
er
(
Header
*
header
,
Panel
*
panel
,
MeterClass
*
type
,
int
param
,
int
column
)
{
Meter
*
meter
=
(
Meter
*
)
Header_addMeter
ByClass
(
header
,
type
,
param
,
column
);
Panel_add
(
panel
,
(
Object
*
)
Meter_toListItem
(
meter
));
Panel_setSelected
(
panel
,
Panel_size
(
panel
)
-
1
);
((
MetersPanel
*
)
panel
)
->
moving
=
true
;
((
ListItem
*
)
Panel_getSelected
(
panel
))
->
moving
=
true
;
}
static
HandlerResult
AvailableMetersPanel_eventHandler
(
Panel
*
super
,
int
ch
)
{
AvailableMetersPanel
*
this
=
(
AvailableMetersPanel
*
)
super
;
Header
*
header
=
this
->
settings
->
header
;
Header
*
header
=
this
->
header
;
ListItem
*
selected
=
(
ListItem
*
)
Panel_getSelected
(
super
);
int
param
=
selected
->
key
&
0xff
;
int
type
=
selected
->
key
>>
16
;
HandlerResult
result
=
IGNORED
;
bool
update
=
false
;
switch
(
ch
)
{
case
KEY_F
(
5
):
case
'l'
:
case
'L'
:
{
AvailableMetersPanel_add
Head
er
(
header
,
this
->
leftPanel
,
Platform_meterTypes
[
type
],
param
,
LEFT_HEADER
);
AvailableMetersPanel_add
Met
er
(
header
,
this
->
leftPanel
,
Platform_meterTypes
[
type
],
param
,
0
);
result
=
HANDLED
;
update
=
true
;
break
;
}
case
0x0a
:
case
0x0d
:
case
KEY_ENTER
:
case
KEY_F
(
6
):
case
'r'
:
case
'R'
:
{
AvailableMetersPanel_addHeader
(
header
,
this
->
rightPanel
,
Platform_meterTypes
[
type
],
param
,
RIGHT_HEADER
);
result
=
HANDLED
;
AvailableMetersPanel_addMeter
(
header
,
this
->
rightPanel
,
Platform_meterTypes
[
type
],
param
,
1
);
result
=
(
KEY_LEFT
<<
16
)
|
SYNTH_KEY
;
update
=
true
;
break
;
}
}
if
(
result
==
HANDLED
)
{
if
(
update
)
{
this
->
settings
->
changed
=
true
;
Header_calculateHeight
(
header
);
Header_draw
(
header
);
...
...
@@ -87,12 +99,13 @@ PanelClass AvailableMetersPanel_class = {
.
eventHandler
=
AvailableMetersPanel_eventHandler
};
AvailableMetersPanel
*
AvailableMetersPanel_new
(
Settings
*
settings
,
Panel
*
leftMeters
,
Panel
*
rightMeters
,
ScreenManager
*
scr
)
{
AvailableMetersPanel
*
AvailableMetersPanel_new
(
Settings
*
settings
,
Header
*
header
,
Panel
*
leftMeters
,
Panel
*
rightMeters
,
ScreenManager
*
scr
,
ProcessList
*
pl
)
{
AvailableMetersPanel
*
this
=
AllocThis
(
AvailableMetersPanel
);
Panel
*
super
=
(
Panel
*
)
this
;
Panel_init
(
super
,
1
,
1
,
1
,
1
,
Class
(
ListItem
),
true
);
this
->
settings
=
settings
;
this
->
header
=
header
;
this
->
leftPanel
=
leftMeters
;
this
->
rightPanel
=
rightMeters
;
this
->
scr
=
scr
;
...
...
@@ -101,11 +114,12 @@ AvailableMetersPanel* AvailableMetersPanel_new(Settings* settings, Panel* leftMe
for
(
int
i
=
1
;
Platform_meterTypes
[
i
];
i
++
)
{
MeterClass
*
type
=
Platform_meterTypes
[
i
];
if
(
type
!=
&
CPUMeter_class
)
{
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
type
->
uiName
,
i
<<
16
));
const
char
*
label
=
type
->
description
?
type
->
description
:
type
->
uiName
;
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
label
,
i
<<
16
));
}
}
MeterClass
*
type
=
&
CPUMeter_class
;
int
cpus
=
settings
->
pl
->
cpuCount
;
int
cpus
=
pl
->
cpuCount
;
if
(
cpus
>
1
)
{
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
"CPU average"
,
0
));
for
(
int
i
=
1
;
i
<=
cpus
;
i
++
)
{
...
...
AvailableMetersPanel.h
View file @
d2acffa5
...
...
@@ -12,19 +12,21 @@ in the source distribution for its full text.
#include "Settings.h"
#include "Panel.h"
#include "ScreenManager.h"
#include "ProcessList.h"
typedef
struct
AvailableMetersPanel_
{
Panel
super
;
ScreenManager
*
scr
;
Settings
*
settings
;
Header
*
header
;
Panel
*
leftPanel
;
Panel
*
rightPanel
;
ScreenManager
*
scr
;
}
AvailableMetersPanel
;
extern
PanelClass
AvailableMetersPanel_class
;
AvailableMetersPanel
*
AvailableMetersPanel_new
(
Settings
*
settings
,
Panel
*
leftMeters
,
Panel
*
rightMeters
,
ScreenManager
*
scr
);
AvailableMetersPanel
*
AvailableMetersPanel_new
(
Settings
*
settings
,
Header
*
header
,
Panel
*
leftMeters
,
Panel
*
rightMeters
,
ScreenManager
*
scr
,
ProcessList
*
pl
);
#endif
BatteryMeter.c
View file @
d2acffa5
...
...
@@ -9,7 +9,7 @@ This meter written by Ian P. Hands (iphands@gmail.com, ihands@redhat.com).
#include "BatteryMeter.h"
#include "
Platform
.h"
#include "
Battery
.h"
#include "ProcessList.h"
#include "CRT.h"
#include "String.h"
...
...
@@ -35,7 +35,7 @@ static void BatteryMeter_setValues(Meter * this, char *buffer, int len) {
ACPresence
isOnAC
;
double
percent
;
Platform
_get
B
at
teryLevel
(
&
percent
,
&
isOnAC
);
Battery
_get
D
at
a
(
&
percent
,
&
isOnAC
);
if
(
percent
==
-
1
)
{
this
->
values
[
0
]
=
0
;
...
...
CPUMeter.c
View file @
d2acffa5
...
...
@@ -8,7 +8,8 @@ in the source distribution for its full text.
#include "CPUMeter.h"
#include "CRT.h"
#include "ProcessList.h"
#include "Settings.h"
#include "Platform.h"
#include <assert.h>
#include <stdlib.h>
...
...
@@ -34,7 +35,7 @@ static void CPUMeter_init(Meter* this) {
int
cpu
=
this
->
param
;
if
(
this
->
pl
->
cpuCount
>
1
)
{
char
caption
[
10
];
sprintf
(
caption
,
"%-3d"
,
ProcessList
_cpuId
(
this
->
pl
,
cpu
-
1
));
sprintf
(
caption
,
"%-3d"
,
Settings
_cpuId
(
this
->
pl
->
settings
,
cpu
-
1
));
Meter_setCaption
(
this
,
caption
);
}
if
(
this
->
param
==
0
)
...
...
@@ -42,39 +43,12 @@ static void CPUMeter_init(Meter* this) {
}
static
void
CPUMeter_setValues
(
Meter
*
this
,
char
*
buffer
,
int
size
)
{
ProcessList
*
pl
=
this
->
pl
;
int
cpu
=
this
->
param
;
if
(
cpu
>
this
->
pl
->
cpuCount
)
{
snprintf
(
buffer
,
size
,
"absent"
);
return
;
}
CPUData
*
cpuData
=
&
(
pl
->
cpus
[
cpu
]);
double
total
=
(
double
)
(
cpuData
->
totalPeriod
==
0
?
1
:
cpuData
->
totalPeriod
);
double
percent
;
double
*
v
=
this
->
values
;
v
[
0
]
=
cpuData
->
nicePeriod
/
total
*
100
.
0
;
v
[
1
]
=
cpuData
->
userPeriod
/
total
*
100
.
0
;
if
(
pl
->
detailedCPUTime
)
{
v
[
2
]
=
cpuData
->
systemPeriod
/
total
*
100
.
0
;
v
[
3
]
=
cpuData
->
irqPeriod
/
total
*
100
.
0
;
v
[
4
]
=
cpuData
->
softIrqPeriod
/
total
*
100
.
0
;
v
[
5
]
=
cpuData
->
stealPeriod
/
total
*
100
.
0
;
v
[
6
]
=
cpuData
->
guestPeriod
/
total
*
100
.
0
;
v
[
7
]
=
cpuData
->
ioWaitPeriod
/
total
*
100
.
0
;
Meter_setItems
(
this
,
8
);
if
(
pl
->
accountGuestInCPUMeter
)
{
percent
=
v
[
0
]
+
v
[
1
]
+
v
[
2
]
+
v
[
3
]
+
v
[
4
]
+
v
[
5
]
+
v
[
6
];
}
else
{
percent
=
v
[
0
]
+
v
[
1
]
+
v
[
2
]
+
v
[
3
]
+
v
[
4
];
}
}
else
{
v
[
2
]
=
cpuData
->
systemAllPeriod
/
total
*
100
.
0
;
v
[
3
]
=
(
cpuData
->
stealPeriod
+
cpuData
->
guestPeriod
)
/
total
*
100
.
0
;
Meter_setItems
(
this
,
4
);
percent
=
v
[
0
]
+
v
[
1
]
+
v
[
2
]
+
v
[
3
];
}
percent
=
MIN
(
100
.
0
,
MAX
(
0
.
0
,
percent
));
if
(
isnan
(
percent
))
percent
=
0
.
0
;
double
percent
=
Platform_setCPUValues
(
this
,
cpu
);
snprintf
(
buffer
,
size
,
"%5.1f%%"
,
percent
);
}
...
...
@@ -89,7 +63,7 @@ static void CPUMeter_display(Object* cast, RichString* out) {
sprintf
(
buffer
,
"%5.1f%% "
,
this
->
values
[
1
]);
RichString_append
(
out
,
CRT_colors
[
METER_TEXT
],
":"
);
RichString_append
(
out
,
CRT_colors
[
CPU_NORMAL
],
buffer
);
if
(
this
->
pl
->
detailedCPUTime
)
{
if
(
this
->
pl
->
settings
->
detailedCPUTime
)
{
sprintf
(
buffer
,
"%5.1f%% "
,
this
->
values
[
2
]);
RichString_append
(
out
,
CRT_colors
[
METER_TEXT
],
"sy:"
);
RichString_append
(
out
,
CRT_colors
[
CPU_KERNEL
],
buffer
);
...
...
@@ -248,6 +222,7 @@ MeterClass AllCPUsMeter_class = {
.
attributes
=
CPUMeter_attributes
,
.
name
=
"AllCPUs"
,
.
uiName
=
"CPUs (1/1)"
,
.
description
=
"CPUs (1/1): all CPUs"
,
.
caption
=
"CPU"
,
.
draw
=
SingleColCPUsMeter_draw
,
.
init
=
AllCPUsMeter_init
,
...
...
@@ -266,6 +241,7 @@ MeterClass AllCPUs2Meter_class = {
.
attributes
=
CPUMeter_attributes
,
.
name
=
"AllCPUs2"
,
.
uiName
=
"CPUs (1&2/2)"
,
.
description
=
"CPUs (1&2/2): all CPUs in 2 shorter columns"
,
.
caption
=
"CPU"
,
.
draw
=
DualColCPUsMeter_draw
,
.
init
=
AllCPUsMeter_init
,
...
...
@@ -284,6 +260,7 @@ MeterClass LeftCPUsMeter_class = {
.
attributes
=
CPUMeter_attributes
,
.
name
=
"LeftCPUs"
,
.
uiName
=
"CPUs (1/2)"
,
.
description
=
"CPUs (1/2): first half of list"
,
.
caption
=
"CPU"
,
.
draw
=
SingleColCPUsMeter_draw
,
.
init
=
AllCPUsMeter_init
,
...
...
@@ -302,6 +279,7 @@ MeterClass RightCPUsMeter_class = {
.
attributes
=
CPUMeter_attributes
,
.
name
=
"RightCPUs"
,
.
uiName
=
"CPUs (2/2)"
,
.
description
=
"CPUs (2/2): second half of list"
,
.
caption
=
"CPU"
,
.
draw
=
SingleColCPUsMeter_draw
,
.
init
=
AllCPUsMeter_init
,
...
...
@@ -319,6 +297,7 @@ MeterClass LeftCPUs2Meter_class = {
.
total
=
100
.
0
,
.
attributes
=
CPUMeter_attributes
,
.
name
=
"LeftCPUs2"
,
.
description
=
"CPUs (1&2/4): first half in 2 shorter columns"
,
.
uiName
=
"CPUs (1&2/4)"
,
.
caption
=
"CPU"
,
.
draw
=
DualColCPUsMeter_draw
,
...
...
@@ -338,6 +317,7 @@ MeterClass RightCPUs2Meter_class = {
.
attributes
=
CPUMeter_attributes
,
.
name
=
"RightCPUs2"
,
.
uiName
=
"CPUs (3&4/4)"
,
.
description
=
"CPUs (3&4/4): second half in 2 shorter columns"
,
.
caption
=
"CPU"
,
.
draw
=
DualColCPUsMeter_draw
,
.
init
=
AllCPUsMeter_init
,
...
...
CRT.c
View file @
d2acffa5
This diff is collapsed.
Click to expand it.
CRT.h
View file @
d2acffa5
...
...
@@ -11,13 +11,6 @@ in the source distribution for its full text.
#define ColorPair(i,j) COLOR_PAIR((7-i)*8+j)
#define COLORSCHEME_DEFAULT 0
#define COLORSCHEME_MONOCHROME 1
#define COLORSCHEME_BLACKONWHITE 2
#define COLORSCHEME_BLACKONWHITE2 3
#define COLORSCHEME_MIDNIGHT 4
#define COLORSCHEME_BLACKNIGHT 5
#define Black COLOR_BLACK
#define Red COLOR_RED
#define Green COLOR_GREEN
...
...
@@ -31,6 +24,27 @@ in the source distribution for its full text.
#include <stdbool.h>
typedef
enum
TreeStr_
{
TREE_STR_HORZ
,
TREE_STR_VERT
,
TREE_STR_RTEE
,
TREE_STR_BEND
,
TREE_STR_TEND
,
TREE_STR_OPEN
,
TREE_STR_SHUT
,
TREE_STR_COUNT
}
TreeStr
;
typedef
enum
ColorSchemes_
{
COLORSCHEME_DEFAULT
=
0
,
COLORSCHEME_MONOCHROME
=
1
,
COLORSCHEME_BLACKONWHITE
=
2
,
COLORSCHEME_LIGHTTERMINAL
=
3
,
COLORSCHEME_MIDNIGHT
=
4
,
COLORSCHEME_BLACKNIGHT
=
5
,
LAST_COLORSCHEME
=
6
,
}
ColorSchemes
;
typedef
enum
ColorElements_
{
RESET_COLOR
,
DEFAULT_COLOR
,
...
...
@@ -65,13 +79,6 @@ typedef enum ColorElements_ {
BAR_SHADOW
,
GRAPH_1
,
GRAPH_2
,
GRAPH_3
,
GRAPH_4
,
GRAPH_5
,
GRAPH_6
,
GRAPH_7
,
GRAPH_8
,
GRAPH_9
,
MEMORY_USED
,
MEMORY_BUFFERS
,
MEMORY_BUFFERS_TEXT
,
...
...
@@ -103,13 +110,19 @@ void CRT_fatalError(const char* note) __attribute__ ((noreturn));
void
CRT_handleSIGSEGV
(
int
sgn
);
// TODO: centralize these in Settings.
extern
const
char
*
CRT_treeStrAscii
[
TREE_STR_COUNT
];
extern
int
CRT_colorScheme
;
extern
const
char
*
CRT_treeStrUtf8
[
TREE_STR_COUNT
];
extern
const
char
**
CRT_treeStr
;
extern
int
CRT_delay
;
extern
bool
CRT_utf8
;
extern
int
CRT_colors
[
LAST_COLORELEMENT
];
int
*
CRT_colors
;
extern
int
CRT_colorSchemes
[
LAST_COLORSCHEME
][
LAST_COLORELEMENT
];
extern
int
CRT_cursorX
;
...
...
@@ -117,6 +130,10 @@ extern int CRT_scrollHAmount;
char
*
CRT_termType
;
// TODO move color scheme to Settings, perhaps?
extern
int
CRT_colorScheme
;
void
*
backtraceArray
[
128
];
// TODO: pass an instance of Settings instead.
...
...
CategoriesPanel.c
View file @
d2acffa5
...
...
@@ -21,19 +21,26 @@ in the source distribution for its full text.
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "ProcessList.h"
typedef struct CategoriesPanel_ {
Panel super;
ScreenManager* scr;
Settings* settings;
ScreenManager* scr;
Header* header;
ProcessList* pl;
} CategoriesPanel;
}*/
static
const
char
*
MetersFunctions
[]
=
{
" "
,
" "
,
" "
,
"Type "
,
" "
,
" "
,
"MoveUp"
,
"MoveDn"
,
"Remove"
,
"Done "
,
NULL
};
static
const
char
*
MetersFunctions
[]
=
{
"Type "
,
"Move "
,
"Delete"
,
"Done "
,
NULL
};
static
const
char
*
MetersKeys
[]
=
{
"Space"
,
"Enter"
,
"Del"
,
"Esc"
};
static
int
MetersEvents
[]
=
{
' '
,
13
,
27
,
KEY_DC
};
static
const
char
*
AvailableMetersFunctions
[]
=
{
" "
,
" "
,
" "
,
" "
,
"Add L "
,
"Add R "
,
" "
,
" "
,
" "
,
"Done "
,
NULL
};
static
const
char
*
AvailableMetersFunctions
[]
=
{
"Add "
,
"Done "
,
NULL
};
static
const
char
*
AvailableMetersKeys
[]
=
{
"Enter"
,
"Esc"
};
static
int
AvailableMetersEvents
[]
=
{
13
,
27
};
static
const
char
*
DisplayOptionsFunctions
[]
=
{
" "
,
" "
,
" "
,
" "
,
" "
,
" "
,
" "
,
" "
,
" "
,
"Done "
,
NULL
};
...
...
@@ -51,12 +58,14 @@ static void CategoriesPanel_delete(Object* object) {
}
void
CategoriesPanel_makeMetersPage
(
CategoriesPanel
*
this
)
{
Panel
*
leftMeters
=
(
Panel
*
)
MetersPanel_new
(
this
->
settings
,
"Left column"
,
this
->
settings
->
header
->
leftMeters
,
this
->
scr
);
Panel
*
rightMeters
=
(
Panel
*
)
MetersPanel_new
(
this
->
settings
,
"Right column"
,
this
->
settings
->
header
->
rightMeters
,
this
->
scr
);
Panel
*
availableMeters
=
(
Panel
*
)
AvailableMetersPanel_new
(
this
->
settings
,
leftMeters
,
rightMeters
,
this
->
scr
);
ScreenManager_add
(
this
->
scr
,
leftMeters
,
FunctionBar_new
(
MetersFunctions
,
NULL
,
NULL
),
20
);
ScreenManager_add
(
this
->
scr
,
rightMeters
,
FunctionBar_new
(
MetersFunctions
,
NULL
,
NULL
),
20
);
ScreenManager_add
(
this
->
scr
,
availableMeters
,
FunctionBar_new
(
AvailableMetersFunctions
,
NULL
,
NULL
),
-
1
);
MetersPanel
*
leftMeters
=
MetersPanel_new
(
this
->
settings
,
"Left column"
,
this
->
header
->
columns
[
0
],
this
->
scr
);
MetersPanel
*
rightMeters
=
MetersPanel_new
(
this
->
settings
,
"Right column"
,
this
->
header
->
columns
[
1
],
this
->
scr
);
leftMeters
->
rightNeighbor
=
rightMeters
;
rightMeters
->
leftNeighbor
=
leftMeters
;
Panel
*
availableMeters
=
(
Panel
*
)
AvailableMetersPanel_new
(
this
->
settings
,
this
->
header
,
(
Panel
*
)
leftMeters
,
(
Panel
*
)
rightMeters
,
this
->
scr
,
this
->
pl
);
ScreenManager_add
(
this
->
scr
,
(
Panel
*
)
leftMeters
,
FunctionBar_new
(
MetersFunctions
,
MetersKeys
,
MetersEvents
),
20
);
ScreenManager_add
(
this
->
scr
,
(
Panel
*
)
rightMeters
,
FunctionBar_new
(
MetersFunctions
,
MetersKeys
,
MetersEvents
),
20
);
ScreenManager_add
(
this
->
scr
,
availableMeters
,
FunctionBar_new
(
AvailableMetersFunctions
,
AvailableMetersKeys
,
AvailableMetersEvents
),
-
1
);
}
static
void
CategoriesPanel_makeDisplayOptionsPage
(
CategoriesPanel
*
this
)
{
...
...
@@ -70,8 +79,8 @@ static void CategoriesPanel_makeColorsPage(CategoriesPanel* this) {
}
static
void
CategoriesPanel_makeColumnsPage
(
CategoriesPanel
*
this
)
{
Panel
*
columns
=
(
Panel
*
)
ColumnsPanel_new
(
this
->
settings
,
this
->
scr
);
Panel
*
availableColumns
=
(
Panel
*
)
AvailableColumnsPanel_new
(
this
->
settings
,
columns
,
this
->
scr
);
Panel
*
columns
=
(
Panel
*
)
ColumnsPanel_new
(
this
->
settings
);
Panel
*
availableColumns
=
(
Panel
*
)
AvailableColumnsPanel_new
(
columns
);
ScreenManager_add
(
this
->
scr
,
columns
,
FunctionBar_new
(
ColumnsFunctions
,
NULL
,
NULL
),
20
);
ScreenManager_add
(
this
->
scr
,
availableColumns
,
FunctionBar_new
(
AvailableColumnsFunctions
,
NULL
,
NULL
),
-
1
);
}
...
...
@@ -108,7 +117,6 @@ static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
result
=
IGNORED
;
break
;
}
if
(
result
==
HANDLED
)
{
int
size
=
ScreenManager_size
(
this
->
scr
);
for
(
int
i
=
1
;
i
<
size
;
i
++
)
...
...
@@ -128,7 +136,6 @@ static HandlerResult CategoriesPanel_eventHandler(Panel* super, int ch) {
break
;
}
}
return
result
;
}
...
...
@@ -140,13 +147,15 @@ PanelClass CategoriesPanel_class = {
.
eventHandler
=
CategoriesPanel_eventHandler
};
CategoriesPanel
*
CategoriesPanel_new
(
S
ettings
*
settings
,
ScreenManager
*
scr
)
{
CategoriesPanel
*
CategoriesPanel_new
(
S
creenManager
*
scr
,
Settings
*
settings
,
Header
*
header
,
ProcessList
*
pl
)
{
CategoriesPanel
*
this
=
AllocThis
(
CategoriesPanel
);
Panel
*
super
=
(
Panel
*
)
this
;
Panel_init
(
super
,
1
,
1
,
1
,
1
,
Class
(
ListItem
),
true
);
this
->
settings
=
settings
;
this
->
scr
=
scr
;
this
->
settings
=
settings
;
this
->
header
=
header
;
this
->
pl
=
pl
;
Panel_setHeader
(
super
,
"Setup"
);
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
"Meters"
,
0
));
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
"Display options"
,
0
));
...
...
CategoriesPanel.h
View file @
d2acffa5
...
...
@@ -12,12 +12,15 @@ in the source distribution for its full text.
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
#include "ProcessList.h"
typedef
struct
CategoriesPanel_
{
Panel
super
;
ScreenManager
*
scr
;
Settings
*
settings
;
ScreenManager
*
scr
;
Header
*
header
;
ProcessList
*
pl
;
}
CategoriesPanel
;
...
...
@@ -25,6 +28,6 @@ void CategoriesPanel_makeMetersPage(CategoriesPanel* this);
extern
PanelClass
CategoriesPanel_class
;
CategoriesPanel
*
CategoriesPanel_new
(
S
ettings
*
settings
,
ScreenManager
*
scr
);
CategoriesPanel
*
CategoriesPanel_new
(
S
creenManager
*
scr
,
Settings
*
settings
,
Header
*
header
,
ProcessList
*
pl
);
#endif
ColorsPanel.c
View file @
d2acffa5
...
...
@@ -16,7 +16,7 @@ in the source distribution for its full text.
// TO ADD A NEW SCHEME:
// * Increment the size of bool check in ColorsPanel.h
// * Add the entry in the ColorSchemes array below in the file
// * Add the entry in the ColorScheme
Name
s array below in the file
// * Add a define in CRT.h that matches the order of the array
// * Add the colors in CRT_setColors
...
...
@@ -34,7 +34,7 @@ typedef struct ColorsPanel_ {
}*/
static
const
char
*
ColorSchemes
[]
=
{
static
const
char
*
ColorScheme
Name
s
[]
=
{
"Default"
,
"Monochromatic"
,
"Black on White"
,
...
...
@@ -63,7 +63,7 @@ static HandlerResult ColorsPanel_eventHandler(Panel* super, int ch) {
case
KEY_ENTER
:
case
KEY_MOUSE
:
case
' '
:
for
(
int
i
=
0
;
ColorSchemes
[
i
]
!=
NULL
;
i
++
)
for
(
int
i
=
0
;
ColorScheme
Name
s
[
i
]
!=
NULL
;
i
++
)
CheckItem_set
((
CheckItem
*
)
Panel_get
(
super
,
i
),
false
);
CheckItem_set
((
CheckItem
*
)
Panel_get
(
super
,
mark
),
true
);
this
->
settings
->
colorScheme
=
mark
;
...
...
@@ -72,7 +72,7 @@ static HandlerResult ColorsPanel_eventHandler(Panel* super, int ch) {
if
(
result
==
HANDLED
)
{
this
->
settings
->
changed
=
true
;
Header
*
header
=
this
->
s
ettings
->
header
;
const
Header
*
header
=
this
->
s
cr
->
header
;
CRT_setColors
(
mark
);
Panel
*
menu
=
(
Panel
*
)
Vector_get
(
this
->
scr
->
panels
,
0
);
Header_draw
(
header
);
...
...
@@ -100,8 +100,8 @@ ColorsPanel* ColorsPanel_new(Settings* settings, ScreenManager* scr) {
this
->
scr
=
scr
;
Panel_setHeader
(
super
,
"Colors"
);
for
(
int
i
=
0
;
ColorSchemes
[
i
]
!=
NULL
;
i
++
)
{
Panel_add
(
super
,
(
Object
*
)
CheckItem_new
(
strdup
(
ColorSchemes
[
i
]),
NULL
,
false
));
for
(
int
i
=
0
;
ColorScheme
Name
s
[
i
]
!=
NULL
;
i
++
)
{
Panel_add
(
super
,
(
Object
*
)
CheckItem_new
(
strdup
(
ColorScheme
Name
s
[
i
]),
NULL
,
false
));
}
CheckItem_set
((
CheckItem
*
)
Panel_get
(
super
,
settings
->
colorScheme
),
true
);
return
this
;
...
...
ColorsPanel.h
View file @
d2acffa5
...
...
@@ -11,7 +11,7 @@ in the source distribution for its full text.
// TO ADD A NEW SCHEME:
// * Increment the size of bool check in ColorsPanel.h
// * Add the entry in the ColorSchemes array below in the file
// * Add the entry in the ColorScheme
Name
s array below in the file
// * Add a define in CRT.h that matches the order of the array
// * Add the colors in CRT_setColors
...
...
ColumnsPanel.c
View file @
d2acffa5
...
...
@@ -8,6 +8,7 @@ in the source distribution for its full text.
#include "ColumnsPanel.h"
#include "String.h"
#include "ListItem.h"
#include <assert.h>
#include <stdlib.h>
...
...
@@ -16,13 +17,12 @@ in the source distribution for its full text.
/*{
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef struct ColumnsPanel_ {
Panel super;
Settings* settings;
ScreenManager* scr
;
bool moving
;
} ColumnsPanel;
}*/
...
...
@@ -35,12 +35,32 @@ static void ColumnsPanel_delete(Object* object) {
}
static
HandlerResult
ColumnsPanel_eventHandler
(
Panel
*
super
,
int
ch
)
{
ColumnsPanel
*
const
this
=
(
ColumnsPanel
*
)
super
;
int
selected
=
Panel_getSelectedIndex
(
super
);
HandlerResult
result
=
IGNORED
;
int
size
=
Panel_size
(
super
);
switch
(
ch
)
{
case
0x0a
:
case
0x0d
:
case
KEY_ENTER
:
case
KEY_MOUSE
:
{
if
(
selected
<
size
-
1
)
{
this
->
moving
=
!
(
this
->
moving
);
((
ListItem
*
)
Panel_getSelected
(
super
))
->
moving
=
this
->
moving
;
result
=
HANDLED
;
}
break
;
}
case
KEY_UP
:
{
if
(
!
this
->
moving
)
{
break
;
}
/* else fallthrough */
}
case
KEY_F
(
7
):
case
'['
:
case
'-'
:
...
...
@@ -50,6 +70,13 @@ static HandlerResult ColumnsPanel_eventHandler(Panel* super, int ch) {
result
=
HANDLED
;
break
;
}
case
KEY_DOWN
:
{
if
(
!
this
->
moving
)
{
break
;
}
/* else fallthrough */
}
case
KEY_F
(
8
):
case
']'
:
case
'+'
:
...
...
@@ -90,47 +117,42 @@ PanelClass ColumnsPanel_class = {
.
eventHandler
=
ColumnsPanel_eventHandler
};
ColumnsPanel
*
ColumnsPanel_new
(
Settings
*
settings
,
ScreenManager
*
scr
)
{
ColumnsPanel
*
ColumnsPanel_new
(
Settings
*
settings
)
{
ColumnsPanel
*
this
=
AllocThis
(
ColumnsPanel
);
Panel
*
super
=
(
Panel
*
)
this
;
Panel_init
(
super
,
1
,
1
,
1
,
1
,
Class
(
ListItem
),
true
);
this
->
settings
=
settings
;
this
->
scr
=
scr
;
this
->
moving
=
false
;
Panel_setHeader
(
super
,
"Active Columns"
);
ProcessField
*
fields
=
this
->
settings
->
pl
->
fields
;
ProcessField
*
fields
=
this
->
settings
->
fields
;
for
(;
*
fields
;
fields
++
)
{
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
Process_field
Name
s
[
*
fields
]
,
0
));
Panel_add
(
super
,
(
Object
*
)
ListItem_new
(
Process_fields
[
*
fields
]
.
name
,
*
fields
));
}
return
this
;
}
int
ColumnsPanel_fieldNameToIndex
(
const
char
*
name
)
{
for
(
int
j
=
1
;
j
<=
LAST_PROCESSFIELD
;
j
++
)
{
if
(
String_eq
(
name
,
Process_field
Name
s
[
j
]))
{
if
(
String_eq
(
name
,
Process_fields
[
j
]
.
name
))
{
return
j
;
}
}
return
0
;
return
-
1
;
}
void
ColumnsPanel_update
(
Panel
*
super
)
{
ColumnsPanel
*
this
=
(
ColumnsPanel
*
)
super
;
int
size
=
Panel_size
(
super
);
this
->
settings
->
changed
=
true
;
// FIXME: this is crappily inefficient
free
(
this
->
settings
->
pl
->
fields
);
this
->
settings
->
pl
->
fields
=
(
ProcessField
*
)
malloc
(
sizeof
(
ProcessField
)
*
(
size
+
1
));
this
->
settings
->
pl
->
flags
=
0
;
this
->
settings
->
fields
=
realloc
(
this
->
settings
->
fields
,
sizeof
(
ProcessField
)
*
(
size
+
1
));
this
->
settings
->
flags
=
0
;
for
(
int
i
=
0
;
i
<
size
;
i
++
)
{
char
*
text
=
((
ListItem
*
)
Panel_get
(
super
,
i
))
->
value
;
int
j
=
ColumnsPanel_fieldNameToIndex
(
text
);
if
(
j
>
0
)
{
this
->
settings
->
pl
->
fields
[
i
]
=
j
;
this
->
settings
->
pl
->
flags
|=
Process_fieldFlags
[
j
];
}
int
key
=
((
ListItem
*
)
Panel_get
(
super
,
i
))
->
key
;
this
->
settings
->
fields
[
i
]
=
key
;
this
->
settings
->
flags
|=
Process_fields
[
key
].
flags
;
}
this
->
settings
->
pl
->
fields
[
size
]
=
0
;
this
->
settings
->
fields
[
size
]
=
0
;
}
ColumnsPanel.h
View file @
d2acffa5
...
...
@@ -11,19 +11,18 @@ in the source distribution for its full text.
#include "Panel.h"
#include "Settings.h"
#include "ScreenManager.h"
typedef
struct
ColumnsPanel_
{
Panel
super
;
Settings
*
settings
;
ScreenManager
*
scr
;
bool
moving
;
}
ColumnsPanel
;
extern
PanelClass
ColumnsPanel_class
;
ColumnsPanel
*
ColumnsPanel_new
(
Settings
*
settings
,
ScreenManager
*
scr
);
ColumnsPanel
*
ColumnsPanel_new
(
Settings
*
settings
);
int
ColumnsPanel_fieldNameToIndex
(
const
char
*
name
);
...
...
Prev
1
2
3
Next
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