#!/usr/bin/perl # Copyright Fulko Hew, 2003. Licensed under the GPL. use Tk; @times = (1, 5, 10, 15); # the list of time intervals to display $time_limit = 5; # which one should we have auto-selected $max_sound_len = 5; # max seconds a sound may run (typically 5 seconds) $but_color = 'light pink'; # default button color $mw = MainWindow->new; $mw->geometry("+0+0"); $mw->title("Lightning Timer"); my $p_time = $mw->Frame(); $p_time->Label(-text => 'Time limit:') -> pack(-side => 'left'); foreach (@times) { $p_time->Radiobutton(-text => $_, -variable => \$time_limit, -value => $_) -> pack(-side => 'left'); } $p_time->pack(-side => 'top'); my %pack_opt = (-side => 'left', -fill => 'x', -expand => 1); # define the common pack options for all buttons my $p_buts = $mw->Frame(); $p_run = $p_buts->Button(-text => 'Start', -background => $but_color, -command => [ \&run ] ) -> pack(%pack_opt); $p_pause = $p_buts->Button(-text => 'Pause', -background => $but_color, -command => [ \&pause ] ) -> pack(%pack_opt); $p_stop = $p_buts->Button(-text => 'Stop', -background => $but_color, -command => [ \&stop ] ) -> pack(%pack_opt); $p_buts ->pack(-side => 'top', -fill => 'x', -expand => 1); my $p_elapsed = $mw->Frame(); $p_elapsed->Label(-text => 'Elapsed Time:') -> pack(-side => 'left'); $elapsed_time = $p_elapsed->Label(-text => '0:00') -> pack(-side => 'right', -anchor => 'e'); $p_elapsed -> pack(-side => 'top', -fill => 'x', -expand => 1); my $p_remaining = $mw->Frame(); $p_remaining->Label(-text => 'Remaining Time:') -> pack(-side => 'left'); $remaining_time = $p_remaining->Label(-text => '0:00') -> pack(-side => 'right', -anchor => 'e'); $p_remaining -> pack(-side => 'top', -fill => 'x', -expand => 1); $current_time = $mw->Label() -> pack(-side => 'top'); # the time will get filled in later $p_exit = $mw->Button(-text => 'Exit', -background => $but_color, -command => sub { $mw->destroy; exit; }) -> pack(-side => 'bottom', -fill => 'x'); $cmd = 'stop'; $mw->repeat(1000 => [ \&doit ] ); MainLoop; sub run { $time = $time_limit * 60; # set the time limit $time-- if ($cmd eq 'run'); # if we're resetting, use one less than the max time, so initial sound doesn't sound again $p_run->configure(-text => 'Reset'); # re-label the button $cmd = 'run'; } sub stop { $cmd = 'stop'; } sub pause { if ($cmd eq 'run') { $cmd = 'pause'; $p_pause->configure(-text => 'Resume'); } elsif ($cmd eq 'pause') { $cmd = 'run'; $p_pause->configure(-text => 'Pause'); } } sub doit { $current_time->configure(-text => scalar(localtime)); if ($cmd eq 'run') { $elapsed_time->configure(-text => tommss(($time_limit*60) - $time)); $remaining_time->configure(-text => tommss($time)); $remaining_time->configure(-foreground => 'red') if ($time < 0); if ($time == ($time_limit * 60)) { mksound("/usr/share/freeciv/stdsounds/bang10.wav"); } # start elsif ($time == 0) { mksound("/usr/share/freeciv/stdsounds/gong10.wav"); } # stop elsif (($time % 60) == 0) { mksound("/usr/share/sounds/KDE_Beep_ClockChime.wav"); } # tick $time--; } if ($time < -((60*60)-1)) { # let the timer overrun by a max of 59:59, cause tommss() can't go past that $cmd = 'stop'; # then turn off the timer } # and fall into the next block of code to shut things down if ($cmd eq 'stop') { $remaining_time->configure(-foreground => 'black'); $remaining_time->configure(-text => '0:00'); $elapsed_time->configure(-text => '0:00'); $p_run->configure(-text => 'Start'); $p_pause->configure(-text => 'Pause'); } } sub tommss { my $time = shift; my $flag; if ($time < 0) { $time = abs($time); $flag = '-'; } my $sec = $time % 60; my $min = ($time - $sec) / 60; return sprintf("%s%d:%02d", $flag, $min, $sec); } sub mksound { my $sound = shift; if (fork) { # the main parent allows the sound to be forked off return; # and simply returns } else { if ($pid = fork) { # a sub-parent goes to sleep for a while sleep $max_sound_len; # goes to sleep for a while then kill 9 => $pid; # kills the sound generator (if its still around) kill 9 => $$; # now kill myself, and we will never return } else { # the grandchild close STDERR; open STDERR, ">>/dev/null"; exec "xmms", $sound; # plays the given soundbyte kill 9 => $$; # now kill myself, just in case, and we will never return } } }