#!/usr/bin/perl -w

#
# Version 0.9.1
#
# imapbiff: check for new mail in an imap account.
#
# Released under the GNU GPL.  A text version of the GPL should have come
# with this program in the file "COPYING".
# Copyright 2000 Michael Arndt
#

use strict;
use IO::Socket;
use Getopt::Std;
use POSIX;
use Tk;
use vars qw($opt_h $opt_u $opt_d $opt_s $opt_q);

#
# set up signal handling.
#
$SIG{'ALRM'} = sub { die "socket timeout" };
$SIG{'QUIT'} = 'cleanup';
$SIG{'HUP'} = 'cleanup';
$SIG{'INT'} = 'cleanup';
$SIG{'KILL'} = 'cleanup';
$SIG{'TERM'} = 'cleanup';

#
# Global vars
#
my ($host,$port,$handle,$response,$user,$password,$new_messages,$sleep,$sleepms);
my ($MW,$frame,$button,$up,$down,$checking,$canvas,$baseline,$repeat,$current);
my ($good_password,$beep);
my $prog = $0;
$prog =~ s,.*/,,g;
$port = "143";
$handle = 0;
$baseline = 0;
$good_password = 0;
$beep = 1;

#
# command line overrides the .imapbiffrc
#
&help unless getopts("h:u:s:dq");
$host = "";
if ( -f "$ENV{'HOME'}/.imapbiffrc") {
	open (RC, "<$ENV{'HOME'}/.imapbiffrc") or &error("$prog: Error opening .imapbiffrc",1);
	while(<RC>) {
		$host = $1 if /host\s+(\S+)/;
		$user = $1 if /user\s+(\S+)/;
		$sleep = $1 if /sleep\s+(\d+)/;
		$password = $1 if /password\s+(\d+)/;
		$beep = 0 if /nobeep/;
	}
	close(RC);
}
if ($opt_h) {
	$host = $opt_h;
}
if ($opt_u) {
	$user = $opt_u;
} else {
	$user = $ENV{'USER'} if (! $user);
}
if ($opt_s) {
	$sleep = $opt_s;
} else {
	$sleep = 120 if (! $sleep);
}
if ($opt_q) {
	$beep = 0;
}
&help if (! $host);
$sleepms = $sleep * 1000;

#
# become a daemon process and start going to work, unless in debug
#
if (! $opt_d) {
	my $pid = fork;
	exit if $pid;
	die "Couldn't fork: $!\n" unless defined($pid);
	POSIX::setsid() or &error("$prog: Can't start a new session: $!",1);
}
$MW = new MainWindow;
$MW->title("imapbiff");
$MW->iconname("imapbiff");
$MW->wm("geometry", "58x58");
$MW->resizable(0,0);
$frame = $MW->Frame->pack(-expand => 'true', -fill => 'both');
$canvas = $frame->Canvas(-width => "48",
                         -height => "48",
                         -bd => 10,
                         -relief => "sunken",
                         )->pack(-expand=>'yes', -fill=>'both');
$button = $canvas->Button(-command => sub { &down; });
$canvas->create( "window", "0", "0",
                 -window => $button,
                 -anchor => 'nw',
                );
&define_pixmaps;
$button->bind("<Button-3>", \&check_now);
$button->configure(-image => $down);
$current = \$down;
$repeat = $button->repeat(1000, \&update);
print STDERR "repeat set to 1sec for now.\n" if $opt_d;
MainLoop;

#
# subroutine to update status
#
sub update {
	my ($new_messages);
	$button->configure(-image => $checking);
	DoOneEvent;
	DoOneEvent;
	if ($good_password) {
		$new_messages = &check_imap;
	} else {
		print STDERR "canceling repeat.\n" if $opt_d;
		$button->afterCancel($repeat);
		$repeat = 0;
		while (! $good_password) {
			&get_password;
			$new_messages = &check_imap;
		}
		$repeat = $button->repeat($sleepms, \&update);
		print STDERR "repeat set to $sleepms.\n" if $opt_d;
	}
	$new_messages = 0 if (! $new_messages);
	if ($new_messages eq "-1") {
		print STDERR "check_imap returned an error, no updates.\n" if $opt_d;
	} elsif ($baseline == $new_messages) {
		print STDERR "no changes...\n" if $opt_d;
	} elsif ($new_messages > $baseline) {
		$current = \$up;
		$button->bell if ($beep);
		$baseline = $new_messages;
		print STDERR "biff set, baseline set to $baseline\n" if $opt_d;
	} else {
		$current = \$down;
		$baseline = $new_messages;
		print STDERR "biff unset, baseline set to $baseline\n" if $opt_d;
	}
	if ($new_messages >= 0) {
		print STDERR "You have $new_messages new message(s)\n" if $opt_d;
	}
	$button->configure(-image => $$current);
	return 1;
}

#
# subroutine to initiate a check from a button 2 press
#
sub check_now {
	print STDERR "doing an immediate check\n" if $opt_d;
	if ($handle) {	
		print STDERR "socket handle already in use\n" if $opt_d;
	} else {
		$button->afterCancel($repeat);
		$repeat = 0;
		&update;
		$repeat = $button->repeat($sleepms, \&update);
	}
	return 1;
}

#
# subroutine that does check of imap mailbox
#
sub check_imap {
	# Set an alarm in case we can not connect or get hung.  Older versions
	# the IO::Socket perl module caused errors with the alarm we set before
	# setting up the socket.  If this program dies in debug mode saying:
	# "Alarm clock", then you can probably fix it by upgrading your perl
	# IO module.
	my ($ret);
	eval {
		alarm 30;
		print STDERR "setting up socket.." if $opt_d;
		$handle = IO::Socket::INET->new(Proto    => "tcp",
                                    	PeerAddr => $host,
                                    	PeerPort => $port)
			or &error("$prog: Can't connect to port $port on $host: $!",0),return "-1";
		$handle->autoflush(1);    # so output gets there right away
		print STDERR ".done\n" if $opt_d;
		&receive;
		&send("A001 LOGIN $user $password",$user);
		while (1) {
			if (($ret=&receive) == -1) {
				return "-1";
			}
			last if $response =~ /LOGIN/;
		}
		if ($response =~ /fail|BAD/) {
			return "-1";
		} else {
			$good_password = 1;
		}
		&send("A003 STATUS INBOX (UNSEEN)");
		while (1) {
			if (($ret=&receive) == -1) {
				return "-1";
			}
			last if $response =~ /STATUS\s+INBOX\s+\(UNSEEN/;
		}
		($new_messages) = $response =~ /\(UNSEEN\s+(\d+)\)/;
		&send("A005 LOGOUT");
		while (1) {
			if (($ret=&receive) == -1) {
				return "-1";
			}
			last if $response =~ /LOGOUT/;
		}
		alarm 0;
	};
	if ($@) {
		alarm 0;
		if ($@ =~ /timeout/) {
			&alarm;
			return "-1";
		} else {
			&error("$prog: $@",0);
			return "-1";
		}
	} 
	$handle = 0;
	return $new_messages;
}

#
# subroutine to put flag down and save baseline status
#
sub down {
	$button->configure(-image => $down);
	$current = \$down;
	$baseline = $new_messages if ($new_messages);
	print STDERR "baseline set to $baseline\n" if $opt_d;
	return 1;
}

#
# subroutine to get user's password.
#
sub get_password {
	my ($w1,$entry);
	$w1 = $MW->Toplevel;
	$w1->Message(-bg => "black",
                 -fg => "green",
                 -width => "400",
                 -justify => "center",
                 -text => "Enter password for\n$user at $host",
                 )->pack(-side => 'top', -fill => 'both');
	$entry = $w1->Entry(-relief=>"sunken",
                    -bg => "grey",
                    -fg => "black",
                    -width => "30",
                    -show => "*",
                   )->pack(-side => 'top');
	$w1->Button(-text => "OK",
                -command => sub { $password=$entry->get; $w1->destroy },
               )->pack(-side => 'bottom');
	$MW->waitVariable(\$password);
	DoOneEvent;
	return 1;
}

#
# subroutine to send a line to the imap server.
#
sub send {
	my ($line,$block) = (@_);
	print $handle "$line\n";
	$line =~ s/(.*$block).*/$1 ----/ if ($block);
	print STDERR "sent: $line\n" if $opt_d;
	return 1;
}

#
# subroutine to get a response from the imap server and print
# that response if in debug mode.
#
sub receive {
	chomp($response = <$handle>);
	if ($response) {
		print STDERR "got: $response\n" if $opt_d;
	} else {
		print STDERR "no response!\n" if $opt_d;
		return "-1";
	}
	return 1;
}

#
# subroutine to display and error message in a text box and exit
#
sub error {
	my ($error,$fatal) = (@_);
	my ($w1,$wait);
	$button->afterCancel($repeat);
	$w1 = $MW->Toplevel;
	$w1->Message(-width => "300",
                 -text => "$error",
                 )->pack(-side => 'top');
	if ($fatal) {
		$w1->Button(-text => "OK",
                	-command => sub { $wait=1; },
               		)->pack(-side => 'bottom');
		$MW->waitVariable(\$wait);
		$MW->destroy;
		exit;
	} else {
		$w1->Button(-text => "Continue",
                	-command => sub { $wait=1; },
               		)->pack(-side => 'bottom');
		$w1->Button(-text => "Exit",
                	-command => "exit",
               		)->pack(-side => 'bottom');
		$MW->waitVariable(\$wait);
		$w1->destroy;
		$repeat = $button->repeat($sleepms, \&update);
		$handle = 0;
		return 1;
	}	
}

#
# subroutine to call when alarm times out
#
sub alarm {
	print STDERR "Alarm went off!\n" if $opt_d;
	return 1;
}

#
# subroutine to clean up and exit if we are signalled
#
sub cleanup {
	if ($handle) {
		&send("A999 LOGOUT");
	}
	print STDERR "Exiting by user request.\n";
	exit;
}

#
# subroutine to print help screen and exit
#
sub help {
	die "Usage: $prog -h host [-u username] [-s sleep_seconds] [-q] [-d]\n";
}

#
# subroutine that puts pixmap data into place
#
sub define_pixmaps {
	$up = $canvas->Pixmap(-data => ' 
/* XPM */
static char *up[] = {
/* width height num_colors chars_per_pixel */
"    48    48        6            1",
/* colors */
". c #5151fb",
"# c #000000",
"a c #ffff00",
"b c #fa1340",
"c c #ffffff",
"d c #009300",
/* pixels */
"................................................",
".............................##########.........",
".............................##########.........",
"........................####.##aaaaaa##.........",
"......................####b####aaaaaa##.........",
".....................###bbbbb##aaaaaa##.........",
"....................##bbbbbbb##aaaaaa##.........",
"...................##bbbbbbbb##########.........",
"..................##bbbbbbbbb##########.........",
".................##bbbbbbbbbb###bb#.............",
"................##bbbbbbbbbbb###bb#.............",
"...............##bbbbbbbbbbbb###b##.............",
"..............#######bbbbbbbb######.............",
".............##########bbbbbb######.............",
"............###bbbbbb###bbbbb####b#.............",
"...........###bbbbbbbbb##bbbb###bb#.............",
"...........##bbbbbbbbbb##bbb####bb#.............",
"..........##bbbbbbbbbbbb##b#####bb#.............",
"..........##bbbbbbbbbbbb########bb#.............",
".........##bbbb######bbbb###b###bb#.............",
".........##bbbbbb##bbbbbb##bb###bb#.............",
".........##bbbbbbbbbbbbbb##bb###bb#.............",
".........##bbbbbbbbbbbbbb##bb###bb#.............",
".........##bbbbbbbbbbbbbb##bb##bbb#.............",
"###########bcbcbbcbbcbcbb##bbbbbbb##############",
"ddddddddd##bcccbcbcbcbcbb##bbbbbbb#ddddddddddddd",
"ddddddddd##bcbcbcccbcbcbb##bbbbbbb#ddddddddddddd",
"ddddddddd##bcbcbcbcbcbcbb##bbbbbb##ddddddddddddd",
"ddddddddd##bcbcbcbcbcbccb##bbbbb##dddddddddddddd",
"ddddddddd##bbbbbbbbbbbbbb##bbbb##ddddddddddddddd",
"ddddddddd##bbbbbbbbbbbbbb##bbb##dddddddddddddddd",
"ddddddddd##bbbbbbbbbbbbbb##bb##ddddddddddddddddd",
"ddddddddd##bbbbbbbbbbbbbb##b##dddddddddddddddddd",
"ddddddddd##bbbbbbbbbbbbbb#####dddddddddddddddddd",
"ddddddddd###################c#dddddddddddddddddd",
"dddddddddd#################c##dddddddddddddddddd",
"ddddddddddddddddddd#c#c#c#c#c#dddddddddddddddddd",
"ddddddddddddddddddd##c###c#c##dddddddddddddddddd",
"ddddddddddddddddddd#c#c#c#c#c#dddddddddddddddddd",
"ddddddddddddddddddd##c###c#c##dddddddddddddddddd",
"ddddddddddddddddddd#c#c#c#c#c#dddddddddddddddddd",
"ddddddddddddddddddd##c###c#c##dddddddddddddddddd",
"ddddddddddddddddddd#c#c#c#c##ddddddddddddddddddd",
"ddddddddddddddddddd##c###c##dddddddddddddddddddd",
"dddddddddddddddddddd##c#c##ddddddddddddddddddddd",
"ddddddddddddddddddddd#####dddddddddddddddddddddd",
"dddddddddddddddddddddddddddddddddddddddddddddddd",
"dddddddddddddddddddddddddddddddddddddddddddddddd"
};
SIMPLE  =                    T                                                  BITPIX  =                    8                                                  NAXIS   =                    2                                                  NAXIS1  =                   48                                                  NAXIS2  =                   48                                                  HISTORY Written by XV 3.10                                                      END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII     IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII     IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII       IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII      IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII        IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII      IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII        IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII      IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII        IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII      IIIIIIIIIIIIIIIIIIIIIIIIIIII                   IIIIIIIIIIIIIIIIIIIIIIIIIII                    IIIIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii     IIIIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  i  IIIIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  ii  IIIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  iii  IIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  iiii  IIIIIIIIIIIIIIIIIIIIIIII  iiiiiii  iiiii  IIIIIIIIIIIIIIIIIIIIIII  iiiiiiii  iiiiii  IIIIIIIIIIIIIIIIIIIIII  iiiiiii  iiiiiii IIIIIIIIIIIIIIIIIIIIII  iiiiiii  iiiiiii IIIIIIIIIIIII           iiiiiiiii  iiiiiii              kkkkkkkkk  iiiiiiiiiiiiii  ii  iii kkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiiiii  ii   ii kkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiiiii  ii   ii kkkkkkkkkkkkkkkkkkkkkk  iiiiii  iiiiii  ii   ii kkkkkkkkkkkkkkkkkkkkkk  iiii      iiii   i   ii kkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiii        ii kkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiii  i     ii kkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiii  iii    ii kkkkkkkkkkkkkkkkkkkkkkkk   iiiiiiiii  iiii   ii kkkkkkkkkkkkkkkkkkkkkkkkk   iiiiii   iiiii    i kkkkkkkkkkkkkkkkkkkkkkkkkk          iiiiii      kkkkkkkkkkkkkkkkkkkkkkkkkkk       iiiiiiii      kkkkkkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiii   i  kkkkkkkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiii   ii kkkkkkkkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiii   ii kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiii          kkkkkkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiii          kkkkkkkkkkkkkkkkkkkkkkkkkkkkk  iiiiiii    kkkkkkkkkkkkkkkkkkkkkkkkkkkkkk   iiiii    kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk    i      kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk    k    kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk          kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk          kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
');
	$down = $canvas->Pixmap(-data => '
/* XPM */
static char *down[] = {
/* width height num_colors chars_per_pixel */
"    48    48        6            1",
/* colors */
". c #5151fb",
"# c #000000",
"a c #fa1340",
"b c #ffff00",
"c c #009300",
"d c #ffffff",
/* pixels */
"................................................",
"................................................",
"................................................",
"........................####....................",
"......................####a####.................",
".....................###aaaaa####...............",
"....................##aaaaaaaaaa##..............",
"...................##aaaaaaaaaaaa##.............",
"..................##aaaaaaaaaaaaa##.............",
".................##aaaaaaaaaaaaaaa#.............",
"................##aaaaaaaaaaaaaaaa#.....#.......",
"...............##aaaaaaaaaaaaaaaa##....##.......",
"..............#######aaaaaaaaaaa###...###.......",
".............##########aaaaaaaa####..##b#.......",
"............###aaaaaa###aaaaaa###a#.##bb#.......",
"...........###aaaaaaaaa##aaaa###aa####bb#.......",
"...........##aaaaaaaaaa##aaa###aaa####b##.......",
"..........##aaaaaaaaaaaa##a###aaa###.###........",
"..........##aaaaaaaaaaaa#####aaa###..##.........",
".........##aaaa######aaaa###aaa####..#..........",
".........##aaaaaa##aaaaaa##aaa###a#.............",
".........##aaaaaaaaaaaaaa##aa###aa#.............",
".........##aaaaaaaaaaaaaa##aa##aaa#.............",
".........##aaaaaaaaaaaaaa##aa#aaaa#.............",
"###########aaaaaaaaaaaaaa##aaaaaaa##############",
"ccccccccc##aaaaaaaaaaaaaa##aaaaaaa#ccccccccccccc",
"ccccccccc##aaaaaaaaaaaaaa##aaaaaaa#ccccccccccccc",
"ccccccccc##aaaaaaaaaaaaaa##aaaaaa##ccccccccccccc",
"ccccccccc##aaaaaaaaaaaaaa##aaaaa##cccccccccccccc",
"ccccccccc##aaaaaaaaaaaaaa##aaaa##ccccccccccccccc",
"ccccccccc##aaaaaaaaaaaaaa##aaa##cccccccccccccccc",
"ccccccccc##aaaaaaaaaaaaaa##aa##ccccccccccccccccc",
"ccccccccc##aaaaaaaaaaaaaa##a##cccccccccccccccccc",
"ccccccccc##aaaaaaaaaaaaaa#####cccccccccccccccccc",
"ccccccccc###################d#cccccccccccccccccc",
"cccccccccc#################d##cccccccccccccccccc",
"ccccccccccccccccccc#d#d#d#d#d#cccccccccccccccccc",
"ccccccccccccccccccc##d###d#d##cccccccccccccccccc",
"ccccccccccccccccccc#d#d#d#d#d#cccccccccccccccccc",
"ccccccccccccccccccc##d###d#d##cccccccccccccccccc",
"ccccccccccccccccccc#d#d#d#d#d#cccccccccccccccccc",
"ccccccccccccccccccc##d###d#d##cccccccccccccccccc",
"ccccccccccccccccccc#d#d#d#d##ccccccccccccccccccc",
"ccccccccccccccccccc##d###d##cccccccccccccccccccc",
"cccccccccccccccccccc##d#d##ccccccccccccccccccccc",
"ccccccccccccccccccccc#####cccccccccccccccccccccc",
"cccccccccccccccccccccccccccccccccccccccccccccccc",
"cccccccccccccccccccccccccccccccccccccccccccccccc"
};
SIMPLE  =                    T                                                  BITPIX  =                    8                                                  NAXIS   =                    2                                                  NAXIS1  =                   48                                                  NAXIS2  =                   48                                                  HISTORY Written by XV 3.10                                                      END                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII     IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII     IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII       IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII      IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII        IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII      IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII        IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII      IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII        IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII      IIIIIIIIIIIIIIIIIIIIIIIIIIII                   IIIIIIIIIIIIIIIIIIIIIIIIIII                    IIIIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii     IIIIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  i  IIIIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  ii  IIIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  iii  IIIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  iiii  IIIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  iiiii  IIIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  iiiiii  IIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  iiiiiii IIIIIIIIIIIIIIIIIIIIII  iiiiiiiiiiiiii  iiiiiii IIIIIIIIIIIII           iiiiiiiiiiiiii  iiiiiii              kkkkkkkkk  iiiiiiiiiiiiii  ii iiii kkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiiiii  ii  iii kkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiiiii  ii   ii kkkkkkkkkkkkkkkkkkkkkk  iiiiii  iiiiii  iii   i kkkkkkkkkkkkkkkkkkkkkk  iiii      iiii   iii    kk kkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiii     iii   kk  kkkkkkkkkkkkkkkkkkk  iiiiiiiiiiii  i   iii   k   kkkkkkkkkkkkkkkkkkk  iiiiiiiiii  iii   iii      kkkkkkkkkkkkkkkkkk   iiiiiiiii  iiii   ii     kkkkkkkkkkkkkkkkkkk   iiiiii   iiiiii   i k   kkkkkkkkkkkkkkkkkkkk          iiiiiiii    kk   kkkkkkkkkkkkkkkkkkkkk       iiiiiiiiiii   kkk   kkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiiiiiii  kkkk  kkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiiiiiii kkkkk kkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiiiiii kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiiii  kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiiiii  kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk  iiiiiiiiii  kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk   iiiii    kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk    i    kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk    kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
');
	$checking = $canvas->Pixmap(-data => ' 
/* XPM */
static char *check[] = {
/* width height num_colors chars_per_pixel */
"    48    48      115            2",
/* colors */
".. c #000000",
".# c #000006",
".a c #020202",
".b c #040404",
".c c #060606",
".d c #090909",
".e c #0a0a0a",
".f c #0b0b0b",
".g c #120f07",
".h c #17130a",
".i c #1f180d",
".j c #292010",
".k c #312713",
".l c #41351d",
".m c #463519",
".n c #655125",
".o c #6a5426",
".p c #8b743f",
".q c #917846",
".r c #977735",
".s c #a7894b",
".t c #a88a47",
".u c #ad914a",
".v c #b49760",
".w c #dab25a",
".x c #e0bb65",
".y c #e5be73",
".z c #fdcd6e",
".A c #ffc351",
".B c #ffc558",
".C c #ffc563",
".D c #ffc659",
".E c #ffc752",
".F c #ffc756",
".G c #ffc85c",
".H c #ffc85f",
".I c #ffc95d",
".J c #ffc964",
".K c #ffca5b",
".L c #ffcb63",
".M c #ffcb64",
".N c #ffcc63",
".O c #ffcc64",
".P c #ffcc65",
".Q c #ffcd61",
".R c #ffcd67",
".S c #ffcd69",
".T c #ffcd6a",
".U c #ffce67",
".V c #ffce69",
".W c #ffce6c",
".X c #ffce6d",
".Y c #ffcf65",
".Z c #ffcf74",
".0 c #ffcf77",
".1 c #ffd069",
".2 c #ffd06b",
".3 c #ffd06f",
".4 c #ffd070",
".5 c #ffd071",
".6 c #ffd077",
".7 c #ffd165",
".8 c #ffd171",
".9 c #ffd172",
"#. c #ffd173",
"## c #ffd174",
"#a c #ffd176",
"#b c #ffd178",
"#c c #ffd17d",
"#d c #ffd271",
"#e c #ffd273",
"#f c #ffd275",
"#g c #ffd277",
"#h c #ffd369",
"#i c #ffd36d",
"#j c #ffd372",
"#k c #ffd377",
"#l c #ffd378",
"#m c #ffd37b",
"#n c #ffd37d",
"#o c #ffd466",
"#p c #ffd470",
"#q c #ffd47d",
"#r c #ffd569",
"#s c #ffd573",
"#t c #ffd576",
"#u c #ffd57f",
"#v c #ffd582",
"#w c #ffd679",
"#x c #ffd692",
"#y c #ffd76e",
"#z c #ffd778",
"#A c #ffd783",
"#B c #ffd78f",
"#C c #ffda74",
"#D c #ffdd73",
"#E c #ffdd78",
"#F c #ffde71",
"#G c #ffe068",
"#H c #ffe07a",
"#I c #ffe081",
"#J c #ffe36d",
"#K c #ffe386",
"#L c #ffe678",
"#M c #ffe786",
"#N c #ffea74",
"#O c #ffec84",
"#P c #ffed71",
"#Q c #ffee8a",
"#R c #fff374",
"#S c #fff77e",
"#T c #fff787",
"#U c #fffa83",
"#V c #fffc81",
"#W c #ffff7b",
/* pixels */
"................................................................................................",
"................................................................................................",
"................................................................................................",
"................................................................................................",
"................................................................................................",
"................................................................................................",
"................................................................................................",
"................................................................................................",
".....................................q.q#l#z#z#E.9.9.5..........................................",
"...................................l#g#g#I#T#T#S#W#W#P.Q.Q.j....................................",
"...................................l#g#g#I#T#T#S#W#W#P.Q.Q.j....................................",
"..............................#a#a#m#k#k............#r#i#i#h.k.k................................",
".............................T#M#M......#u#y#y.7.w.w......#y.O.O................................",
".............................T#M#M......#u#y#y.7.w.w......#y.O.O................................",
"............................#p#K#K..#A#A.H.A.A.E.2.2.u....#C#J#J.m..............................",
".........................p.p#L.....n#H#H........#N#N.U....#w#R#R.D..............................",
".........................p.p#L.....n#H#H........#N#N.U....#w#R#R.D..............................",
"........................#s#s.S#d#d.C.V.V........#V#V.M....#e#G#G.........e.e....................",
".............................Y.R.R.X..........#.#U#U......#F.I.I.........c.c....................",
".............................Y.R.R.X..........#.#U#U......#F.I.I.........c.c....................",
"..............................................##.Z.Z..#c#c#o.r.r.......c........................",
"..........................................#d#d#n.......6.6.K.......a.a..........................",
"..........................................#d#d#n.......6.6.K.......a.a..........................",
".........................................z#j#j#x....#B.0.0.........c.c..........................",
".........................................W#Q#Q......#q#n#n.......a.#.#..........................",
".........................................W#Q#Q......#q#n#n.......a.#.#..........................",
".........................................8#O#O...1.1.X...........c..............................",
"........................................#b#C#C...N.N.J..........................................",
"........................................#b#C#C...N.N.J..........................................",
".........................................v#d#d.G.1.1.g..........................................",
"...........................................y.y...x.x.........b.b................................",
"...........................................y.y...x.x.........b.b................................",
"................................................................................................",
"...........................................s.s.o.t.t............................................",
"...........................................s.s.o.t.t............................................",
"........................................#v.4.4.B.L.L#t..........................................",
"........................................#f.P.P...F.F.h..........................................",
"........................................#f.P.P...F.F.h..........................................",
".........................................3.5.5#D.3.3............................................",
".................................................i.i.........f.f................................",
".................................................i.i.........f.f................................",
"................................................................................................",
".....................................................d.d.d......................................",
".....................................................d.d.d......................................",
".....................................................d..........................................",
"................................................................................................",
"................................................................................................",
"................................................................................................"
};
');
	return 1;
}
