This is a little thing I wrote that simulates a telephone ring via the Linux console. The underlying console is used so that it can be used for Tcl and/or Tk.
I'd rather that this work via an open'ed FD on /dev/console but I can't seem to get that to work. It will ring ok, but doesn't change the frequency as it does via echo. But it does open a door to a lot of simple sound possibilities via the PC speaker, and without any extensions. Alarm clocks, fancy alerts, whatever...
This is not perfected yet. If run under a user's desktop it needs to be run by root (su root),
# ring proc by Mike Tuxford proc ring {} { # duration (ms) exec /bin/echo -e '\\33\[11\;40]' > /dev/console for {set i 0} {$i < 8} {incr i} { # freq. (HZ) exec /bin/echo -e '\\33\[10\;770]' > /dev/console exec /bin/echo -e '\\a' > /dev/console after 40 exec /bin/echo -e '\\33\[10\;870]' > /dev/console exec /bin/echo -e '\\a' > /dev/console if {$i == 3} { after 200 } else { after 40 } } # From the kernel console.c # Here is the default bell parameters: 750HZ, 1/8th of a second # reset the defaults exec /bin/echo -e '\\33\[10\;750\]\\33\[11\;125\]' > /dev/console return } ring
rmax - As it is, this program does funny things on the console. Mind you, that single quotes don't have a special meaning in Tcl. To quote the escape sequences, the single quotes should become pairs of braces, the single backslashes can go, and the double backslashes become single ones. Also echo should get a -n switch to avoid printing lots of newlines to the console. So the echos will look like this:
exec /bin/echo -en {\33[11;40]} > /dev/console
A version that doesn't need the external echo could look like this:
proc ring {} { set fd [open /dev/console w] fconfigure $fd -buffering none # duration (ms) puts -nonewline $fd "\033\[11;40\]" for {set i 0} {$i < 8} {incr i} { # freq. (HZ) puts -nonewline $fd "\033\[10;770\]\a" after 40 puts -nonewline $fd "\033\[10;870\]\a" if {$i == 3} { after 200 } else { after 40 } } # From the kernel console.c # Here is the default bell parameters: 750HZ, 1/8th of a second # reset the defaults puts -nonewline $fd "\033\[10;750\]\033\[11;125\]" close $fd return } ring
MT Great additions rmax! This still requires root. Under an X desktop it won't work on an xterm pts/<n> but will work on the tty<n> that the X server was launched from without requiring root access. Getting the origin tty<n> for the server is still an issue. There could be multiple instances of X, and the tty<n> may be several levels of parent processes higher depending on how the X server/desktop/terminal were launched.
MT Ok, a version that can be used by a user rather than root, even under an X desktop we hope. It still won't work for gdm, xdm, etc and those kinds of desktops that have no underlying tty.
proc getTTY {} { if {[string match tty* [exec /bin/ps h -p [pid] -o tty]]} { # it's a tty shell return [exec /bin/ps h -p [pid] -o tty] } # try to find parent tty foreach cmd {xinit startx startkde gnome-session} { if {[catch {exec /bin/ps h -C $cmd -o tty} t]} { # no such process so skip it continue } if {[string match tty* $t]} { return $t } } return "none" } proc ring {} { set tty [getTTY] if {$tty == "none"} { return 0 } else { set tty [file join /dev $tty] } set fd [open $tty r+] fconfigure $fd -buffering none puts -nonewline $fd "\033\[11;40\]" for {set i 0} {$i < 8} {incr i} { puts -nonewline $fd "\033\[10\;770]\a" after 40 puts -nonewline $fd "\033\[10\;870]\a" if {$i == 3} { after 200 } else { after 40 } } puts -nonewline $fd "\033\[11;125\]\033\[10\;750]" close $fd return 1 } # starter if {![ring]} { # do something else here puts "can't use ring" }