diff options
author | Hisham Muhammad <hisham@gobolinux.org> | 2008-03-09 02:33:23 +0000 |
---|---|---|
committer | Hisham Muhammad <hisham@gobolinux.org> | 2008-03-09 02:33:23 +0000 |
commit | 8fa33dc3365f0e27a5013748321def4bef937049 (patch) | |
tree | cf1498456001b55157c4ce9dcd516dd5226158e3 | |
parent | fa87ff02514cdd148cdcf8d24de0599a400f3918 (diff) |
Add Unicode support, enabled with the --enable-unicode
flag, which requires libncursesw.
Thanks to Sergej Pupykin!
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | Meter.c | 5 | ||||
-rw-r--r-- | Meter.h | 1 | ||||
-rw-r--r-- | Panel.c | 14 | ||||
-rw-r--r-- | Process.c | 28 | ||||
-rw-r--r-- | Process.h | 1 | ||||
-rw-r--r-- | ProcessList.c | 2 | ||||
-rw-r--r-- | RichString.c | 100 | ||||
-rw-r--r-- | RichString.h | 44 | ||||
-rw-r--r-- | configure.ac | 10 | ||||
-rw-r--r-- | htop.c | 7 | ||||
-rw-r--r-- | htop.h | 1 |
13 files changed, 171 insertions, 47 deletions
@@ -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 \ @@ -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; @@ -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> @@ -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; @@ -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); } } @@ -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.)) @@ -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")) { @@ -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" |