Skip to content

Commit

Permalink
monitor: Use UTF-8 instead of ACS (#77)
Browse files Browse the repository at this point in the history
Some terminal emulators such as PuTTY or the macOS terminal don't have full VT100 ACS support. For this reason, the RTS2 monitor borders and lines are not rendered properly.

Some applications rely on using directly the equivalent UTF-8 character, making sure the terminal supports UTF-8 encoding.

This way, the monitor appareance is consistent between terminal emulators.
  • Loading branch information
XePeleato authored May 15, 2024
1 parent 6ac8bf7 commit a529691
Show file tree
Hide file tree
Showing 14 changed files with 105 additions and 47 deletions.
22 changes: 11 additions & 11 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -181,28 +181,28 @@ AC_ARG_WITH(ncurses,
*) ncurses=${withval} ;;
esac],[ncurses=yes])

PKG_CHECK_MODULES([NCURSES],[ncurses],,[
PKG_CHECK_MODULES([NCURSESW],[ncursesw],,[
AC_MSG_RESULT(not found)
AS_IF([test "x${ncurses}" !- "xyes"], [LDFLAGS="${LDFLAGS} -L${ncurses}"])
AC_CHECK_LIB([ncurses], [mvwprintw], [
NCURSES_LIBS="-lncurses"
AS_IF([test "x${ncursesw}" != "xyes"], [LDFLAGS="${LDFLAGS} -L${ncursesw}"])
AC_CHECK_LIB([ncursesw], [mvwprintw], [
NCURSESW_LIBS="-lncursesw"
],[
cat<<EOF
**** ncurses library is not installed.
**** ncursesw library is not installed.
**** Please install ncurses (development package)
EOF
exit 1
])
AS_IF([test "x${ncurses}" != "xyes"], [
NCURSES_LIBS="-L${ncurses} ${NCURSES_LIBS}"
NCURSES_CFLAGS="-I${ncurses}"
AS_IF([test "x${ncursesw}" != "xyes"], [
NCURSESW_LIBS="-L${ncursesw} ${NCURSES_LIBS}"
NCURSESW_CFLAGS="-I${ncursesw}"
],[
NCURSES_CFLAGS=""
NCURSESW_CFLAGS=""
])
])

AC_SUBST(NCURSES_LIBS)
AC_SUBST(NCURSES_CFLAGS)
AC_SUBST(NCURSESW_LIBS)
AC_SUBST(NCURSESW_CFLAGS)

dnl Check for GraphicsMagic++ library

Expand Down
6 changes: 3 additions & 3 deletions src/focusc/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ noinst_LIBRARIES = libfocusclient.a

libfocusclient_a_SOURCES = focusclient.cpp

AM_CXXFLAGS = @NOVA_CFLAGS@ @CFITSIO_CFLAGS@ @MAGIC_CFLAGS@ @NCURSES_CFLAGS@ -I../../include
AM_CXXFLAGS = @NOVA_CFLAGS@ @CFITSIO_CFLAGS@ @MAGIC_CFLAGS@ @NCURSESW_CFLAGS@ -I../../include

rts2_focusc_SOURCES = focusc.cpp
rts2_focusc_LDADD = libfocusclient.a -L../../lib/rts2fits -lrts2image -L../../lib/rts2 -lrts2 @LIB_M@ @CFITSIO_LIBS@ @LIB_NOVA@ @MAGIC_LIBS@ @NCURSES_LIBS@
rts2_focusc_LDADD = libfocusclient.a -L../../lib/rts2fits -lrts2image -L../../lib/rts2 -lrts2 @LIB_M@ @CFITSIO_LIBS@ @LIB_NOVA@ @MAGIC_LIBS@ @NCURSESW_LIBS@

rts2_foctest_SOURCES = foctest.cpp
rts2_foctest_LDADD = -L../../lib/rts2fits -lrts2image -L../../lib/rts2 -lrts2 @CFITSIO_LIBS@ @LIB_M@ @LIB_NOVA@ @MAGIC_LIBS@

if XFOCUSC
bin_PROGRAMS += rts2-xfocusc
rts2_xfocusc_SOURCES = xfocusc.cpp xfitsimage.cpp
rts2_xfocusc_LDADD = libfocusclient.a -L../../lib/rts2fits -lrts2image -L../../lib/rts2 -lrts2 @X_LIBS@ @X_CFLAGS@ -lX11 @LIB_M@ @CFITSIO_LIBS@ @LIB_NOVA@ @MAGIC_LIBS@ @NCURSES_LIBS@
rts2_xfocusc_LDADD = libfocusclient.a -L../../lib/rts2fits -lrts2image -L../../lib/rts2 -lrts2 @X_LIBS@ @X_CFLAGS@ -lX11 @LIB_M@ @CFITSIO_LIBS@ @LIB_NOVA@ @MAGIC_LIBS@ @NCURSESW_LIBS@
endif
8 changes: 4 additions & 4 deletions src/monitor/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ rts2_mon_SOURCES = nmonitor.cpp nwindow.cpp daemonwindow.cpp nmenu.cpp nmsgbox.c

if PGSQL

rts2_mon_CXXFLAGS = @LIBXML_CFLAGS@ @NCURSES_CFLAGS@ @NOVA_CFLAGS@ @LIBPG_CFLAGS@ @CFITSIO_CFLAGS@ @MAGIC_CFLAGS@ @JSONGLIB_CFLAGS@ -I../../include
rts2_mon_LDADD = -L../../lib/rts2db -lrts2db -L../../lib/pluto -lpluto -L../../lib/xmlrpc++ -lrts2xmlrpc -L../../lib/rts2fits -lrts2imagedb -L../../lib/rts2 -lrts2 @LIBXML_LIBS@ @CFITSIO_LIBS@ @MAGIC_LIBS@ @NCURSES_LIBS@ @LIB_M@ @LIB_CRYPT@ @LIB_NOVA@ @LIB_ECPG@
rts2_mon_CXXFLAGS = @LIBXML_CFLAGS@ @NCURSESW_CFLAGS@ @NOVA_CFLAGS@ @LIBPG_CFLAGS@ @CFITSIO_CFLAGS@ @MAGIC_CFLAGS@ @JSONGLIB_CFLAGS@ -I../../include
rts2_mon_LDADD = -L../../lib/rts2db -lrts2db -L../../lib/pluto -lpluto -L../../lib/xmlrpc++ -lrts2xmlrpc -L../../lib/rts2fits -lrts2imagedb -L../../lib/rts2 -lrts2 @LIBXML_LIBS@ @CFITSIO_LIBS@ @MAGIC_LIBS@ @NCURSESW_LIBS@ @LIB_M@ @LIB_CRYPT@ @LIB_NOVA@ @LIB_ECPG@

else

rts2_mon_CXXFLAGS = @NCURSES_CFLAGS@ @NOVA_CFLAGS@ @CFITSIO_CFLAGS@ @MAGIC_CFLAGS@ -I../../include
rts2_mon_LDADD = -L../../lib/rts2 -lrts2 @CFITSIO_LIBS@ @MAGIC_LIBS@ @NCURSES_LIBS@ @LIB_M@ @LIB_NOVA@
rts2_mon_CXXFLAGS = @NCURSESW_CFLAGS@ @NOVA_CFLAGS@ @CFITSIO_CFLAGS@ @MAGIC_CFLAGS@ -I../../include
rts2_mon_LDADD = -L../../lib/rts2 -lrts2 @CFITSIO_LIBS@ @MAGIC_LIBS@ @NCURSESW_LIBS@ @LIB_M@ @LIB_NOVA@

endif

Expand Down
8 changes: 4 additions & 4 deletions src/monitor/ndevicewindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,14 +441,14 @@ void NDeviceWindow::draw ()
drawValuesList ();

wcolor_set (getWriteWindow (), CLR_DEFAULT, NULL);
mvwvline (getWriteWindow (), 0, valueBegins, ACS_VLINE, (maxrow > getHeight () ? maxrow + 1 : getHeight ()));
mvwvline_set (getWriteWindow (), 0, valueBegins, &utf8Chars.getChar ("VLINE"), (maxrow > getHeight () ? maxrow + 1 : getHeight ()));
if (isActive ())
wattron (window, A_REVERSE);
mvwaddch (window, 0, valueBegins + 1, ACS_TTEE);
mvwaddch (window, getHeight () - 1, valueBegins + 1, ACS_BTEE);
mvwadd_wch (window, 0, valueBegins + 1, &utf8Chars.getChar ("TTEE"));
mvwadd_wch (window, getHeight () - 1, valueBegins + 1, &utf8Chars.getChar ("BTEE"));
// Scrollbar
if (maxrow > 1)
mvwaddch (window, 1 + (getHeight () - 3)*getSelRow () / (maxrow - 1), getWidth()-1, ACS_DIAMOND);
mvwadd_wch (window, 1 + (getHeight () - 3)*getSelRow () / (maxrow - 1), getWidth()-1, &utf8Chars.getChar ("DIAMOND"));

// Value list filtering
if (filterMode == 1)
Expand Down
2 changes: 2 additions & 0 deletions src/monitor/nlayout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

using namespace rts2ncurses;

Utf8Chars Layout::utf8Chars;

void LayoutBlock::resize (int x, int y, int w, int h)
{
int tmp_i;
Expand Down
3 changes: 3 additions & 0 deletions src/monitor/nlayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#ifndef __RTS2_NLAYOUT__
#define __RTS2_NLAYOUT__
#include "utf8chars.h"

namespace rts2ncurses
{
Expand All @@ -28,6 +29,8 @@ namespace rts2ncurses
*/
class Layout
{
protected:
static Utf8Chars utf8Chars;
public:
Layout ()
{
Expand Down
4 changes: 2 additions & 2 deletions src/monitor/nmenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ void NActionBool::draw (WINDOW *window, int y)
{
if (isActive)
{
mvwaddch (window, y, 0, ACS_DIAMOND);
mvwadd_wch (window, y, 0, &utf8Chars.getChar ("DIAMOND"));
wprintw (window, " %s ", text);
}
else
{
mvwaddch (window, y, 0, ACS_BULLET);
mvwadd_wch (window, y, 0, &utf8Chars.getChar ("BULLET"));
wprintw (window, " %s ", text_unactive);
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/monitor/nmenu.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace rts2ncurses
class NAction
{
public:
NAction (const char *in_text, int in_code)
NAction (const char *in_text, int in_code, Utf8Chars& chars) : utf8Chars (chars)
{
text = in_text;
code = in_code;
Expand All @@ -58,6 +58,7 @@ class NAction

protected:
const char *text;
Utf8Chars& utf8Chars;

private:
int code;
Expand All @@ -69,7 +70,7 @@ class NAction
class NActionBool:public NAction
{
public:
NActionBool (const char *_text_active, const char *_text_unactive, int _code):NAction (_text_active, _code) { isActive = true; text_unactive = _text_unactive; }
NActionBool (const char *_text_active, const char *_text_unactive, int _code, Utf8Chars chars):NAction (_text_active, _code, chars) { isActive = true; text_unactive = _text_unactive; }

virtual void draw (WINDOW *window, int y);
void setActive (bool _active) { isActive = _active; }
Expand Down Expand Up @@ -100,15 +101,15 @@ class NSubmenu:public NSelWindow
*/
NAction * createAction (const char *in_text, int in_code)
{
NAction *ret = new NAction (in_text, in_code);
NAction *ret = new NAction (in_text, in_code, utf8Chars);
addAction (ret);
grow (strlen (in_text) + 4, 1);
return ret;
}

NActionBool * createActionBool (const char *in_text, const char *_unactive, int in_code)
{
NActionBool *ret = new NActionBool (in_text, _unactive, in_code);
NActionBool *ret = new NActionBool (in_text, _unactive, in_code, utf8Chars);
addAction (ret);
grow (strlen (in_text) + 5, 1);
return ret;
Expand Down
11 changes: 11 additions & 0 deletions src/monitor/nmonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <string.h>
#include <unistd.h>
#include <list>
#include <langinfo.h>

#include <iostream>
#include <fstream>
Expand Down Expand Up @@ -509,13 +510,23 @@ int NMonitor::repaint ()
int NMonitor::init ()
{
int ret;
const char *s;
ret = rts2core::Client::init ();
if (ret)
return ret;

rts2core::Configuration::instance ()->loadFile ();

// init ncurses
if (setlocale (LC_CTYPE, "en_US.UTF-8") == NULL &&
setlocale (LC_CTYPE, "C.UTF-8") == NULL) {
if (setlocale (LC_CTYPE, "") == NULL)
std::cerr << "invalid LC_ALL, LC_CTYPE or LANG" << std::endl;

s = nl_langinfo (CODESET);
if (strcasecmp (s, "UTF-8") != 0 && strcasecmp (s, "UTF8") != 0)
std::cerr << "need UTF-8 locale (LC_CTYPE) but have " << s << std::endl;
}
cursesWin = initscr ();
if (!cursesWin)
{
Expand Down
14 changes: 7 additions & 7 deletions src/monitor/nmsgwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,18 @@ void NMsgWindow::draw ()
}

wcolor_set (getWriteWindow (), CLR_DEFAULT, NULL);
mvwvline (getWriteWindow (), 0, 12, ACS_VLINE, (maxrow > getHeight ()? maxrow : getHeight ()));
mvwvline (getWriteWindow (), 0, 14, ACS_VLINE, (maxrow > getHeight ()? maxrow : getHeight ()));
mvwvline_set (getWriteWindow (), 0, 12, &utf8Chars.getChar ("VLINE"), (maxrow > getHeight ()? maxrow : getHeight ()));
mvwvline_set (getWriteWindow (), 0, 14, &utf8Chars.getChar ("VLINE"), (maxrow > getHeight ()? maxrow : getHeight ()));

if (isActive ())
wattron (window, A_REVERSE);
mvwaddch (window, 0, 15, ACS_TTEE);
mvwaddch (window, getHeight () - 1, 15, ACS_BTEE);
mvwaddch (window, 0, 13, ACS_TTEE);
mvwaddch (window, getHeight () - 1, 13, ACS_BTEE);
mvwadd_wch (window, 0, 15, &utf8Chars.getChar ("TTEE"));
mvwadd_wch (window, getHeight () - 1, 15, &utf8Chars.getChar ("BTEE"));
mvwadd_wch (window, 0, 13, &utf8Chars.getChar ("TTEE"));
mvwadd_wch (window, getHeight () - 1, 13, &utf8Chars.getChar ("BTEE"));
// Scrollbar
if (maxrow > 1)
mvwaddch (window, 1 + (getHeight () - 3)*getSelRow () / (maxrow - 1), getWidth()-1, ACS_DIAMOND);
mvwadd_wch (window, 1 + (getHeight () - 3)*getSelRow () / (maxrow - 1), getWidth()-1, &utf8Chars.getChar ("DIAMOND"));
wattroff (window, A_REVERSE);

winrefresh ();
Expand Down
16 changes: 9 additions & 7 deletions src/monitor/nwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,16 @@ void NWindow::draw ()
if (haveBox ())
{
if (isActive ())
wborder (window, A_REVERSE | ACS_VLINE, A_REVERSE | ACS_VLINE,
A_REVERSE | ACS_HLINE, A_REVERSE | ACS_HLINE,
A_REVERSE | ACS_ULCORNER,
A_REVERSE | ACS_URCORNER,
A_REVERSE | ACS_LLCORNER,
A_REVERSE | ACS_LRCORNER);
{
wattron (window, A_REVERSE);
wborder_set (window, &utf8Chars.getChar ("VLINE"), &utf8Chars.getChar ("VLINE"),
&utf8Chars.getChar ("HLINE"), &utf8Chars.getChar ("HLINE"),
&utf8Chars.getChar ("ULCORNER"), &utf8Chars.getChar ("URCORNER"),
&utf8Chars.getChar ("LLCORNER"), &utf8Chars.getChar ("LRCORNER"));
wattroff (window, A_REVERSE);
}
else
box (window, 0, 0);
box_set (window, &utf8Chars.getChar ("VLINE"), &utf8Chars.getChar ("HLINE"));
}

if (!title.empty ())
Expand Down
2 changes: 1 addition & 1 deletion src/monitor/nwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#ifdef RTS2_HAVE_CURSES_H
#include <curses.h>
#elif defined(RTS2_HAVE_NCURSES_CURSES_H)
#include <ncurses/curses.h>
#include <ncursesw/curses.h>
#endif

#include "nlayout.h"
Expand Down
39 changes: 39 additions & 0 deletions src/monitor/utf8chars.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include <ncursesw/ncurses.h>
#include <unordered_map>
#include <string>

namespace rts2ncurses {

class Utf8Chars {
private:
std::unordered_map<std::string, cchar_t> charMap;

public:
Utf8Chars() {
initUtf8();
}

void initUtf8() {
setChar("HLINE", L"\u2500", A_NORMAL);
setChar("VLINE", L"\u2502", A_NORMAL);
setChar("ULCORNER", L"\u250c", A_NORMAL);
setChar("URCORNER", L"\u2510", A_NORMAL);
setChar("LLCORNER", L"\u2514", A_NORMAL);
setChar("LRCORNER", L"\u2518", A_NORMAL);
setChar("BULLET", L"\u2022", A_NORMAL);
setChar("DIAMOND", L"\u2666", A_NORMAL);
setChar("BTEE", L"\u2534", A_NORMAL);
setChar("TTEE", L"\u252c", A_NORMAL);
}

void setChar(const std::string& name, const wchar_t* wch, attr_t attr) {
cchar_t ch;
setcchar(&ch, wch, attr, 0, NULL);
charMap[name] = ch;
}

const cchar_t& getChar(const std::string& name) {
return charMap.at(name);
}
};
}
8 changes: 4 additions & 4 deletions src/plan/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ CLEANFILES = selector.cpp rts2devcliphot.cpp
PLAN_STDLIBS = @LIBPG_CFLAGS@ @NOVA_CFLAGS@ @CFITSIO_CFLAGS@ @MAGIC_CFLAGS@ @LIBXML_CFLAGS@

rts2_scriptexec_SOURCES = scriptexec.cpp
rts2_scriptexec_CXXFLAGS = @NOVA_CFLAGS@ @CFITSIO_CFLAGS@ @MAGIC_CFLAGS@ @LIBXML_CFLAGS@ @NCURSES_CFLAGS@ -I../../include
rts2_scriptexec_CXXFLAGS = @NOVA_CFLAGS@ @CFITSIO_CFLAGS@ @MAGIC_CFLAGS@ @LIBXML_CFLAGS@ @NCURSESW_CFLAGS@ -I../../include

# LDFLAGS are defined in PGSQL/nonPGSQL

Expand All @@ -20,7 +20,7 @@ if PGSQL
PG_LDADD = -L../../lib/rts2script -lrts2script -L../../lib/rts2db -lrts2db -L../../lib/pluto -lpluto -L../../lib/xmlrpc++ -lrts2xmlrpc -L../../lib/rts2fits -lrts2imagedb -L../../lib/rts2 -lrts2 @LIBXML_LIBS@ @LIBPG_LIBS@ @LIB_ECPG@ @LIB_CRYPT@ @LIB_NOVA@ @CFITSIO_LIBS@ @LIB_M@ @MAGIC_LIBS@

rts2_scriptexec_CXXFLAGS += @LIBPG_CFLAGS@ -I../../include
rts2_scriptexec_LDADD = ${PG_LDADD} @NCURSES_LIBS@
rts2_scriptexec_LDADD = ${PG_LDADD} @NCURSESW_LIBS@
rts2_scriptor_CXXFLAGS += @LIBPG_CFLAGS@ -I../../include
rts2_scriptor_LDADD = ${PG_LDADD}

Expand All @@ -42,7 +42,7 @@ rts2_selector_LDADD = ${PG_LDADD}

nodist_rts2_seltest_SOURCES = selector.cpp
rts2_seltest_SOURCES = seltest.cpp
rts2_seltest_CXXFLAGS = @NCURSES_CFLAGS@ ${PLAN_STDLIBS} -I../../include
rts2_seltest_CXXFLAGS = @NCURSESW_CFLAGS@ ${PLAN_STDLIBS} -I../../include
rts2_seltest_LDADD = ${PG_LDADD}

rts2_marchive_SOURCES = marchive.cpp
Expand All @@ -54,7 +54,7 @@ rts2_marchive_LDADD = ${PG_LDADD}

else

rts2_scriptexec_LDFLAGS = -L../../lib/rts2script -lrts2script -L../../lib/rts2fits -lrts2image -L../../lib/rts2 -lrts2 @LIBXML_LIBS@ @LIB_NOVA@ @CFITSIO_LIBS@ @LIB_M@ @MAGIC_LIBS@ @NCURSES_LIBS@
rts2_scriptexec_LDFLAGS = -L../../lib/rts2script -lrts2script -L../../lib/rts2fits -lrts2image -L../../lib/rts2 -lrts2 @LIBXML_LIBS@ @LIB_NOVA@ @CFITSIO_LIBS@ @LIB_M@ @MAGIC_LIBS@ @NCURSESW_LIBS@
rts2_scriptor_LDADD = -L../../lib/rts2script -lrts2script -L../../lib/rts2fits -lrts2image -L../../lib/rts2 -lrts2 @LIBXML_LIBS@ @LIB_NOVA@ @CFITSIO_LIBS@ @LIB_M@ @MAGIC_LIBS@

rts2_imgproc_SOURCES = imgproc.cpp
Expand Down

0 comments on commit a529691

Please sign in to comment.