#!/usr/bin/perl -w # # morsecat.pl # # Jacek Fedorynski # http://www.jfedor.org/ # 2001-11-15 # # Displays a text file in Morse code using a LED on your keyboard. # # (as in the book Cryptonomicon by Neal Stephenson) # # If the DISPLAY environment variable is set we will use xset to control # the LED. If it's not set we will use setleds (which is probably very # Linux-specific). To make it work under X I had to change the InputDevice # section for the keyboard in /etc/X11/XF86Config-4 to look like this # (the side effect was that my xmodmap keyboard mappings stopped working): # # Section "InputDevice" # Identifier "Keyboard0" # Driver "keyboard" # Option "Xleds" "1 2 3" # Option "XkbDisable" # EndSection # # If you know a way to control keyboard LEDs (or other LEDs) on other platforms # please let me know. If you think there's something wrong with the Morse # code this program generates also let me know. # # Have fun! # use strict; my $UNIT_TIME = 0.12; # length of a single dot in seconds my %code = ( 'A' => [0, 1], 'B' => [1, 0, 0, 0], 'C' => [1, 0, 1, 0], 'D' => [1, 0, 0], 'E' => [0], 'F' => [0, 0, 1, 0], 'G' => [1, 1, 0], 'H' => [0, 0, 0, 0], 'I' => [0, 0], 'J' => [0, 1, 1, 1], 'K' => [1, 0, 1], 'L' => [0, 1, 0, 0], 'M' => [1, 1], 'N' => [1, 0], 'O' => [1, 1, 1], 'P' => [0, 1, 1, 0], 'Q' => [1, 1, 0, 1], 'R' => [0, 1, 0], 'S' => [0, 0, 0], 'T' => [1], 'U' => [0, 0, 1], 'V' => [0, 0, 0, 1], 'W' => [0, 1, 1], 'X' => [1, 0, 0, 1], 'Y' => [1, 0, 1, 1], 'Z' => [1, 1, 0, 0], '0' => [1, 1, 1, 1, 1], '1' => [0, 1, 1, 1, 1], '2' => [0, 0, 1, 1, 1], '3' => [0, 0, 0, 1, 1], '4' => [0, 0, 0, 0, 1], '5' => [0, 0, 0, 0, 0], '6' => [1, 0, 0, 0, 0], '7' => [1, 1, 0, 0, 0], '8' => [1, 1, 1, 0, 0], '9' => [1, 1, 1, 1, 0], ' ' => [2] ); sub mysleep { my ($time) = @_; select(undef, undef, undef, $time); } sub turn { my ($on) = (@_); if (defined $ENV{DISPLAY}) { system("xset ".($on ? "" : "-")."led 2"); } else { system("setleds -L ".($on ? "+" : "-")."num"); } } my $buf; my $filename = $ARGV[0] || "-"; open(INPUT, "< $filename") or die "cannot open input file"; while (sysread INPUT, $buf, 1) { if (defined $code{uc($buf)}) { for my $i (@{$code{uc $buf}}) { turn(1) unless $i == 2; if ($i == 0) { mysleep($UNIT_TIME); # dot } elsif ($i == 1) { mysleep($UNIT_TIME * 3); # dash } elsif ($i == 2) { mysleep($UNIT_TIME * 3); # word space } turn(0); mysleep($UNIT_TIME); } mysleep($UNIT_TIME * 2); # letter space } }