curses screen saver

VI 2004-02-13:

This isn't a screen saver really. It just uses the minimalist curses package to draw boxes of various sizes on your screen. Any keypress exits it. There's some element of randomness in how often it draws because every second it picks four coordinates. But it only draws a rectangle if those coordinates make sense. Only works on terminals that support vt100 like alt character set : true of linux, vt100 and xterm and derivatives. Any keypress exits.

2004-10-12 VI: Changed to support minimalist curses changes. No more timeout and getch. See the ssaver proc for an example of non-blocking input

package require curses

# Order is nswe

set ldc(nw)   j
set ldc(ne)   m
set ldc(se)   l
set ldc(sw)   k
set ldc(nswe) n
set ldc(we)   q
set ldc(nse)  t
set ldc(nsw)  u
set ldc(nwe)  v
set ldc(swe)  w
set ldc(ns)   x


proc box {row1 col1 row2 col2} {
    global ldc

    curses attr on alt
    curses move $row1 $col1
    curses puts $ldc(se)
    curses move $row2 $col1
    curses puts $ldc(ne)
    for {set i [expr $row1 + 1] } {$i < $row2} {incr i} {
        curses move $i $col1
        curses puts $ldc(ns)
        curses move $i $col2
        curses puts $ldc(ns)
    }
    for {set i [expr $col1 + 1] } {$i < $col2} {incr i} {
        curses move $row1 $i
        curses puts $ldc(we)
        curses move $row2 $i
        curses puts $ldc(we)
    }
    curses move $row1 $col2
    curses puts $ldc(sw)
    curses move $row2 $col2
    curses puts $ldc(nw)
}


proc boxer {} {
    set rows [curses info lines]
    set cols [curses info cols]

    if {int(rand()*$rows) % 2 == 0} {
        curses attr on reverse
    } else {
        curses attr off reverse
    }
    set row1 [expr int(rand()*$rows)]
    set row2 [expr int(rand()*$rows)]
    set col1 [expr int(rand()*$cols-1)]
    set col2 [expr int(rand()*$cols-1)]
    if {$row2 - $row1 >= 2 && $col2 - $col1 >= 2} {
        box $row1 $col1 $row2 $col2
        curses refresh
    }
    after 1000 boxer
}
    

proc ssaver {} {
    expr srand([clock seconds])
    fconfigure stdin -buffering none -blocking 0
    fileevent stdin readable  {set ::done 1}
    set ::done 0
    curses refresh;  # empty the screen before we start
    boxer
    vwait ::done
    read stdin;  #  clear out input queue before exit
}


ssaver