Bourne | Ash |  #!  | find | ARG_MAX | Shells | whatshell | portability | permissions | UUOC | ancient | - | ../Various | HOME
"$@" | echo/printf | set -e | test | tty defs | tty chars | $() vs ) | IFS | using siginfo | nanosleep | line charset | locale


About the 'alternate linedrawing character set'

Getting gif:alternate characters instead of gif:normal characters, and how to reset a terminal after it has messed up.


Content:


Video Terminal Information

If you are interested in terminals in any way, you must not miss the following places:


The main purpose of the following page is not the solution below (sort of overkill and not sufficient in all possible cases anyway),
but to show the reason for the mess.

Short summary: One can not only switch the character set, but also translation tables, which are pointers to the various character sets.

(The former messes up your terminal in a simple way, the latter is more difficult.)


The most frequent cause

From an affiliated usenet thread:

   From: "Radu G. Sofronici"
   Subject: dmesg question?
   Message-ID: <mXgk2.1690$Xk3.10001@news.cwix.com>
   Newsgroups: comp.sys.sun.hardware
   Date: Tue, 05 Jan 1999 04:55:46 GMT

   [...]
   Sometimes when I run dmesg I get ASCII characters at the end of dmesg
   output on the screen,  something like -|  -_| L _-|.
   [...] 

He had seen the 'Alternate Character Set', so there must have been a <ctrl-n> in that output (how strange).

Obvious to suggest the 'standard trick':

    $ cat
    <ctrl-o>
    <ctrl-d>

(or even just "echo <ctrl-v><ctrl-o>", if supported)

This should fix it, if there had only been a <ctrl-n> in the output.

But that particular day, I for myself couldn't provoke the linedrawing character set with <ctrl-n>
on the system I was using that moment - although I tried variations of TERM, xterms, shells, etc.

-> At that time there was something different messed up at my place.
Means: perhaps also the <ctrl-O> - trick might not always suffice?
I had not heard about the 'translation table' until then...


How to provoke the mess the hard way?

Especially
    $ cat
    <esc>(0 <esc>)B
    <ctrl-D>   

or

    $ echo "X(0X)B" | tr 'X' '\033'   

likely will lead to a weird terminal state in a vt100-like. The <ctrl-O> trick won't help.

For certain TERM values (e.g. xterm and xterm-color) on some systems,
even reset(1) (let alone the tty specific 'stty sane'), won't help on many systems.


The Reason?

It's all about both switching between several 'character sets' and 'translation tables' as well.

The following paragraph from the VT100 Manual:

    The appropriate G0 and G1 character sets are designated from one of the
    five possible character sets. The G0 and G1 sets are invoked by the
    codes SI and SO (shift in and shift out) respectively.  

(Note: this page is concerning all the VT100 alike terminals, emulations and related emulators like xterm(1) or dtterm(1), but not hpterm(1) in contrast.)

So, in general, there are two different "modes", initially G0 is the current one. "shift in" (Ctrl-N) causes G1 to become current, "shift out" (Ctrl-O) causes G0 to become current. These variables G0 and G1 each point at a translation table. The most recommended echoing of Ctrl-O will only make G0 current, but there is no guarantee that G0 points at the right translation table. But this is done with the following:

    G0 Sets Sequence   G1 Sets Sequence   Meaning
    ESC ( A            ESC ) A            United Kingdom Set
    ESC ( B            ESC ) B            ASCII Set
    ESC ( 0            ESC ) 0            Special Graphics
    ESC ( 1            ESC ) 1            Alternate Character ROM Standard Character Set
    ESC ( 2            ESC ) 2            Alternate Character ROM Special Graphic   

For xterm(1) see also the responsible XTerm Control Sequences.
(Thomas Dickeys's version, as his package is much better documented and better maintained than the MIT version).


The Solution

Note: The following only concerns a terminal setting similar to vt100 (and higher), xterm or dtterm.

Eventually I found this hint:

     Forums: comp.unix.admin, comp.unix.unixware
     Author: Tony Nugent
     Email: T.Nugent@sct.gu.edu.au
     Date: 1995/04/19
     Message-ID: <3n4721$h3r@griffin.itc.gu.edu.au>
     Subject: Re: Alternate Character Set Revisted !!!
  
     [...] Try using this.  It resets a vt-terminal into its default
     character set mode.  I use it on the odd occasion when something
     sets my vt terminal to graphics with the ^[(0 sequence:
  
     alias vtn 'echo "X[mX(BX)0OX[?5lX7X[rX8" | tr '\''XO'\'' '\''\033\017'\'''
  
     [...] include the tr command to [...] make it mail-portable.  

I am using bourne-compatible shells, so I am using:

  alias vtn='echo "X[mX(BX)0OX[?5lX7X[rX8" | tr "XO" "\033\017"' 

and 'disassembled' it is:

  ESC [m   (actually ESC [0m) Character Attributes: Normal (not bold f.i.)
  ESC (B                      Select G0 Character Set: United States (USASCII)
  ESC )0                      Select G1 Character Set: Special Character and Line Drawing Set
  O        ( Ctrl-O )         Switch to Standard Character Set
  ESC [?5l                    DEC Private Mode Reset: Normal Video
  ESC 7                       Save Cursor
  ESC [r                      weird (actually 'ESC [0;0r' ? Set Scrolling Region [top;bottom] )
  ESC 8                       Restore Cursor   

One might need <ctrl-J> instead of <Return>, simulating a linefeed instead of a newline.


Richard S. Shuford has posted an even more interesting version of such a hack:

From: "Richard S. Shuford"
Newsgroups: comp.unix.solaris,comp.terminals,comp.windows.x.apps,comp.unix.questions
Subject: Re: resetting xterm under Solaris 8
Date: Wed, 4 Jul 2001 19:00:00 GMT
Message-ID: <20010704190000_rshu@stratagy.com> 

Using tr(1) this boils down to

   alias vtn='echo "X[4iX[?4iX[?38lX\X(BX)0OX[?5lX[0mX[rX[HX[J" | tr "XO" "\033\017"' 


Other ways?...

Some more details to the idea of using 'tput enacs'.

The vt100 entry for enacs is

  $ infocmp -1 vt100|grep enacs
        enacs=\E(B\E)0  

This is ok when using curses/ncurses tput(1), but might not work with tput from the termutils, as it reads /etc/termcap (here the capability is named "eA" instead of "enacs", btw), which doesn't contain such a sequence on many systems.

And it's even only ok for vt100, not xterm:

  $ infocmp -1 xterm|grep enacs
         enacs=\E)0  

Actually the whole terminfo entry for 'xterm' doesn't contain any '('. Thus it cannot repair the important one of the two character sets, because the pointer of the first character set to its translation table is changed by '('.

The terminfo entry for xterm-xfree86 in contrast is ok, but is often not available per default on all the unix flavours shipping MIT X11. It's also contained in the ncurses package, by the way.

Affiliated commands:

Some of them usually help, if you only had a <ctrl-n> in your ouput.
They sometimes don't help, if you have the 'translation tables' mixed up themselves.

In very simple cases, printing random characters (e.g. "cat /dev/random") is reported to help, but a simple <ctrl-v><ctrl-n> might have helped then either...


credits also to Stefan Le Breton and Richard L. Hamilton, in the abovementioned dmesg(1) thread