mirror of https://github.com/xzeldon/htop.git
Add Unicode support, enabled with the --enable-unicode
flag, which requires libncursesw. Thanks to Sergej Pupykin!
This commit is contained in:
parent
fa87ff0251
commit
8fa33dc336
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
5
Meter.c
5
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;
|
||||
|
|
1
Meter.h
1
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>
|
||||
|
|
14
Panel.c
14
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;
|
||||
|
|
28
Process.c
28
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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]);
|
||||
|
|
104
RichString.c
104
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,14 +48,76 @@ 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++) {
|
||||
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_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++;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#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[j] | attrs;
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
@ -43,22 +127,6 @@ void RichString_write(RichString* this, int attrs, char* data) {
|
|||
RichString_append(this, attrs, data);
|
||||
}
|
||||
|
||||
void RichString_setAttr(RichString *this, int attrs) {
|
||||
chtype* ch = this->chstr;
|
||||
for (int i = 0; i < this->len; 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;
|
||||
ch++;
|
||||
}
|
||||
}
|
||||
|
||||
RichString RichString_quickString(int attrs, char* data) {
|
||||
RichString str;
|
||||
RichString_initVal(str);
|
||||
|
|
46
RichString.h
46
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,16 +49,30 @@ 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_appendn(RichString* this, int attrs, char* data_c, int len);
|
||||
|
||||
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);
|
||||
|
||||
extern void RichString_append(RichString* this, int attrs, char* data);
|
||||
|
||||
void RichString_write(RichString* this, int attrs, char* data);
|
||||
|
||||
void RichString_setAttr(RichString *this, int attrs);
|
||||
|
||||
void RichString_applyAttr(RichString *this, int attrs);
|
||||
|
||||
RichString RichString_quickString(int attrs, char* data);
|
||||
|
||||
#endif
|
||||
|
|
10
configure.ac
10
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.))
|
||||
|
|
7
htop.c
7
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")) {
|
||||
|
|
Loading…
Reference in New Issue