Support for UTF-8 tree drawing

(thanks to Bin Guo)
This commit is contained in:
Hisham Muhammad 2011-11-03 22:12:12 +00:00
parent b45b9e2b33
commit ca6b9238a3
5 changed files with 114 additions and 14 deletions

View File

@ -2,6 +2,8 @@
What's new in version 0.9.1
* Switch from PLPA, which is now deprecated, to HWLOC.
* Support for UTF-8 tree drawing
(thanks to Bin Guo)
* Option for counting CPUs from zero
(thanks to Sean Noonan)
* Meters update in every screen (no longer halting while on Setup, etc.)

View File

@ -387,21 +387,26 @@ static void Process_writeField(Process* this, RichString* str, ProcessField fiel
} else {
char* buf = buffer;
int maxIndent = 0;
const char **treeStr = this->pl->treeStr;
bool lastItem = (this->indent < 0);
int indent = (this->indent < 0 ? -this->indent : this->indent);
if (treeStr == NULL)
treeStr = ProcessList_treeStrAscii;
for (int i = 0; i < 32; i++)
if (this->indent & (1 << i))
if (indent & (1 << i))
maxIndent = i+1;
for (int i = 0; i < maxIndent - 1; i++) {
if (this->indent & (1 << i))
snprintf(buf, n, " | ");
int written;
if (indent & (1 << i))
written = snprintf(buf, n, "%s ", treeStr[TREE_STR_VERT]);
else
snprintf(buf, n, " ");
buf += 4;
n -= 4;
written = snprintf(buf, n, " ");
buf += written;
n -= written;
}
if (this->pl->direction == 1)
snprintf(buf, n, " `%s ", this->showChildren ? "-" : "+" );
else
snprintf(buf, n, " ,%s ", this->showChildren ? "-" : "+" );
const char* draw = treeStr[lastItem ? (this->pl->direction == 1 ? TREE_STR_BEND : TREE_STR_TEND) : TREE_STR_RTEE];
snprintf(buf, n, "%s%s ", draw, this->showChildren ? treeStr[TREE_STR_SHUT] : treeStr[TREE_STR_OPEN] );
RichString_append(str, CRT_colors[PROCESS_TREE], buffer);
Process_writeCommand(this, attr, baseattr, str);
return;

View File

@ -57,9 +57,23 @@ in the source distribution for its full text.
#ifndef ProcessList_cpuId
#define ProcessList_cpuId(pl, cpu) ((pl)->countCPUsFromZero ? (cpu) : (cpu)+1)
#endif
}*/
/*{
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 TreeType_ {
TREE_TYPE_AUTO,
TREE_TYPE_ASCII,
TREE_TYPE_UTF8,
} TreeType;
typedef struct CPUData_ {
unsigned long long int totalTime;
@ -132,12 +146,34 @@ typedef struct ProcessList_ {
bool highlightThreads;
bool detailedCPUTime;
bool countCPUsFromZero;
const char **treeStr;
} ProcessList;
}*/
static ProcessField defaultHeaders[] = { PID, USER, PRIORITY, NICE, M_SIZE, M_RESIDENT, M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
const char *ProcessList_treeStrAscii[TREE_STR_COUNT] = {
"-", // TREE_STR_HORZ
"|", // TREE_STR_VERT
"`", // TREE_STR_RTEE
"`", // TREE_STR_BEND
",", // TREE_STR_TEND
"+", // TREE_STR_OPEN
"-", // TREE_STR_SHUT
};
const char *ProcessList_treeStrUtf8[TREE_STR_COUNT] = {
"\xe2\x94\x80", // TREE_STR_HORZ ─
"\xe2\x94\x82", // TREE_STR_VERT │
"\xe2\x94\x9c", // TREE_STR_RTEE ├
"\xe2\x94\x94", // TREE_STR_BEND └
"\xe2\x94\x8c", // TREE_STR_TEND ┌
"+", // TREE_STR_OPEN +
"\xe2\x94\x80", // TREE_STR_SHUT ─
};
ProcessList* ProcessList_new(UsersTable* usersTable) {
ProcessList* this;
this = calloc(sizeof(ProcessList), 1);
@ -194,6 +230,7 @@ ProcessList* ProcessList_new(UsersTable* usersTable) {
this->highlightMegabytes = false;
this->detailedCPUTime = false;
this->countCPUsFromZero = false;
this->treeStr = NULL;
return this;
}
@ -282,6 +319,9 @@ static void ProcessList_buildTree(ProcessList* this, pid_t pid, int level, int i
assert(this->processes2->items == s+1); (void)s;
int nextIndent = indent | (1 << level);
ProcessList_buildTree(this, process->pid, level+1, (i < size - 1) ? nextIndent : indent, direction, show ? process->showChildren : false);
if (i == size - 1)
process->indent = -nextIndent;
else
process->indent = nextIndent;
}
Vector_delete(children);

View File

@ -60,6 +60,22 @@ in the source distribution for its full text.
#define ProcessList_cpuId(pl, cpu) ((pl)->countCPUsFromZero ? (cpu) : (cpu)+1)
#endif
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 TreeType_ {
TREE_TYPE_AUTO,
TREE_TYPE_ASCII,
TREE_TYPE_UTF8,
} TreeType;
typedef struct CPUData_ {
unsigned long long int totalTime;
@ -132,9 +148,15 @@ typedef struct ProcessList_ {
bool highlightThreads;
bool detailedCPUTime;
bool countCPUsFromZero;
const char **treeStr;
} ProcessList;
extern const char *ProcessList_treeStrAscii[TREE_STR_COUNT];
extern const char *ProcessList_treeStrUtf8[TREE_STR_COUNT];
ProcessList* ProcessList_new(UsersTable* usersTable);
void ProcessList_delete(ProcessList* this);

33
htop.c
View File

@ -263,6 +263,7 @@ int main(int argc, char** argv) {
bool userOnly = false;
uid_t userId = 0;
int usecolors = 1;
TreeType treeType = TREE_TYPE_AUTO;
int opt, opti=0;
static struct option long_opts[] =
@ -281,8 +282,10 @@ int main(int argc, char** argv) {
char *lc_ctype = getenv("LC_CTYPE");
if(lc_ctype != NULL)
setlocale(LC_CTYPE, lc_ctype);
else if ((lc_ctype = getenv("LC_ALL")))
setlocale(LC_CTYPE, lc_ctype);
else
setlocale(LC_CTYPE, getenv("LC_ALL"));
setlocale(LC_CTYPE, "");
/* Parse arguments */
while ((opt = getopt_long(argc, argv, "hvCs:d:u:", long_opts, &opti))) {
@ -362,6 +365,34 @@ int main(int argc, char** argv) {
if (!usecolors)
settings->colorScheme = COLORSCHEME_MONOCHROME;
if (treeType == TREE_TYPE_AUTO) {
#ifdef HAVE_LIBNCURSESW
char *locale = setlocale(LC_ALL, NULL);
if (locale == NULL || locale[0] == '\0')
locale = setlocale(LC_CTYPE, NULL);
if (locale != NULL &&
(strstr(locale, "UTF-8") ||
strstr(locale, "utf-8") ||
strstr(locale, "UTF8") ||
strstr(locale, "utf8")))
treeType = TREE_TYPE_UTF8;
else
treeType = TREE_TYPE_ASCII;
#else
treeType = TREE_TYPE_ASCII;
#endif
}
switch (treeType) {
default:
case TREE_TYPE_ASCII:
pl->treeStr = ProcessList_treeStrAscii;
break;
case TREE_TYPE_UTF8:
pl->treeStr = ProcessList_treeStrUtf8;
break;
}
CRT_init(settings->delay, settings->colorScheme);
panel = Panel_new(0, headerHeight, COLS, LINES - headerHeight - 2, PROCESS_CLASS, false, NULL);