summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2008-03-09 02:33:23 +0000
committerHisham Muhammad <hisham@gobolinux.org>2008-03-09 02:33:23 +0000
commit8fa33dc3365f0e27a5013748321def4bef937049 (patch)
treecf1498456001b55157c4ce9dcd516dd5226158e3
parentfa87ff02514cdd148cdcf8d24de0599a400f3918 (diff)
Add Unicode support, enabled with the --enable-unicode
flag, which requires libncursesw. Thanks to Sergej Pupykin!
-rw-r--r--ChangeLog3
-rw-r--r--Makefile.am2
-rw-r--r--Meter.c5
-rw-r--r--Meter.h1
-rw-r--r--Panel.c14
-rw-r--r--Process.c28
-rw-r--r--Process.h1
-rw-r--r--ProcessList.c2
-rw-r--r--RichString.c100
-rw-r--r--RichString.h44
-rw-r--r--configure.ac10
-rw-r--r--htop.c7
-rw-r--r--htop.h1
13 files changed, 171 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog
index 1cfbbfb8..b4ecb17e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
What's new in version 0.7.1
+* Add Unicode support, enabled with the --enable-unicode
+ flag, which requires libncursesw.
+ (thanks to Sergej Pupykin)
* BUGFIX: Fix display of CPU count for threaded processes.
When user threads are hidden, process now shows the
sum of processor usage for all processors. When user
diff --git a/Makefile.am b/Makefile.am
index 26b18aa7..5c148685 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -10,7 +10,7 @@ applications_DATA = htop.desktop
pixmapdir = $(datadir)/pixmaps
pixmap_DATA = htop.png
-htop_CFLAGS = -pedantic -Wall -std=c99
+htop_CFLAGS = -pedantic -Wall -std=c99 -D_XOPEN_SOURCE_EXTENDED
AM_CPPFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
myhtopsources = AvailableMetersPanel.c CategoriesPanel.c CheckItem.c \
diff --git a/Meter.c b/Meter.c
index 0e9ef05f..fb7d8425 100644
--- a/Meter.c
+++ b/Meter.c
@@ -18,6 +18,7 @@ in the source distribution for its full text.
#include "ListItem.h"
#include "String.h"
#include "ProcessList.h"
+#include "RichString.h"
#include "debug.h"
#include <assert.h>
@@ -266,7 +267,7 @@ void TextMeterMode_draw(Meter* this, int x, int y, int w) {
Meter_displayToStringBuffer(this, buffer);
mvhline(y, x, ' ', CRT_colors[DEFAULT_COLOR]);
attrset(CRT_colors[RESET_COLOR]);
- mvaddchstr(y, x, Meter_stringBuffer.chstr);
+ RichString_printVal(Meter_stringBuffer, y, x);
}
/* ---------- BarMeterMode ---------- */
@@ -418,7 +419,7 @@ void LEDMeterMode_draw(Meter* this, int x, int y, int w) {
mvaddstr(y+2, x, this->caption);
int xx = x + strlen(this->caption);
for (int i = 0; i < Meter_stringBuffer.len; i++) {
- char c = Meter_stringBuffer.chstr[i];
+ char c = RichString_getCharVal(Meter_stringBuffer, i);
if (c >= '0' && c <= '9') {
LEDMeterMode_drawDigit(xx, y, c-48);
xx += 4;
diff --git a/Meter.h b/Meter.h
index e564d3c3..8099a8ec 100644
--- a/Meter.h
+++ b/Meter.h
@@ -21,6 +21,7 @@ in the source distribution for its full text.
#include "ListItem.h"
#include "String.h"
#include "ProcessList.h"
+#include "RichString.h"
#include "debug.h"
#include <assert.h>
diff --git a/Panel.c b/Panel.c
index 14f542bc..00ff4c69 100644
--- a/Panel.c
+++ b/Panel.c
@@ -265,8 +265,8 @@ void Panel_draw(Panel* this, bool focus) {
attrset(attr);
mvhline(y, x, ' ', this->w);
if (scrollH < this->header.len) {
- mvaddchnstr(y, x, this->header.chstr + scrollH,
- MIN(this->header.len - scrollH, this->w));
+ RichString_printoffnVal(this->header, y, x, scrollH,
+ MIN(this->header.len - scrollH, this->w));
}
attrset(CRT_colors[RESET_COLOR]);
y++;
@@ -289,12 +289,12 @@ void Panel_draw(Panel* this, bool focus) {
RichString_setAttr(&itemRef, highlight);
mvhline(y + j, x+0, ' ', this->w);
if (amt > 0)
- mvaddchnstr(y+j, x+0, itemRef.chstr + scrollH, amt);
+ RichString_printoffnVal(itemRef, y+j, x+0, scrollH, amt);
attrset(CRT_colors[RESET_COLOR]);
} else {
mvhline(y+j, x+0, ' ', this->w);
if (amt > 0)
- mvaddchnstr(y+j, x+0, itemRef.chstr + scrollH, amt);
+ RichString_printoffnVal(itemRef, y+j, x+0, scrollH, amt);
}
}
for (int i = y + (last - first); i < y + this->h; i++)
@@ -312,12 +312,14 @@ void Panel_draw(Panel* this, bool focus) {
newObj->display(newObj, &newRef);
mvhline(y+ this->oldSelected - this->scrollV, x+0, ' ', this->w);
if (scrollH < oldRef.len)
- mvaddchnstr(y+ this->oldSelected - this->scrollV, x+0, oldRef.chstr + this->scrollH, MIN(oldRef.len - scrollH, this->w));
+ RichString_printoffnVal(oldRef, y+this->oldSelected - this->scrollV, x,
+ this->scrollH, MIN(oldRef.len - scrollH, this->w));
attrset(highlight);
mvhline(y+this->selected - this->scrollV, x+0, ' ', this->w);
RichString_setAttr(&newRef, highlight);
if (scrollH < newRef.len)
- mvaddchnstr(y+this->selected - this->scrollV, x+0, newRef.chstr + this->scrollH, MIN(newRef.len - scrollH, this->w));
+ RichString_printoffnVal(newRef, y+this->selected - this->scrollV, x,
+ this->scrollH, MIN(newRef.len - scrollH, this->w));
attrset(CRT_colors[RESET_COLOR]);
}
this->oldSelected = this->selected;
diff --git a/Process.c b/Process.c
index ab66d5bb..0b551ebb 100644
--- a/Process.c
+++ b/Process.c
@@ -11,6 +11,7 @@ in the source distribution for its full text.
#include "CRT.h"
#include "String.h"
#include "Process.h"
+#include "RichString.h"
#include "debug.h"
@@ -265,23 +266,20 @@ static void Process_printTime(RichString* str, unsigned long t) {
}
static inline void Process_writeCommand(Process* this, int attr, int baseattr, RichString* str) {
+ int start = str->len;
+ RichString_append(str, attr, this->comm);
if (this->pl->highlightBaseName) {
- char* firstSpace = strchr(this->comm, ' ');
- if (firstSpace) {
- char* slash = firstSpace;
- while (slash > this->comm && *slash != '/')
- slash--;
- if (slash > this->comm) {
- slash++;
- RichString_appendn(str, attr, this->comm, slash - this->comm);
- }
- RichString_appendn(str, baseattr, slash, firstSpace - slash);
- RichString_append(str, attr, firstSpace);
- } else {
- RichString_append(str, baseattr, this->comm);
+ int finish = str->len - 1;
+ int space = RichString_findChar(str, ' ', start);
+ if (space != -1)
+ finish = space - 1;
+ for (;;) {
+ int slash = RichString_findChar(str, '/', start);
+ if (slash == -1 || slash > finish)
+ break;
+ start = slash + 1;
}
- } else {
- RichString_append(str, attr, this->comm);
+ RichString_setAttrn(str, baseattr, start, finish);
}
}
diff --git a/Process.h b/Process.h
index ac1c1af7..b107073d 100644
--- a/Process.h
+++ b/Process.h
@@ -14,6 +14,7 @@ in the source distribution for its full text.
#include "Object.h"
#include "CRT.h"
#include "String.h"
+#include "RichString.h"
#include "debug.h"
diff --git a/ProcessList.c b/ProcessList.c
index 66d60949..04ac6f3e 100644
--- a/ProcessList.c
+++ b/ProcessList.c
@@ -283,7 +283,7 @@ void ProcessList_invertSortOrder(ProcessList* this) {
RichString ProcessList_printHeader(ProcessList* this) {
RichString out;
- RichString_init(&out);
+ RichString_initVal(out);
ProcessField* fields = this->fields;
for (int i = 0; fields[i]; i++) {
char* field = Process_printField(fields[i]);
diff --git a/RichString.c b/RichString.c
index 2cc7d172..c397f3f1 100644
--- a/RichString.c
+++ b/RichString.c
@@ -1,12 +1,20 @@
#include "RichString.h"
+#ifndef CONFIG_H
+#define CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <curses.h>
#include "debug.h"
#include <assert.h>
+#ifdef HAVE_LIBNCURSESW
+#include <wchar.h>
+#endif
#define RICHSTRING_MAXLEN 300
@@ -15,9 +23,23 @@
#define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0
+#ifdef HAVE_LIBNCURSESW
+#define RichString_printVal(this, y, x) mvadd_wchstr(y, x, this.chstr)
+#define RichString_printoffnVal(this, y, x, off, n) mvadd_wchnstr(y, x, this.chstr + off, n)
+#define RichString_getCharVal(this, i) (this.chstr[i].chars[0] & 255)
+#else
+#define RichString_printVal(this, y, x) mvaddchstr(y, x, this.chstr)
+#define RichString_printoffnVal(this, y, x, off, n) mvaddchnstr(y, x, this.chstr + off, n)
+#define RichString_getCharVal(this, i) (this.chstr[i])
+#endif
+
typedef struct RichString_ {
int len;
+#ifdef HAVE_LIBNCURSESW
+ cchar_t chstr[RICHSTRING_MAXLEN+1];
+#else
chtype chstr[RICHSTRING_MAXLEN+1];
+#endif
} RichString;
}*/
@@ -26,37 +48,83 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
-inline void RichString_appendn(RichString* this, int attrs, char* data, int len) {
+#ifdef HAVE_LIBNCURSESW
+
+inline void RichString_appendn(RichString* this, int attrs, char* data_c, int len) {
+ wchar_t data[RICHSTRING_MAXLEN];
+ len = mbstowcs(data, data_c, RICHSTRING_MAXLEN);
+ if (len<0)
+ return;
int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
- for (int i = this->len, j = 0; i < last; i++, j++)
- this->chstr[i] = data[j] | attrs;
- this->chstr[last] = 0;
+ for (int i = this->len, j = 0; i < last; i++, j++) {
+ memset(&this->chstr[i], 0, sizeof(this->chstr[i]));
+ this->chstr[i].chars[0] = data[j];
+ this->chstr[i].attr = attrs;
+ }
+ this->chstr[last].chars[0] = 0;
this->len = last;
}
-inline void RichString_append(RichString* this, int attrs, char* data) {
- RichString_appendn(this, attrs, data, strlen(data));
+inline void RichString_setAttrn(RichString *this, int attrs, int start, int finish) {
+ cchar_t* ch = this->chstr + start;
+ for (int i = start; i <= finish; i++) {
+ ch->attr = attrs;
+ ch++;
+ }
}
-void RichString_write(RichString* this, int attrs, char* data) {
- RichString_init(this);
- RichString_append(this, attrs, data);
+int RichString_findChar(RichString *this, char c, int start) {
+ wchar_t wc = btowc(c);
+ cchar_t* ch = this->chstr + start;
+ for (int i = start; i < this->len; i++) {
+ if (ch->chars[0] == wc)
+ return i;
+ ch++;
+ }
+ return -1;
}
-void RichString_setAttr(RichString *this, int attrs) {
- chtype* ch = this->chstr;
- for (int i = 0; i < this->len; i++) {
+#else
+
+inline void RichString_appendn(RichString* this, int attrs, char* data_c, int len) {
+ int last = MIN(RICHSTRING_MAXLEN - 1, len + this->len);
+ for (int i = this->len, j = 0; i < last; i++, j++)
+ this->chstr[i] = data_c[j] | attrs;
+ this->chstr[last] = 0;
+ this->len = last;
+}
+
+void RichString_setAttrn(RichString *this, int attrs, int start, int finish) {
+ chtype* ch = this->chstr + start;
+ for (int i = start; i <= finish; i++) {
*ch = (*ch & 0xff) | attrs;
ch++;
}
}
-void RichString_applyAttr(RichString *this, int attrs) {
- chtype* ch = this->chstr;
- for (int i = 0; i < this->len; i++) {
- *ch |= attrs;
+int RichString_findChar(RichString *this, char c, int start) {
+ chtype* ch = this->chstr + start;
+ for (int i = start; i < this->len; i++) {
+ if ((*ch & 0xff) == c)
+ return i;
ch++;
}
+ return -1;
+}
+
+#endif
+
+void RichString_setAttr(RichString *this, int attrs) {
+ RichString_setAttrn(this, attrs, 0, this->len - 1);
+}
+
+inline void RichString_append(RichString* this, int attrs, char* data) {
+ RichString_appendn(this, attrs, data, strlen(data));
+}
+
+void RichString_write(RichString* this, int attrs, char* data) {
+ RichString_init(this);
+ RichString_append(this, attrs, data);
}
RichString RichString_quickString(int attrs, char* data) {
diff --git a/RichString.h b/RichString.h
index 6eed0d92..7f777bba 100644
--- a/RichString.h
+++ b/RichString.h
@@ -4,12 +4,20 @@
#define HEADER_RichString
+#ifndef CONFIG_H
+#define CONFIG_H
+#include "config.h"
+#endif
+
#include <stdlib.h>
#include <string.h>
#include <curses.h>
#include "debug.h"
#include <assert.h>
+#ifdef HAVE_LIBNCURSESW
+#include <wchar.h>
+#endif
#define RICHSTRING_MAXLEN 300
@@ -17,9 +25,23 @@
#define RichString_init(this) (this)->len = 0
#define RichString_initVal(this) (this).len = 0
+#ifdef HAVE_LIBNCURSESW
+#define RichString_printVal(this, y, x) mvadd_wchstr(y, x, this.chstr)
+#define RichString_printoffnVal(this, y, x, off, n) mvadd_wchnstr(y, x, this.chstr + off, n)
+#define RichString_getCharVal(this, i) (this.chstr[i].chars[0] & 255)
+#else
+#define RichString_printVal(this, y, x) mvaddchstr(y, x, this.chstr)
+#define RichString_printoffnVal(this, y, x, off, n) mvaddchnstr(y, x, this.chstr + off, n)
+#define RichString_getCharVal(this, i) (this.chstr[i])
+#endif
+
typedef struct RichString_ {
int len;
+#ifdef HAVE_LIBNCURSESW
+ cchar_t chstr[RICHSTRING_MAXLEN+1];
+#else
chtype chstr[RICHSTRING_MAXLEN+1];
+#endif
} RichString;
@@ -27,15 +49,29 @@ typedef struct RichString_ {
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif
-extern void RichString_appendn(RichString* this, int attrs, char* data, int len);
+#ifdef HAVE_LIBNCURSESW
-extern void RichString_append(RichString* this, int attrs, char* data);
+extern void RichString_appendn(RichString* this, int attrs, char* data_c, int len);
-void RichString_write(RichString* this, int attrs, char* data);
+extern void RichString_setAttrn(RichString *this, int attrs, int start, int finish);
+
+int RichString_findChar(RichString *this, char c, int start);
+
+#else
+
+extern void RichString_appendn(RichString* this, int attrs, char* data_c, int len);
+
+void RichString_setAttrn(RichString *this, int attrs, int start, int finish);
+
+int RichString_findChar(RichString *this, char c, int start);
+
+#endif
void RichString_setAttr(RichString *this, int attrs);
-void RichString_applyAttr(RichString *this, int attrs);
+extern void RichString_append(RichString* this, int attrs, char* data);
+
+void RichString_write(RichString* this, int attrs, char* data);
RichString RichString_quickString(int attrs, char* data);
diff --git a/configure.ac b/configure.ac
index f54310fc..f82eff9d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,7 +16,6 @@ AM_ENABLE_STATIC
AC_PROG_LIBTOOL
# Checks for libraries.
-AC_CHECK_LIB([ncurses], [refresh], [], [missing_libraries="$missing_libraries libncurses"])
AC_CHECK_LIB([m], [ceil], [], [missing_libraries="$missing_libraries libm"])
if test ! -z "$missing_libraries"; then
@@ -67,7 +66,14 @@ AC_ARG_WITH(proc, [ --with-proc=DIR Location of a Linux-compatible proc fi
AC_ARG_ENABLE(openvz, [AC_HELP_STRING([--enable-openvz], [enable OpenVZ support])], ,enable_openvz="no")
if test "x$enable_openvz" = xyes; then
- AC_DEFINE(HAVE_OPENVZ, 1, [Define if openvz support enabled.])
+ AC_DEFINE(HAVE_OPENVZ, 1, [Define if openvz support enabled.])
+fi
+
+AC_ARG_ENABLE(unicode, [AC_HELP_STRING([--enable-unicode], [enable Unicode support])], ,enable_unicode="no")
+if test "x$enable_unicode" = xyes; then
+ AC_CHECK_LIB([ncursesw], [refresh], [], [missing_libraries="$missing_libraries libncursesw"])
+else
+ AC_CHECK_LIB([ncurses], [refresh], [], [missing_libraries="$missing_libraries libncurses"])
fi
AC_CHECK_FILE($PROCDIR/stat,,AC_MSG_ERROR(Cannot find /proc/stat. Make sure you have a Linux-compatible /proc filesystem mounted. See the file README for help.))
diff --git a/htop.c b/htop.c
index ec5d79e3..50ecb416 100644
--- a/htop.c
+++ b/htop.c
@@ -11,6 +11,7 @@ in the source distribution for its full text.
#include <sys/param.h>
#include <ctype.h>
#include <stdbool.h>
+#include <locale.h>
#include "ProcessList.h"
#include "CRT.h"
@@ -221,6 +222,12 @@ int main(int argc, char** argv) {
uid_t userId = 0;
int sortKey = 0;
+ char *lc_ctype = getenv("LC_CTYPE");
+ if(lc_ctype != NULL)
+ setlocale(LC_CTYPE, lc_ctype);
+ else
+ setlocale(LC_CTYPE, getenv("LC_ALL"));
+
int arg = 1;
while (arg < argc) {
if (String_eq(argv[arg], "--help")) {
diff --git a/htop.h b/htop.h
index 33745eb5..139019e0 100644
--- a/htop.h
+++ b/htop.h
@@ -15,6 +15,7 @@ in the source distribution for its full text.
#include <sys/param.h>
#include <ctype.h>
#include <stdbool.h>
+#include <locale.h>
#include "ProcessList.h"
#include "CRT.h"

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