summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2011-11-03 22:12:12 +0000
committerHisham Muhammad <hisham@gobolinux.org>2011-11-03 22:12:12 +0000
commitca6b9238a39980aac650eb4bd82ace74c31a285f (patch)
treeded9fb3f434b3b2b313f5581a969a0e91cec10c1
parentb45b9e2b33d474f6bef70ead2011f2da65333fa2 (diff)
Support for UTF-8 tree drawing
(thanks to Bin Guo)
-rw-r--r--ChangeLog2
-rw-r--r--Process.c25
-rw-r--r--ProcessList.c46
-rw-r--r--ProcessList.h22
-rw-r--r--htop.c33
5 files changed, 114 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 957e0090..80ef0f94 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.)
diff --git a/Process.c b/Process.c
index 0632278a..31c87406 100644
--- a/Process.c
+++ b/Process.c
@@ -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;
diff --git a/ProcessList.c b/ProcessList.c
index c986cecd..b681fede 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -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,7 +319,10 @@ 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);
- process->indent = nextIndent;
+ if (i == size - 1)
+ process->indent = -nextIndent;
+ else
+ process->indent = nextIndent;
}
Vector_delete(children);
}
diff --git a/ProcessList.h b/ProcessList.h
index e68ca49e..5432c187 100644
--- a/ProcessList.h
+++ b/ProcessList.h
@@ -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);
diff --git a/htop.c b/htop.c
index 10924a1d..b71198a6 100644
--- a/htop.c
+++ b/htop.c
@@ -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))) {
@@ -361,6 +364,34 @@ int main(int argc, char** argv) {
settings->delay = delay;
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);

© 2014-2024 Faster IT GmbH | imprint | privacy policy