xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/lib/Term/ReadLine.pm (revision 0:68f95e015346)
1*0Sstevel@tonic-gate=head1 NAME
2*0Sstevel@tonic-gate
3*0Sstevel@tonic-gateTerm::ReadLine - Perl interface to various C<readline> packages.
4*0Sstevel@tonic-gateIf no real package is found, substitutes stubs instead of basic functions.
5*0Sstevel@tonic-gate
6*0Sstevel@tonic-gate=head1 SYNOPSIS
7*0Sstevel@tonic-gate
8*0Sstevel@tonic-gate  use Term::ReadLine;
9*0Sstevel@tonic-gate  my $term = new Term::ReadLine 'Simple Perl calc';
10*0Sstevel@tonic-gate  my $prompt = "Enter your arithmetic expression: ";
11*0Sstevel@tonic-gate  my $OUT = $term->OUT || \*STDOUT;
12*0Sstevel@tonic-gate  while ( defined ($_ = $term->readline($prompt)) ) {
13*0Sstevel@tonic-gate    my $res = eval($_);
14*0Sstevel@tonic-gate    warn $@ if $@;
15*0Sstevel@tonic-gate    print $OUT $res, "\n" unless $@;
16*0Sstevel@tonic-gate    $term->addhistory($_) if /\S/;
17*0Sstevel@tonic-gate  }
18*0Sstevel@tonic-gate
19*0Sstevel@tonic-gate=head1 DESCRIPTION
20*0Sstevel@tonic-gate
21*0Sstevel@tonic-gateThis package is just a front end to some other packages. At the moment
22*0Sstevel@tonic-gatethis description is written, the only such package is Term-ReadLine,
23*0Sstevel@tonic-gateavailable on CPAN near you. The real target of this stub package is to
24*0Sstevel@tonic-gateset up a common interface to whatever Readline emerges with time.
25*0Sstevel@tonic-gate
26*0Sstevel@tonic-gate=head1 Minimal set of supported functions
27*0Sstevel@tonic-gate
28*0Sstevel@tonic-gateAll the supported functions should be called as methods, i.e., either as
29*0Sstevel@tonic-gate
30*0Sstevel@tonic-gate  $term = new Term::ReadLine 'name';
31*0Sstevel@tonic-gate
32*0Sstevel@tonic-gateor as
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gate  $term->addhistory('row');
35*0Sstevel@tonic-gate
36*0Sstevel@tonic-gatewhere $term is a return value of Term::ReadLine-E<gt>new().
37*0Sstevel@tonic-gate
38*0Sstevel@tonic-gate=over 12
39*0Sstevel@tonic-gate
40*0Sstevel@tonic-gate=item C<ReadLine>
41*0Sstevel@tonic-gate
42*0Sstevel@tonic-gatereturns the actual package that executes the commands. Among possible
43*0Sstevel@tonic-gatevalues are C<Term::ReadLine::Gnu>, C<Term::ReadLine::Perl>,
44*0Sstevel@tonic-gateC<Term::ReadLine::Stub>.
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate=item C<new>
47*0Sstevel@tonic-gate
48*0Sstevel@tonic-gatereturns the handle for subsequent calls to following
49*0Sstevel@tonic-gatefunctions. Argument is the name of the application. Optionally can be
50*0Sstevel@tonic-gatefollowed by two arguments for C<IN> and C<OUT> filehandles. These
51*0Sstevel@tonic-gatearguments should be globs.
52*0Sstevel@tonic-gate
53*0Sstevel@tonic-gate=item C<readline>
54*0Sstevel@tonic-gate
55*0Sstevel@tonic-gategets an input line, I<possibly> with actual C<readline>
56*0Sstevel@tonic-gatesupport. Trailing newline is removed. Returns C<undef> on C<EOF>.
57*0Sstevel@tonic-gate
58*0Sstevel@tonic-gate=item C<addhistory>
59*0Sstevel@tonic-gate
60*0Sstevel@tonic-gateadds the line to the history of input, from where it can be used if
61*0Sstevel@tonic-gatethe actual C<readline> is present.
62*0Sstevel@tonic-gate
63*0Sstevel@tonic-gate=item C<IN>, C<OUT>
64*0Sstevel@tonic-gate
65*0Sstevel@tonic-gatereturn the filehandles for input and output or C<undef> if C<readline>
66*0Sstevel@tonic-gateinput and output cannot be used for Perl.
67*0Sstevel@tonic-gate
68*0Sstevel@tonic-gate=item C<MinLine>
69*0Sstevel@tonic-gate
70*0Sstevel@tonic-gateIf argument is specified, it is an advice on minimal size of line to
71*0Sstevel@tonic-gatebe included into history.  C<undef> means do not include anything into
72*0Sstevel@tonic-gatehistory. Returns the old value.
73*0Sstevel@tonic-gate
74*0Sstevel@tonic-gate=item C<findConsole>
75*0Sstevel@tonic-gate
76*0Sstevel@tonic-gatereturns an array with two strings that give most appropriate names for
77*0Sstevel@tonic-gatefiles for input and output using conventions C<"E<lt>$in">, C<"E<gt>out">.
78*0Sstevel@tonic-gate
79*0Sstevel@tonic-gate=item Attribs
80*0Sstevel@tonic-gate
81*0Sstevel@tonic-gatereturns a reference to a hash which describes internal configuration
82*0Sstevel@tonic-gateof the package. Names of keys in this hash conform to standard
83*0Sstevel@tonic-gateconventions with the leading C<rl_> stripped.
84*0Sstevel@tonic-gate
85*0Sstevel@tonic-gate=item C<Features>
86*0Sstevel@tonic-gate
87*0Sstevel@tonic-gateReturns a reference to a hash with keys being features present in
88*0Sstevel@tonic-gatecurrent implementation. Several optional features are used in the
89*0Sstevel@tonic-gateminimal interface: C<appname> should be present if the first argument
90*0Sstevel@tonic-gateto C<new> is recognized, and C<minline> should be present if
91*0Sstevel@tonic-gateC<MinLine> method is not dummy.  C<autohistory> should be present if
92*0Sstevel@tonic-gatelines are put into history automatically (maybe subject to
93*0Sstevel@tonic-gateC<MinLine>), and C<addhistory> if C<addhistory> method is not dummy.
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gateIf C<Features> method reports a feature C<attribs> as present, the
96*0Sstevel@tonic-gatemethod C<Attribs> is not dummy.
97*0Sstevel@tonic-gate
98*0Sstevel@tonic-gate=back
99*0Sstevel@tonic-gate
100*0Sstevel@tonic-gate=head1 Additional supported functions
101*0Sstevel@tonic-gate
102*0Sstevel@tonic-gateActually C<Term::ReadLine> can use some other package, that will
103*0Sstevel@tonic-gatesupport reacher set of commands.
104*0Sstevel@tonic-gate
105*0Sstevel@tonic-gateAll these commands are callable via method interface and have names
106*0Sstevel@tonic-gatewhich conform to standard conventions with the leading C<rl_> stripped.
107*0Sstevel@tonic-gate
108*0Sstevel@tonic-gateThe stub package included with the perl distribution allows some
109*0Sstevel@tonic-gateadditional methods:
110*0Sstevel@tonic-gate
111*0Sstevel@tonic-gate=over 12
112*0Sstevel@tonic-gate
113*0Sstevel@tonic-gate=item C<tkRunning>
114*0Sstevel@tonic-gate
115*0Sstevel@tonic-gatemakes Tk event loop run when waiting for user input (i.e., during
116*0Sstevel@tonic-gateC<readline> method).
117*0Sstevel@tonic-gate
118*0Sstevel@tonic-gate=item C<ornaments>
119*0Sstevel@tonic-gate
120*0Sstevel@tonic-gatemakes the command line stand out by using termcap data.  The argument
121*0Sstevel@tonic-gateto C<ornaments> should be 0, 1, or a string of a form
122*0Sstevel@tonic-gateC<"aa,bb,cc,dd">.  Four components of this string should be names of
123*0Sstevel@tonic-gateI<terminal capacities>, first two will be issued to make the prompt
124*0Sstevel@tonic-gatestandout, last two to make the input line standout.
125*0Sstevel@tonic-gate
126*0Sstevel@tonic-gate=item C<newTTY>
127*0Sstevel@tonic-gate
128*0Sstevel@tonic-gatetakes two arguments which are input filehandle and output filehandle.
129*0Sstevel@tonic-gateSwitches to use these filehandles.
130*0Sstevel@tonic-gate
131*0Sstevel@tonic-gate=back
132*0Sstevel@tonic-gate
133*0Sstevel@tonic-gateOne can check whether the currently loaded ReadLine package supports
134*0Sstevel@tonic-gatethese methods by checking for corresponding C<Features>.
135*0Sstevel@tonic-gate
136*0Sstevel@tonic-gate=head1 EXPORTS
137*0Sstevel@tonic-gate
138*0Sstevel@tonic-gateNone
139*0Sstevel@tonic-gate
140*0Sstevel@tonic-gate=head1 ENVIRONMENT
141*0Sstevel@tonic-gate
142*0Sstevel@tonic-gateThe environment variable C<PERL_RL> governs which ReadLine clone is
143*0Sstevel@tonic-gateloaded. If the value is false, a dummy interface is used. If the value
144*0Sstevel@tonic-gateis true, it should be tail of the name of the package to use, such as
145*0Sstevel@tonic-gateC<Perl> or C<Gnu>.
146*0Sstevel@tonic-gate
147*0Sstevel@tonic-gateAs a special case, if the value of this variable is space-separated,
148*0Sstevel@tonic-gatethe tail might be used to disable the ornaments by setting the tail to
149*0Sstevel@tonic-gatebe C<o=0> or C<ornaments=0>.  The head should be as described above, say
150*0Sstevel@tonic-gate
151*0Sstevel@tonic-gateIf the variable is not set, or if the head of space-separated list is
152*0Sstevel@tonic-gateempty, the best available package is loaded.
153*0Sstevel@tonic-gate
154*0Sstevel@tonic-gate  export "PERL_RL=Perl o=0"	# Use Perl ReadLine without ornaments
155*0Sstevel@tonic-gate  export "PERL_RL= o=0"		# Use best available ReadLine without ornaments
156*0Sstevel@tonic-gate
157*0Sstevel@tonic-gate(Note that processing of C<PERL_RL> for ornaments is in the discretion of the
158*0Sstevel@tonic-gateparticular used C<Term::ReadLine::*> package).
159*0Sstevel@tonic-gate
160*0Sstevel@tonic-gate=head1 CAVEATS
161*0Sstevel@tonic-gate
162*0Sstevel@tonic-gateIt seems that using Term::ReadLine from Emacs minibuffer doesn't work
163*0Sstevel@tonic-gatequite right and one will get an error message like
164*0Sstevel@tonic-gate
165*0Sstevel@tonic-gate    Cannot open /dev/tty for read at ...
166*0Sstevel@tonic-gate
167*0Sstevel@tonic-gateOne possible workaround for this is to explicitly open /dev/tty like this
168*0Sstevel@tonic-gate
169*0Sstevel@tonic-gate    open (FH, "/dev/tty" )
170*0Sstevel@tonic-gate      or eval 'sub Term::ReadLine::findConsole { ("&STDIN", "&STDERR") }';
171*0Sstevel@tonic-gate    die $@ if $@;
172*0Sstevel@tonic-gate    close (FH);
173*0Sstevel@tonic-gate
174*0Sstevel@tonic-gateor you can try using the 4-argument form of Term::ReadLine->new().
175*0Sstevel@tonic-gate
176*0Sstevel@tonic-gate=cut
177*0Sstevel@tonic-gate
178*0Sstevel@tonic-gateuse strict;
179*0Sstevel@tonic-gate
180*0Sstevel@tonic-gatepackage Term::ReadLine::Stub;
181*0Sstevel@tonic-gateour @ISA = qw'Term::ReadLine::Tk Term::ReadLine::TermCap';
182*0Sstevel@tonic-gate
183*0Sstevel@tonic-gate$DB::emacs = $DB::emacs;	# To peacify -w
184*0Sstevel@tonic-gateour @rl_term_set;
185*0Sstevel@tonic-gate*rl_term_set = \@Term::ReadLine::TermCap::rl_term_set;
186*0Sstevel@tonic-gate
187*0Sstevel@tonic-gatesub PERL_UNICODE_STDIN () { 0x0001 }
188*0Sstevel@tonic-gate
189*0Sstevel@tonic-gatesub ReadLine {'Term::ReadLine::Stub'}
190*0Sstevel@tonic-gatesub readline {
191*0Sstevel@tonic-gate  my $self = shift;
192*0Sstevel@tonic-gate  my ($in,$out,$str) = @$self;
193*0Sstevel@tonic-gate  my $prompt = shift;
194*0Sstevel@tonic-gate  print $out $rl_term_set[0], $prompt, $rl_term_set[1], $rl_term_set[2];
195*0Sstevel@tonic-gate  $self->register_Tk
196*0Sstevel@tonic-gate     if not $Term::ReadLine::registered and $Term::ReadLine::toloop
197*0Sstevel@tonic-gate	and defined &Tk::DoOneEvent;
198*0Sstevel@tonic-gate  #$str = scalar <$in>;
199*0Sstevel@tonic-gate  $str = $self->get_line;
200*0Sstevel@tonic-gate  $str =~ s/^\s*\Q$prompt\E// if ($^O eq 'MacOS');
201*0Sstevel@tonic-gate  utf8::upgrade($str)
202*0Sstevel@tonic-gate      if (${^UNICODE} & PERL_UNICODE_STDIN || defined ${^ENCODING}) &&
203*0Sstevel@tonic-gate         utf8::valid($str);
204*0Sstevel@tonic-gate  print $out $rl_term_set[3];
205*0Sstevel@tonic-gate  # bug in 5.000: chomping empty string creats length -1:
206*0Sstevel@tonic-gate  chomp $str if defined $str;
207*0Sstevel@tonic-gate  $str;
208*0Sstevel@tonic-gate}
209*0Sstevel@tonic-gatesub addhistory {}
210*0Sstevel@tonic-gate
211*0Sstevel@tonic-gatesub findConsole {
212*0Sstevel@tonic-gate    my $console;
213*0Sstevel@tonic-gate
214*0Sstevel@tonic-gate    if ($^O eq 'MacOS') {
215*0Sstevel@tonic-gate        $console = "Dev:Console";
216*0Sstevel@tonic-gate    } elsif (-e "/dev/tty") {
217*0Sstevel@tonic-gate	$console = "/dev/tty";
218*0Sstevel@tonic-gate    } elsif (-e "con" or $^O eq 'MSWin32') {
219*0Sstevel@tonic-gate	$console = "con";
220*0Sstevel@tonic-gate    } else {
221*0Sstevel@tonic-gate	$console = "sys\$command";
222*0Sstevel@tonic-gate    }
223*0Sstevel@tonic-gate
224*0Sstevel@tonic-gate    if (($^O eq 'amigaos') || ($^O eq 'beos') || ($^O eq 'epoc')) {
225*0Sstevel@tonic-gate	$console = undef;
226*0Sstevel@tonic-gate    }
227*0Sstevel@tonic-gate    elsif ($^O eq 'os2') {
228*0Sstevel@tonic-gate      if ($DB::emacs) {
229*0Sstevel@tonic-gate	$console = undef;
230*0Sstevel@tonic-gate      } else {
231*0Sstevel@tonic-gate	$console = "/dev/con";
232*0Sstevel@tonic-gate      }
233*0Sstevel@tonic-gate    }
234*0Sstevel@tonic-gate
235*0Sstevel@tonic-gate    my $consoleOUT = $console;
236*0Sstevel@tonic-gate    $console = "&STDIN" unless defined $console;
237*0Sstevel@tonic-gate    if (!defined $consoleOUT) {
238*0Sstevel@tonic-gate      $consoleOUT = defined fileno(STDERR) ? "&STDERR" : "&STDOUT";
239*0Sstevel@tonic-gate    }
240*0Sstevel@tonic-gate    ($console,$consoleOUT);
241*0Sstevel@tonic-gate}
242*0Sstevel@tonic-gate
243*0Sstevel@tonic-gatesub new {
244*0Sstevel@tonic-gate  die "method new called with wrong number of arguments"
245*0Sstevel@tonic-gate    unless @_==2 or @_==4;
246*0Sstevel@tonic-gate  #local (*FIN, *FOUT);
247*0Sstevel@tonic-gate  my ($FIN, $FOUT, $ret);
248*0Sstevel@tonic-gate  if (@_==2) {
249*0Sstevel@tonic-gate    my($console, $consoleOUT) = $_[0]->findConsole;
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate    open(FIN, "<$console");
252*0Sstevel@tonic-gate    open(FOUT,">$consoleOUT");
253*0Sstevel@tonic-gate    #OUT->autoflush(1);		# Conflicts with debugger?
254*0Sstevel@tonic-gate    my $sel = select(FOUT);
255*0Sstevel@tonic-gate    $| = 1;				# for DB::OUT
256*0Sstevel@tonic-gate    select($sel);
257*0Sstevel@tonic-gate    $ret = bless [\*FIN, \*FOUT];
258*0Sstevel@tonic-gate  } else {			# Filehandles supplied
259*0Sstevel@tonic-gate    $FIN = $_[2]; $FOUT = $_[3];
260*0Sstevel@tonic-gate    #OUT->autoflush(1);		# Conflicts with debugger?
261*0Sstevel@tonic-gate    my $sel = select($FOUT);
262*0Sstevel@tonic-gate    $| = 1;				# for DB::OUT
263*0Sstevel@tonic-gate    select($sel);
264*0Sstevel@tonic-gate    $ret = bless [$FIN, $FOUT];
265*0Sstevel@tonic-gate  }
266*0Sstevel@tonic-gate  if ($ret->Features->{ornaments}
267*0Sstevel@tonic-gate      and not ($ENV{PERL_RL} and $ENV{PERL_RL} =~ /\bo\w*=0/)) {
268*0Sstevel@tonic-gate    local $Term::ReadLine::termcap_nowarn = 1;
269*0Sstevel@tonic-gate    $ret->ornaments(1);
270*0Sstevel@tonic-gate  }
271*0Sstevel@tonic-gate  return $ret;
272*0Sstevel@tonic-gate}
273*0Sstevel@tonic-gate
274*0Sstevel@tonic-gatesub newTTY {
275*0Sstevel@tonic-gate  my ($self, $in, $out) = @_;
276*0Sstevel@tonic-gate  $self->[0] = $in;
277*0Sstevel@tonic-gate  $self->[1] = $out;
278*0Sstevel@tonic-gate  my $sel = select($out);
279*0Sstevel@tonic-gate  $| = 1;				# for DB::OUT
280*0Sstevel@tonic-gate  select($sel);
281*0Sstevel@tonic-gate}
282*0Sstevel@tonic-gate
283*0Sstevel@tonic-gatesub IN { shift->[0] }
284*0Sstevel@tonic-gatesub OUT { shift->[1] }
285*0Sstevel@tonic-gatesub MinLine { undef }
286*0Sstevel@tonic-gatesub Attribs { {} }
287*0Sstevel@tonic-gate
288*0Sstevel@tonic-gatemy %features = (tkRunning => 1, ornaments => 1, 'newTTY' => 1);
289*0Sstevel@tonic-gatesub Features { \%features }
290*0Sstevel@tonic-gate
291*0Sstevel@tonic-gatepackage Term::ReadLine;		# So late to allow the above code be defined?
292*0Sstevel@tonic-gate
293*0Sstevel@tonic-gateour $VERSION = '1.01';
294*0Sstevel@tonic-gate
295*0Sstevel@tonic-gatemy ($which) = exists $ENV{PERL_RL} ? split /\s+/, $ENV{PERL_RL} : undef;
296*0Sstevel@tonic-gateif ($which) {
297*0Sstevel@tonic-gate  if ($which =~ /\bgnu\b/i){
298*0Sstevel@tonic-gate    eval "use Term::ReadLine::Gnu;";
299*0Sstevel@tonic-gate  } elsif ($which =~ /\bperl\b/i) {
300*0Sstevel@tonic-gate    eval "use Term::ReadLine::Perl;";
301*0Sstevel@tonic-gate  } else {
302*0Sstevel@tonic-gate    eval "use Term::ReadLine::$which;";
303*0Sstevel@tonic-gate  }
304*0Sstevel@tonic-gate} elsif (defined $which and $which ne '') {	# Defined but false
305*0Sstevel@tonic-gate  # Do nothing fancy
306*0Sstevel@tonic-gate} else {
307*0Sstevel@tonic-gate  eval "use Term::ReadLine::Gnu; 1" or eval "use Term::ReadLine::Perl; 1";
308*0Sstevel@tonic-gate}
309*0Sstevel@tonic-gate
310*0Sstevel@tonic-gate#require FileHandle;
311*0Sstevel@tonic-gate
312*0Sstevel@tonic-gate# To make possible switch off RL in debugger: (Not needed, work done
313*0Sstevel@tonic-gate# in debugger).
314*0Sstevel@tonic-gateour @ISA;
315*0Sstevel@tonic-gateif (defined &Term::ReadLine::Gnu::readline) {
316*0Sstevel@tonic-gate  @ISA = qw(Term::ReadLine::Gnu Term::ReadLine::Stub);
317*0Sstevel@tonic-gate} elsif (defined &Term::ReadLine::Perl::readline) {
318*0Sstevel@tonic-gate  @ISA = qw(Term::ReadLine::Perl Term::ReadLine::Stub);
319*0Sstevel@tonic-gate} elsif (defined $which && defined &{"Term::ReadLine::$which\::readline"}) {
320*0Sstevel@tonic-gate  @ISA = "Term::ReadLine::$which";
321*0Sstevel@tonic-gate} else {
322*0Sstevel@tonic-gate  @ISA = qw(Term::ReadLine::Stub);
323*0Sstevel@tonic-gate}
324*0Sstevel@tonic-gate
325*0Sstevel@tonic-gatepackage Term::ReadLine::TermCap;
326*0Sstevel@tonic-gate
327*0Sstevel@tonic-gate# Prompt-start, prompt-end, command-line-start, command-line-end
328*0Sstevel@tonic-gate#     -- zero-width beautifies to emit around prompt and the command line.
329*0Sstevel@tonic-gateour @rl_term_set = ("","","","");
330*0Sstevel@tonic-gate# string encoded:
331*0Sstevel@tonic-gateour $rl_term_set = ',,,';
332*0Sstevel@tonic-gate
333*0Sstevel@tonic-gateour $terminal;
334*0Sstevel@tonic-gatesub LoadTermCap {
335*0Sstevel@tonic-gate  return if defined $terminal;
336*0Sstevel@tonic-gate
337*0Sstevel@tonic-gate  require Term::Cap;
338*0Sstevel@tonic-gate  $terminal = Tgetent Term::Cap ({OSPEED => 9600}); # Avoid warning.
339*0Sstevel@tonic-gate}
340*0Sstevel@tonic-gate
341*0Sstevel@tonic-gatesub ornaments {
342*0Sstevel@tonic-gate  shift;
343*0Sstevel@tonic-gate  return $rl_term_set unless @_;
344*0Sstevel@tonic-gate  $rl_term_set = shift;
345*0Sstevel@tonic-gate  $rl_term_set ||= ',,,';
346*0Sstevel@tonic-gate  $rl_term_set = 'us,ue,md,me' if $rl_term_set eq '1';
347*0Sstevel@tonic-gate  my @ts = split /,/, $rl_term_set, 4;
348*0Sstevel@tonic-gate  eval { LoadTermCap };
349*0Sstevel@tonic-gate  unless (defined $terminal) {
350*0Sstevel@tonic-gate    warn("Cannot find termcap: $@\n") unless $Term::ReadLine::termcap_nowarn;
351*0Sstevel@tonic-gate    $rl_term_set = ',,,';
352*0Sstevel@tonic-gate    return;
353*0Sstevel@tonic-gate  }
354*0Sstevel@tonic-gate  @rl_term_set = map {$_ ? $terminal->Tputs($_,1) || '' : ''} @ts;
355*0Sstevel@tonic-gate  return $rl_term_set;
356*0Sstevel@tonic-gate}
357*0Sstevel@tonic-gate
358*0Sstevel@tonic-gate
359*0Sstevel@tonic-gatepackage Term::ReadLine::Tk;
360*0Sstevel@tonic-gate
361*0Sstevel@tonic-gateour($count_handle, $count_DoOne, $count_loop);
362*0Sstevel@tonic-gate$count_handle = $count_DoOne = $count_loop = 0;
363*0Sstevel@tonic-gate
364*0Sstevel@tonic-gateour($giveup);
365*0Sstevel@tonic-gatesub handle {$giveup = 1; $count_handle++}
366*0Sstevel@tonic-gate
367*0Sstevel@tonic-gatesub Tk_loop {
368*0Sstevel@tonic-gate  # Tk->tkwait('variable',\$giveup);	# needs Widget
369*0Sstevel@tonic-gate  $count_DoOne++, Tk::DoOneEvent(0) until $giveup;
370*0Sstevel@tonic-gate  $count_loop++;
371*0Sstevel@tonic-gate  $giveup = 0;
372*0Sstevel@tonic-gate}
373*0Sstevel@tonic-gate
374*0Sstevel@tonic-gatesub register_Tk {
375*0Sstevel@tonic-gate  my $self = shift;
376*0Sstevel@tonic-gate  $Term::ReadLine::registered++
377*0Sstevel@tonic-gate    or Tk->fileevent($self->IN,'readable',\&handle);
378*0Sstevel@tonic-gate}
379*0Sstevel@tonic-gate
380*0Sstevel@tonic-gatesub tkRunning {
381*0Sstevel@tonic-gate  $Term::ReadLine::toloop = $_[1] if @_ > 1;
382*0Sstevel@tonic-gate  $Term::ReadLine::toloop;
383*0Sstevel@tonic-gate}
384*0Sstevel@tonic-gate
385*0Sstevel@tonic-gatesub get_c {
386*0Sstevel@tonic-gate  my $self = shift;
387*0Sstevel@tonic-gate  $self->Tk_loop if $Term::ReadLine::toloop && defined &Tk::DoOneEvent;
388*0Sstevel@tonic-gate  return getc $self->IN;
389*0Sstevel@tonic-gate}
390*0Sstevel@tonic-gate
391*0Sstevel@tonic-gatesub get_line {
392*0Sstevel@tonic-gate  my $self = shift;
393*0Sstevel@tonic-gate  $self->Tk_loop if $Term::ReadLine::toloop && defined &Tk::DoOneEvent;
394*0Sstevel@tonic-gate  my $in = $self->IN;
395*0Sstevel@tonic-gate  local ($/) = "\n";
396*0Sstevel@tonic-gate  return scalar <$in>;
397*0Sstevel@tonic-gate}
398*0Sstevel@tonic-gate
399*0Sstevel@tonic-gate1;
400*0Sstevel@tonic-gate
401