Recipe 15.18. Program: Small termcap program
Author: Tom Christiansen & Nathan Torkington
Date: 1999-07-02T01:43:32Z

#

| Chapter 15 User Interfaces |

## 15.18. Program: Small termcap program

### Description

This program clears your screen and scribbles all over it until you interrupt it. It shows how to use Term::Cap to clear the screen, move the cursor, and write anywhere on the screen. It also uses Recipe 16.6.

The program text is shown in Example 15.9.

#### Example 15.9: tcapdemo

    #!/usr/bin/perl -w
    # tcapdemo - show off direct cursor placement

    use POSIX;
    use Term::Cap;

    init();                     # Initialize Term::Cap.
    zip();                      # Bounce lines around the screen.
    finish();                   # Clean up afterward.
    exit();

    # Two convenience functions.  clear_screen is obvious, and
    # clear_end clears to the end of the screen.
    sub clear_screen { $tcap->Tputs('cl', 1, *STDOUT) }
    sub clear_end    { $tcap->Tputs('cd', 1, *STDOUT) }

    # Move the cursor to a particular location.
    sub gotoxy {
        my($x, $y) = @_;
        $tcap->Tgoto('cm', $x, $y, *STDOUT);
    }

    # Get the terminal speed through the POSIX module and use that
    # to initialize Term::Cap.
    sub init {
        $| = 1;
        $delay = (shift() || 0) * 0.005;
        my $termios = POSIX::Termios->new();
        $termios->getattr;
        my $ospeed = $termios->getospeed;
        $tcap = Term::Cap->Tgetent ({ TERM => undef, OSPEED => $ospeed });
        $tcap->Trequire(qw(cl cm cd));
    }

    # Bounce lines around the screen until the user interrupts with
    # Ctrl-C.
    sub zip {
        clear_screen();
        ($maxrow, $maxcol) = ($tcap->{_li} - 1, $tcap->{_co} - 1);

        @chars = qw(* - / | \ _ );
        sub circle { push(@chars, shift @chars); }

        $interrupted = 0;
        $SIG{INT} = sub { ++$interrupted };

        $col = $row = 0;
        ($row_sign, $col_sign) = (1,1);

        do {
            gotoxy($col, $row);
            print $chars[0];
            select(undef, undef, undef, $delay);

            $row += $row_sign;
            $col += $col_sign;

            if    ($row == $maxrow) { $row_sign = -1; circle; }
            elsif ($row == 0 )      { $row_sign = +1; circle; }

            if    ($col == $maxcol) { $col_sign = -1; circle; }
            elsif ($col == 0 )      { $col_sign = +1; circle; }

        } until $interrupted;

    }

    # Clean up the screen.
    sub finish {
        gotoxy(0, $maxrow);
        clear_end();
    }

This is what it looks like in mid-run:

    *     _                       /     |                       \     -
     *   _ \                     - /   | /                     | \   - *
      * _   \                   -   / |   /                   |   \ -   *
       *     \                 -     |     /                 |     -     *
      _ *     \               -     | /     /               |     - \     *
     _   *     \             -     |   /     /             |     -   \     *
    *     *     \           -     |     /     /           |     -     \     *
     *     *     \         -     |       /     /         |     -       \     *
      *     *     \       -     |         /     /       |     -         \     *
       *     *     \     -     |           /     /     |     -           \     *
        *     *     \   -     |             /     /   |     -             \     *
         *     *     \ -     |               /     / |     -               \
          *     -     \     |                 /     /     -                 \
           *   - *   - \   |                   /   | /   -                   \
            * -   * -   \ |                     / |   / -                     \ _
             -     -     \                       |     /                       _

### See Also

termcap (5) (if you have it); the documentation for the standard Term::Cap module

15.17. Removing the DOS Shell Window with Windows Perl/Tk |  | 15.19. Program: tkshufflepod