Commit 8fa33dc3 authored by Hisham Muhammad's avatar Hisham Muhammad
Browse files

Add Unicode support, enabled with the --enable-unicode

flag, which requires libncursesw.
Thanks to Sergej Pupykin!
parent fa87ff02
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
......
......@@ -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"
......
......@@ -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]);
......
#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) {
......
......@@ -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);
......
......@@ -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"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment