bug-ncurses
[Top][All Lists]
Advanced

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

Using ncurses only for terminfo (no I/O)


From: Grant Edwards
Subject: Using ncurses only for terminfo (no I/O)
Date: Fri, 15 Jan 2021 23:22:33 -0000 (UTC)
User-agent: slrn/1.0.3 (Linux)

I've recently been working with ncurses from Python, and would like to
use ncurses only for terminfo purposes. I can call tigetstr() and then
tparm() if needed, and write the result using Python's normal output
stream.  Everything works as expected using urxvt, but what sort of
failure modes I should be expecting because I'm not using tputs() or
putp() as specified in the man page?

    Parameterized strings should be passed through tparm to
    instantiate them.  All terminfo strings (including the output of
    tparm) should be printed with tputs or putp.

Apparently, one of the things tputs does is "apply padding
information":

    The tputs routine applies padding information to the string str
    and outputs it.

I have no idea what "applies padding information" means, or what's
going to fail without it. Does that mean adding NULs to allow time for
the terminal to complete certain commands? Are there still terminals
in use that require that sort of thing? I can live with it if my apps
don't work on a Lear-Siegler ADM-3.

The basic 'problem' is that tputs and putp write to libc's FILE
*stdout stream. Python's normal output mechanisms have their own
buffering and write to file descriptor 1 instead of FILE
*stdout. Therefore, "normal" Python output can't be mixed with putp()
or tputs() calls without a fair amount of ugliness[1].


I thought about using tputs() to do all output, but the ncurses man
page appears to forbid that:

       * The str parameter must be a terminfo string variable or the
         return value from tparm, tiparm, tgetstr, or tgoto.

Alternateivly, with enough hacking (and Python's foreign function
intrface), I could probably get Python's "normal" output calls to
write to libc's FILE *stdout instead of to file descriptor 1.

Here's a small example of what I'm doing now (which seems to work):

    #!/usr/bin/python
    
    import curses,sys
    
    curses.setupterm()
    
    write = sys.stdout.write
    
    bold = curses.tigetstr('bold').decode('ascii')
    norm = curses.tigetstr('sgr0').decode('ascii')
    cls = curses.tigetstr('clear').decode('ascii')
    cup = curses.tigetstr('cup')
    
    def goto(row,column):
        write(curses.tparm(cup,row,column).decode('ascii'))
    
    def clear():
        write(cls)
    
    clear()    
    name = input("enter name: ")
    
    for row in [3,5,10,20]:
        goto(row, row+5)
        write(f'{bold}Hi there {name}{norm}')
        goto(row+1, row+6)
        write(f'Hi there {name}')
    
    goto(24,0)    
    input("press enter to exit: ")
    clear()



[1] The ugliness needed to mix putp/tputs and "normal" output
    comprises wrapping all the output functions (of both the Python
    and ncurses flavors) with code that does flushes both before and
    after the actual output calls. And just to add to the smell,
    calling fflush() is not something that Python supports natively
    (you've got to use a foreign function interface subsystem to call
    libc functions).





reply via email to

[Prev in Thread] Current Thread [Next in Thread]