Win32.pm.svn-base
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:15k
- #########################################################################
- # OpenKore - Interface::Console::Win32
- #
- # Copyright (c) 2004 OpenKore development team
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- #
- # $Revision$
- # $Id$
- #
- #########################################################################
- ##
- # MODULE DESCRIPTION:
- #
- # Support for asyncronous input on MS Windows computers
- package Interface::Console::Win32;
- use strict;
- use warnings;
- die "W32 only, this module should never be called on any other OSn"
- unless ($^O eq 'MSWin32' || $^O eq 'cygwin');
- use Carp;
- use Time::HiRes qw/time sleep/;
- use Text::Wrap;
- use Win32::Console;
- use Utils::Win32;
- use encoding 'utf8';
- use Encode;
- use I18N qw(stringToBytes);
- use Translation qw(T);
- use Globals;
- use Settings qw(%sys);
- use base qw(Interface::Console);
- our %fgcolors;
- our %bgcolors;
- sub new {
- my $class = shift;
- my $self = {
- input_list => [],
- last_line_end => 1,
- input_lines => [],
- input_offset => 0,
- input_part => '',
- };
- bless $self, $class;
- $self->{out_con} = new Win32::Console(STD_OUTPUT_HANDLE())
- or die "Could not init output Console: $!n";
- $self->{in_con} = new Win32::Console(STD_INPUT_HANDLE())
- or die "Could not init input Console: $!n";
- $self->setWinDim();
-
- $self->{out_con}->Cursor(0, $self->{in_line});
- $self->{codepage} = $self->{out_con}->OutputCP;
- return $self;
- }
- sub DESTROY {
- my $self = shift;
- $self->color('reset');
- }
- sub setWinDim {
- my $self = shift;
- my($wLeft, $wTop, $wRight, $wBottom) = $self->{out_con}->Window() or die "Can't find initial dimentions for the output windown";
- my($bCol, $bRow) = $self->{out_con}->Size() or die "Can't find dimentions for the output buffern";
- $self->{out_con}->Window(1, $wLeft, $bRow - $wBottom - 1, $wRight, $bRow - 1);# or die "Can't set dimentions for the output windown";
- @{$self}{qw(left out_top right in_line)} = $self->{out_con}->Window() or die "Can't find new dimentions for the output windown";
- $self->{out_bot} = $self->{in_line} - 1; #one line above the input line
- $self->{out_line} = $self->{in_line};
- $self->{out_col} = $self->{in_pos} = $self->{left};
- }
- sub getInput {
- # return undef unless ($enabled);
- my $self = shift;
- my $timeout = shift;
- $self->readEvents();
- my $msg;
- if ($timeout < 0) {
- until (defined $msg) {
- $self->readEvents();
- sleep 0.01;
- if (@{$self->{input_lines}}) {
- $msg = shift @{$self->{input_lines}};
- }
- }
- } elsif ($timeout > 0) {
- my $end = time + $timeout;
- until ($end < time || defined $msg) {
- $self->readEvents();
- sleep 0.01;
- if (@{$self->{input_lines}}) {
- $msg = shift @{$self->{input_lines}};
- }
- }
- } else {
- if (@{$self->{input_lines}}) {
- $msg = shift @{$self->{input_lines}};
- }
- }
- undef $msg if (defined $msg && $msg eq '');
- return $msg;
- }
- ##
- # readEvents()
- #
- # reads low level events from the input console, for key presses it
- # updates the console input variables
- #
- # note: most of this is commented out, it need a cordinated output
- # system to use the separate input line (meaning output does not
- # over write your input line)
- sub readEvents {
- my $self = shift;
- # local($|) = 1;
- while ($self->{in_con}->GetEvents()) {
- my @event = $self->{in_con}->Input();
- if (@event && $event[5] < 0) {
- # Special characters are returned as unsigned integer
- # (dunno why). Fix this.
- $event[5] = 256 + $event[5];
- }
- if (@event && $event[0] == 1 && $event[1] == 0 && $event[3] == 18) {
- # Alt was released and there's an ASCII code. This is
- # a special character. Change @events as if a normal key
- # was pressed.
- $event[1] = 1;
- }
- if (@event && $event[0] == 1 && $event[1] == 1) {
- ##Ctrl+U (erases entire line)
- if ($event[6] == 40 && $event[5] == 21) {
- $self->{in_pos} = 0;
- $self->{out_con}->Scroll(
- 0, $self->{in_line}, $self->{right}, $self->{in_line},
- -$self->{right}, $self->{in_line}, ord(' '), $main::ATTR_NORMAL,
- 0, $self->{in_line}, $self->{right}, $self->{in_line},
- );
- $self->{out_con}->Cursor(0, $self->{in_line});
- $self->{input_part} = '';
- ##Backspace
- } elsif ($event[5] == 8) {
- $self->{in_pos}-- if $self->{in_pos} > 0;
- substr($self->{input_part}, $self->{in_pos}, 1, '');
- $self->{out_con}->Scroll(
- $self->{in_pos}, $self->{in_line}, $self->{right}, $self->{in_line},
- $self->{in_pos}-1, $self->{in_line}, ord(' '), $main::ATTR_NORMAL,
- $self->{in_pos}, $self->{in_line}, $self->{right}, $self->{in_line},
- );
- $self->{out_con}->Cursor($self->{in_pos}, $self->{in_line});
- # print "