File Coverage

blib/lib/Win32/Console/GetC.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Win32::Console::GetC;
2              
3 1     1   4 use strict;
  1         2  
  1         33  
4 1     1   5 use warnings;
  1         2  
  1         28  
5 1     1   240420 use threads;
  0            
  0            
6             use threads::shared;
7             use Win32::API;
8             use IO::Scalar;
9             our $VERSION = '0.01';
10              
11             sub STD_INPUT_HANDLE { 0xfffffff6 }
12             sub FILE_TYPE_CHAR { 0x0002 }
13             sub FILE_TYPE_PIPE { 0x0003 }
14             sub ENABLE_PROCESS_INPUT { 0x0001 }
15             sub ENABLE_LINE_INPUT { 0x0002 }
16             sub ENABLE_ECHO_INPUT { 0x0004 }
17              
18             my $GetStdHandle = Win32::API->new('kernel32.dll',
19             'GetStdHandle',
20             'N',
21             'N',
22             ) or die ": $^E";
23             my $GetFileType = Win32::API->new('kernel32.dll',
24             'GetFileType',
25             'N',
26             'N',
27             ) or die ": $^E";
28             my $_kbhit = Win32::API->new('msvcrt.dll',
29             '_kbhit',
30             '',
31             'I',
32             ) or die ": $^E";
33             my $ReadConsole = Win32::API->new('kernel32.dll',
34             'ReadConsoleA',
35             'NPNPP',
36             'N',
37             ) or die ": $^E";
38             my $GetConsoleMode = Win32::API->new('kernel32.dll',
39             'GetConsoleMode',
40             'NP',
41             'I',
42             ) or die ": $^E";
43             my $SetConsoleMode = Win32::API->new('kernel32.dll',
44             'SetConsoleMode',
45             'NN',
46             'I',
47             ) or die ": $^E";
48              
49             my $inputs = &share([]);
50             tie *STDIN, 'Win32::Console::GetC::Tied', $inputs;
51              
52             my $handle = $GetStdHandle->Call(STD_INPUT_HANDLE);
53             if ($GetFileType->Call($handle) eq FILE_TYPE_CHAR) {
54             my $mode = 0;
55             $GetConsoleMode->Call($handle, \$mode);
56             $SetConsoleMode->Call( $handle,
57             $mode &
58             ~ENABLE_LINE_INPUT &
59             ~ENABLE_ECHO_INPUT |
60             ENABLE_PROCESS_INPUT );
61             async {
62             while (1) {
63             if ($_kbhit->Call()) {
64             my ($buf, $num) = (' ', 0);
65             if ($ReadConsole->Call($handle, $buf, 1, \$num, 0)) {
66             push @$inputs, $buf;
67             }
68             }
69             }
70             }->detach;
71             }
72              
73             package Win32::Console::GetC::Tied;
74              
75             sub TIEHANDLE {
76             my ($class, $ref) = @_;
77             bless { ref => $ref }, $class;
78             }
79              
80             sub GETC {
81             my $self = shift;
82             shift @{$self->{ref}};
83             }
84              
85             1;
86              
87             __END__