File Coverage

blib/lib/Term/InKey.pm
Criterion Covered Total %
statement 82 142 57.7
branch 18 68 26.4
condition 2 10 20.0
subroutine 7 12 58.3
pod 0 10 0.0
total 109 242 45.0


line stmt bran cond sub pod time code
1             package Term::InKey;
2              
3             # Ariel Brosh (R.I.P), November 2001, for Raz Information Systems
4             # Now manitained by Oded S. Resnik Raz Information Systems
5              
6             require Exporter;
7 1     1   1406 use strict qw(vars subs);
  1         1  
  1         40  
8 1     1   5 use vars qw(@ISA @EXPORT $VERSION $WIN32CONSOLE $BAD_CLS $BAD_RKEY $TER_CLS);
  1         1  
  1         3529  
9             @ISA = qw(Exporter);
10             @EXPORT = qw(ReadKey Clear ReadPassword);
11              
12             $VERSION = '1.04';
13              
14             sub WinSetConsole {
15 0 0   0 0 0 return $WIN32CONSOLE if $WIN32CONSOLE;
16 0         0 require Win32::Console;
17 0         0 import Win32::Console;
18             {
19 0         0 local *STDERR;
  0         0  
20 0         0 open STDERR, ">/dev/null";
21 0         0 $WIN32CONSOLE = Win32::Console->
22             new(Win32::Console->STD_INPUT_HANDLE);
23             }
24 0         0 return $WIN32CONSOLE;
25             }
26              
27             sub WinReadKey {
28 0     0 0 0 my $y;
29 0         0 eval {
30 0 0       0 if(&WinSetConsole)
31             {
32 0   0     0 my $mode = $WIN32CONSOLE->Mode || die $^E;
33 0         0 my $newmode = $mode;
34 0         0 $newmode &= ~(&ENABLE_LINE_INPUT | &ENABLE_ECHO_INPUT);
35 0 0       0 $WIN32CONSOLE->Mode($newmode) || die $^E;
36 0 0       0 $WIN32CONSOLE->Flush || die $^E;
37              
38 0         0 $y = $WIN32CONSOLE->InputChar(1);
39 0 0       0 $WIN32CONSOLE->Flush || die $^E;
40 0 0       0 $WIN32CONSOLE->Mode($mode) || die $^E;
41 0 0       0 die $^E unless defined($y);
42             }
43             };
44 0 0       0 die "Not implemented on $^O: $@" if $@;
45 0         0 $y;
46             }
47              
48             sub BadReadKey {
49 0 0   0 0 0 if ($^O !~ /Win32/i) {
50 0         0 $BAD_RKEY =1;
51 0         0 system "stty raw -echo";
52 0         0 my $ch = getc;
53 0         0 system "stty -raw echo";
54 0         0 $ch;
55             }
56             }
57              
58             sub ReadKey {
59 73 50   73 0 501 if ($^O =~ /Win32/i) {
60 0         0 return &WinReadKey;
61             };
62              
63 73         86 my $save;
64              
65 73 50       166 &BadReadKey if $BAD_RKEY;
66              
67 73         123 eval {
68 73         1565 require POSIX;
69 73         8692 import POSIX;
70              
71 73         223519 $save = new POSIX::Termios;
72             };
73 73 50       244 return &BadReadKey if $@;
74              
75 73         556 $save->getattr(0);
76              
77 73         293 my $x = new POSIX::Termios;
78              
79 73         288 $x->getattr(0);
80              
81 73         101 my %flags;
82              
83 73         190 &getit($x, \%flags);
84              
85             # +raw
86             {
87 73         116 $flags{'i'} &= ~(&IGNBRK|&BRKINT|&PARMRK|&ISTRIP
  73         524  
88             |&INLCR|&IGNCR|&ICRNL|&IXON);
89 73         131 $flags{'o'} &= ~&OPOST;
90 73         330 $flags{'l'} &= ~(&ECHO|&ECHONL|&ICANON|&ISIG|&IEXTEN);
91 73         160 $flags{'c'} &= ~(&CSIZE|&PARENB);
92 73         135 $flags{'c'} |= &CS8;
93             }
94 73         172 &setit($x, \%flags);
95              
96 73         466 $x->setattr(0);
97              
98 73         255 my $ch = getc;
99              
100 73         400 $save->setattr(0);
101              
102 73         331 $ch;
103             }
104              
105             sub getit {
106 73     73 0 121 my ($x, $flags) = @_;
107 73         163 foreach (qw(i o c l)) {
108 292         855 my $meth = $x->can("get${_}flag");
109 292         1075 $flags->{$_} = &$meth($x);
110             }
111             }
112              
113             sub setit {
114 73     73 0 108 my ($x, $flags) = @_;
115 73         125 foreach (qw(i o c l)) {
116 292         782 my $meth = $x->can("set${_}flag");
117 292         795 &$meth($x, $flags->{$_});
118             }
119             }
120              
121             sub WinClear {
122              
123 0 0   0 0 0 &BadClear if $BAD_CLS;
124              
125 0         0 eval {
126 0 0       0 if(&WinSetConsole)
127             {
128 0         0 local *STDERR;
129 0         0 open STDERR, ">/dev/null";
130 0 0       0 $WIN32CONSOLE->Cls || die $^E;
131 0         0 $WIN32CONSOLE->Display;
132             }
133             else {
134 0         0 &BadClear;
135             };
136             };
137 0 0       0 &BadClear if $@;
138             }
139              
140              
141             sub BadClear {
142 0     0 0 0 $BAD_CLS = 1;
143 0 0 0     0 if ($^O =~ /Win/i || $^O =~ /Dos/i) {
144 0         0 system "cls";
145 0         0 return;
146             }
147              
148 0         0 system "clear";
149             }
150              
151             sub Clear {
152              
153 1 50   1 0 135 &BadClear if $BAD_CLS;
154              
155 1 50 33     14 if ($^O =~ /Win32/i || $^O =~ /Dos/i) {
156 0         0 &WinClear;
157 0         0 return;
158             }
159            
160              
161 1 50       4 unless ($TER_CLS) {
162              
163 1         2 my $speed = 9600;
164              
165 1         4 eval {
166 1         6 require POSIX;
167 1         25 import POSIX;
168              
169 1         3040 my $x = new POSIX::Termios;
170 1         10 POSIX::Termios::getattr($x, 0);
171 1         7 $speed = $x->getospeed;
172             };
173              
174 1         2 eval {
175 1         1255 require Term::Cap;
176 1   50     3530 my $emu = $ENV{'TERM'} || 'vt100';
177 1         12 my $term = Term::Cap->Tgetent({'TERM' => $emu,
178             'OSPEED' => $speed});
179 1         13445 $TER_CLS = $term->Tputs('cl');
180             };
181             }
182              
183 1 50       114 unless ($TER_CLS) {
184 0         0 &BadClear;
185 0         0 return;
186             }
187              
188 1         15 my $desc = select;
189 1         7 select STDOUT;
190 1         5 my $pipe = $|;
191 1         7 $| = 1;
192 1         32 print $TER_CLS;
193              
194 1         3 $| = $pipe;
195 1         38 select $desc;
196             }
197              
198             sub ReadPassword {
199 1     1 0 6 my ($opt) = @_;
200 1         2 my $bullet = "*";
201 1         3 my ($bs, $ws, $nl) = ("\b", " ", "\n");
202 1 50       4 if ($opt) {
203 1 50       4 $bullet = $opt if length($opt) == 1;
204 1 50       3 ($bs, $ws, $nl, $bullet)
205             = () if ($opt =~ /-\d+/);
206             }
207 1         4 my $save = $|;
208 1         2 $| = 1;
209 1         2 my $pass = '';
210 1         2 for (;;) {
211 72         183 my $ch = &ReadKey;
212 72 50       210 if ($ch eq "\3") {
213 0         0 $pass = "";
214 0         0 $ch = "\n";
215             }
216 72 100       239 if ($ch =~ /[\r\n]/) {
217 1         3 $| = $save;
218 1 50       48 print $nl if $nl;
219 1         65 return $pass;
220             }
221 71 50       176 if ($ch =~ /[\b\x7F]/) {
222 0 0       0 next unless $pass;
223 0         0 chop $pass;
224 0 0       0 print "$bs$ws$bs" if $bs;
225 0         0 next;
226             }
227 71 50       146 if ($ch eq "\025") {
228 0         0 my $len = length($pass);
229 0 0       0 if ($ws) {
230 0         0 my $res = ($bs x $len) . ($ws x $len) .
231             ($bs x $len);
232 0         0 print "$res";
233             }
234 0         0 $pass = '';
235             }
236 71 50       170 if (ord($ch) < 32) {
237 0         0 print "\7";
238 0         0 next;
239             }
240 71         93 $pass .= $ch;
241 71 50       2447 print $bullet if $bullet;
242             }
243             }
244              
245              
246             1;
247             __END__