# Copyright (c) 1992-1994 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1995-1999 Nick Ing-Simmons. All rights reserved.
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself, subject
# to additional disclaimer in Tk/license.terms due to partial
# derivation from Tk8.0 sources.
use AutoLoader
qw(AUTOLOAD);
use base
qw(Exporter DynaLoader);
*fileevent
= \
&Tk
::Event
::IO
::fileevent
;
$Tk::platform
= $Tk::Config
::win_arch
;
$Tk::platform
= 'unix' if $Tk::platform
eq 'x';
$Tk::platform
= ($^O
eq 'MSWin32') ?
$^O
: 'unix';
$Tk::tearoff
= 1 if ($Tk::platform
eq 'unix');
@EXPORT = qw(Exists Ev exit MainLoop DoOneEvent tkinit);
@EXPORT_OK = qw(NoOp after *widget *event lsearch catch $XS_VERSION
DONT_WAIT WINDOW_EVENTS FILE_EVENTS TIMER_EVENTS
NORMAL_BG ACTIVE_BG SELECT_BG
SELECT_FG TROUGH INDICATOR DISABLED BLACK WHITE);
%EXPORT_TAGS = (eventtypes
=> [qw(DONT_WAIT WINDOW_EVENTS FILE_EVENTS
TIMER_EVENTS IDLE_EVENTS ALL_EVENTS)],
variables
=> [qw(*widget *event)],
colors
=> [qw(NORMAL_BG ACTIVE_BG SELECT_BG SELECT_FG
TROUGH INDICATOR DISABLED BLACK WHITE)],
# $tk_version and $tk_patchLevel are reset by pTk when a mainwindow
# is created, $VERSION is checked by bootstrap
$Tk::VERSION
= '800.023';
$Tk::XS_VERSION
= $Tk::VERSION
;
{($Tk::library
) = __FILE__
=~ /^(.*)\.pm$/;}
$Tk::library
= Tk
->findINC('.') unless (defined($Tk::library
) && -d
$Tk::library
);
use vars
qw($inMainLoop);
my $boot_time = timeofday();
# This is a workround for Solaris X11 locale handling
Preload(DynaLoader::dl_findfile('-L/usr/openwin/lib','-lX11'))
if (NeedPreload() && -d '/usr/openwin/lib');
use Tk::Submethods ('option' => [qw(add get clear readfile)],
'clipboard' => [qw(clear append)]
my ($pack,$file,$line,$sub) = caller($i++);
my $loc = "at $file line $line";
($pack,$file,$line,$sub) = caller($i++);
last unless defined($sub);
return 1 if $sub eq '(eval)';
$w->AddErrorInfo("$sub $loc");
return unless (@_ || $@
);
my $mess = (@_) ?
shift : "$@";
die "$mess\n" if $w->_backTrace;
# if we get here we are not in an eval so report now
# This is a $SIG{__DIE__} handler which does not change the $@
# string in the way 'croak' does, but rather add to Tk's ErrorInfo.
# It stops at 1st enclosing eval on assumption that the eval
# is part of Tk call process and will add its own context to ErrorInfo
# and then pass on the error.
# Note that if a __DIE__ handler returns it re-dies up the chain.
return unless defined $w;
return if $w->_backTrace;
# Not in an eval - should not happen
sub XEvent
::xy
{ shift->Info('xy') }
my ($meth) = $XEvent::AUTOLOAD
=~ /(\w)$/;
*{$XEvent::AUTOLOAD
} = sub { shift->Info($meth) };
$obj = (ref $arg) ?
$arg : \
$arg;
return bless $obj,'Tk::Ev';
my ($package,$parent) = @_;
croak
"Unexpected type of parent $parent" unless(ref $parent);
croak
"$parent is not a widget" unless($parent->IsWidget);
my $mw = $parent->MainWindow;
my $hash = $mw->TkHash('_ClassInit_');
unless (exists $hash->{$package})
$hash->{$package} = $package->ClassInit($mw);
return defined($w) && ref($w) && $w->IsWidget && $w->exists;
return timeofday
() - $boot_time;
# Selection* are not autoloaded as names are too long.
selection
('own',(@_,$widget));
selection
('own','-displayof',@_);
selection
('clear','-displayof',@_);
selection
('exists','-displayof',@_);
selection
('handle',@_,$widget,$command);
while (/\{([^{}]*)\}|((?:[^\s\\]|\\.)+)/gs) {
if (defined $1) { push @arr, $1 }
else { $tmp = $2 ; $tmp =~ s/\\([\s\\])/$1/g; push @arr, $tmp }
# carp '('.join(',',@arr).")";
*{$package."::$meth"} = sub { shift->WidgetMethod($name,@_) };
my $parent = delete $args{'-parent'};
$args->{-bitmap
} = delete $args->{-icon
} if defined $args->{-icon
};
$args->{-text
} = delete $args->{-message
} if defined $args->{-message
};
$args->{-type
} = 'OK' unless defined $args->{-type
};
if (defined($type = delete $args->{-type
})) {
my @buttons = grep($_,map(ucfirst($_),
split(/(abort|retry|ignore|yes|no|cancel|ok)/,
$args->{-buttons
} = [@buttons];
$args->{-default_button
} = delete $args->{-default} if
defined $args->{-default};
if (not defined $args->{-default_button
} and scalar(@buttons) == 1) {
$args->{-default_button
} = $buttons[0];
my $md = $parent->Dialog(%$args);
$args{'-type'} = (exists $args{'-type'}) ?
lc($args{'-type'}) : 'ok';
tk_messageBox
(-parent
=> $widget, %args);
tk_getOpenFile
(-parent
=> shift,@_);
tk_getSaveFile
(-parent
=> shift,@_);
tk_chooseColor
(-parent
=> shift,@_);
my ($method,$kind,%args) = @_;
my $w = delete $args{'-parent'};
$mw->{$kind} = $fs = $mw->$method(%args);
DialogWrapper
('ColorDialog',@_);
push @_, -type
=> 'save';
DialogWrapper
('FBox', $cmd, @_);
*MotifFDialog
= \
&FDialog
;
while (Tk
::MainWindow
->Count)
sub tkinit
{ return MainWindow
->new(@_) }
# a wrapper on eval which turns off user $SIG{__DIE__}
eval {local $SIG{'__DIE__'}; &$sub };
$Home = $ENV{'HOME'} || ($ENV{'HOMEDRIVE'}.$ENV{'HOMEPATH'});
$Home .= '/' unless $Home =~ m
#/$#;
return $path if (-e
($path = "$dir/$file"));
shift->update('idletasks');
my $grab = $w->grab('current');
$grab->Unbusy if (defined $grab);
warn "Tk::Error: $error\n " . join("\n ",@_)."\n";
my $w = shift->MainWindow;
my $id = delete $w->{_afterId_
};
$w->after('cancel',$id) if (defined $id);
#----------------------------------------------------------------------------
# This file defines several procedures for managing the input
# @(#) focus.tcl 1.6 94/12/19 17:06:46
# Copyright (c) 1994 Sun Microsystems, Inc.
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
sub FocusChildren
{ shift->children }
# This procedure is invoked to move the input focus to the next window
# after a given one. "Next" is defined in terms of the window
# stacking order, with all the windows underneath a given top-level
# (no matter how deeply nested in the hierarchy) considered except
# for frames and toplevels.
# w - Name of a window: the procedure will set the focus
# to the next window after this one in the traversal
# Descend to just before the first child of the current widget.
my @children = $cur->FocusChildren();
# Look for the next sibling that isn't a top-level.
next if ($cur->toplevel == $cur);
# No more siblings, so go to the current widget's parent.
# If it's a top-level, break out of the loop, otherwise
# look for its next sibling.
last if ($cur->toplevel() == $cur);
$parent = $parent->parent();
@children = $parent->FocusChildren();
$i = lsearch
(\
@children,$cur);
if ($cur == $w || $cur->FocusOK)
# This procedure is invoked to move the input focus to the previous
# window before a given one. "Previous" is defined in terms of the
# window stacking order, with all the windows underneath a given
# top-level (no matter how deeply nested in the hierarchy) considered.
# w - Name of a window: the procedure will set the focus
# to the previous window before this one in the traversal
# Collect information about the current window's position
# among its siblings. Also, if the window is a top-level,
# then reposition to just after the last child of the window.
if ($cur->toplevel() == $cur)
@children = $cur->FocusChildren();
$parent = $cur->parent();
@children = $parent->FocusChildren();
$i = lsearch
(\
@children,$cur);
# Go to the previous sibling, then descend to its last descendant
# (highest in stacking order. While doing this, ignore top-levels
# and their descendants. When we run out of descendants, go up
# one level to the parent.
next if ($cur->toplevel() == $cur);
@children = $parent->FocusChildren();
if ($cur == $w || $cur->FocusOK)
catch
{ $value = $w->cget('-takefocus') };
if (!$@
&& defined($value))
return 0 if ($value eq '0');
return $w->viewable if ($value eq '1');
return $value if (defined $value);
catch
{ $value = $w->cget('-state') } ;
if (!$@
&& defined($value) && $value eq 'disabled')
$value = grep(/Key|Focus/,$w->Tk::bind(),$w->Tk::bind(ref($w)));
# If this procedure is invoked, Tk will enter "focus-follows-mouse"
# mode, where the focus is always on whatever window contains the
# mouse. If this procedure isn't invoked, then the user typically
# has to click on a window to give it the focus.
$w->Tk::focus
() if ($d eq 'NotifyAncestor' || $d eq 'NotifyNonlinear' || $d eq 'NotifyInferior');
$widget->bind('all','<Enter>','EnterFocus');
# This procedure implements keyboard traversal of menus. Given an
# ASCII character "char", it looks for a menubutton with that character
# underlined. If one is found, it posts the menubutton's menu
# w - Window in which the key was typed (selects
# char - Character that selects a menu. The case
# is ignored. If an empty string, nothing
return unless(defined $char && $char ne '');
$w = $w->toplevel->FindMenu($char);
# This procedure traverses to the first menubutton in the toplevel
# for a given window, and posts that menubutton's menu.
# w - Name of a window. Selects which toplevel
# to search for menubuttons.
$w = $w->toplevel->FindMenu('');
# These wrappers don't use method syntax so need to live
# in same package as raw Tk routines are newXS'ed into.
croak
'Use SelectionOwn/SelectionOwner' if ($cmd eq 'own');
croak
"Use Selection\u$cmd()";
# If we have sub Clipboard in Tk then use base qw(Tk::Clipboard ....)
# calls it when it does its eval "require $base"
# croak "Use clipboard\u$cmd()";
warn 'Receive(' . join(',',@_) .')';
die 'Tk rejects send(' . join(',',@_) .")\n";
while ($w->DoOneEvent(DONT_WAIT
|IDLE_EVENTS
|WINDOW_EVENTS
))
return $w->winfo('interps','-displayof');
for ($i = 0; $i < scalar @
$ar; $i++)
return $i if ($$ar[$i] eq $x);