[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: RFS: bashish -- Theme environment for text terminals



On Sat, Jul 15, 2006 at 10:03:56PM +0200, Thomas Eriksson wrote:
> 2006/7/15, Adam Borowski <kilobyte@angband.pl>:
> >on many terminals, some of bashish themes don't work well, miss some
> >glyphs, etc.  This kind of things is impossible to detect -- at least
> >not in any portable or semi-portable way.  And termcap/terminfo are
> >just bad jokes.
> 
> Yup, currently most fancy prompts in Bashish are hardcoded in UTF-8
> Let's see if I can hack together better 8859-1 support for 2.0.6

What I meant is that it's impossible to tell whether a given glyph is
present; downgrading to an 8-bit encoding can't help.

If you want to bother with supporting ancient charsets, utfness
actually _can_ be detected.  In two ways:

1: checking the locale:

{
    setlocale(LC_CTYPE, "");
    charset_name=nl_langinfo(CODESET);
    return !strcmp(charset_name, "UTF-8");
}

This relies on the user setting his locale set correctly -- but this
way is consistent with the vast majority of software in Debian.

Too bad, I'm unsure how to do this from shell.  You can't check for
locales ending in .UTF-8, as this won't catch vi_VI, or, if gods and
the release team get reasonable, en_US or pl_PL in the near future.


2. writing something to the terminal:
(program attached)

This doesn't rely on the locale support.



And, the whole exercise is sort of pointless -- you need UTF-8 for
block graphics, which is NOT SUPPORTED IN ISO-8859-* ANYWAY.  That
said, you can often switch to the IBM charset (dubbed "cp437" by a
certain unrelated company) with "\e[11m" and go back with "\e[10m".

So, detecting utfness just to tell them they can go to hell is not
worth your effort :p


> I really appreciate reviews or bug-reports of Bashish. Having Bashish
> in Debian would be really cool, but perhaps there are some features
> lacking now.
> 
> If no one steps up to sponsor it right away, I'll just regulary upload
> packages anyway to http://mentors.debian.net :)

Just uploading to mentors doesn't work, I'm afraid.  There is much
more sponsorees than sponsors, so no one appears to check old RFS or
listings such as sponsors.debian.net


Cheers and schtuff,
-- 
1KB		// Microsoft corollary to Hanlon's razor:
		//	Never attribute to stupidity what can be
		//	adequately explained by malice.
/*
 * small tool to figure whenever a tty runs in utf8 mode or not.
 * writes a utf-8 multibyte sequence and then checks how far the
 * cursor has been moved.
 *
 * return codes:
 *      2 - don't know (stdin isn't a terminal, timeout, some error, ...)
 *      1 - not in utf8
 *      0 - utf-8
 *
 * Written by Gerd Krorr, minor changes by Adam Borowski.
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <termios.h>

struct termios  saved_attributes;
int             saved_fl;

void
tty_raw()
{
    struct termios tattr;

    fcntl(0,F_GETFL,&saved_fl);
    tcgetattr (0, &saved_attributes);

    fcntl(0,F_SETFL,O_NONBLOCK);
    memcpy(&tattr,&saved_attributes,sizeof(struct termios));
    tattr.c_lflag &= ~(ICANON|ECHO);
    tattr.c_cc[VMIN] = 1;
    tattr.c_cc[VTIME] = 0;
    tcsetattr (0, TCSAFLUSH, &tattr);
}

void
tty_restore()
{
    fcntl(0,F_SETFL,saved_fl);
    tcsetattr (0, TCSANOW, &saved_attributes);
}

int
select_wait()
{
    struct timeval  tv;
    fd_set          se;

    FD_ZERO(&se);
    FD_SET(0,&se);
    tv.tv_sec = 3;
    tv.tv_usec = 0;
    return select(1,&se,NULL,NULL,&tv);
}

int
main(int argc, char **argv)
{
    static char *teststr = "\r\xc3\xb6";
    static char *cleanup = "\r  \r";
    static char *getpos  = "\033[6n";
    char retstr[16];
    int pos,rc,row,col;

    if (!isatty(0) || !isatty(1))
        exit(2);

    tty_raw();
    write(1,teststr,strlen(teststr));
    write(1,getpos,strlen(getpos));
    for (pos = 0; pos < sizeof(retstr)-1;)
    {
        if (0 == select_wait())
            break;
        if (-1 == (rc = read(0,retstr+pos,sizeof(retstr)-1-pos)))
        {
            perror("read");
            exit(2);
        }
        pos += rc;
        if (retstr[pos-1] == 'R')
            break;
    }
    retstr[pos] = 0;
    write(1,cleanup,strlen(cleanup));
    tty_restore();

    rc = sscanf(retstr,"\033[%d;%dR",&row,&col);
    if (2 == rc && 2 == col)
    {
        fprintf(stderr,"Terminal is in UTF-8 mode.\n");
        exit(0);
    }
    fprintf(stderr,"Terminal is in single-char mode.\n");
    exit(1);
}

Reply to: