# 
# 
# To apply this patch:
# STEP 1: Chdir to the source directory.
# STEP 2: Run the 'applypatch' program with this patch file as input.
#
# If you do not have 'applypatch', it is part of the 'makepatch' package
# that you can fetch from the Comprehensive Perl Archive Network:
# http://www.perl.com/CPAN/authors/Johan_Vromans/makepatch-x.y.tar.gz
# In the above URL, 'x' should be 2 or higher.
#
# To apply this patch without the use of 'applypatch':
# STEP 1: Chdir to the source directory.
# If you have a decent Bourne-type shell:
# STEP 2: Run the shell with this file as input.
# If you don't have such a shell, you may need to manually create
# the files as shown below.
# STEP 3: Run the 'patch' program with this file as input.
#
# These are the commands needed to create/delete files/directories:
#
touch 't/00wmcheck.t'
chmod 0775 't/00wmcheck.t'
touch 't/canvas.t'
chmod 0775 't/canvas.t'
touch 't/wm-tcl.t'
chmod 0775 't/wm-tcl.t'
#
# This command terminates the shell and need not be executed manually.
exit
#
#### End of Preamble ####

#### Patch data follows ####
diff -up '/usr/local/src/Tk-804.027/Event/Event.pm' '/home/e/eserte/work/svk-checkouts/Tk/Event/Event.pm'
Index: ./Event/Event.pm
--- ./Event/Event.pm	Sun Apr 11 20:38:23 2004
+++ ./Event/Event.pm	Sat Nov 11 15:55:01 2006
@@ -2,7 +2,8 @@ package Tk::Event;
 use vars qw($VERSION $XS_VERSION @EXPORT_OK);
 END { CleanupGlue() }
 $VERSION = sprintf '4.%03d', q$Revision: #15 $ =~ /\D(\d+)\s*$/;
-$XS_VERSION = '804.027';
+$XS_VERSION = '804.027_001';
+$XS_VERSION = eval $XS_VERSION;
 use base  qw(Exporter);
 use XSLoader;
 @EXPORT_OK = qw($XS_VERSION DONT_WAIT WINDOW_EVENTS  FILE_EVENTS
diff -up '/usr/local/src/Tk-804.027/MANIFEST' '/home/e/eserte/work/svk-checkouts/Tk/MANIFEST'
Index: ./MANIFEST
--- ./MANIFEST	Thu Apr  8 13:16:50 2004
+++ ./MANIFEST	Thu Nov  9 00:13:45 2006
@@ -1825,6 +1825,7 @@ stripblib
 style_test
 submethods
 symbols
+t/00wmcheck.t			Provide information about wm
 t/after.t
 t/autoload.t
 t/balloon.t
@@ -1833,6 +1834,7 @@ t/browseentry-subclassing.t
 t/browseentry.t
 t/browseentry2.t
 t/button.t
+t/canvas.t
 t/create.t
 t/cursor.t
 t/dash.t
@@ -1869,6 +1871,7 @@ t/slaves.t
 t/widget.t
 t/wm.t
 t/wm-time.t
+t/wm-tcl.t
 t/X.t
 t/zzHList.t
 t/zzPhoto.t
diff -up '/usr/local/src/Tk-804.027/MANIFEST.SKIP' '/home/e/eserte/work/svk-checkouts/Tk/MANIFEST.SKIP'
Index: ./MANIFEST.SKIP
--- ./MANIFEST.SKIP	Sat Dec 13 19:13:25 2003
+++ ./MANIFEST.SKIP	Sat Nov 11 03:16:11 2006
@@ -74,7 +74,6 @@ pTk/default\.h$
 pTk/exWinHandle\.c$
 pTk/img\.h$
 pTk/imgBMP\.c$
-pTk/imgGIF\.c$
 pTk/imgInit\.c$
 pTk/imgInt\.h$
 pTk/imgObj\.c$
@@ -207,6 +206,7 @@ pTk/tkGrab\.c$
 pTk/tkGrid\.c$
 pTk/tkImage\.c$
 pTk/tkImgBmap\.c$
+pTk/tkImgGIF\.c$
 pTk/tkImgPPM\.c$
 pTk/tkImgPhoto\.c$
 pTk/tkImgUtil\.c$
diff -up '/usr/local/src/Tk-804.027/Makefile.PL' '/home/e/eserte/work/svk-checkouts/Tk/Makefile.PL'
Index: ./Makefile.PL
--- ./Makefile.PL	Mon Mar  8 11:15:17 2004
+++ ./Makefile.PL	Sat Nov 11 15:52:16 2006
@@ -18,6 +18,7 @@ BEGIN
     if (/\$Tk::VERSION\s+=\s+'([0-9._]+)'/)
      {
       $VERSION = $1;
+      $VERSION = eval $VERSION;
       last;
      }
    }
diff -up '/usr/local/src/Tk-804.027/Menubutton/Menubutton.pm' '/home/e/eserte/work/svk-checkouts/Tk/Menubutton/Menubutton.pm'
Index: ./Menubutton/Menubutton.pm
Prereq:  1.34 
--- ./Menubutton/Menubutton.pm	Sun Jul 20 19:43:28 2003
+++ ./Menubutton/Menubutton.pm	Sat Nov 11 03:01:00 2006
@@ -269,8 +269,11 @@ sub Post
  if ($tearoff)
   {
    $menu->focus;
-   $w->SaveGrabInfo;
-   $w->grabGlobal;
+   if ($w->viewable)
+    {
+     $w->SaveGrabInfo;
+     $w->grabGlobal;
+    }
   }
 }
 # Motion --
diff -up '/usr/local/src/Tk-804.027/Text/Text.pm' '/home/e/eserte/work/svk-checkouts/Tk/Text/Text.pm'
Index: ./Text/Text.pm
Prereq:  1.18 
--- ./Text/Text.pm	Wed Mar 17 21:33:56 2004
+++ ./Text/Text.pm	Sat Nov  4 14:52:55 2006
@@ -20,7 +20,8 @@ use strict;
 use Text::Tabs;
 
 use vars qw($VERSION);
-$VERSION = sprintf '4.%03d', q$Revision: #24 $ =~ /\D(\d+)\s*$/;
+#$VERSION = sprintf '4.%03d', q$Revision: #24 $ =~ /\D(\d+)\s*$/;
+$VERSION = '4.025';
 
 use Tk qw(Ev $XS_VERSION);
 use base  qw(Tk::Clipboard Tk::Widget);
@@ -275,7 +276,12 @@ sub ButtonRelease2
  my $Ev = $w->XEvent;
  if (!$Tk::mouseMoved)
   {
-   Tk::catch { $w->insert($Ev->xy,$w->SelectionGet) }
+   Tk::catch
+    {
+     $w->mark('set','insert',$Ev->xy);
+     $w->insert($Ev->xy,$w->SelectionGet);
+     $w->focus if ($w->cget('-state') eq "normal");
+    }
   }
 }
 
diff -up '/usr/local/src/Tk-804.027/TextList/TextList.pm' '/home/e/eserte/work/svk-checkouts/Tk/TextList/TextList.pm'
Index: ./TextList/TextList.pm
--- ./TextList/TextList.pm	Tue Mar 16 17:37:26 2004
+++ ./TextList/TextList.pm	Thu Nov  9 00:32:30 2006
@@ -125,7 +125,7 @@ sub activate
 sub bbox
 {
  my($w,$element)=@_;
- $element=$w->index($element).'.0' unless ($element=~/./);
+ $element=$w->index($element).'.0' unless ($element=~/\./);
  return $w->SUPER::bbox($element);
 }
 
@@ -235,6 +235,7 @@ sub index
 {
  my ($w,$element)=@_;
  return undef unless(defined($element));
+ $element=0 if $element<0;
  $element .= '.0' unless $element=~/\D/;
  $element = $w->SUPER::index($element);
  my($line,$col)=split(/\./,$element);
diff -up '/usr/local/src/Tk-804.027/Tixish/NoteBook.pm' '/home/e/eserte/work/svk-checkouts/Tk/Tixish/NoteBook.pm'
Index: ./Tixish/NoteBook.pm
--- ./Tixish/NoteBook.pm	Sun Dec 14 20:44:50 2003
+++ ./Tixish/NoteBook.pm	Sat Nov  4 14:55:46 2006
@@ -9,7 +9,8 @@ package Tk::NoteBook;
 
 use vars qw($VERSION);
 
-$VERSION = sprintf '4.%03d', q$Revision: #9 $ =~ /\D(\d+)\s*$/;
+#$VERSION = sprintf '4.%03d', q$Revision: #9 $ =~ /\D(\d+)\s*$/;
+$VERSION = '4.010';
 require Tk::NBFrame;
 
 use base  qw(Tk::Derived Tk::NBFrame);
@@ -231,7 +232,7 @@ sub delete
   {
    $childw->bind('<Destroy>', undef);
    $childw->destroy;
-   @{$w->{'windows'}} = grep($_ !~ /$child/, @{$w->{'windows'}});
+   @{$w->{'windows'}} = grep($_ ne $child, @{$w->{'windows'}});
    $w->{'nWindows'}--;
    $w->SUPER::delete($child);
    # see if the child to be deleted was the top child
diff -up '/usr/local/src/Tk-804.027/Tk.pm' '/home/e/eserte/work/svk-checkouts/Tk/Tk.pm'
Index: ./Tk.pm
Prereq:  1.6 
--- ./Tk.pm	Sun Apr 11 20:39:43 2004
+++ ./Tk.pm	Sat Nov 11 15:46:42 2006
@@ -62,13 +62,15 @@ use strict;
 use Carp;
 
 # Record author's perforce depot record
-$Tk::CHANGE      = q$Change: 3279 $;
+#$Tk::CHANGE      = q$Change: 3279 $;
+$Tk::CHANGE      = 'sfsvn-' . q$Change: 27 $;
 
 # $tk_version and $tk_patchLevel are reset by pTk when a mainwindow
 # is created, $VERSION is checked by bootstrap
 $Tk::version     = '8.4';
 $Tk::patchLevel  = '8.4';
-$Tk::VERSION     = '804.027';
+$Tk::VERSION     = '804.027_001';
+$Tk::VERSION     = eval $Tk::VERSION;
 $Tk::XS_VERSION  = $Tk::VERSION;
 $Tk::strictMotif = 0;
 
diff -up '/usr/local/src/Tk-804.027/Tk/FBox.pm' '/home/e/eserte/work/svk-checkouts/Tk/Tk/FBox.pm'
Index: ./Tk/FBox.pm
--- ./Tk/FBox.pm	Sat Dec 13 13:15:48 2003
+++ ./Tk/FBox.pm	Sat Nov  4 16:28:08 2006
@@ -39,7 +39,8 @@ require Tk::Toplevel;
 use strict;
 use vars qw($VERSION $updirImage $folderImage $fileImage);
 
-$VERSION = sprintf '4.%03d', q$Revision: #18 $ =~ /\D(\d+)\s*$/;
+#$VERSION = sprintf '4.%03d', q$Revision: #18 $ =~ /\D(\d+)\s*$/;
+$VERSION = '4.019';
 
 use base qw(Tk::Toplevel);
 
@@ -796,6 +797,7 @@ sub OkCmd {
     }
 
     my $filename = $filenames->[0];
+    $filename = "" if !defined $filename;
     if ($w->cget('-type') eq 'dir' && $from ne "iconlist") {
 	my $file = $filename eq '' ? $w->{'selectPath'} : JoinFile($w->{'selectPath'}, $filename);
 	$w->Done($file);
diff -up '/usr/local/src/Tk-804.027/Tk/MMtry.pm' '/home/e/eserte/work/svk-checkouts/Tk/Tk/MMtry.pm'
Index: ./Tk/MMtry.pm
--- ./Tk/MMtry.pm	Sun Sep  7 12:15:36 2003
+++ ./Tk/MMtry.pm	Sat Nov  4 14:54:47 2006
@@ -6,7 +6,8 @@ use Config;
 require Exporter;
 
 use vars qw($VERSION @EXPORT);
-$VERSION = sprintf '4.%03d', q$Revision: #9 $ =~ /\D(\d+)\s*$/;
+#$VERSION = sprintf '4.%03d', q$Revision: #9 $ =~ /\D(\d+)\s*$/;
+$VERSION = '4.010';
 
 use base  qw(Exporter);
 @EXPORT = qw(try_compile try_run);
@@ -18,12 +19,13 @@ my $stderr_too = ($^O eq 'MSWin32') ? ''
 
 sub try_compile
 {
- my ($file,$inc,$lib)  = @_;
+ my ($file,$inc,$lib,$def)  = @_;
  $inc = [] unless $inc;
  $lib = [] unless $lib;
+ $def = [] unless $def;
  my $out   = basename($file,'.c').$Config{'exe_ext'};
  warn "Test Compiling $file\n";
- my $msgs  = `$Config{'cc'} -o $out $Config{'ccflags'} @$inc $file @$lib $stderr_too`;
+ my $msgs  = `$Config{'cc'} -o $out $Config{'ccflags'} @$inc $file @$lib @$def $stderr_too`;
  my $ok = ($? == 0);
 # warn $msgs if $msgs;
  unlink($out) if (-f $out);
@@ -32,14 +34,15 @@ sub try_compile
 
 sub try_run
 {
- my ($file,$inc,$lib)  = @_;
+ my ($file,$inc,$lib,$def)  = @_;
  $inc = [] unless $inc;
  $lib = [] unless $lib;
+ $def = [] unless $def;
  my $out   = basename($file,'.c').$Config{'exe_ext'};
  warn "Test Compile/Run $file\n";
- my $msgs  = `$Config{'cc'} -o $out $Config{'ccflags'} @$inc $file @$lib $stderr_too`;
+ my $msgs  = `$Config{'cc'} -o $out $Config{'ccflags'} @$inc $file @$lib @$def $stderr_too`;
  my $ok = ($? == 0);
-# warn "$Config{'cc'} -o $out $Config{'ccflags'} @$inc $file @$lib:\n$msgs" if $msgs;
+# warn "$Config{'cc'} -o $out $Config{'ccflags'} @$inc $file @$lib @$def:\n$msgs" if $msgs;
  if ($ok)
   {
    my $path = File::Spec->rel2abs($out);
diff -up '/usr/local/src/Tk-804.027/Tk/Menu.pm' '/home/e/eserte/work/svk-checkouts/Tk/Tk/Menu.pm'
Index: ./Tk/Menu.pm
Prereq:  1.34 
--- ./Tk/Menu.pm	Sat Feb 28 17:32:50 2004
+++ ./Tk/Menu.pm	Sat Nov 11 02:58:16 2006
@@ -404,8 +404,9 @@ sub Motion
 sub ButtonDown
 {
  my $menu = shift;
+ return if (!$menu->viewable);
  $menu->postcascade('active');
- if (defined $Tk::postedMb)
+ if (defined $Tk::postedMb && $Tk::postedMb->viewable)
   {
    $Tk::postedMb->grabGlobal
   }
@@ -515,8 +516,8 @@ sub Invoke
   }
  elsif ($w->typeIS('active','tearoff'))
   {
-   $w->Unpost();
    $w->tearOffMenu();
+   $w->Unpost();
   }
  elsif ($w->typeIS('active','menubar'))
   {
@@ -602,15 +603,14 @@ sub NextMenu
    my $m2 = $menu->parent;
    if ($m2->IsMenu)
     {
+     $menu->activate('none');
+     $menu->GenerateMenuSelect;
+     $m2->SetFocus;
+
+     $m2->postcascade('none');
+
      if ($m2->cget('-type') ne 'menubar')
       {
-       $menu->activate('none');
-       $menu->GenerateMenuSelect;
-       $m2->SetFocus;
-       # This code unposts any posted submenu in the parent.
-       my $tmp = $m2->index('active');
-       $m2->activate('none');
-       $m2->activate($tmp);
        return;
       }
     }
@@ -796,7 +796,7 @@ sub FirstEntry
      if ($menu->type($i) eq 'cascade')
       {
        my $cascade = $menu->entrycget($i,'-menu');
-       if (defined $cascade)
+       if (0 && defined $cascade)
         {
          $menu->postcascade($i);
          $cascade->FirstEntry;
@@ -892,10 +892,13 @@ sub Post
  my $entry = shift;
  Unpost(undef) if (defined($Tk::popup) || defined($Tk::postedMb));
  $menu->PostOverPoint($x,$y,$entry);
- $menu->grabGlobal;
- $Tk::popup = $menu;
- $Tk::focus = $menu->focusCurrent;
- $menu->focus();
+ if ($Tk::platform eq 'unix' && $menu->viewable)
+  {
+   $menu->grabGlobal;
+   $Tk::popup = $menu;
+   $Tk::focus = $menu->focusCurrent;
+   $menu->focus();
+  }
 }
 
 sub SetFocus
@@ -961,7 +964,7 @@ sub tearOffMenu
  # original: if the parent is a menu, then use the text of the active
  # entry. If it's a menubutton then use its text.
  my $title = $w->cget('-title');
- # print ref($w),' ',$w->PathName," $w\n";
+ # print ref($w),' ',$w->PathName," ",$menu->PathName," $w\n";
  unless (defined $title && length($title))
   {
    $parent = $w->parent;
@@ -979,6 +982,12 @@ sub tearOffMenu
   }
  $menu->title($title) if (defined $title && length($title));
  $menu->post($x,$y);
+
+ if (!Tk::Exists($menu))
+  {
+   return;
+  }
+
  # Set tkPriv(focus) on entry: otherwise the focus will get lost
  # after keyboard invocation of a sub-menu (it will stay on the
  # submenu).
@@ -989,6 +998,11 @@ sub tearOffMenu
  # will get saved in $Tk::focus
  # $menu->bind('<Enter>','EnterFocus');
  $menu->Callback('-tearoffcommand');
+
+ # Strangely tear-off menus do not work in tkpod and Tk804.027.
+ # Explicitely setting normal state helps here - why?
+ $menu->state("normal");
+
  return $menu;
 }
 
diff -up '/usr/local/src/Tk-804.027/Tk/Wm.pm' '/home/e/eserte/work/svk-checkouts/Tk/Tk/Wm.pm'
Index: ./Tk/Wm.pm
--- ./Tk/Wm.pm	Sun Dec 14 20:44:50 2003
+++ ./Tk/Wm.pm	Mon Nov  6 22:38:55 2006
@@ -23,9 +23,9 @@ use Tk::Submethods;
 
 Direct Tk::Submethods ('wm' => [qw(aspect attributes client colormapwindows command
                        deiconify focusmodel frame geometry group
-                       iconbitmap iconify iconimage iconmask iconname
+                       iconbitmap iconify iconimage iconmask iconname iconphoto
                        iconwindow maxsize minsize overrideredirect positionfrom
-                       protocol resizable sizefrom state title transient
+                       protocol resizable sizefrom stackorder state title transient
                        withdraw wrapper)]);
 		
 sub SetBindtags
diff -up '/usr/local/src/Tk-804.027/ToDo' '/home/e/eserte/work/svk-checkouts/Tk/ToDo'
Index: ./ToDo
--- ./ToDo	Sat Dec 13 19:21:41 2003
+++ ./ToDo	Sun Nov  5 21:13:59 2006
@@ -1,3 +1,27 @@
+Tk::Tree has a dual live on CPAN. Incorporate the 4.3 version.
+
+Support for some OpenDesktop window manager standards, like setting
+icons through _NET_WM_ICON or using utf8 window titles.
+
+Port more Tcl/Tk tests to Perl/Tk (text.test etc.)
+
+messageBox fixes: <Return> does not use the currently selected button,
+but always the default button, which seems not untuitive. Also, the
+Tcl/Tk counterpart has nicer colored bitmaps, port them to Perl/Tk.
+
+Check all Tk-related bugs on rt.cpan.org (some are already fixed).
+
+Tk::FBox should deal with 8bit characters in filenames (i.e. use byte
+semantics in filesystem operations, maybe use system encoding when
+displaying filenames, but with graceful degradation).
+
+What about getOpen/SaveFile and Windows, are there also encoding
+issues with filenames?
+
+Minimize diffs to original Tcl/Tk sources to make merging easier.
+
+----------------------------------------------------------------------
+- OLDER ToDos --------------------------------------------------------
 
 Debug icon redraw issues on Solaris/olvwm
 
@@ -11,7 +35,7 @@ Do HTML build
 
 Make "compiled" Tk scripts work.
 
-Add one of FontSelect variants
+Add one of FontSelect variants (e.g. Tk::FontDialog)
 
 TixGrid repair/replace.
 
@@ -20,12 +44,6 @@ Release tkmail
 Start tkdraw ;-)
 
 Non-Sun Drag&Drop (e.g. linux) (Win32 Site now at least partly working.)
-
-Now 5.005_5X has utf8 how do we display it?
-
-Tk::Photo::data dumps core with beta9 and perl5.8.2:
-	$photo = $mw->Photo(-file => "some.gif");
-	$string = $photo->data(-format => "gif");
 
 Stipple bug, see Message-ID: <2uwCb.683348$pl3.76050@pd7tw3no> (should
 be fixed with Tk 8.4.5).
diff -up '/usr/local/src/Tk-804.027/config/xft.c' '/home/e/eserte/work/svk-checkouts/Tk/config/xft.c'
Index: ./config/xft.c
--- ./config/xft.c	Sun Aug 31 20:13:23 2003
+++ ./config/xft.c	Fri Nov  3 20:36:08 2006
@@ -1,3 +1,6 @@
+#ifdef NEED_FT2BUILD_H
+#include <ft2build.h>
+#endif
 #include <X11/Xft/Xft.h>
 
 const char *name = "-*-fixed-medium-r-*-*-*-120-*-*-*-*-iso8859-1";
diff -up '/usr/local/src/Tk-804.027/demos/widget' '/home/e/eserte/work/svk-checkouts/Tk/demos/widget'
Index: ./demos/widget
--- ./demos/widget	Sat Feb 28 17:35:25 2004
+++ ./demos/widget	Tue Oct 31 01:32:41 2006
@@ -62,7 +62,7 @@ my $file = $menubar->cascade(qw/-label F
         ], # end cascade menuitems
       ], # end view cascade
       '',
-      [command    => '~Quit', -command => [\&exit]],
+      [command    => '~Quit', -command => [\&exit], -accelerator => 'Ctrl-Q'],
     ]);
 
 my $help = $menubar->cascade(qw/-label Help -underline 0 -menuitems/ =>
@@ -85,6 +85,8 @@ my $T = $MW->Scrolled('ROText',
 $MW->gridRowconfigure(   0, -weight => 1); # allow expansion in both ...
 $MW->gridColumnconfigure(0, -weight => 1); # ... X and Y dimensions
 
+$MW->bind('<Control-q>' => \&exit);
+
 my $STATUS_VAR;
 my $status = $MW->Label(-textvariable => \$STATUS_VAR, qw/-anchor w/);
 $status->grid(qw/-sticky ew/);
@@ -270,6 +272,7 @@ while ($_ = shift @dirent) {
     my($name) = /^(.*)\.pl$/;
     $_ = <C>;
     my($title) = /^#\s*(.*)$/;
+    $title =~ s{\r}{}g; # strip DOS newlines
     $DEMO_DESCRIPTION{$name} = $title;
     close C;
     $T->insert('end', ++$i . ". $title\n", ['demo', "demo-$name"]);
@@ -307,7 +310,7 @@ sub build_about_dialog {
         -default_button => 'OK',
         -buttons        => ['OK'],
     );
-    my $df = $dialog->add( 'Labelframe', -text => '  2004 - Feb - 11  ' );
+    my $df = $dialog->add( 'Labelframe', -text => '  2006 - Oct - 31  ' );
     $df->pack( qw/ -fill both -expand 1 / );
     my( $change ) = $Tk::CHANGE =~ /Change:\s+(.*)/;
     my( $tk_date ) = scalar localtime( ( stat $Tk::library )[9] );
diff -up '/usr/local/src/Tk-804.027/myConfig' '/home/e/eserte/work/svk-checkouts/Tk/myConfig'
Index: ./myConfig
--- ./myConfig	Sat Feb 28 17:59:28 2004
+++ ./myConfig	Sat Nov 11 15:55:37 2006
@@ -348,15 +348,31 @@ if ($win_arch eq 'x') {
     if ($ftinc)
      {
       print "xlib='$xlib' xinc='$xinc'\n";
-      if (try_run("config/xft.c",[$xinc,$ftinc],[$xlib,'-lXft','-lfontconfig']))
+      my $success = 0;
+      # Including ft2build.h additionally seems to be necessary
+      # on an old RedHat 8.0 system
+      for my $def ([], ["-DNEED_FT2BUILD_H"])
        {
-        $inc .= " $ftinc";
-        warn "Seem to have -lXft\n";
-        $define{USE_XFT_FONTS} = 1;
-        $xlib .= " -lXft";
-        $xtra = ' -lfontconfig';
+	if (try_run("config/xft.c",[$xinc,$ftinc],[$xlib,'-lXft','-lfontconfig'],$def))
+         {
+          $inc .= " $ftinc";
+          warn "Seem to have -lXft\n";
+          $define{USE_XFT_FONTS} = 1;
+          $xlib .= " -lXft";
+          $xtra = ' -lfontconfig';
+	  if (@$def)
+	   {
+	    for my $d (@$def)
+	     {
+	      $d =~ s{-D}{};
+	      $define{$d} = 1;
+	     }
+	   }
+	  $success = 1;
+	  last;
+         }
        }
-      else
+      if (!$success)
        {
 	warn "Xft and/or fontconfig libraries and/or includes are missing\n";
        }
@@ -428,7 +444,7 @@ sub WriteIfChanged
 
 if (!defined($MakefileName) || $MakefileName eq 'Makefile')
  {
-  my $config = "package Tk::Config;\nrequire Exporter;\nuse base qw(Exporter);\n";
+  my $config = "# DO NOT EDIT. CREATED AUTOMATICALLY BY myConfig\npackage Tk::Config;\nrequire Exporter;\nuse base qw(Exporter);\n";
   my $sym;
   my @export = ();
   foreach $sym (qw(VERSION inc define xlib xinc gccopt win_arch))
diff -up '/usr/local/src/Tk-804.027/pTk/mTk/generic/tkCanvWind.c' '/home/e/eserte/work/svk-checkouts/Tk/pTk/mTk/generic/tkCanvWind.c'
Index: ./pTk/mTk/generic/tkCanvWind.c
Prereq:  1.9 
--- ./pTk/mTk/generic/tkCanvWind.c	Fri Dec 19 12:54:51 2003
+++ ./pTk/mTk/generic/tkCanvWind.c	Tue Oct 31 01:40:39 2006
@@ -383,6 +383,14 @@ ConfigureWinItem(interp, canvas, itemPtr
 		    (ClientData) winItemPtr);
 	}
     }
+    if ((winItemPtr->tkwin != NULL)
+	    && (itemPtr->state == TK_STATE_HIDDEN)) {
+	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
+	    Tk_UnmapWindow(winItemPtr->tkwin);
+	} else {
+	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
+	}
+    }
 
     ComputeWindowBbox(canvas, winItemPtr);
 
diff -up '/usr/local/src/Tk-804.027/pTk/mTk/generic/tkEvent.c' '/home/e/eserte/work/svk-checkouts/Tk/pTk/mTk/generic/tkEvent.c'
Index: ./pTk/mTk/generic/tkEvent.c
Prereq:  1.17.2.1 
--- ./pTk/mTk/generic/tkEvent.c	Tue Dec 30 12:54:31 2003
+++ ./pTk/mTk/generic/tkEvent.c	Mon Oct 30 23:18:14 2006
@@ -986,7 +986,9 @@ Tk_HandleEvent(eventPtr)
 		TkWmProtocolEventProc(winPtr, eventPtr);
 	    } else {
 		/* Perl/Tk had/has its own hook for this */
-		LangClientMessage(winPtr->mainPtr->interp, (Tk_Window) winPtr, eventPtr);
+		if (eventPtr && winPtr && winPtr->mainPtr) {
+		    LangClientMessage(winPtr->mainPtr->interp, (Tk_Window) winPtr, eventPtr);
+		}
 
 		/*
 		 * Finally, invoke any ClientMessage event handlers.
diff -up '/usr/local/src/Tk-804.027/pTk/mTk/generic/tkInt.h' '/home/e/eserte/work/svk-checkouts/Tk/pTk/mTk/generic/tkInt.h'
Index: ./pTk/mTk/generic/tkInt.h
Prereq:  1.56.2.1 
--- ./pTk/mTk/generic/tkInt.h	Fri Dec 19 12:54:53 2003
+++ ./pTk/mTk/generic/tkInt.h	Sun Nov  5 20:17:58 2006
@@ -504,6 +504,8 @@ typedef struct TkDisplay {
 				 * defined in below. */
     TkCaret caret;		/* information about the caret for this
 				 * display.  This is not a pointer. */
+    int iconDataSize;		/* Size of default iconphoto image data */
+    unsigned char *iconDataPtr;	/* Default iconphoto image data, if set */
 } TkDisplay;
 
 /*
diff -up '/usr/local/src/Tk-804.027/pTk/mTk/tclUnix/tclUnixTime.c' '/home/e/eserte/work/svk-checkouts/Tk/pTk/mTk/tclUnix/tclUnixTime.c'
Index: ./pTk/mTk/tclUnix/tclUnixTime.c
Prereq:  1.15 
--- ./pTk/mTk/tclUnix/tclUnixTime.c	Fri Dec 19 12:55:00 2003
+++ ./pTk/mTk/tclUnix/tclUnixTime.c	Mon Oct 30 23:18:12 2006
@@ -18,6 +18,8 @@
 
 #ifdef __EMX__
 #   include <sys/time.h>
+#else
+#   include <time.h>
 #endif
 
 #if 0
diff -up '/usr/local/src/Tk-804.027/pTk/mTk/unix/tkUnixWm.c' '/home/e/eserte/work/svk-checkouts/Tk/pTk/mTk/unix/tkUnixWm.c'
Index: ./pTk/mTk/unix/tkUnixWm.c
Prereq:  1.36 
--- ./pTk/mTk/unix/tkUnixWm.c	Fri Mar 26 23:03:02 2004
+++ ./pTk/mTk/unix/tkUnixWm.c	Tue Nov  7 22:46:27 2006
@@ -2,45 +2,42 @@
  * tkUnixWm.c --
  *
  *	This module takes care of the interactions between a Tk-based
- *	application and the window manager.  Among other things, it
- *	implements the "wm" command and passes geometry information
- *	to the window manager.
+ *	application and the window manager. Among other things, it implements
+ *	the "wm" command and passes geometry information to the window
+ *	manager.
  *
  * Copyright (c) 1991-1994 The Regents of the University of California.
  * Copyright (c) 1994-1997 Sun Microsystems, Inc.
  *
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * RCS: @(#) $Id: tkUnixWm.c,v 1.36 2002/12/27 21:23:04 jenglish Exp $
+ * RCS: @(#) $Id: tkUnixWm.c,v 1.51 2006/05/29 22:21:40 hobbs Exp $
  */
 
 #include "tkPort.h"
 #include "tkInt.h"
 #include "tkUnixInt.h"
-#include <errno.h>
 
 /*
- * A data structure of the following type holds information for
- * each window manager protocol (such as WM_DELETE_WINDOW) for
- * which a handler (i.e. a Tcl command) has been defined for a
- * particular top-level window.
+ * A data structure of the following type holds information for each window
+ * manager protocol (such as WM_DELETE_WINDOW) for which a handler (i.e. a Tcl
+ * command) has been defined for a particular top-level window.
  */
 
 typedef struct ProtocolHandler {
     Atom protocol;		/* Identifies the protocol. */
     struct ProtocolHandler *nextPtr;
-				/* Next in list of protocol handlers for
-				 * the same top-level window, or NULL for
-				 * end of list. */
+				/* Next in list of protocol handlers for the
+				 * same top-level window, or NULL for end of
+				 * list. */
     Tcl_Interp *interp;		/* Interpreter in which to invoke command. */
 #if 0
-    char command[4];		/* Tcl command to invoke when a client
-				 * message for this protocol arrives.
-				 * The actual size of the structure varies
-				 * to accommodate the needs of the actual
-				 * command. THIS MUST BE THE LAST FIELD OF
-				 * THE STRUCTURE. */
+    char command[4];		/* Tcl command to invoke when a client message
+				 * for this protocol arrives. The actual size
+				 * of the structure varies to accommodate the
+				 * needs of the actual command. THIS MUST BE
+				 * THE LAST FIELD OF THE STRUCTURE. */
 #else
     LangCallback *command;
 #endif
@@ -57,32 +54,52 @@ char *clientData;
 }
 
 /*
+ * Data for [wm attributes] command:
+ */
+typedef struct {
+    double 	alpha;		/* Transparency; 0.0=transparent, 1.0=opaque */
+    int 	topmost;	/* Flag: true=>stay-on-top */
+    int 	zoomed;		/* Flag: true=>maximized */
+    int 	fullscreen;	/* Flag: true=>fullscreen */
+} WmAttributes;
+
+typedef enum { 
+    WMATT_ALPHA, WMATT_TOPMOST, WMATT_ZOOMED, WMATT_FULLSCREEN, 
+    _WMATT_LAST_ATTRIBUTE
+} WmAttribute;
+
+static const char *WmAttributeNames[] = {
+    "-alpha", "-topmost", "-zoomed", "-fullscreen",
+    NULL
+};
+
+/*
  * A data structure of the following type holds window-manager-related
  * information for each top-level window in an application.
  */
 
 typedef struct TkWmInfo {
-    TkWindow *winPtr;		/* Pointer to main Tk information for
-				 * this window. */
+    TkWindow *winPtr;		/* Pointer to main Tk information for this
+				 * window. */
     Window reparent;		/* If the window has been reparented, this
 				 * gives the ID of the ancestor of the window
-				 * that is a child of the root window (may
-				 * not be window's immediate parent).  If
-				 * the window isn't reparented, this has the
-				 * value None. */
-    char *title;		/* Title to display in window caption.  If
-				 * NULL, use name of widget.  Malloced. */
-    char *iconName;		/* Name to display in icon.  Malloced. */
-    XWMHints hints;		/* Various pieces of information for
-				 * window manager. */
+				 * that is a child of the root window (may not
+				 * be window's immediate parent). If the
+				 * window isn't reparented, this has the value
+				 * None. */
+    char *title;		/* Title to display in window caption. If
+				 * NULL, use name of widget. Malloced. */
+    char *iconName;		/* Name to display in icon. Malloced. */
+    XWMHints hints;		/* Various pieces of information for window
+				 * manager. */
     char *leaderName;		/* Path name of leader of window group
 				 * (corresponds to hints.window_group).
-				 * Malloc-ed.  Note:  this field doesn't
-				 * get updated if leader is destroyed. */
+				 * Malloc-ed. Note: this field doesn't get
+				 * updated if leader is destroyed. */
     TkWindow *masterPtr;	/* Master window for TRANSIENT_FOR property,
 				 * or NULL. */
-    Tk_Window icon;		/* Window to use as icon for this window,
-				 * or NULL. */
+    Tk_Window icon;		/* Window to use as icon for this window, or
+				 * NULL. */
     Tk_Image  iconImage;	/* Image used to generate Icon - or NULL */
     Tk_Window iconFor;		/* Window for which this window is icon, or
 				 * NULL if this isn't an icon for anyone. */
@@ -90,86 +107,85 @@ typedef struct TkWmInfo {
 
     /*
      * In order to support menubars transparently under X, each toplevel
-     * window is encased in an additional window, called the wrapper,
-     * that holds the toplevel and the menubar, if any.  The information
-     * below is used to keep track of the wrapper and the menubar.
+     * window is encased in an additional window, called the wrapper, that
+     * holds the toplevel and the menubar, if any. The information below is
+     * used to keep track of the wrapper and the menubar.
      */
 
     TkWindow *wrapperPtr;	/* Pointer to information about the wrapper.
-				 * This is the "real" toplevel window as
-				 * seen by the window manager. Although
-				 * this is an official Tk window, it
-				 * doesn't appear in the application's
-				 * window hierarchy.  NULL means that
-				 * the wrapper hasn't been created yet. */
-    Tk_Window menubar;		/* Pointer to information about the
-				 * menubar, or NULL if there is no
-				 * menubar for this toplevel. */
+				 * This is the "real" toplevel window as seen
+				 * by the window manager. Although this is an
+				 * official Tk window, it doesn't appear in
+				 * the application's window hierarchy. NULL
+				 * means that the wrapper hasn't been created
+				 * yet. */
+    Tk_Window menubar;		/* Pointer to information about the menubar,
+				 * or NULL if there is no menubar for this
+				 * toplevel. */
     int menuHeight;		/* Amount of vertical space needed for
-				 * menubar, measured in pixels.  If
-				 * menubar is non-NULL, this is >= 1 (X
-				 * servers don't like dimensions of 0). */
-
-    /*
-     * Information used to construct an XSizeHints structure for
-     * the window manager:
-     */
-
-    int sizeHintsFlags;		/* Flags word for XSizeHints structure.
-				 * If the PBaseSize flag is set then the
-				 * window is gridded;  otherwise it isn't
-				 * gridded. */
-    int minWidth, minHeight;	/* Minimum dimensions of window, in
-				 * grid units, not pixels. */
-    int maxWidth, maxHeight;	/* Maximum dimensions of window, in
-				 * grid units, not pixels. */
+				 * menubar, measured in pixels. If menubar is
+				 * non-NULL, this is >= 1 (X servers don't
+				 * like dimensions of 0). */
+
+    /*
+     * Information used to construct an XSizeHints structure for the window
+     * manager:
+     */
+
+    int sizeHintsFlags;		/* Flags word for XSizeHints structure. If the
+				 * PBaseSize flag is set then the window is
+				 * gridded; otherwise it isn't gridded. */
+    int minWidth, minHeight;	/* Minimum dimensions of window, in pixels or
+				 * grid units. */
+    int maxWidth, maxHeight;	/* Maximum dimensions of window, in pixels or
+				 * grid units. 0 to default.*/
     Tk_Window gridWin;		/* Identifies the window that controls
-				 * gridding for this top-level, or NULL if
-				 * the top-level isn't currently gridded. */
-    int widthInc, heightInc;	/* Increments for size changes (# pixels
-				 * per step). */
+				 * gridding for this top-level, or NULL if the
+				 * top-level isn't currently gridded. */
+    int widthInc, heightInc;	/* Increments for size changes (# pixels per
+				 * step). */
     struct {
-	int x;	/* numerator */
-	int y;  /* denominator */
+	int x;			/* numerator */
+	int y;			/* denominator */
     } minAspect, maxAspect;	/* Min/max aspect ratios for window. */
     int reqGridWidth, reqGridHeight;
-				/* The dimensions of the window (in
-				 * grid units) requested through
-				 * the geometry manager. */
+				/* The dimensions of the window (in grid
+				 * units) requested through the geometry
+				 * manager. */
     int gravity;		/* Desired window gravity. */
 
     /*
      * Information used to manage the size and location of a window.
      */
 
-    int width, height;		/* Desired dimensions of window, specified
-				 * in grid units.  These values are
-				 * set by the "wm geometry" command and by
-				 * ConfigureNotify events (for when wm
-				 * resizes window).  -1 means user hasn't
-				 * requested dimensions. */
+    int width, height;		/* Desired dimensions of window, specified in
+				 * pixels or grid units. These values are set
+				 * by the "wm geometry" command and by
+				 * ConfigureNotify events (for when wm resizes
+				 * window). -1 means user hasn't requested
+				 * dimensions. */
     int x, y;			/* Desired X and Y coordinates for window.
-				 * These values are set by "wm geometry",
-				 * plus by ConfigureNotify events (when wm
-				 * moves window).  These numbers are
-				 * different than the numbers stored in
-				 * winPtr->changes because (a) they could be
-				 * measured from the right or bottom edge
-				 * of the screen (see WM_NEGATIVE_X and
-				 * WM_NEGATIVE_Y flags) and (b) if the window
-				 * has been reparented then they refer to the
-				 * parent rather than the window itself. */
+				 * These values are set by "wm geometry", plus
+				 * by ConfigureNotify events (when wm moves
+				 * window). These numbers are different than
+				 * the numbers stored in winPtr->changes
+				 * because (a) they could be measured from the
+				 * right or bottom edge of the screen (see
+				 * WM_NEGATIVE_X and WM_NEGATIVE_Y flags) and
+				 * (b) if the window has been reparented then
+				 * they refer to the parent rather than the
+				 * window itself. */
     int parentWidth, parentHeight;
 				/* Width and height of reparent, in pixels
-				 * *including border*.  If window hasn't been
+				 * *including border*. If window hasn't been
 				 * reparented then these will be the outer
 				 * dimensions of the window, including
 				 * border. */
     int xInParent, yInParent;	/* Offset of wrapperPtr within reparent,
 				 * measured in pixels from upper-left outer
 				 * corner of reparent's border to upper-left
-				 * outer corner of wrapperPtr's border.  If
-				 * not reparented then these are zero. */
+				 * outer corner of wrapperPtr's border. If not
+				 * reparented then these are zero. */
     int configWidth, configHeight;
 				/* Dimensions passed to last request that we
 				 * issued to change geometry of the wrapper.
@@ -177,36 +193,37 @@ typedef struct TkWmInfo {
 				 * operations. */
 
     /*
-     * Information about the virtual root window for this top-level,
-     * if there is one.
+     * Information about the virtual root window for this top-level, if there
+     * is one.
      */
 
-    Window vRoot;		/* Virtual root window for this top-level,
-				 * or None if there is no virtual root
-				 * window (i.e. just use the screen's root). */
+    Window vRoot;		/* Virtual root window for this top-level, or
+				 * None if there is no virtual root window
+				 * (i.e. just use the screen's root). */
     int vRootX, vRootY;		/* Position of the virtual root inside the
-				 * root window.  If the WM_VROOT_OFFSET_STALE
+				 * root window. If the WM_VROOT_OFFSET_STALE
 				 * flag is set then this information may be
 				 * incorrect and needs to be refreshed from
-				 * the X server.  If vRoot is None then these
+				 * the X server. If vRoot is None then these
 				 * values are both 0. */
-    int vRootWidth, vRootHeight;/* Dimensions of the virtual root window.
-				 * If vRoot is None, gives the dimensions
-				 * of the containing screen.  This information
-				 * is never stale, even though vRootX and
-				 * vRootY can be. */
+    int vRootWidth, vRootHeight;/* Dimensions of the virtual root window. If
+				 * vRoot is None, gives the dimensions of the
+				 * containing screen. This information is
+				 * never stale, even though vRootX and vRootY
+				 * can be. */
 
     /*
      * Miscellaneous information.
      */
 
-    ProtocolHandler *protPtr;	/* First in list of protocol handlers for
-				 * this window (NULL means none). */
+    WmAttributes attributes;	/* Current state of [wm attributes] */
+    WmAttributes reqState;	/* Requested state of [wm attributes] */
+    ProtocolHandler *protPtr;	/* First in list of protocol handlers for this
+				 * window (NULL means none). */
 #ifndef _LANG
     int cmdArgc;		/* Number of elements in cmdArgv below. */
-    CONST char **cmdArgv;	/* Array of strings to store in the
-				 * WM_COMMAND property.  NULL means nothing
-				 * available. */
+    CONST char **cmdArgv;	/* Array of strings to store in the WM_COMMAND
+				 * property. NULL means nothing available. */
 #else
     Tcl_Obj *cmdArg;		/* Object holding list - to keep strings live */
 #endif
@@ -214,21 +231,23 @@ typedef struct TkWmInfo {
 				 * property, or NULL. */
     int flags;			/* Miscellaneous flags, defined below. */
     int numTransients;		/* number of transients on this window */
+    int iconDataSize;		/* size of iconphoto image data */
+    unsigned char *iconDataPtr;	/* iconphoto image data, if set */
     struct TkWmInfo *nextPtr;	/* Next in list of all top-level windows. */
 } WmInfo;
 
 /*
  * Flag values for WmInfo structures:
  *
- * WM_NEVER_MAPPED -		non-zero means window has never been
- *				mapped;  need to update all info when
- *				window is first mapped.
+ * WM_NEVER_MAPPED -		non-zero means window has never been mapped;
+ *				need to update all info when window is first
+ *				mapped.
  * WM_UPDATE_PENDING -		non-zero means a call to UpdateGeometryInfo
- *				has already been scheduled for this
- *				window;  no need to schedule another one.
+ *				has already been scheduled for this window;
+ *				no need to schedule another one.
  * WM_NEGATIVE_X -		non-zero means x-coordinate is measured in
- *				pixels from right edge of screen, rather
- *				than from left edge.
+ *				pixels from right edge of screen, rather than
+ *				from left edge.
  * WM_NEGATIVE_Y -		non-zero means y-coordinate is measured in
  *				pixels up from bottom of screen, rather than
  *				down from top.
@@ -239,27 +258,24 @@ typedef struct TkWmInfo {
  * WM_VROOT_OFFSET_STALE -	non-zero means that (x,y) offset information
  *				about the virtual root window is stale and
  *				needs to be fetched fresh from the X server.
- * WM_ABOUT_TO_MAP -		non-zero means that the window is about to
- *				be mapped by TkWmMapWindow.  This is used
- *				by UpdateGeometryInfo to modify its behavior.
- * WM_MOVE_PENDING -		non-zero means the application has requested
- *				a new position for the window, but it hasn't
- *				been reflected through the window manager
- *				yet.
- * WM_COLORMAPS_EXPLICIT -	non-zero means the colormap windows were
- *				set explicitly via "wm colormapwindows".
+ * WM_ABOUT_TO_MAP -		non-zero means that the window is about to be
+ *				mapped by TkWmMapWindow. This is used by
+ *				UpdateGeometryInfo to modify its behavior.
+ * WM_MOVE_PENDING -		non-zero means the application has requested a
+ *				new position for the window, but it hasn't
+ *				been reflected through the window manager yet.
+ * WM_COLORMAPS_EXPLICIT -	non-zero means the colormap windows were set
+ *				explicitly via "wm colormapwindows".
  * WM_ADDED_TOPLEVEL_COLORMAP - non-zero means that when "wm colormapwindows"
  *				was called the top-level itself wasn't
- *				specified, so we added it implicitly at
- *				the end of the list.
+ *				specified, so we added it implicitly at the
+ *				end of the list.
  * WM_WIDTH_NOT_RESIZABLE -	non-zero means that we're not supposed to
  *				allow the user to change the width of the
- *				window (controlled by "wm resizable"
- *				command).
+ *				window (controlled by "wm resizable" command).
  * WM_HEIGHT_NOT_RESIZABLE -	non-zero means that we're not supposed to
  *				allow the user to change the height of the
- *				window (controlled by "wm resizable"
- *				command).
+ *				window (controlled by "wm resizable" command).
  * WM_WITHDRAWN -		non-zero means that this window has explicitly
  *				been withdrawn. If it's a transient, it should
  *				not mirror state changes in the master.
@@ -278,12 +294,12 @@ typedef struct TkWmInfo {
 #define WM_ADDED_TOPLEVEL_COLORMAP	0x800
 #define WM_WIDTH_NOT_RESIZABLE		0x1000
 #define WM_HEIGHT_NOT_RESIZABLE		0x2000
-#define WM_WITHDRAWN		       	0x4000
+#define WM_WITHDRAWN			0x4000
 
 /*
- * This module keeps a list of all top-level windows, primarily to
- * simplify the job of Tk_CoordsToWindow.  The list is called
- * firstWmPtr and is stored in the TkDisplay structure.
+ * This module keeps a list of all top-level windows, primarily to simplify
+ * the job of Tk_CoordsToWindow. The list is called firstWmPtr and is stored
+ * in the TkDisplay structure.
  */
 
 /*
@@ -291,9 +307,8 @@ typedef struct TkWmInfo {
  * management of top-level and menubar windows.
  */
 
-static void		TopLevelReqProc _ANSI_ARGS_((ClientData dummy,
-			    Tk_Window tkwin));
-static  void		TopLevelLostSlaveProc _ANSI_ARGS_((ClientData clientData,
+static void		TopLevelReqProc(ClientData dummy, Tk_Window tkwin);
+static void		TopLevelLostSlaveProc _ANSI_ARGS_((ClientData clientData,
 			    Tk_Window tkwin));
 
 
@@ -302,7 +317,6 @@ static Tk_GeomMgr wmMgrType = {
     TopLevelReqProc,			/* requestProc */
     TopLevelLostSlaveProc,		/* lostSlaveProc */
 };
-
 /*
  * Forward declarations for procedures defined in this file:
  */
@@ -319,7 +333,7 @@ static void		MenubarReqProc _ANSI_ARGS_(
 static Tk_GeomMgr menubarMgrType = {
     "menubar",				/* name */
     MenubarReqProc,			/* requestProc */
-    (Tk_GeomLostSlaveProc *) NULL,	/* lostSlaveProc */
+    NULL,				/* lostSlaveProc */
 };
 
 /*
@@ -332,12 +346,12 @@ typedef struct WaitRestrictInfo {
     WmInfo *wmInfoPtr;
     int type;			/* We only care about this type of event. */
     XEvent *eventPtr;		/* Where to store the event when it's found. */
-    int foundEvent;		/* Non-zero means that an event of the
-				 * desired type has been found. */
+    int foundEvent;		/* Non-zero means that an event of the desired
+				 * type has been found. */
 } WaitRestrictInfo;
 
 /*
- * Forward declarations for procedures defined in this file:
+ * Forward declarations for functions defined in this file:
  */
 
 static int		ComputeReparentGeometry _ANSI_ARGS_((WmInfo *wmPtr));
@@ -354,6 +368,7 @@ static void		ReparentEvent _ANSI_ARGS_((
 			    XReparentEvent *eventPtr));
 static void		TkWmStackorderToplevelWrapperMap _ANSI_ARGS_((
 			    TkWindow *winPtr,
+			    Display *display,
 			    Tcl_HashTable *reparentTable));
 static void		TopLevelEventProc _ANSI_ARGS_((ClientData clientData,
 			    XEvent *eventPtr));
@@ -363,9 +378,16 @@ static void		UpdateCommand _ANSI_ARGS_((
 static void		UpdateGeometryInfo _ANSI_ARGS_((
 			    ClientData clientData));
 static void		UpdateHints _ANSI_ARGS_((TkWindow *winPtr));
-static void		UpdateSizeHints _ANSI_ARGS_((TkWindow *winPtr));
+static void		UpdateSizeHints _ANSI_ARGS_((TkWindow *winPtr,
+			    int newWidth,
+			    int newHeight));
+static void		UpdateTitle(TkWindow *winPtr);
+static void		UpdatePhotoIcon(TkWindow *winPtr);
 static void		UpdateVRootGeometry _ANSI_ARGS_((WmInfo *wmPtr));
 static void		UpdateWmProtocols _ANSI_ARGS_((WmInfo *wmPtr));
+static void 		SetNetWmState(TkWindow*, const char *atomName, int on);
+static void 		CheckNetWmState(WmInfo *, Atom *atoms, int numAtoms);
+static void 		UpdateNetWmState(WmInfo *);
 static void		WaitForConfigureNotify _ANSI_ARGS_((TkWindow *winPtr,
 			    unsigned long serial));
 static int		WaitForEvent _ANSI_ARGS_((Display *display,
@@ -375,6 +397,31 @@ static void		WaitForMapNotify _ANSI_ARGS
 
 static void		UnmanageGeometry _ANSI_ARGS_((Tk_Window tkwin));
 
+static int		WmProtocolCmd(Tk_Window tkwin, TkWindow *winPtr,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *CONST objv[]);
+static int		WmResizableCmd(Tk_Window tkwin, TkWindow *winPtr,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *CONST objv[]);
+static int		WmSizefromCmd(Tk_Window tkwin, TkWindow *winPtr,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *CONST objv[]);
+static int		WmStackorderCmd(Tk_Window tkwin, TkWindow *winPtr,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *CONST objv[]);
+static int		WmStateCmd(Tk_Window tkwin, TkWindow *winPtr,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *CONST objv[]);
+static int		WmTitleCmd(Tk_Window tkwin, TkWindow *winPtr,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *CONST objv[]);
+static int		WmTransientCmd(Tk_Window tkwin, TkWindow *winPtr,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *CONST objv[]);
+static int		WmWithdrawCmd(Tk_Window tkwin, TkWindow *winPtr,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *CONST objv[]);
+static void		WmUpdateGeom(WmInfo *wmPtr, TkWindow *winPtr);
 static Tk_RestrictAction
 			WaitRestrictProc _ANSI_ARGS_((ClientData clientData,
 			    XEvent *eventPtr));
@@ -434,6 +481,9 @@ static int 		WmIconmaskCmd _ANSI_ARGS_((
 static int 		WmIconnameCmd _ANSI_ARGS_((Tk_Window tkwin,
 			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
 			    Tcl_Obj *CONST objv[]));
+static int		WmIconphotoCmd(Tk_Window tkwin, TkWindow *winPtr,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *CONST objv[]);
 static int 		WmIconpositionCmd _ANSI_ARGS_((Tk_Window tkwin,
 			    TkWindow *winPtr, Tcl_Interp *interp, int objc,
 			    Tcl_Obj *CONST objv[]));
@@ -490,8 +540,8 @@ static void		WmUpdateGeom _ANSI_ARGS_((W
  *
  * TkWmCleanup --
  *
- *	This procedure is invoked to cleanup remaining wm resources
- *	associated with a display.
+ *	This function is invoked to cleanup remaining wm resources associated
+ *	with a display.
  *
  * Results:
  *	None.
@@ -502,7 +552,6 @@ static void		WmUpdateGeom _ANSI_ARGS_((W
  *--------------------------------------------------------------
  */
 
-
 static void
 TkWmFreeCmd(wmPtr)
 WmInfo *wmPtr;
@@ -513,15 +562,17 @@ WmInfo *wmPtr;
     }
 }
 
-void TkWmCleanup(dispPtr)
-    TkDisplay *dispPtr;
+void TkWmCleanup(
+    TkDisplay *dispPtr)
 {
     WmInfo *wmPtr, *nextPtr;
+
     for (wmPtr = dispPtr->firstWmPtr; wmPtr != NULL; wmPtr = nextPtr) {
 	/*
-	 * We can't assume we have access to winPtr's anymore, so some
-	 * cleanup requiring winPtr data is avoided.
+	 * We can't assume we have access to winPtr's anymore, so some cleanup
+	 * requiring winPtr data is avoided.
 	 */
+
 	nextPtr = wmPtr->nextPtr;
 	if (wmPtr->title != NULL) {
 	    ckfree(wmPtr->title);
@@ -529,6 +580,9 @@ void TkWmCleanup(dispPtr)
 	if (wmPtr->iconName != NULL) {
 	    ckfree(wmPtr->iconName);
 	}
+	if (wmPtr->iconDataPtr != NULL) {
+	    ckfree((char *)wmPtr->iconDataPtr);
+	}
 	if (wmPtr->leaderName != NULL) {
 	    ckfree(wmPtr->leaderName);
 	}
@@ -557,6 +611,10 @@ void TkWmCleanup(dispPtr)
 	}
 	ckfree((char *) wmPtr);
     }
+    if (dispPtr->iconDataPtr != NULL) {
+	ckfree((char *)dispPtr->iconDataPtr);
+	dispPtr->iconDataPtr = NULL;
+    }
 }
 
 /*
@@ -564,9 +622,8 @@ void TkWmCleanup(dispPtr)
  *
  * TkWmNewWindow --
  *
- *	This procedure is invoked whenever a new top-level
- *	window is created.  Its job is to initialize the WmInfo
- *	structure for the window.
+ *	This function is invoked whenever a new top-level window is created.
+ *	Its job is to initialize the WmInfo structure for the window.
  *
  * Results:
  *	None.
@@ -578,8 +635,8 @@ void TkWmCleanup(dispPtr)
  */
 
 void
-TkWmNewWindow(winPtr)
-    TkWindow *winPtr;		/* Newly-created top-level window. */
+TkWmNewWindow(
+    TkWindow *winPtr)		/* Newly-created top-level window. */
 {
     register WmInfo *wmPtr;
     TkDisplay *dispPtr = winPtr->dispPtr;
@@ -598,13 +655,24 @@ TkWmNewWindow(winPtr)
     wmPtr->hints.icon_x = wmPtr->hints.icon_y = 0;
     wmPtr->hints.icon_mask = None;
     wmPtr->hints.window_group = None;
-    wmPtr->minWidth = wmPtr->minHeight = 1;
 
     /*
-     * Default the maximum dimensions to the size of the display, minus
-     * a guess about how space is needed for window manager decorations.
+     * Initialize attributes.
      */
+    wmPtr->attributes.alpha = 1.0;
+    wmPtr->attributes.topmost = 0;
+    wmPtr->attributes.zoomed = 0;
+    wmPtr->attributes.fullscreen = 0;
+    wmPtr->reqState = wmPtr->attributes;
 
+    /*
+     * Default the maximum dimensions to the size of the display, minus a
+     * guess about how space is needed for window manager decorations.
+     */
+
+    wmPtr->gridWin = NULL;
+    wmPtr->minWidth = wmPtr->minHeight = 1;
+    wmPtr->maxWidth = wmPtr->maxHeight = 0;
     wmPtr->widthInc = wmPtr->heightInc = 1;
     wmPtr->minAspect.x = wmPtr->minAspect.y = 1;
     wmPtr->maxAspect.x = wmPtr->maxAspect.y = 1;
@@ -629,8 +697,8 @@ TkWmNewWindow(winPtr)
     UpdateVRootGeometry(wmPtr);
 
     /*
-     * Arrange for geometry requests to be reflected from the window
-     * to the window manager.
+     * Arrange for geometry requests to be reflected from the window to the
+     * window manager.
      */
 
     Tk_ManageGeometry((Tk_Window) winPtr, &wmMgrType, (ClientData) 0);
@@ -641,32 +709,31 @@ TkWmNewWindow(winPtr)
  *
  * TkWmMapWindow --
  *
- *	This procedure is invoked to map a top-level window.  This
- *	module gets a chance to update all window-manager-related
- *	information in properties before the window manager sees
- *	the map event and checks the properties.  It also gets to
- *	decide whether or not to even map the window after all.
+ *	This function is invoked to map a top-level window. This module gets a
+ *	chance to update all window-manager-related information in properties
+ *	before the window manager sees the map event and checks the
+ *	properties. It also gets to decide whether or not to even map the
+ *	window after all.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	Properties of winPtr may get updated to provide up-to-date
- *	information to the window manager.  The window may also get
- *	mapped, but it may not be if this procedure decides that
- *	isn't appropriate (e.g. because the window is withdrawn).
+ *	Properties of winPtr may get updated to provide up-to-date information
+ *	to the window manager. The window may also get mapped, but it may not
+ *	be if this function decides that isn't appropriate (e.g. because the
+ *	window is withdrawn).
  *
  *--------------------------------------------------------------
  */
 
 void
-TkWmMapWindow(winPtr)
-    TkWindow *winPtr;		/* Top-level window that's about to
-				 * be mapped. */
+TkWmMapWindow(
+    TkWindow *winPtr)		/* Top-level window that's about to be
+				 * mapped. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     XTextProperty textProp;
-    Tk_Uid string;
 
     if (wmPtr->flags & WM_NEVER_MAPPED) {
 	Tcl_DString ds;
@@ -674,9 +741,8 @@ TkWmMapWindow(winPtr)
 	wmPtr->flags &= ~WM_NEVER_MAPPED;
 
 	/*
-	 * This is the first time this window has ever been mapped.
-	 * First create the wrapper window that provides space for a
-	 * menubar.
+	 * This is the first time this window has ever been mapped. First
+	 * create the wrapper window that provides space for a menubar.
 	 */
 
 	if (wmPtr->wrapperPtr == NULL) {
@@ -684,13 +750,20 @@ TkWmMapWindow(winPtr)
 	}
 
 	/*
-	 * Store all the window-manager-related information for the
-	 * window.
+	 * Store all the window-manager-related information for the window.
 	 */
 
-	string = (wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid;
-	Tcl_UtfToExternalDString(NULL, string, -1, &ds);
-	string = Tcl_DStringValue(&ds);
+#if 0
+REMOVED >>>> ORIGINAL tkUnixWm.c#1
+	if (XStringListToTextProperty(&(Tcl_DStringValue(&ds)), 1,
+		&textProp)  != 0) {
+	    XSetWMName(winPtr->display, wmPtr->wrapperPtr->window, &textProp);
+	    XFree((char *) textProp.value);
+	}
+	Tcl_DStringFree(&ds);
+
+REMOVED ==== THEIRS tkUnixWm.c#3
+REMOVED ==== YOURS tkUnixWm.c
 	if (XStringListToTextProperty((char **)&string, 1,
 		&textProp)  != 0) {
 	    XSetWMName(winPtr->display, wmPtr->wrapperPtr->window, &textProp);
@@ -698,14 +771,11 @@ TkWmMapWindow(winPtr)
 	}
 	Tcl_DStringFree(&ds);
 
+REMOVED <<<<
+#endif
 	TkWmSetClass(winPtr);
-
-	if (wmPtr->iconName != NULL) {
-	    Tcl_UtfToExternalDString(NULL, wmPtr->iconName, -1, &ds);
-	    XSetIconName(winPtr->display, wmPtr->wrapperPtr->window,
-		    Tcl_DStringValue(&ds));
-	    Tcl_DStringFree(&ds);
-	}
+	UpdateTitle(winPtr);
+	UpdatePhotoIcon(winPtr);
 
 	if (wmPtr->masterPtr != NULL) {
 	    /*
@@ -713,11 +783,12 @@ TkWmMapWindow(winPtr)
 	     */
 
 	    if (!Tk_IsMapped(wmPtr->masterPtr)) {
-	        wmPtr->withdrawn = 1;
-	        wmPtr->hints.initial_state = WithdrawnState;
+		wmPtr->withdrawn = 1;
+		wmPtr->hints.initial_state = WithdrawnState;
 	    } else {
-	        XSetTransientForHint(winPtr->display, wmPtr->wrapperPtr->window,
-		        wmPtr->masterPtr->wmInfoPtr->wrapperPtr->window);
+		XSetTransientForHint(winPtr->display,
+			wmPtr->wrapperPtr->window,
+			wmPtr->masterPtr->wmInfoPtr->wrapperPtr->window);
 	    }
 	}
 
@@ -745,9 +816,8 @@ TkWmMapWindow(winPtr)
     }
     if (wmPtr->iconFor != NULL) {
 	/*
-	 * This window is an icon for somebody else.  Make sure that
-	 * the geometry is up-to-date, then return without mapping
-	 * the window.
+	 * This window is an icon for somebody else. Make sure that the
+	 * geometry is up-to-date, then return without mapping the window.
 	 */
 
 	if (wmPtr->flags & WM_UPDATE_PENDING) {
@@ -764,6 +834,11 @@ TkWmMapWindow(winPtr)
     wmPtr->flags &= ~WM_ABOUT_TO_MAP;
 
     /*
+     * Update _NET_WM_STATE hints:
+     */
+    UpdateNetWmState(wmPtr);
+
+    /*
      * Map the window, then wait to be sure that the window manager has
      * processed the map operation.
      */
@@ -779,9 +854,8 @@ TkWmMapWindow(winPtr)
  *
  * TkWmUnmapWindow --
  *
- *	This procedure is invoked to unmap a top-level window.  The
- *	only thing it does special is to wait for the window actually
- *	to be unmapped.
+ *	This function is invoked to unmap a top-level window. The only thing
+ *	it does special is to wait for the window actually to be unmapped.
  *
  * Results:
  *	None.
@@ -793,20 +867,20 @@ TkWmMapWindow(winPtr)
  */
 
 void
-TkWmUnmapWindow(winPtr)
-    TkWindow *winPtr;		/* Top-level window that's about to
-				 * be mapped. */
+TkWmUnmapWindow(
+    TkWindow *winPtr)		/* Top-level window that's about to be
+				 * mapped. */
 {
     /*
-     * It seems to be important to wait after unmapping a top-level
-     * window until the window really gets unmapped.  I don't completely
-     * understand all the interactions with the window manager, but if
-     * we go on without waiting, and if the window is then mapped again
-     * quickly, events seem to get lost so that we think the window isn't
-     * mapped when in fact it is mapped.  I suspect that this has something
-     * to do with the window manager filtering Map events (and possily not
-     * filtering Unmap events?).
+     * It seems to be important to wait after unmapping a top-level window
+     * until the window really gets unmapped. I don't completely understand
+     * all the interactions with the window manager, but if we go on without
+     * waiting, and if the window is then mapped again quickly, events seem to
+     * get lost so that we think the window isn't mapped when in fact it is
+     * mapped. I suspect that this has something to do with the window manager
+     * filtering Map events (and possily not filtering Unmap events?).
      */
+
     XUnmapWindow(winPtr->display, winPtr->wmInfoPtr->wrapperPtr->window);
     WaitForMapNotify(winPtr, 0);
 }
@@ -817,9 +891,8 @@ TkWmUnmapWindow(winPtr)
  *
  * TkWmDeadWindow --
  *
- *	This procedure is invoked when a top-level window is
- *	about to be deleted.  It cleans up the wm-related data
- *	structures for the window.
+ *	This function is invoked when a top-level window is about to be
+ *	deleted. It cleans up the wm-related data structures for the window.
  *
  * Results:
  *	None.
@@ -832,8 +905,8 @@ TkWmUnmapWindow(winPtr)
 
 
 void
-TkWmDeadWindow(winPtr)
-    TkWindow *winPtr;		/* Top-level window that's being deleted. */
+TkWmDeadWindow(
+    TkWindow *winPtr)		/* Top-level window that's being deleted. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     WmInfo *wmPtr2;
@@ -847,9 +920,9 @@ TkWmDeadWindow(winPtr)
 	register WmInfo *prevPtr;
 
 	for (prevPtr = (WmInfo *) winPtr->dispPtr->firstWmPtr; ;
-                prevPtr = prevPtr->nextPtr) {
+		prevPtr = prevPtr->nextPtr) {
 	    if (prevPtr == NULL) {
-		panic("couldn't unlink window in TkWmDeadWindow");
+		Tcl_Panic("couldn't unlink window in TkWmDeadWindow");
 	    }
 	    if (prevPtr->nextPtr == wmPtr) {
 		prevPtr->nextPtr = wmPtr->nextPtr;
@@ -863,6 +936,9 @@ TkWmDeadWindow(winPtr)
     if (wmPtr->iconName != NULL) {
 	ckfree(wmPtr->iconName);
     }
+    if (wmPtr->iconDataPtr != NULL) {
+	ckfree((char *)wmPtr->iconDataPtr);
+    }
 
     if (wmPtr->hints.icon_pixmap) {
 	if (wmPtr->iconImage) {
@@ -898,10 +974,10 @@ TkWmDeadWindow(winPtr)
     }
     if (wmPtr->wrapperPtr != NULL) {
 	/*
-	 * The rest of Tk doesn't know that we reparent the toplevel
-	 * inside the wrapper, so reparent it back out again before
-	 * deleting the wrapper; otherwise the toplevel will get deleted
-	 * twice (once implicitly by the deletion of the wrapper).
+	 * The rest of Tk doesn't know that we reparent the toplevel inside
+	 * the wrapper, so reparent it back out again before deleting the
+	 * wrapper; otherwise the toplevel will get deleted twice (once
+	 * implicitly by the deletion of the wrapper).
 	 */
 
 	XUnmapWindow(winPtr->display, winPtr->window);
@@ -929,42 +1005,47 @@ TkWmDeadWindow(winPtr)
     if (wmPtr->flags & WM_UPDATE_PENDING) {
 	Tcl_CancelIdleCall(UpdateGeometryInfo, (ClientData) winPtr);
     }
+
     /*
      * Reset all transient windows whose master is the dead window.
      */
 
     for (wmPtr2 = winPtr->dispPtr->firstWmPtr; wmPtr2 != NULL;
-	 wmPtr2 = wmPtr2->nextPtr) {
+	    wmPtr2 = wmPtr2->nextPtr) {
 	if (wmPtr2->masterPtr == winPtr) {
 	    wmPtr->numTransients--;
 	    Tk_DeleteEventHandler((Tk_Window) wmPtr2->masterPtr,
-	            StructureNotifyMask,
-	            WmWaitMapProc, (ClientData) wmPtr2->winPtr);
+		    StructureNotifyMask,
+		    WmWaitMapProc, (ClientData) wmPtr2->winPtr);
 	    wmPtr2->masterPtr = NULL;
 	    if (!(wmPtr2->flags & WM_NEVER_MAPPED)) {
-		XSetTransientForHint(wmPtr2->winPtr->display,
-		        wmPtr2->wrapperPtr->window, None);
-		/* FIXME: Need a call like Win32's UpdateWrapper() so
-		   we can recreate the wrapper and get rid of the
-		   transient window decorations. */
+		XDeleteProperty(winPtr->display, wmPtr2->wrapperPtr->window,
+			Tk_InternAtom((Tk_Window) winPtr, "WM_TRANSIENT_FOR"));
+
+		/*
+		 * FIXME: Need a call like Win32's UpdateWrapper() so we can
+		 * recreate the wrapper and get rid of the transient window
+		 * decorations.
+		 */
 	    }
 	}
     }
-    if (wmPtr->numTransients != 0)
-        panic("numTransients should be 0");
+    if (wmPtr->numTransients != 0) {
+	Tcl_Panic("numTransients should be 0");
+    }
 
     if (wmPtr->masterPtr != NULL) {
 	wmPtr2 = wmPtr->masterPtr->wmInfoPtr;
+
 	/*
-	 * If we had a master, tell them that we aren't tied
-	 * to them anymore
+	 * If we had a master, tell them that we aren't tied to them anymore
 	 */
+
 	if (wmPtr2 != NULL) {
 	    wmPtr2->numTransients--;
 	}
 	Tk_DeleteEventHandler((Tk_Window) wmPtr->masterPtr,
-		StructureNotifyMask,
-		WmWaitMapProc, (ClientData) winPtr);
+		StructureNotifyMask, WmWaitMapProc, (ClientData) winPtr);
 	wmPtr->masterPtr = NULL;
     }
     ckfree((char *) wmPtr);
@@ -976,11 +1057,10 @@ TkWmDeadWindow(winPtr)
  *
  * TkWmSetClass --
  *
- *	This procedure is invoked whenever a top-level window's
- *	class is changed.  If the window has been mapped then this
- *	procedure updates the window manager property for the
- *	class.  If the window hasn't been mapped, the update is
- *	deferred until just before the first mapping.
+ *	This function is invoked whenever a top-level window's class is
+ *	changed. If the window has been mapped then this function updates the
+ *	window manager property for the class. If the window hasn't been
+ *	mapped, the update is deferred until just before the first mapping.
  *
  * Results:
  *	None.
@@ -992,8 +1072,8 @@ TkWmDeadWindow(winPtr)
  */
 
 void
-TkWmSetClass(winPtr)
-    TkWindow *winPtr;		/* Newly-created top-level window. */
+TkWmSetClass(
+    TkWindow *winPtr)		/* Newly-created top-level window. */
 {
     if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
 	return;
@@ -1048,41 +1128,35 @@ Tk_Window tkwin;
  * Tk_WmObjCmd --
  * Tk_WmCmd --
  *
- *	This procedure is invoked to process the "wm" Tcl command.
- *	See the user documentation for details on what it does.
- *
- * Results:
- *	A standard Tcl result.
- *
- * Side effects:
- *	See the user documentation.
+ *	This function is invoked to process the "wm" Tcl command. 
  *
  *----------------------------------------------------------------------
  */
 /* ARGSUSED */
 int
-Tk_WmObjCmd(clientData, interp, objc, objv)
-    ClientData clientData;	/* Main window associated with
-				 * interpreter. */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+Tk_WmObjCmd(
+    ClientData clientData,	/* Main window associated with interpreter. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     Tk_Window tkwin = (Tk_Window) clientData;
     static CONST char *optionStrings[] = {
 	"aspect", "attributes", "capture", "client", "colormapwindows",
 	"command", "deiconify", "focusmodel", "frame",
 	"geometry", "grid", "group", "iconbitmap",
-	"iconify", "iconimage", "iconmask", "iconname", "iconposition",
+	"iconify", "iconimage", "iconmask", "iconname",
+	"iconphoto", "iconposition",
 	"iconwindow", "maxsize", "minsize", "overrideredirect",
-        "positionfrom", "protocol", "release", "resizable", "sizefrom",
-        "stackorder", "state", "title", "transient",
-	"withdraw", "wrapper", (char *) NULL };
+	"positionfrom", "protocol", "release", "resizable", "sizefrom",
+	"stackorder", "state", "title", "transient",
+	"withdraw", "wrapper", NULL };
     enum options {
         WMOPT_ASPECT, WMOPT_ATTRIBUTES, WMOPT_CAPTURE, WMOPT_CLIENT, WMOPT_COLORMAPWINDOWS,
 	WMOPT_COMMAND, WMOPT_DEICONIFY, WMOPT_FOCUSMODEL, WMOPT_FRAME,
 	WMOPT_GEOMETRY, WMOPT_GRID, WMOPT_GROUP, WMOPT_ICONBITMAP,
-	WMOPT_ICONIFY, WMOPT_ICONIMAGE, WMOPT_ICONMASK, WMOPT_ICONNAME, WMOPT_ICONPOSITION,
+	WMOPT_ICONIFY, WMOPT_ICONIMAGE, WMOPT_ICONMASK, WMOPT_ICONNAME,
+	WMOPT_ICONPHOTO, WMOPT_ICONPOSITION,
 	WMOPT_ICONWINDOW, WMOPT_MAXSIZE, WMOPT_MINSIZE, WMOPT_OVERRIDEREDIRECT,
         WMOPT_POSITIONFROM, WMOPT_PROTOCOL, WMOPT_RELEASE, WMOPT_RESIZABLE, WMOPT_SIZEFROM,
         WMOPT_STACKORDER, WMOPT_STATE, WMOPT_TITLE, WMOPT_TRANSIENT,
@@ -1094,7 +1168,7 @@ Tk_WmObjCmd(clientData, interp, objc, ob
     TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
 
     if (objc < 2) {
-	wrongNumArgs:
+    wrongNumArgs:
 	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
 	return TCL_ERROR;
     }
@@ -1103,17 +1177,18 @@ Tk_WmObjCmd(clientData, interp, objc, ob
     if ((argv1[0] == 't') && (strncmp(argv1, "tracing", (size_t) length) == 0)
 	    && (length >= 3)) {
 	int wmTracing;
-	if ((objc != 2) && (objc != 3)) {
+	/* Perl/Tk: increased parameter position by one because of implicite window parameter */
+	if ((objc != 3) && (objc != 4)) {
 	    Tcl_WrongNumArgs(interp, 2, objv, "?boolean?");
 	    return TCL_ERROR;
 	}
-	if (objc == 2) {
+	if (objc == 3) {
 	    Tcl_SetResult(interp,
 		    ((dispPtr->flags & TK_DISPLAY_WM_TRACING) ? "1" : ""),
                     TCL_STATIC);
 	    return TCL_OK;
 	}
-	if (Tcl_GetBooleanFromObj(interp, objv[2], &wmTracing) != TCL_OK) {
+	if (Tcl_GetBooleanFromObj(interp, objv[3], &wmTracing) != TCL_OK) {
 	    return TCL_ERROR;
 	}
 	if (wmTracing) {
@@ -1147,76 +1222,78 @@ Tk_WmObjCmd(clientData, interp, objc, ob
     }
     else if ((enum options) index != WMOPT_RELEASE) {
 	Tcl_AppendResult(interp, "window \"", winPtr->pathName,
-		"\" isn't a top-level window", (char *) NULL);
+		"\" isn't a top-level window", NULL);
 	    return TCL_ERROR;
     }
 
     switch ((enum options) index) {
-      case WMOPT_ASPECT:
+    case WMOPT_ASPECT:
 	return WmAspectCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_ATTRIBUTES:
+    case WMOPT_ATTRIBUTES:
 	return WmAttributesCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_CLIENT:
+    case WMOPT_CLIENT:
 	return WmClientCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_CAPTURE:
+    case WMOPT_CAPTURE:
 	return WmCaptureCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_COLORMAPWINDOWS:
+    case WMOPT_COLORMAPWINDOWS:
 	return WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_COMMAND:
+    case WMOPT_COMMAND:
 	return WmCommandCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_DEICONIFY:
+    case WMOPT_DEICONIFY:
 	return WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_FOCUSMODEL:
+    case WMOPT_FOCUSMODEL:
 	return WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_FRAME:
+    case WMOPT_FRAME:
 	return WmFrameCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_GEOMETRY:
+    case WMOPT_GEOMETRY:
 	return WmGeometryCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_GRID:
+    case WMOPT_GRID:
 	return WmGridCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_GROUP:
+    case WMOPT_GROUP:
 	return WmGroupCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_ICONBITMAP:
+    case WMOPT_ICONBITMAP:
 	return WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_ICONIFY:
+    case WMOPT_ICONIFY:
 	return WmIconifyCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_ICONIMAGE:
+    case WMOPT_ICONIMAGE:
 	return WmIconimageCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_ICONMASK:
+    case WMOPT_ICONMASK:
 	return WmIconmaskCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_ICONNAME:
+    case WMOPT_ICONNAME:
 	return WmIconnameCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_ICONPOSITION:
+    case WMOPT_ICONPHOTO:
+	return WmIconphotoCmd(tkwin, winPtr, interp, objc, objv);
+    case WMOPT_ICONPOSITION:
 	return WmIconpositionCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_ICONWINDOW:
+    case WMOPT_ICONWINDOW:
 	return WmIconwindowCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_MAXSIZE:
+    case WMOPT_MAXSIZE:
 	return WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_MINSIZE:
+    case WMOPT_MINSIZE:
 	return WmMinsizeCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_OVERRIDEREDIRECT:
+    case WMOPT_OVERRIDEREDIRECT:
 	return WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_POSITIONFROM:
+    case WMOPT_POSITIONFROM:
 	return WmPositionfromCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_PROTOCOL:
+    case WMOPT_PROTOCOL:
 	return WmProtocolCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_RESIZABLE:
+    case WMOPT_RESIZABLE:
 	return WmResizableCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_RELEASE:
+    case WMOPT_RELEASE:
 	return WmReleaseCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_SIZEFROM:
+    case WMOPT_SIZEFROM:
 	return WmSizefromCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_STACKORDER:
+    case WMOPT_STACKORDER:
 	return WmStackorderCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_STATE:
+    case WMOPT_STATE:
 	return WmStateCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_TITLE:
+    case WMOPT_TITLE:
 	return WmTitleCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_TRANSIENT:
+    case WMOPT_TRANSIENT:
 	return WmTransientCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_WITHDRAW:
+    case WMOPT_WITHDRAW:
 	return WmWithdrawCmd(tkwin, winPtr, interp, objc, objv);
-      case WMOPT_WRAPPER:
+    case WMOPT_WRAPPER:
 	return WmWrapperCmd(tkwin, winPtr, interp, objc, objv);
     }
 
@@ -1229,8 +1306,8 @@ Tk_WmObjCmd(clientData, interp, objc, ob
  *
  * WmAspectCmd --
  *
- *	This procedure is invoked to process the "wm aspect" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm aspect" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -1242,12 +1319,12 @@ Tk_WmObjCmd(clientData, interp, objc, ob
  */
 
 static int
-WmAspectCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmAspectCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     int numer1, denom1, numer2, denom2;
@@ -1259,12 +1336,9 @@ WmAspectCmd(tkwin, winPtr, interp, objc,
     }
     if (objc == 3) {
 	if (wmPtr->sizeHintsFlags & PAspect) {
-	    char buf[TCL_INTEGER_SPACE * 4];
-
-	    sprintf(buf, "%d %d %d %d", wmPtr->minAspect.x,
-		    wmPtr->minAspect.y, wmPtr->maxAspect.x,
-		    wmPtr->maxAspect.y);
-	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
+	    Tcl_IntResults(interp, 4, 0, wmPtr->minAspect.x,
+			   wmPtr->minAspect.y, wmPtr->maxAspect.x,
+			   wmPtr->maxAspect.y);
 	}
 	return TCL_OK;
     }
@@ -1297,30 +1371,184 @@ WmAspectCmd(tkwin, winPtr, interp, objc,
 /*
  *----------------------------------------------------------------------
  *
+ * WmSetAttribute --
+ *
+ * 	Helper routine for WmAttributesCmd.  Sets the value
+ * 	of the specified attribute.
+ *
+ * Returns:
+ *
+ * 	TCL_OK if successful, TCL_ERROR otherwise.  In case of an
+ * 	error, leaves a message in the interpreter's result.
+ *
+ *----------------------------------------------------------------------
+ */
+static int WmSetAttribute(
+    TkWindow *winPtr,           /* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter */
+    WmAttribute attribute,	/* Code of attribute to set */
+    Tcl_Obj *value)		/* New value */
+{
+    WmInfo *wmPtr = winPtr->wmInfoPtr;
+    switch (attribute) {
+	case WMATT_ALPHA:
+	{
+	    unsigned long opacity;	/* 0=transparent, 0xFFFFFFFF=opaque */
+
+	    if (TCL_OK != Tcl_GetDoubleFromObj(
+		    interp, value, &wmPtr->reqState.alpha)) {
+		return TCL_ERROR;
+	    }
+	    if (wmPtr->reqState.alpha < 0.0) {
+		wmPtr->reqState.alpha = 0.0;
+	    }
+	    if (wmPtr->reqState.alpha > 1.0) {
+		wmPtr->reqState.alpha = 1.0;
+	    }
+
+	    if (!wmPtr->wrapperPtr) {
+		break;
+	    }
+
+	    opacity = 0xFFFFFFFFul * wmPtr->reqState.alpha;
+	    XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window, 
+		    Tk_InternAtom((Tk_Window)winPtr, "_NET_WM_WINDOW_OPACITY"),
+		    XA_CARDINAL, 32, PropModeReplace,
+		    (unsigned char *)&opacity, 1L);
+	    wmPtr->attributes.alpha = wmPtr->reqState.alpha;
+
+	    break;
+	}
+	case WMATT_TOPMOST:
+	    if (TCL_OK != Tcl_GetBooleanFromObj(
+		    interp, value, &wmPtr->reqState.topmost)) {
+		return TCL_ERROR;
+	    }
+	    SetNetWmState(winPtr, 
+		"_NET_WM_STATE_ABOVE", wmPtr->reqState.topmost);
+	    break;
+	case WMATT_ZOOMED:
+	    if (TCL_OK != Tcl_GetBooleanFromObj(
+		    interp, value, &wmPtr->reqState.zoomed)) {
+		return TCL_ERROR;
+	    }
+	    SetNetWmState(winPtr,
+		"_NET_WM_STATE_MAXIMIZED_VERT", wmPtr->reqState.zoomed);
+	    SetNetWmState(winPtr,
+		"_NET_WM_STATE_MAXIMIZED_HORZ", wmPtr->reqState.zoomed);
+	    break;
+	case WMATT_FULLSCREEN:
+	    if (TCL_OK != Tcl_GetBooleanFromObj(
+		    interp, value, &wmPtr->reqState.fullscreen)) {
+		return TCL_ERROR;
+	    }
+	    SetNetWmState(winPtr,
+		"_NET_WM_STATE_FULLSCREEN", wmPtr->reqState.fullscreen);
+	    break;
+	case _WMATT_LAST_ATTRIBUTE:	/* NOTREACHED */
+	    return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmGetAttribute --
+ *
+ * 	Helper routine for WmAttributesCmd.  Returns the current value
+ * 	of the specified attribute.
+ *
+ * See also: CheckNetWmState().
+ *
+ *----------------------------------------------------------------------
+ */
+static Tcl_Obj *WmGetAttribute(
+    TkWindow *winPtr,           /* Toplevel to work with */
+    WmAttribute attribute)	/* Code of attribute to get */
+{
+    WmInfo *wmPtr = winPtr->wmInfoPtr;
+    switch (attribute) {
+	case WMATT_ALPHA:
+	    return Tcl_NewDoubleObj(wmPtr->attributes.alpha);
+	case WMATT_TOPMOST:
+	    return Tcl_NewBooleanObj(wmPtr->attributes.topmost);
+	case WMATT_ZOOMED:
+	    return Tcl_NewBooleanObj(wmPtr->attributes.zoomed);
+	case WMATT_FULLSCREEN:
+	    return Tcl_NewBooleanObj(wmPtr->attributes.fullscreen);
+	case _WMATT_LAST_ATTRIBUTE:	/*NOTREACHED*/
+	    break;
+    }
+    /*NOTREACHED*/
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
  * WmAttributesCmd --
  *
- *	This procedure is invoked to process the "wm attributes" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm attributes" Tcl command.
  *
- * Results:
- *	A standard Tcl result.
+ * Syntax:
  *
- * Side effects:
- *	See the user documentation.
+ * 	wm attributes $win ?-attribute ?value attribute value...??
+ *
+ * Notes:
+ *
+ *	Attributes of mapped windows are set by sending a _NET_WM_STATE
+ *	ClientMessage to the root window (see SetNetWmState).
+ *	For withdrawn windows, we keep track of the requested attribute
+ *	state, and set the _NET_WM_STATE property ourselves immediately
+ *	prior to mapping the window.
+ *
+ * See also: TIP#231, EWMH.
  *
  *----------------------------------------------------------------------
  */
 
 static int
-WmAttributesCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
-{
-    if (objc != 3) {
-	Tcl_WrongNumArgs(interp, 2, objv, "window");
+WmAttributesCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
+{
+    int attribute = 0;
+    if (objc == 3) {		/* wm attributes $win */
+	Tcl_Obj *result = Tcl_NewListObj(0,0);
+	for (attribute = 0; attribute < _WMATT_LAST_ATTRIBUTE; ++attribute) {
+	    Tcl_ListObjAppendElement(interp, result,
+		    Tcl_NewStringObj(WmAttributeNames[attribute], -1));
+	    Tcl_ListObjAppendElement(interp, result,
+		    WmGetAttribute(winPtr, attribute));
+	}
+	Tcl_SetObjResult(interp, result);
+	return TCL_OK;
+    } else if (objc == 4)  {	/* wm attributes $win -attribute */
+	if (Tcl_GetIndexFromObj(interp, objv[3], WmAttributeNames,
+		    "attribute", 0, &attribute) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, 
+		WmGetAttribute(winPtr, attribute));
+	return TCL_OK;
+    } else if ((objc - 3) % 2 == 0) {	/* wm attributes $win -att value... */
+	int i;
+	for (i = 3; i < objc; i += 2) {
+	    if (Tcl_GetIndexFromObj(interp, objv[i], WmAttributeNames,
+			"attribute", 0, &attribute) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (WmSetAttribute(winPtr,interp,attribute,objv[i+1]) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+	return TCL_OK;
+    } else {
+	Tcl_WrongNumArgs(interp, 2, objv, "window ?-attribute ?value ...??");
 	return TCL_ERROR;
     }
     return TCL_OK;
@@ -1331,8 +1559,8 @@ WmAttributesCmd(tkwin, winPtr, interp, o
  *
  * WmClientCmd --
  *
- *	This procedure is invoked to process the "wm client" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm client" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -1344,12 +1572,12 @@ WmAttributesCmd(tkwin, winPtr, interp, o
  */
 
 static int
-WmClientCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmClientCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     char *argv3;
@@ -1372,8 +1600,7 @@ WmClientCmd(tkwin, winPtr, interp, objc,
 	    wmPtr->clientMachine = NULL;
 	    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
 		XDeleteProperty(winPtr->display, wmPtr->wrapperPtr->window,
-			Tk_InternAtom((Tk_Window) winPtr,
-				"WM_CLIENT_MACHINE"));
+			Tk_InternAtom((Tk_Window)winPtr, "WM_CLIENT_MACHINE"));
 	    }
 	}
 	return TCL_OK;
@@ -1407,9 +1634,8 @@ WmClientCmd(tkwin, winPtr, interp, objc,
  *
  * WmColormapwindowsCmd --
  *
- *	This procedure is invoked to process the "wm colormapwindows"
- *	Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm colormapwindows" Tcl
+ *	command. See the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -1421,12 +1647,12 @@ WmClientCmd(tkwin, winPtr, interp, objc,
  */
 
 static int
-WmColormapwindowsCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmColormapwindowsCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     Window *cmapList;
@@ -1453,7 +1679,7 @@ WmColormapwindowsCmd(tkwin, winPtr, inte
 		    && (wmPtr->flags & WM_ADDED_TOPLEVEL_COLORMAP)) {
 		break;
 	    }
-	    winPtr2  = (TkWindow *) Tk_IdToWindow(winPtr->display,
+	    winPtr2 = (TkWindow *) Tk_IdToWindow(winPtr->display,
 		    cmapList[i]);
 	    if (winPtr2 == NULL) {
 		sprintf(buffer, "0x%lx", cmapList[i]);
@@ -1474,8 +1700,7 @@ WmColormapwindowsCmd(tkwin, winPtr, inte
     gotToplevel = 0;
     for (i = 0; i < windowObjc; i++) {
 	if (TkGetWindowFromObj(interp, tkwin, windowObjv[i],
-		(Tk_Window *) &winPtr2) != TCL_OK)
-	{
+		(Tk_Window *) &winPtr2) != TCL_OK) {
 	    ckfree((char *) cmapList);
 	    return TCL_ERROR;
 	}
@@ -1506,8 +1731,8 @@ WmColormapwindowsCmd(tkwin, winPtr, inte
  *
  * WmCommandCmd --
  *
- *	This procedure is invoked to process the "wm command" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm command" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -1519,12 +1744,12 @@ WmColormapwindowsCmd(tkwin, winPtr, inte
  */
 
 static int
-WmCommandCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmCommandCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     char *argv3;
@@ -1600,7 +1825,7 @@ WmCommandCmd(tkwin, winPtr, interp, objc
  *
  * WmDeiconifyCmd --
  *
- *	This procedure is invoked to process the "wm deiconify" Tcl command.
+ *	This function is invoked to process the "wm deiconify" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -1613,12 +1838,12 @@ WmCommandCmd(tkwin, winPtr, interp, objc
  */
 
 static int
-WmDeiconifyCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmDeiconifyCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
 
@@ -1628,13 +1853,12 @@ WmDeiconifyCmd(tkwin, winPtr, interp, ob
     }
     if (wmPtr->iconFor != NULL) {
 	Tcl_AppendResult(interp, "can't deiconify ", Tcl_GetString(objv[2]),
-		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
-		(char *) NULL);
+		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);
 	return TCL_ERROR;
     }
     if (winPtr->flags & TK_EMBEDDED) {
 	Tcl_AppendResult(interp, "can't deiconify ", winPtr->pathName,
-		": it is an embedded window", (char *) NULL);
+		": it is an embedded window", NULL);
 	return TCL_ERROR;
     }
     wmPtr->flags &= ~WM_WITHDRAWN;
@@ -1647,7 +1871,7 @@ WmDeiconifyCmd(tkwin, winPtr, interp, ob
  *
  * WmFocusmodelCmd --
  *
- *	This procedure is invoked to process the "wm focusmodel" Tcl command.
+ *	This function is invoked to process the "wm focusmodel" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -1660,16 +1884,16 @@ WmDeiconifyCmd(tkwin, winPtr, interp, ob
  */
 
 static int
-WmFocusmodelCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmFocusmodelCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     static CONST char *optionStrings[] = {
-	"active", "passive", (char *) NULL };
+	"active", "passive", NULL };
     enum options {
 	OPT_ACTIVE, OPT_PASSIVE };
     int index;
@@ -1702,8 +1926,8 @@ WmFocusmodelCmd(tkwin, winPtr, interp, o
  *
  * WmFrameCmd --
  *
- *	This procedure is invoked to process the "wm frame" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm frame" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -1715,12 +1939,12 @@ WmFocusmodelCmd(tkwin, winPtr, interp, o
  */
 
 static int
-WmFrameCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmFrameCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     Window window;
@@ -1744,7 +1968,7 @@ WmFrameCmd(tkwin, winPtr, interp, objc, 
  *
  * WmGeometryCmd --
  *
- *	This procedure is invoked to process the "wm geometry" Tcl command.
+ *	This function is invoked to process the "wm geometry" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -1757,12 +1981,12 @@ WmFrameCmd(tkwin, winPtr, interp, objc, 
  */
 
 static int
-WmGeometryCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmGeometryCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     char xSign, ySign;
@@ -1807,8 +2031,8 @@ WmGeometryCmd(tkwin, winPtr, interp, obj
  *
  * WmGridCmd --
  *
- *	This procedure is invoked to process the "wm grid" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm grid" Tcl command. See the
+ *	user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -1820,12 +2044,12 @@ WmGeometryCmd(tkwin, winPtr, interp, obj
  */
 
 static int
-WmGridCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmGridCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     int reqWidth, reqHeight, widthInc, heightInc;
@@ -1837,19 +2061,16 @@ WmGridCmd(tkwin, winPtr, interp, objc, o
     }
     if (objc == 3) {
 	if (wmPtr->sizeHintsFlags & PBaseSize) {
-	    char buf[TCL_INTEGER_SPACE * 4];
-
-	    sprintf(buf, "%d %d %d %d", wmPtr->reqGridWidth,
-		    wmPtr->reqGridHeight, wmPtr->widthInc,
-		    wmPtr->heightInc);
-	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
+	    Tcl_IntResults(interp, 4, 0, wmPtr->reqGridWidth,
+			   wmPtr->reqGridHeight, wmPtr->widthInc,
+			   wmPtr->heightInc);
 	}
 	return TCL_OK;
     }
     if (*Tcl_GetString(objv[3]) == '\0') {
 	/*
-	 * Turn off gridding and reset the width and height
-	 * to make sense as ungridded numbers.
+	 * Turn off gridding and reset the width and height to make sense as
+	 * ungridded numbers.
 	 */
 
 	wmPtr->sizeHintsFlags &= ~(PBaseSize|PResizeInc);
@@ -1865,7 +2086,7 @@ WmGridCmd(tkwin, winPtr, interp, objc, o
 	if ((Tcl_GetIntFromObj(interp, objv[3], &reqWidth) != TCL_OK)
 		|| (Tcl_GetIntFromObj(interp, objv[4], &reqHeight) != TCL_OK)
 		|| (Tcl_GetIntFromObj(interp, objv[5], &widthInc) != TCL_OK)
-		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) != TCL_OK)) {
+		|| (Tcl_GetIntFromObj(interp, objv[6], &heightInc) !=TCL_OK)) {
 	    return TCL_ERROR;
 	}
 	if (reqWidth < 0) {
@@ -1876,12 +2097,12 @@ WmGridCmd(tkwin, winPtr, interp, objc, o
 	    Tcl_SetResult(interp, "baseHeight can't be < 0", TCL_STATIC);
 	    return TCL_ERROR;
 	}
-	if (widthInc < 0) {
-	    Tcl_SetResult(interp, "widthInc can't be < 0", TCL_STATIC);
+	if (widthInc <= 0) {
+	    Tcl_SetResult(interp, "widthInc can't be <= 0", TCL_STATIC);
 	    return TCL_ERROR;
 	}
-	if (heightInc < 0) {
-	    Tcl_SetResult(interp, "heightInc can't be < 0", TCL_STATIC);
+	if (heightInc <= 0) {
+	    Tcl_SetResult(interp, "heightInc can't be <= 0", TCL_STATIC);
 	    return TCL_ERROR;
 	}
 	Tk_SetGrid((Tk_Window) winPtr, reqWidth, reqHeight, widthInc,
@@ -1897,8 +2118,8 @@ WmGridCmd(tkwin, winPtr, interp, objc, o
  *
  * WmGroupCmd --
  *
- *	This procedure is invoked to process the "wm group" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm group" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -1910,12 +2131,12 @@ WmGridCmd(tkwin, winPtr, interp, objc, o
  */
 
 static int
-WmGroupCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmGroupCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     Tk_Window tkwin2;
@@ -1973,7 +2194,7 @@ WmGroupCmd(tkwin, winPtr, interp, objc, 
  *
  * WmIconbitmapCmd --
  *
- *	This procedure is invoked to process the "wm iconbitmap" Tcl command.
+ *	This function is invoked to process the "wm iconbitmap" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -1986,12 +2207,12 @@ WmGroupCmd(tkwin, winPtr, interp, objc, 
  */
 
 static int
-WmIconbitmapCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmIconbitmapCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     Pixmap pixmap;
@@ -2033,8 +2254,8 @@ WmIconbitmapCmd(tkwin, winPtr, interp, o
  *
  * WmIconifyCmd --
  *
- *	This procedure is invoked to process the "wm iconify" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm iconify" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -2046,12 +2267,12 @@ WmIconbitmapCmd(tkwin, winPtr, interp, o
  */
 
 static int
-WmIconifyCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmIconifyCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     if (objc != 3) {
@@ -2060,23 +2281,22 @@ WmIconifyCmd(tkwin, winPtr, interp, objc
     }
     if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
 	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
-		"\": override-redirect flag is set", (char *) NULL);
+		"\": override-redirect flag is set", NULL);
 	return TCL_ERROR;
     }
     if (wmPtr->masterPtr != NULL) {
 	Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
-		"\": it is a transient", (char *) NULL);
+		"\": it is a transient", NULL);
 	return TCL_ERROR;
     }
     if (wmPtr->iconFor != NULL) {
 	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
-		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
-		(char *) NULL);
+		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);
 	return TCL_ERROR;
     }
     if (winPtr->flags & TK_EMBEDDED) {
 	Tcl_AppendResult(interp, "can't iconify ", winPtr->pathName,
-		": it is an embedded window", (char *) NULL);
+		": it is an embedded window", NULL);
 	return TCL_ERROR;
     }
     if (TkpWmSetState(winPtr, IconicState) == 0) {
@@ -2093,7 +2313,7 @@ WmIconifyCmd(tkwin, winPtr, interp, objc
  *
  * WmIconmaskCmd --
  *
- *	This procedure is invoked to process the "wm iconmask" Tcl command.
+ *	This function is invoked to process the "wm iconmask" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -2106,12 +2326,12 @@ WmIconifyCmd(tkwin, winPtr, interp, objc
  */
 
 static int
-WmIconmaskCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmIconmaskCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     Pixmap pixmap;
@@ -2152,7 +2372,7 @@ WmIconmaskCmd(tkwin, winPtr, interp, obj
  *
  * WmIconnameCmd --
  *
- *	This procedure is invoked to process the "wm iconname" Tcl command.
+ *	This function is invoked to process the "wm iconname" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -2165,12 +2385,12 @@ WmIconmaskCmd(tkwin, winPtr, interp, obj
  */
 
 static int
-WmIconnameCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmIconnameCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     char *argv3;
@@ -2193,13 +2413,162 @@ WmIconnameCmd(tkwin, winPtr, interp, obj
 	wmPtr->iconName = ckalloc((unsigned) (length + 1));
 	strcpy(wmPtr->iconName, argv3);
 	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
-	    Tcl_DString ds;
+	    UpdateTitle(winPtr);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WmIconphotoCmd --
+ *
+ *	This function is invoked to process the "wm iconphoto" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
 
-	    Tcl_UtfToExternalDString(NULL, wmPtr->iconName, -1, &ds);
-	    XSetIconName(winPtr->display, wmPtr->wrapperPtr->window,
-		    Tcl_DStringValue(&ds));
-	    Tcl_DStringFree(&ds);
+static int
+WmIconphotoCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
+{
+    register WmInfo *wmPtr = winPtr->wmInfoPtr;
+    Tk_PhotoHandle photo;
+    Tk_PhotoImageBlock block;
+    int i, size = 0, width, height, index = 0, x, y, isDefault = 0;
+    long R, G, B, A;
+    long *iconPropertyData;
+    unsigned char *pixelByte;
+
+    if (objc < 4) {
+	Tcl_WrongNumArgs(interp, 2, objv,
+		"window ?-default? image1 ?image2 ...?");
+	return TCL_ERROR;
+    }
+    if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {
+	isDefault = 1;
+	if (objc == 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv,
+		    "window ?-default? image1 ?image2 ...?");
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Iterate over all images to retrieve their sizes, in order to allocate a
+     * buffer large enough to hold all images.
+     */
+
+    for (i = 3 + isDefault; i < objc; i++) {
+	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
+	if (photo == NULL) {
+	    Tcl_AppendResult(interp, "can't use \"", Tcl_GetString(objv[i]),
+		    "\" as iconphoto: not a photo image", NULL);
+	    return TCL_ERROR;
 	}
+	Tk_PhotoGetSize(photo, &width, &height);
+
+	/*
+	 * We need to cardinals for width & height and one cardinal for each
+	 * image pixel.
+	 */
+
+	size += 2 + width * height;
+    }
+
+    /*
+     * We have calculated the size of the data. Try to allocate the needed
+     * memory space.
+     */
+
+#ifdef NOTYET_XXX
+    iconPropertyData = (long *) Tcl_AttemptAlloc(sizeof(long)*size);
+#else
+    iconPropertyData = (long *) ckalloc(sizeof(long)*size);
+#endif
+    if (iconPropertyData == NULL) {
+	return TCL_ERROR;
+    }
+    memset(iconPropertyData, 0, sizeof(long)*size);
+
+    for (i = 3 + isDefault; i < objc; i++) {
+	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
+	if (photo == NULL) {
+	    Tcl_Free((char *) iconPropertyData);
+	    return TCL_ERROR;
+	}
+	Tk_PhotoGetSize(photo, &width, &height);
+	Tk_PhotoGetImage(photo, &block);
+
+	/*
+	 * Each image data will be placed as an array of 32bit packed
+	 * CARDINAL, in a window property named "_NET_WM_ICON": _NET_WM_ICON
+	 *
+	 * _NET_WM_ICON CARDINAL[][2+n]/32
+	 *
+	 * This is an array of possible icons for the client. This spec. does
+	 * not stipulate what size these icons should be, but individual
+	 * desktop environments or toolkits may do so. The Window Manager MAY
+	 * scale any of these icons to an appropriate size.
+	 *
+	 * This is an array of 32bit packed CARDINAL ARGB with high byte being
+	 * A, low byte being B. The first two cardinals are width, height.
+	 * Data is in rows, left to right and top to bottom.
+	 */
+
+	/*
+	 * Encode the image data in the iconPropertyData array.
+	 */
+
+	iconPropertyData[index++] = width;
+	iconPropertyData[index++] = height;
+	for (y = 0; y < height; y++) {
+	    for (x = 0; x < width; x++) {
+		R = *(block.pixelPtr + x*block.pixelSize +
+			y*block.pitch + block.offset[0]);
+		G = *(block.pixelPtr + x*block.pixelSize +
+			y*block.pitch + block.offset[1]);
+		B = *(block.pixelPtr + x*block.pixelSize +
+			y*block.pitch + block.offset[2]);
+		A = *(block.pixelPtr + x*block.pixelSize +
+			y*block.pitch + block.offset[3]);
+		pixelByte = (unsigned char *) &iconPropertyData[index];
+		pixelByte[3] = A;
+		pixelByte[2] = R;
+		pixelByte[1] = G;
+		pixelByte[0] = B;
+		index++;
+	    }
+	}
+    }
+    if (wmPtr->iconDataPtr != NULL) {
+	ckfree((char *)wmPtr->iconDataPtr);
+	wmPtr->iconDataPtr = NULL;
+    }
+    if (isDefault) {
+	if (winPtr->dispPtr->iconDataPtr != NULL) {
+	    ckfree((char *) winPtr->dispPtr->iconDataPtr);
+	}
+	winPtr->dispPtr->iconDataPtr = (unsigned char *) iconPropertyData;
+	winPtr->dispPtr->iconDataSize = size;
+    } else {
+	wmPtr->iconDataPtr = (unsigned char *) iconPropertyData;
+	wmPtr->iconDataSize = size;
+    }
+    if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
+	UpdatePhotoIcon(winPtr);
     }
     return TCL_OK;
 }
@@ -2209,8 +2578,7 @@ WmIconnameCmd(tkwin, winPtr, interp, obj
  *
  * WmIconpositionCmd --
  *
- *	This procedure is invoked to process the "wm iconposition"
- *	Tcl command.
+ *	This function is invoked to process the "wm iconposition" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -2223,12 +2591,12 @@ WmIconnameCmd(tkwin, winPtr, interp, obj
  */
 
 static int
-WmIconpositionCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmIconpositionCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     int x, y;
@@ -2239,11 +2607,8 @@ WmIconpositionCmd(tkwin, winPtr, interp,
     }
     if (objc == 3) {
 	if (wmPtr->hints.flags & IconPositionHint) {
-	    char buf[TCL_INTEGER_SPACE * 2];
-
-	    sprintf(buf, "%d %d", wmPtr->hints.icon_x,
-		    wmPtr->hints.icon_y);
-	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
+	    Tcl_IntResults(interp, 2, 0, wmPtr->hints.icon_x,
+			   wmPtr->hints.icon_y);
 	}
 	return TCL_OK;
     }
@@ -2267,7 +2632,7 @@ WmIconpositionCmd(tkwin, winPtr, interp,
  *
  * WmIconwindowCmd --
  *
- *	This procedure is invoked to process the "wm iconwindow" Tcl command.
+ *	This function is invoked to process the "wm iconwindow" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -2280,12 +2645,12 @@ WmIconpositionCmd(tkwin, winPtr, interp,
  */
 
 static int
-WmIconwindowCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmIconwindowCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     Tk_Window tkwin2;
@@ -2306,13 +2671,12 @@ WmIconwindowCmd(tkwin, winPtr, interp, o
 	wmPtr->hints.flags &= ~IconWindowHint;
 	if (wmPtr->icon != NULL) {
 	    /*
-	     * Remove the icon window relationship.  In principle we
-	     * should also re-enable button events for the window, but
-	     * this doesn't work in general because the window manager
-	     * is probably selecting on them (we'll get an error if
-	     * we try to re-enable the events).  So, just leave the
-	     * icon window event-challenged;  the user will have to
-	     * recreate it if they want button events.
+	     * Remove the icon window relationship. In principle we should
+	     * also re-enable button events for the window, but this doesn't
+	     * work in general because the window manager is probably
+	     * selecting on them (we'll get an error if we try to re-enable
+	     * the events). So, just leave the icon window event-challenged;
+	     * the user will have to recreate it if they want button events.
 	     */
 
 	    wmPtr2 = ((TkWindow *) wmPtr->icon)->wmInfoPtr;
@@ -2327,14 +2691,14 @@ WmIconwindowCmd(tkwin, winPtr, interp, o
 	}
 	if (!Tk_IsTopLevel(tkwin2)) {
 	    Tcl_AppendResult(interp, "can't use ", Tcl_GetString(objv[3]),
-		    " as icon window: not at top level", (char *) NULL);
+		    " as icon window: not at top level", NULL);
 	    return TCL_ERROR;
 	}
 	wmPtr2 = ((TkWindow *) tkwin2)->wmInfoPtr;
 	if (wmPtr2->iconFor != NULL) {
 	    Tcl_AppendResult(interp, Tcl_GetString(objv[3]),
-		    " is already an icon for ",
-		    Tk_PathName(wmPtr2->iconFor), (char *) NULL);
+		    " is already an icon for ", Tk_PathName(wmPtr2->iconFor),
+		    NULL);
 	    return TCL_ERROR;
 	}
 	if (wmPtr->icon != NULL) {
@@ -2345,10 +2709,9 @@ WmIconwindowCmd(tkwin, winPtr, interp, o
 	}
 
 	/*
-	 * Disable button events in the icon window:  some window
-	 * managers (like olvwm) want to get the events themselves,
-	 * but X only allows one application at a time to receive
-	 * button events for a window.
+	 * Disable button events in the icon window: some window managers
+	 * (like olvwm) want to get the events themselves, but X only allows
+	 * one application at a time to receive button events for a window.
 	 */
 
 	atts.event_mask = Tk_Attributes(tkwin2)->event_mask
@@ -2384,8 +2747,8 @@ WmIconwindowCmd(tkwin, winPtr, interp, o
  *
  * WmMaxsizeCmd --
  *
- *	This procedure is invoked to process the "wm maxsize" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm maxsize" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -2397,12 +2760,12 @@ WmIconwindowCmd(tkwin, winPtr, interp, o
  */
 
 static int
-WmMaxsizeCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmMaxsizeCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     int width, height;
@@ -2440,8 +2803,8 @@ WmMaxsizeCmd(tkwin, winPtr, interp, objc
  *
  * WmMinsizeCmd --
  *
- *	This procedure is invoked to process the "wm minsize" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm minsize" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -2453,12 +2816,12 @@ WmMaxsizeCmd(tkwin, winPtr, interp, objc
  */
 
 static int
-WmMinsizeCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmMinsizeCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     int width, height;
@@ -2487,9 +2850,8 @@ WmMinsizeCmd(tkwin, winPtr, interp, objc
  *
  * WmOverrideredirectCmd --
  *
- *	This procedure is invoked to process the "wm overrideredirect"
- *	Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm overrideredirect" Tcl
+ *	command. See the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -2501,12 +2863,12 @@ WmMinsizeCmd(tkwin, winPtr, interp, objc
  */
 
 static int
-WmOverrideredirectCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmOverrideredirectCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     int boolean, curValue;
     XSetWindowAttributes atts;
@@ -2525,9 +2887,10 @@ WmOverrideredirectCmd(tkwin, winPtr, int
     }
     if (curValue != boolean) {
 	/*
-	 * Only do this if we are really changing value, because it
-	 * causes some funky stuff to occur
+	 * Only do this if we are really changing value, because it causes
+	 * some funky stuff to occur
 	 */
+
 	atts.override_redirect = (boolean) ? True : False;
 	atts.save_under = (boolean) ? True : False;
 
@@ -2547,8 +2910,7 @@ WmOverrideredirectCmd(tkwin, winPtr, int
  *
  * WmPositionfromCmd --
  *
- *	This procedure is invoked to process the "wm positionfrom"
- *	Tcl command.
+ *	This function is invoked to process the "wm positionfrom" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -2561,16 +2923,16 @@ WmOverrideredirectCmd(tkwin, winPtr, int
  */
 
 static int
-WmPositionfromCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmPositionfromCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     static CONST char *optionStrings[] = {
-	"program", "user", (char *) NULL };
+	"program", "user", NULL };
     enum options {
 	OPT_PROGRAM, OPT_USER };
     int index;
@@ -2612,8 +2974,8 @@ WmPositionfromCmd(tkwin, winPtr, interp,
  *
  * WmProtocolCmd --
  *
- *	This procedure is invoked to process the "wm protocol" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm protocol" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -2625,12 +2987,12 @@ WmPositionfromCmd(tkwin, winPtr, interp,
  */
 
 static int
-WmProtocolCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmProtocolCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     register ProtocolHandler *protPtr, *prevPtr;
@@ -2646,8 +3008,9 @@ WmProtocolCmd(tkwin, winPtr, interp, obj
 	/*
 	 * Return a list of all defined protocols for the window.
 	 */
+
 	for (protPtr = wmPtr->protPtr; protPtr != NULL;
-	     protPtr = protPtr->nextPtr) {
+		protPtr = protPtr->nextPtr) {
 	    Tcl_AppendElement(interp,
 		    Tk_GetAtomName((Tk_Window) winPtr, protPtr->protocol));
 	}
@@ -2658,8 +3021,9 @@ WmProtocolCmd(tkwin, winPtr, interp, obj
 	/*
 	 * Return the command to handle a given protocol.
 	 */
+
 	for (protPtr = wmPtr->protPtr; protPtr != NULL;
-	     protPtr = protPtr->nextPtr) {
+		protPtr = protPtr->nextPtr) {
 	    if (protPtr->protocol == protocol) {
                 Tcl_SetObjResult(interp,LangCallbackObj(protPtr->command));
 		return TCL_OK;
@@ -2669,13 +3033,12 @@ WmProtocolCmd(tkwin, winPtr, interp, obj
     }
 
     /*
-     * Delete any current protocol handler, then create a new
-     * one with the specified command, unless the command is
-     * empty.
+     * Delete any current protocol handler, then create a new one with the
+     * specified command, unless the command is empty.
      */
 
     for (protPtr = wmPtr->protPtr, prevPtr = NULL; protPtr != NULL;
-	 prevPtr = protPtr, protPtr = protPtr->nextPtr) {
+	    prevPtr = protPtr, protPtr = protPtr->nextPtr) {
 	if (protPtr->protocol == protocol) {
 	    if (prevPtr == NULL) {
 		wmPtr->protPtr = protPtr->nextPtr;
@@ -2714,7 +3077,7 @@ WmProtocolCmd(tkwin, winPtr, interp, obj
  *
  * WmResizableCmd --
  *
- *	This procedure is invoked to process the "wm resizable" Tcl command.
+ *	This function is invoked to process the "wm resizable" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -2727,12 +3090,12 @@ WmProtocolCmd(tkwin, winPtr, interp, obj
  */
 
 static int
-WmResizableCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmResizableCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     int width, height;
@@ -2742,12 +3105,9 @@ WmResizableCmd(tkwin, winPtr, interp, ob
 	return TCL_ERROR;
     }
     if (objc == 3) {
-	char buf[TCL_INTEGER_SPACE * 2];
-
-	sprintf(buf, "%d %d",
-		(wmPtr->flags  & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
-		(wmPtr->flags  & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
-	Tcl_SetResult(interp, buf, TCL_VOLATILE);
+	Tcl_IntResults(interp, 2, 0,
+		       (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) ? 0 : 1,
+		       (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) ? 0 : 1);
 	return TCL_OK;
     }
     if ((Tcl_GetBooleanFromObj(interp, objv[3], &width) != TCL_OK)
@@ -2774,8 +3134,8 @@ WmResizableCmd(tkwin, winPtr, interp, ob
  *
  * WmSizefromCmd --
  *
- *	This procedure is invoked to process the "wm sizefrom" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm sizefrom" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -2787,16 +3147,16 @@ WmResizableCmd(tkwin, winPtr, interp, ob
  */
 
 static int
-WmSizefromCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmSizefromCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     static CONST char *optionStrings[] = {
-	"program", "user", (char *) NULL };
+	"program", "user", NULL };
     enum options {
 	OPT_PROGRAM, OPT_USER };
     int index;
@@ -2839,7 +3199,7 @@ WmSizefromCmd(tkwin, winPtr, interp, obj
  *
  * WmStackorderCmd --
  *
- *	This procedure is invoked to process the "wm stackorder" Tcl command.
+ *	This function is invoked to process the "wm stackorder" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -2852,16 +3212,16 @@ WmSizefromCmd(tkwin, winPtr, interp, obj
  */
 
 static int
-WmStackorderCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmStackorderCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     TkWindow **windows, **window_ptr;
     static CONST char *optionStrings[] = {
-	"isabove", "isbelow", (char *) NULL };
+	"isabove", "isbelow", NULL };
     enum options {
 	OPT_ISABOVE, OPT_ISBELOW };
     int index;
@@ -2874,7 +3234,7 @@ WmStackorderCmd(tkwin, winPtr, interp, o
     if (objc == 3) {
 	windows = TkWmStackorderToplevel(winPtr);
 	if (windows == NULL) {
-	    panic("TkWmStackorderToplevel failed");
+	    Tcl_Panic("TkWmStackorderToplevel failed");
 	} else {
 	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
 		Tcl_AppendElement(interp, (*window_ptr)->pathName);
@@ -2893,45 +3253,47 @@ WmStackorderCmd(tkwin, winPtr, interp, o
 
 	if (!Tk_IsTopLevel(winPtr2)) {
 	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
-		    "\" isn't a top-level window", (char *) NULL);
+		    "\" isn't a top-level window", NULL);
 	    return TCL_ERROR;
 	}
 
 	if (!Tk_IsMapped(winPtr)) {
 	    Tcl_AppendResult(interp, "window \"", winPtr->pathName,
-		    "\" isn't mapped", (char *) NULL);
+		    "\" isn't mapped", NULL);
 	    return TCL_ERROR;
 	}
 
 	if (!Tk_IsMapped(winPtr2)) {
 	    Tcl_AppendResult(interp, "window \"", winPtr2->pathName,
-		    "\" isn't mapped", (char *) NULL);
+		    "\" isn't mapped", NULL);
 	    return TCL_ERROR;
 	}
 
 	/*
-	 * Lookup stacking order of all toplevels that are children
-	 * of "." and find the position of winPtr and winPtr2
-	 * in the stacking order.
+	 * Lookup stacking order of all toplevels that are children of "." and
+	 * find the position of winPtr and winPtr2 in the stacking order.
 	 */
 
 	windows = TkWmStackorderToplevel(winPtr->mainPtr->winPtr);
 
 	if (windows == NULL) {
-	    Tcl_AppendResult(interp, "TkWmStackorderToplevel failed",
-                    (char *) NULL);
+	    Tcl_AppendResult(interp, "TkWmStackorderToplevel failed", NULL);
 	    return TCL_ERROR;
 	} else {
 	    for (window_ptr = windows; *window_ptr ; window_ptr++) {
-		if (*window_ptr == winPtr)
+		if (*window_ptr == winPtr) {
 		    index1 = (window_ptr - windows);
-		if (*window_ptr == winPtr2)
+		}
+		if (*window_ptr == winPtr2) {
 		    index2 = (window_ptr - windows);
+		}
+	    }
+	    if (index1 == -1) {
+		Tcl_Panic("winPtr window not found");
+	    }
+	    if (index2 == -1) {
+		Tcl_Panic("winPtr2 window not found");
 	    }
-	    if (index1 == -1)
-		panic("winPtr window not found");
-	    if (index2 == -1)
-		panic("winPtr2 window not found");
 
 	    ckfree((char *) windows);
 	}
@@ -2956,8 +3318,8 @@ WmStackorderCmd(tkwin, winPtr, interp, o
  *
  * WmStateCmd --
  *
- *	This procedure is invoked to process the "wm state" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm state" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -2969,16 +3331,16 @@ WmStackorderCmd(tkwin, winPtr, interp, o
  */
 
 static int
-WmStateCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmStateCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     static CONST char *optionStrings[] = {
-	"normal", "iconic", "withdrawn", (char *) NULL };
+	"normal", "iconic", "withdrawn", NULL };
     enum options {
 	OPT_NORMAL, OPT_ICONIC, OPT_WITHDRAWN };
     int index;
@@ -2990,9 +3352,8 @@ WmStateCmd(tkwin, winPtr, interp, objc, 
     if (objc == 4) {
 	if (wmPtr->iconFor != NULL) {
 	    Tcl_AppendResult(interp, "can't change state of ",
-		    Tcl_GetString(objv[2]),
-		    ": it is an icon for ", Tk_PathName(wmPtr->iconFor),
-		    (char *) NULL);
+		    Tcl_GetString(objv[2]), ": it is an icon for ",
+		    Tk_PathName(wmPtr->iconFor), NULL);
 	    return TCL_ERROR;
 	}
 
@@ -3006,16 +3367,13 @@ WmStateCmd(tkwin, winPtr, interp, objc, 
 	    (void) TkpWmSetState(winPtr, NormalState);
 	} else if (index == OPT_ICONIC) {
 	    if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) {
-		Tcl_AppendResult(interp, "can't iconify \"",
-			winPtr->pathName,
-			"\": override-redirect flag is set",
-			(char *) NULL);
+		Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
+			"\": override-redirect flag is set", NULL);
 		return TCL_ERROR;
 	    }
 	    if (wmPtr->masterPtr != NULL) {
-		Tcl_AppendResult(interp, "can't iconify \"",
-			winPtr->pathName,
-			"\": it is a transient", (char *) NULL);
+		Tcl_AppendResult(interp, "can't iconify \"", winPtr->pathName,
+			"\": it is a transient", NULL);
 		return TCL_ERROR;
 	    }
 	    if (TkpWmSetState(winPtr, IconicState) == 0) {
@@ -3054,8 +3412,8 @@ WmStateCmd(tkwin, winPtr, interp, objc, 
  *
  * WmTitleCmd --
  *
- *	This procedure is invoked to process the "wm title" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm title" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -3067,12 +3425,12 @@ WmStateCmd(tkwin, winPtr, interp, objc, 
  */
 
 static int
-WmTitleCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmTitleCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     char *argv3;
@@ -3096,19 +3454,7 @@ WmTitleCmd(tkwin, winPtr, interp, objc, 
 	strcpy(wmPtr->title, argv3);
 
 	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
-	    XTextProperty textProp;
-	    Tcl_DString ds;
-            char *string;
-
-	    Tcl_UtfToExternalDString(NULL, wmPtr->title, -1, &ds);
-            string = Tcl_DStringValue(&ds);
-	    if (XStringListToTextProperty(&string, 1,
-		    &textProp)  != 0) {
-		XSetWMName(winPtr->display, wmPtr->wrapperPtr->window,
-			&textProp);
-		XFree((char *) textProp.value);
-	    }
-	    Tcl_DStringFree(&ds);
+	    UpdateTitle(winPtr);
 	}
     }
     return TCL_OK;
@@ -3119,7 +3465,7 @@ WmTitleCmd(tkwin, winPtr, interp, objc, 
  *
  * WmTransientCmd --
  *
- *	This procedure is invoked to process the "wm transient" Tcl command.
+ *	This function is invoked to process the "wm transient" Tcl command.
  *	See the user documentation for details on what it does.
  *
  * Results:
@@ -3132,12 +3478,12 @@ WmTitleCmd(tkwin, winPtr, interp, objc, 
  */
 
 static int
-WmTransientCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmTransientCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     TkWindow *masterPtr = wmPtr->masterPtr;
@@ -3157,18 +3503,19 @@ WmTransientCmd(tkwin, winPtr, interp, ob
     if (Tcl_GetString(objv[3])[0] == '\0') {
 	if (masterPtr != NULL) {
 	    /*
-	     * If we had a master, tell them that we aren't tied
-	     * to them anymore
+	     * If we had a master, tell them that we aren't tied to them
+	     * anymore
 	     */
 
 	    masterPtr->wmInfoPtr->numTransients--;
-	    Tk_DeleteEventHandler((Tk_Window) masterPtr,
-		    StructureNotifyMask,
+	    Tk_DeleteEventHandler((Tk_Window) masterPtr, StructureNotifyMask,
 		    WmWaitMapProc, (ClientData) winPtr);
 
-	    /* FIXME: Need a call like Win32's UpdateWrapper() so
-	       we can recreate the wrapper and get rid of the
-	       transient window decorations. */
+	    /*
+	     * FIXME: Need a call like Win32's UpdateWrapper() so we can
+	     * recreate the wrapper and get rid of the transient window
+	     * decorations.
+	     */
 	}
 
 	wmPtr->masterPtr = NULL;
@@ -3187,11 +3534,9 @@ WmTransientCmd(tkwin, winPtr, interp, ob
 	Tk_MakeWindowExist((Tk_Window) masterPtr);
 
 	if (wmPtr->iconFor != NULL) {
-	    Tcl_AppendResult(interp, "can't make \"",
-		    Tcl_GetString(objv[2]),
+	    Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[2]),
 		    "\" a transient: it is an icon for ",
-		    Tk_PathName(wmPtr->iconFor),
-		    (char *) NULL);
+		    Tk_PathName(wmPtr->iconFor), NULL);
 	    return TCL_ERROR;
 	}
 
@@ -3201,24 +3546,21 @@ WmTransientCmd(tkwin, winPtr, interp, ob
 	}
 
 	if (wmPtr2->iconFor != NULL) {
-	    Tcl_AppendResult(interp, "can't make \"",
-		    Tcl_GetString(objv[3]),
+	    Tcl_AppendResult(interp, "can't make \"", Tcl_GetString(objv[3]),
 		    "\" a master: it is an icon for ",
-		    Tk_PathName(wmPtr2->iconFor),
-		    (char *) NULL);
+		    Tk_PathName(wmPtr2->iconFor), NULL);
 	    return TCL_ERROR;
 	}
 
 	if (masterPtr == winPtr) {
 	    Tcl_AppendResult(interp, "can't make \"", Tk_PathName(winPtr),
-		    "\" its own master",
-		    (char *) NULL);
+		    "\" its own master", NULL);
 	    return TCL_ERROR;
 	} else if (masterPtr != wmPtr->masterPtr) {
 	    /*
-	     * Remove old master map/unmap binding before setting
-	     * the new master. The event handler will ensure that
-	     * transient states reflect the state of the master.
+	     * Remove old master map/unmap binding before setting the new
+	     * master. The event handler will ensure that transient states
+	     * reflect the state of the master.
 	     */
 
 	    if (wmPtr->masterPtr != NULL) {
@@ -3230,8 +3572,7 @@ WmTransientCmd(tkwin, winPtr, interp, ob
 
 	    masterPtr->wmInfoPtr->numTransients++;
 	    Tk_CreateEventHandler((Tk_Window) masterPtr,
-		    StructureNotifyMask,
-		    WmWaitMapProc, (ClientData) winPtr);
+		    StructureNotifyMask, WmWaitMapProc, (ClientData) winPtr);
 
 	    wmPtr->masterPtr = masterPtr;
 	}
@@ -3245,10 +3586,14 @@ WmTransientCmd(tkwin, winPtr, interp, ob
 		return TCL_ERROR;
 	    }
 	} else {
-	    Window xwin = (wmPtr->masterPtr == NULL) ? None :
-		    wmPtr->masterPtr->wmInfoPtr->wrapperPtr->window;
-	    XSetTransientForHint(winPtr->display, wmPtr->wrapperPtr->window,
-		    xwin);
+	    if (wmPtr->masterPtr != NULL) {
+		XSetTransientForHint(winPtr->display,
+			wmPtr->wrapperPtr->window,
+			wmPtr->masterPtr->wmInfoPtr->wrapperPtr->window);
+	    } else {
+		XDeleteProperty(winPtr->display, wmPtr->wrapperPtr->window,
+			Tk_InternAtom((Tk_Window)winPtr, "WM_TRANSIENT_FOR"));
+	    }
 	}
     }
     return TCL_OK;
@@ -3259,8 +3604,8 @@ WmTransientCmd(tkwin, winPtr, interp, ob
  *
  * WmWithdrawCmd --
  *
- *	This procedure is invoked to process the "wm withdraw" Tcl command.
- *	See the user documentation for details on what it does.
+ *	This function is invoked to process the "wm withdraw" Tcl command. See
+ *	the user documentation for details on what it does.
  *
  * Results:
  *	A standard Tcl result.
@@ -3272,12 +3617,12 @@ WmTransientCmd(tkwin, winPtr, interp, ob
  */
 
 static int
-WmWithdrawCmd(tkwin, winPtr, interp, objc, objv)
-    Tk_Window tkwin;		/* Main window of the application. */
-    TkWindow *winPtr;           /* Toplevel to work with */
-    Tcl_Interp *interp;		/* Current interpreter. */
-    int objc;			/* Number of arguments. */
-    Tcl_Obj *CONST objv[];	/* Argument objects. */
+WmWithdrawCmd(
+    Tk_Window tkwin,		/* Main window of the application. */
+    TkWindow *winPtr,		/* Toplevel to work with */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *CONST objv[])	/* Argument objects. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
 
@@ -3287,8 +3632,7 @@ WmWithdrawCmd(tkwin, winPtr, interp, obj
     }
     if (wmPtr->iconFor != NULL) {
 	Tcl_AppendResult(interp, "can't withdraw ", Tcl_GetString(objv[2]),
-		": it is an icon for ", Tk_PathName(wmPtr->iconFor),
-		(char *) NULL);
+		": it is an icon for ", Tk_PathName(wmPtr->iconFor), NULL);
 	return TCL_ERROR;
     }
     wmPtr->flags |= WM_WITHDRAWN;
@@ -3302,13 +3646,14 @@ WmWithdrawCmd(tkwin, winPtr, interp, obj
 }
 
 /*
- * Invoked by those wm subcommands that affect geometry.
- * Schedules a geometry update.
+ * Invoked by those wm subcommands that affect geometry. Schedules a geometry
+ * update.
  */
+
 static void
-WmUpdateGeom(wmPtr, winPtr)
-    WmInfo *wmPtr;
-    TkWindow *winPtr;
+WmUpdateGeom(
+    WmInfo *wmPtr,
+    TkWindow *winPtr)
 {
     if (!(wmPtr->flags & (WM_UPDATE_PENDING|WM_NEVER_MAPPED))) {
 	Tcl_DoWhenIdle(UpdateGeometryInfo, (ClientData) winPtr);
@@ -3317,25 +3662,28 @@ WmUpdateGeom(wmPtr, winPtr)
 }
 
 /*
- * Invoked when a MapNotify or UnmapNotify event is delivered for a
- * toplevel that is the master of a transient toplevel.
+ * Invoked when a MapNotify or UnmapNotify event is delivered for a toplevel
+ * that is the master of a transient toplevel.
  */
+
 static void
-WmWaitMapProc(clientData, eventPtr)
-    ClientData clientData;	/* Pointer to window. */
-    XEvent *eventPtr;		/* Information about event. */
+WmWaitMapProc(
+    ClientData clientData,	/* Pointer to window. */
+    XEvent *eventPtr)		/* Information about event. */
 {
     TkWindow *winPtr = (TkWindow *) clientData;
     TkWindow *masterPtr = winPtr->wmInfoPtr->masterPtr;
 
-    if (masterPtr == NULL)
-        return;
+    if (masterPtr == NULL) {
+	return;
+    }
 
     if (eventPtr->type == MapNotify) {
-        if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN))
-            (void) TkpWmSetState(winPtr, NormalState);
+	if (!(winPtr->wmInfoPtr->flags & WM_WITHDRAWN)) {
+	    (void) TkpWmSetState(winPtr, NormalState);
+	}
     } else if (eventPtr->type == UnmapNotify) {
-        (void) TkpWmSetState(winPtr, WithdrawnState);
+	(void) TkpWmSetState(winPtr, WithdrawnState);
     }
 }
 
@@ -3344,39 +3692,50 @@ WmWaitMapProc(clientData, eventPtr)
  *
  * Tk_SetGrid --
  *
- *	This procedure is invoked by a widget when it wishes to set a grid
- *	coordinate system that controls the size of a top-level window.
- *	It provides a C interface equivalent to the "wm grid" command and
- *	is usually asscoiated with the -setgrid option.
+ *	This function is invoked by a widget when it wishes to set a grid
+ *	coordinate system that controls the size of a top-level window. It
+ *	provides a C interface equivalent to the "wm grid" command and is
+ *	usually asscoiated with the -setgrid option.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	Grid-related information will be passed to the window manager, so
- *	that the top-level window associated with tkwin will resize on
- *	even grid units.  If some other window already controls gridding
- *	for the top-level window then this procedure call has no effect.
+ *	Grid-related information will be passed to the window manager, so that
+ *	the top-level window associated with tkwin will resize on even grid
+ *	units. If some other window already controls gridding for the
+ *	top-level window then this function call has no effect.
  *
  *----------------------------------------------------------------------
  */
 
 void
-Tk_SetGrid(tkwin, reqWidth, reqHeight, widthInc, heightInc)
-    Tk_Window tkwin;		/* Token for window.  New window mgr info
-				 * will be posted for the top-level window
+Tk_SetGrid(
+    Tk_Window tkwin,		/* Token for window. New window mgr info will
+				 * be posted for the top-level window
 				 * associated with this window. */
-    int reqWidth;		/* Width (in grid units) corresponding to
-				 * the requested geometry for tkwin. */
-    int reqHeight;		/* Height (in grid units) corresponding to
-				 * the requested geometry for tkwin. */
-    int widthInc, heightInc;	/* Pixel increments corresponding to a
-				 * change of one grid unit. */
+    int reqWidth,		/* Width (in grid units) corresponding to the
+				 * requested geometry for tkwin. */
+    int reqHeight,		/* Height (in grid units) corresponding to the
+				 * requested geometry for tkwin. */
+    int widthInc, int heightInc)/* Pixel increments corresponding to a change
+				 * of one grid unit. */
 {
     TkWindow *winPtr = (TkWindow *) tkwin;
     register WmInfo *wmPtr;
 
     /*
+     * Ensure widthInc and heightInc are greater than 0
+     */
+
+    if (widthInc <= 0) {
+	widthInc = 1;
+    }
+    if (heightInc <= 0) {
+	heightInc = 1;
+    }
+
+    /*
      * Find the top-level window for tkwin, plus the window manager
      * information.
      */
@@ -3410,15 +3769,15 @@ Tk_SetGrid(tkwin, reqWidth, reqHeight, w
     }
 
     /*
-     * If gridding was previously off, then forget about any window
-     * size requests made by the user or via "wm geometry":  these are
-     * in pixel units and there's no easy way to translate them to
-     * grid units since the new requested size of the top-level window in
-     * pixels may not yet have been registered yet (it may filter up
-     * the hierarchy in DoWhenIdle handlers).  However, if the window
-     * has never been mapped yet then just leave the window size alone:
-     * assume that it is intended to be in grid units but just happened
-     * to have been specified before this procedure was called.
+     * If gridding was previously off, then forget about any window size
+     * requests made by the user or via "wm geometry": these are in pixel
+     * units and there's no easy way to translate them to grid units since the
+     * new requested size of the top-level window in pixels may not yet have
+     * been registered yet (it may filter up the hierarchy in DoWhenIdle
+     * handlers). However, if the window has never been mapped yet then just
+     * leave the window size alone: assume that it is intended to be in grid
+     * units but just happened to have been specified before this function was
+     * called.
      */
 
     if ((wmPtr->gridWin == NULL) && !(wmPtr->flags & WM_NEVER_MAPPED)) {
@@ -3427,8 +3786,8 @@ Tk_SetGrid(tkwin, reqWidth, reqHeight, w
     }
 
     /*
-     * Set the new gridding information, and start the process of passing
-     * all of this information to the window manager.
+     * Set the new gridding information, and start the process of passing all
+     * of this information to the window manager.
      */
 
     wmPtr->gridWin = tkwin;
@@ -3449,23 +3808,22 @@ Tk_SetGrid(tkwin, reqWidth, reqHeight, w
  *
  * Tk_UnsetGrid --
  *
- *	This procedure cancels the effect of a previous call
- *	to Tk_SetGrid.
+ *	This function cancels the effect of a previous call to Tk_SetGrid.
  *
  * Results:
  *	None.
  *
  * Side effects:
  *	If tkwin currently controls gridding for its top-level window,
- *	gridding is cancelled for that top-level window;  if some other
- *	window controls gridding then this procedure has no effect.
+ *	gridding is cancelled for that top-level window; if some other window
+ *	controls gridding then this function has no effect.
  *
  *----------------------------------------------------------------------
  */
 
 void
-Tk_UnsetGrid(tkwin)
-    Tk_Window tkwin;		/* Token for window that is currently
+Tk_UnsetGrid(
+    Tk_Window tkwin)		/* Token for window that is currently
 				 * controlling gridding. */
 {
     TkWindow *winPtr = (TkWindow *) tkwin;
@@ -3518,24 +3876,25 @@ Tk_UnsetGrid(tkwin)
  *
  * ConfigureEvent --
  *
- *	This procedure is called to handle ConfigureNotify events on
- *	wrapper windows.
+ *	This function is called to handle ConfigureNotify events on wrapper
+ *	windows.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	Information gets updated in the WmInfo structure for the window
- *	and the toplevel itself gets repositioned within the wrapper.
+ *	Information gets updated in the WmInfo structure for the window and
+ *	the toplevel itself gets repositioned within the wrapper.
  *
  *----------------------------------------------------------------------
  */
 
 static void
-ConfigureEvent(wmPtr, configEventPtr)
-    WmInfo *wmPtr;			/* Information about toplevel window. */
-    XConfigureEvent *configEventPtr;	/* Event that just occurred for
-					 * wmPtr->wrapperPtr. */
+ConfigureEvent(
+    WmInfo *wmPtr,		/* Information about toplevel window. */
+    XConfigureEvent *configEventPtr)
+				/* Event that just occurred for
+				 * wmPtr->wrapperPtr. */
 {
     TkWindow *wrapperPtr = wmPtr->wrapperPtr;
     TkWindow *winPtr = wmPtr->winPtr;
@@ -3543,21 +3902,21 @@ ConfigureEvent(wmPtr, configEventPtr)
     Tk_ErrorHandler handler;
 
     /*
-     * Update size information from the event.  There are a couple of
-     * tricky points here:
+     * Update size information from the event. There are a couple of tricky
+     * points here:
      *
-     * 1. If the user changed the size externally then set wmPtr->width
-     *    and wmPtr->height just as if a "wm geometry" command had been
-     *    invoked with the same information.
-     * 2. However, if the size is changing in response to a request
-     *    coming from us (WM_SYNC_PENDING is set), then don't set wmPtr->width
-     *    or wmPtr->height if they were previously -1 (otherwise the
-     *    window will stop tracking geometry manager requests).
+     * 1. If the user changed the size externally then set wmPtr->width and
+     *    wmPtr->height just as if a "wm geometry" command had been invoked
+     *    with the same information.
+     * 2. However, if the size is changing in response to a request coming
+     *    from us (WM_SYNC_PENDING is set), then don't set wmPtr->width or
+     *    wmPtr->height if they were previously -1 (otherwise the window will
+     *    stop tracking geometry manager requests).
      */
 
     if (((wrapperPtr->changes.width != configEventPtr->width)
 	    || (wrapperPtr->changes.height != configEventPtr->height))
-	    && !(wmPtr->flags & WM_SYNC_PENDING)){
+	    && !(wmPtr->flags & WM_SYNC_PENDING)) {
 	if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
 	    printf("TopLevelEventProc: user changed %s size to %dx%d\n",
 		    winPtr->pathName, configEventPtr->width,
@@ -3566,17 +3925,17 @@ ConfigureEvent(wmPtr, configEventPtr)
 	if ((wmPtr->width == -1)
 		&& (configEventPtr->width == winPtr->reqWidth)) {
 	    /*
-	     * Don't set external width, since the user didn't change it
-	     * from what the widgets asked for.
+	     * Don't set external width, since the user didn't change it from
+	     * what the widgets asked for.
 	     */
 	} else {
 	    /*
 	     * Note: if this window is embedded then don't set the external
 	     * size, since it came from the containing application, not the
-	     * user.  In this case we want to keep sending our size requests
-	     * to the containing application;  if the user fixes the size
-	     * of that application then it will still percolate down to us
-	     * in the right way.
+	     * user. In this case we want to keep sending our size requests to
+	     * the containing application; if the user fixes the size of that
+	     * application then it will still percolate down to us in the
+	     * right way.
 	     */
 
 	    if (!(winPtr->flags & TK_EMBEDDED)) {
@@ -3596,13 +3955,13 @@ ConfigureEvent(wmPtr, configEventPtr)
 		&& (configEventPtr->height ==
 			(winPtr->reqHeight + wmPtr->menuHeight))) {
 	    /*
-	     * Don't set external height, since the user didn't change it
-	     * from what the widgets asked for.
+	     * Don't set external height, since the user didn't change it from
+	     * what the widgets asked for.
 	     */
 	} else {
 	    /*
-	     * See note for wmPtr->width about not setting external size
-	     * for embedded windows.
+	     * See note for wmPtr->width about not setting external size for
+	     * embedded windows.
 	     */
 
 	    if (!(winPtr->flags & TK_EMBEDDED)) {
@@ -3616,7 +3975,7 @@ ConfigureEvent(wmPtr, configEventPtr)
 		} else {
 		    wmPtr->height = configEventPtr->height - wmPtr->menuHeight;
 		}
-            }
+	    }
 	}
 	wmPtr->configWidth = configEventPtr->width;
 	wmPtr->configHeight = configEventPtr->height;
@@ -3637,19 +3996,17 @@ ConfigureEvent(wmPtr, configEventPtr)
     wrapperPtr->changes.stack_mode = Above;
 
     /*
-     * Reparenting window managers make life difficult.  If the
-     * window manager reparents a top-level window then the x and y
-     * information that comes in events for the window is wrong:
-     * it gives the location of the window inside its decorative
-     * parent, rather than the location of the window in root
-     * coordinates, which is what we want.  Window managers
-     * are supposed to send synthetic events with the correct
-     * information, but ICCCM doesn't require them to do this
-     * under all conditions, and the information provided doesn't
-     * include everything we need here.  So, the code below
-     * maintains a bunch of information about the parent window.
-     * If the window hasn't been reparented, we pretend that
-     * there is a parent shrink-wrapped around the window.
+     * Reparenting window managers make life difficult. If the window manager
+     * reparents a top-level window then the x and y information that comes in
+     * events for the window is wrong: it gives the location of the window
+     * inside its decorative parent, rather than the location of the window in
+     * root coordinates, which is what we want. Window managers are supposed
+     * to send synthetic events with the correct information, but ICCCM
+     * doesn't require them to do this under all conditions, and the
+     * information provided doesn't include everything we need here. So, the
+     * code below maintains a bunch of information about the parent window.
+     * If the window hasn't been reparented, we pretend that there is a parent
+     * shrink-wrapped around the window.
      */
 
     if (dispPtr->flags & TK_DISPLAY_WM_TRACING) {
@@ -3675,11 +4032,11 @@ ConfigureEvent(wmPtr, configEventPtr)
 
     /*
      * Make sure that the toplevel and menubar are properly positioned within
-     * the wrapper.  If the menuHeight happens to be zero, we'll get a
-     * BadValue X error that we want to ignore [Bug: 3377]
+     * the wrapper. If the menuHeight happens to be zero, we'll get a BadValue
+     * X error that we want to ignore [Bug: 3377]
      */
-    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
-	    (Tk_ErrorProc *) NULL, (ClientData) NULL);
+
+    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, NULL, NULL);
     XMoveResizeWindow(winPtr->display, winPtr->window, 0,
 	    wmPtr->menuHeight, (unsigned) wrapperPtr->changes.width,
 	    (unsigned) (wrapperPtr->changes.height - wmPtr->menuHeight));
@@ -3693,9 +4050,9 @@ ConfigureEvent(wmPtr, configEventPtr)
 
     /*
      * Update the coordinates in the toplevel (they should refer to the
-     * position in root window coordinates, not the coordinates of the
-     * wrapper window).  Then synthesize a ConfigureNotify event to tell
-     * the application about the change.
+     * position in root window coordinates, not the coordinates of the wrapper
+     * window). Then synthesize a ConfigureNotify event to tell the
+     * application about the change.
      */
 
     winPtr->changes.x = wrapperPtr->changes.x;
@@ -3710,8 +4067,8 @@ ConfigureEvent(wmPtr, configEventPtr)
  *
  * ReparentEvent --
  *
- *	This procedure is called to handle ReparentNotify events on
- *	wrapper windows.
+ *	This function is called to handle ReparentNotify events on wrapper
+ *	windows.
  *
  * Results:
  *	None.
@@ -3723,10 +4080,11 @@ ConfigureEvent(wmPtr, configEventPtr)
  */
 
 static void
-ReparentEvent(wmPtr, reparentEventPtr)
-    WmInfo *wmPtr;			/* Information about toplevel window. */
-    XReparentEvent *reparentEventPtr;	/* Event that just occurred for
-					 * wmPtr->wrapperPtr. */
+ReparentEvent(
+    WmInfo *wmPtr,		/* Information about toplevel window. */
+    XReparentEvent *reparentEventPtr)
+				/* Event that just occurred for
+				 * wmPtr->wrapperPtr. */
 {
     TkWindow *wrapperPtr = wmPtr->wrapperPtr;
     Window vRoot, ancestor, *children, dummy2, *virtualRootPtr;
@@ -3738,17 +4096,16 @@ ReparentEvent(wmPtr, reparentEventPtr)
     TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;
 
     /*
-     * Identify the root window for wrapperPtr.  This is tricky because of
-     * virtual root window managers like tvtwm.  If the window has a
-     * property named __SWM_ROOT or __WM_ROOT then this property gives
-     * the id for a virtual root window that should be used instead of
-     * the root window of the screen.
+     * Identify the root window for wrapperPtr. This is tricky because of
+     * virtual root window managers like tvtwm. If the window has a property
+     * named __SWM_ROOT or __WM_ROOT then this property gives the id for a
+     * virtual root window that should be used instead of the root window of
+     * the screen.
      */
 
     vRoot = RootWindow(wrapperPtr->display, wrapperPtr->screenNum);
     wmPtr->vRoot = None;
-    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1, -1, -1,
-	    (Tk_ErrorProc *) NULL, (ClientData) NULL);
+    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1,-1,-1, NULL,NULL);
     if (((XGetWindowProperty(wrapperPtr->display, wrapperPtr->window,
 	    Tk_InternAtom((Tk_Window) wrapperPtr, "__WM_ROOT"), 0, (long) 1,
 	    False, XA_WINDOW, &actualType, &actualFormat, &numItems,
@@ -3783,12 +4140,12 @@ ReparentEvent(wmPtr, reparentEventPtr)
     UpdateVRootGeometry(wmPtr);
 
     /*
-     * If the window's new parent is the root window, then mark it as
-     * no longer reparented.
+     * If the window's new parent is the root window, then mark it as no
+     * longer reparented.
      */
 
     if (reparentEventPtr->parent == vRoot) {
-	noReparent:
+    noReparent:
 	wmPtr->reparent = None;
 	wmPtr->parentWidth = wrapperPtr->changes.width;
 	wmPtr->parentHeight = wrapperPtr->changes.height;
@@ -3801,17 +4158,15 @@ ReparentEvent(wmPtr, reparentEventPtr)
     }
 
     /*
-     * Search up the window hierarchy to find the ancestor of this
-     * window that is just below the (virtual) root.  This is tricky
-     * because it's possible that things have changed since the event
-     * was generated so that the ancestry indicated by the event no
-     * longer exists.  If this happens then an error will occur and
-     * we just discard the event (there will be a more up-to-date
-     * ReparentNotify event coming later).
+     * Search up the window hierarchy to find the ancestor of this window that
+     * is just below the (virtual) root. This is tricky because it's possible
+     * that things have changed since the event was generated so that the
+     * ancestry indicated by the event no longer exists. If this happens then
+     * an error will occur and we just discard the event (there will be a more
+     * up-to-date ReparentNotify event coming later).
      */
 
-    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1, -1, -1,
-	    (Tk_ErrorProc *) NULL, (ClientData) NULL);
+    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1,-1,-1, NULL,NULL);
     wmPtr->reparent = reparentEventPtr->parent;
     while (1) {
 	if (XQueryTree(wrapperPtr->display, wmPtr->reparent, &dummy2,
@@ -3839,28 +4194,26 @@ ReparentEvent(wmPtr, reparentEventPtr)
  *
  * ComputeReparentGeometry --
  *
- *	This procedure is invoked to recompute geometry information
- *	related to a reparented top-level window, such as the position
- *	and total size of the parent and the position within it of
- *	the top-level window.
+ *	This function is invoked to recompute geometry information related to
+ *	a reparented top-level window, such as the position and total size of
+ *	the parent and the position within it of the top-level window.
  *
  * Results:
- *	The return value is 1 if everything completed successfully
- *	and 0 if an error occurred while querying information about
- *	winPtr's parents.  In this case winPtr is marked as no longer
- *	being reparented.
+ *	The return value is 1 if everything completed successfully and 0 if an
+ *	error occurred while querying information about winPtr's parents. In
+ *	this case winPtr is marked as no longer being reparented.
  *
  * Side effects:
- *	Geometry information in wmPtr, wmPtr->winPtr, and
- *	wmPtr->wrapperPtr gets updated.
+ *	Geometry information in wmPtr, wmPtr->winPtr, and wmPtr->wrapperPtr
+ *	gets updated.
  *
  *----------------------------------------------------------------------
  */
 
 static int
-ComputeReparentGeometry(wmPtr)
-    WmInfo *wmPtr;		/* Information about toplevel window
-				 * whose reparent info is to be recomputed. */
+ComputeReparentGeometry(
+    WmInfo *wmPtr)		/* Information about toplevel window whose
+				 * reparent info is to be recomputed. */
 {
     TkWindow *wrapperPtr = wmPtr->wrapperPtr;
     int width, height, bd;
@@ -3871,8 +4224,7 @@ ComputeReparentGeometry(wmPtr)
     Tk_ErrorHandler handler;
     TkDisplay *dispPtr = wmPtr->winPtr->dispPtr;
 
-    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1, -1, -1,
-	    (Tk_ErrorProc *) NULL, (ClientData) NULL);
+    handler = Tk_CreateErrorHandler(wrapperPtr->display, -1,-1,-1, NULL,NULL);
     (void) XTranslateCoordinates(wrapperPtr->display, wrapperPtr->window,
 	    wmPtr->reparent, 0, 0, &xOffset, &yOffset, &dummy2);
     status = XGetGeometry(wrapperPtr->display, wmPtr->reparent,
@@ -3881,10 +4233,10 @@ ComputeReparentGeometry(wmPtr)
     Tk_DeleteErrorHandler(handler);
     if (status == 0) {
 	/*
-	 * It appears that the reparented parent went away and
-	 * no-one told us.  Reset the window to indicate that
-	 * it's not reparented.
+	 * It appears that the reparented parent went away and no-one told us.
+	 * Reset the window to indicate that it's not reparented.
 	 */
+
 	wmPtr->reparent = None;
 	wmPtr->xInParent = wmPtr->yInParent = 0;
 	return 0;
@@ -3897,28 +4249,27 @@ ComputeReparentGeometry(wmPtr)
     /*
      * Some tricky issues in updating wmPtr->x and wmPtr->y:
      *
-     * 1. Don't update them if the event occurred because of something
-     * we did (i.e. WM_SYNC_PENDING and WM_MOVE_PENDING are both set).
-     * This is because window managers treat coords differently than Tk,
-     * and no two window managers are alike. If the window manager moved
-     * the window because we told it to, remember the coordinates we told
-     * it, not the ones it actually moved it to.  This allows us to move
-     * the window back to the same coordinates later and get the same
-     * result. Without this check, windows can "walk" across the screen
-     * under some conditions.
+     * 1. Don't update them if the event occurred because of something we did
+     * (i.e. WM_SYNC_PENDING and WM_MOVE_PENDING are both set). This is
+     * because window managers treat coords differently than Tk, and no two
+     * window managers are alike. If the window manager moved the window
+     * because we told it to, remember the coordinates we told it, not the
+     * ones it actually moved it to. This allows us to move the window back to
+     * the same coordinates later and get the same result. Without this check,
+     * windows can "walk" across the screen under some conditions.
      *
-     * 2. Don't update wmPtr->x and wmPtr->y unless wrapperPtr->changes.x
-     * or wrapperPtr->changes.y has changed (otherwise a size change can
-     * spoof us into thinking that the position changed too and defeat
-     * the intent of (1) above.
+     * 2. Don't update wmPtr->x and wmPtr->y unless wrapperPtr->changes.x or
+     * wrapperPtr->changes.y has changed (otherwise a size change can spoof us
+     * into thinking that the position changed too and defeat the intent of
+     * (1) above.
      *
-     * (As of 9/96 the above 2 comments appear to be stale.  They're
-     * being left in place as a reminder of what was once true (and
-     * perhaps should still be true?)).
+     * (As of 9/96 the above 2 comments appear to be stale. They're being left
+     * in place as a reminder of what was once true (and perhaps should still
+     * be true?)).
      *
-     * 3. Ignore size changes coming from the window system if we're
-     * about to change the size ourselves but haven't seen the event for
-     * it yet:  our size change is supposed to take priority.
+     * 3. Ignore size changes coming from the window system if we're about to
+     * change the size ourselves but haven't seen the event for it yet: our
+     * size change is supposed to take priority.
      */
 
     if (!(wmPtr->flags & WM_MOVE_PENDING)
@@ -3948,25 +4299,70 @@ ComputeReparentGeometry(wmPtr)
 /*
  *----------------------------------------------------------------------
  *
+ * PropertyEvent --
+ *
+ *	Handle PropertyNotify events on wrapper windows.
+ *	The following properties are of interest:
+ *
+ *	_NET_WM_STATE:
+ *		Used to keep wmPtr->attributes up to date.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PropertyEvent(
+    WmInfo *wmPtr,		/* Information about toplevel window. */
+    XPropertyEvent *eventPtr)	/* PropertyNotify event structure */
+{
+    TkWindow *wrapperPtr = wmPtr->wrapperPtr;
+    Atom _NET_WM_STATE =
+	Tk_InternAtom((Tk_Window)wmPtr->winPtr, "_NET_WM_STATE");
+
+    if (eventPtr->atom == _NET_WM_STATE) {
+	Atom actualType;
+	int actualFormat;
+	unsigned long numItems, bytesAfter;
+	unsigned char *propertyValue = 0;
+	long maxLength = 1024;
+
+	if (XGetWindowProperty(
+		wrapperPtr->display, wrapperPtr->window, _NET_WM_STATE,
+		0l, maxLength, False, XA_ATOM,
+		&actualType, &actualFormat, &numItems, &bytesAfter, 
+		&propertyValue) == Success
+	) {
+	    CheckNetWmState(wmPtr, (Atom*)propertyValue, (int)numItems);
+	    XFree(propertyValue);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
  * WrapperEventProc --
  *
- *	This procedure is invoked by the event loop when a wrapper window
- *	is restructured.
+ *	This function is invoked by the event loop when a wrapper window is
+ *	restructured.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	Tk's internal data structures for the window get modified to
- *	reflect the structural change.
+ *	Tk's internal data structures for the window get modified to reflect
+ *	the structural change.
  *
  *----------------------------------------------------------------------
  */
 
+static const unsigned int WrapperEventMask = 
+    (StructureNotifyMask | PropertyChangeMask);
+
 static void
-WrapperEventProc(clientData, eventPtr)
-    ClientData clientData;		/* Information about toplevel window. */
-    XEvent *eventPtr;			/* Event that just happened. */
+WrapperEventProc(
+    ClientData clientData,	/* Information about toplevel window. */
+    XEvent *eventPtr)		/* Event that just happened. */
 {
     WmInfo *wmPtr = (WmInfo *) clientData;
     XEvent mapEvent;
@@ -3979,14 +4375,14 @@ WrapperEventProc(clientData, eventPtr)
 	if (!(wmPtr->wrapperPtr->flags & TK_ALREADY_DEAD)) {
 	    /*
 	     * A top-level window was deleted externally (e.g., by the window
-	     * manager).  This is probably not a good thing, but cleanup as
-	     * best we can.  The error handler is needed because
+	     * manager). This is probably not a good thing, but cleanup as
+	     * best we can. The error handler is needed because
 	     * Tk_DestroyWindow will try to destroy the window, but of course
 	     * it's already gone.
 	     */
 
 	    handler = Tk_CreateErrorHandler(wmPtr->winPtr->display, -1, -1, -1,
-		    (Tk_ErrorProc *) NULL, (ClientData) NULL);
+		    NULL, NULL);
 	    Tk_DestroyWindow((Tk_Window) wmPtr->winPtr);
 	    Tk_DeleteErrorHandler(handler);
 	}
@@ -3995,13 +4391,12 @@ WrapperEventProc(clientData, eventPtr)
 	}
     } else if (eventPtr->type == ConfigureNotify) {
 	/*
-	 * Ignore the event if the window has never been mapped yet.
-	 * Such an event occurs only in weird cases like changing the
-	 * internal border width of a top-level window, which results
-	 * in a synthetic Configure event.  These events are not relevant
-	 * to us, and if we process them confusion may result (e.g. we
-	 * may conclude erroneously that the user repositioned or resized
-	 * the window).
+	 * Ignore the event if the window has never been mapped yet. Such an
+	 * event occurs only in weird cases like changing the internal border
+	 * width of a top-level window, which results in a synthetic Configure
+	 * event. These events are not relevant to us, and if we process them
+	 * confusion may result (e.g. we may conclude erroneously that the
+	 * user repositioned or resized the window).
 	 */
 
 	if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
@@ -4019,6 +4414,8 @@ WrapperEventProc(clientData, eventPtr)
 	goto doMapEvent;
     } else if (eventPtr->type == ReparentNotify) {
 	ReparentEvent(wmPtr, &eventPtr->xreparent);
+    } else if (eventPtr->type == PropertyNotify) {
+	PropertyEvent(wmPtr, &eventPtr->xproperty);
     } else if (0 && eventPtr->type == Expose) {
 	mapEvent = *eventPtr;
 	mapEvent.xexpose.window = wmPtr->winPtr->window;
@@ -4026,7 +4423,7 @@ WrapperEventProc(clientData, eventPtr)
     }
     return;
 
-    doMapEvent:
+  doMapEvent:
     mapEvent = *eventPtr;
     mapEvent.xmap.event = wmPtr->winPtr->window;
     mapEvent.xmap.window = wmPtr->winPtr->window;
@@ -4038,24 +4435,24 @@ WrapperEventProc(clientData, eventPtr)
  *
  * TopLevelReqProc --
  *
- *	This procedure is invoked by the geometry manager whenever
- *	the requested size for a top-level window is changed.
+ *	This function is invoked by the geometry manager whenever the
+ *	requested size for a top-level window is changed.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	Arrange for the window to be resized to satisfy the request
- *	(this happens as a when-idle action).
+ *	Arrange for the window to be resized to satisfy the request (this
+ *	happens as a when-idle action).
  *
  *----------------------------------------------------------------------
  */
 
 	/* ARGSUSED */
 static void
-TopLevelReqProc(dummy, tkwin)
-    ClientData dummy;			/* Not used. */
-    Tk_Window tkwin;			/* Information about window. */
+TopLevelReqProc(
+    ClientData dummy,		/* Not used. */
+    Tk_Window tkwin)		/* Information about window. */
 {
     TkWindow *winPtr = (TkWindow *) tkwin;
     WmInfo *wmPtr;
@@ -4064,16 +4461,15 @@ TopLevelReqProc(dummy, tkwin)
 
     if ((wmPtr->width >= 0) && (wmPtr->height >= 0)) {
 	/*
-	 * Explicit dimensions have been set for this window, so we
-	 * should ignore the geometry request.  It's actually important
-	 * to ignore the geometry request because, due to quirks in
-	 * window managers, invoking UpdateGeometryInfo may cause the
-	 * window to move.  For example, if "wm geometry -10-20" was
-	 * invoked, the window may be positioned incorrectly the first
-	 * time it appears (because we didn't know the proper width of
-	 * the window manager borders); if we invoke UpdateGeometryInfo
-	 * again, the window will be positioned correctly, which may
-	 * cause it to jump on the screen.
+	 * Explicit dimensions have been set for this window, so we should
+	 * ignore the geometry request. It's actually important to ignore the
+	 * geometry request because, due to quirks in window managers,
+	 * invoking UpdateGeometryInfo may cause the window to move. For
+	 * example, if "wm geometry -10-20" was invoked, the window may be
+	 * positioned incorrectly the first time it appears (because we didn't
+	 * know the proper width of the window manager borders); if we invoke
+	 * UpdateGeometryInfo again, the window will be positioned correctly,
+	 * which may cause it to jump on the screen.
 	 */
 
 	return;
@@ -4086,8 +4482,8 @@ TopLevelReqProc(dummy, tkwin)
     }
 
     /*
-     * If the window isn't being positioned by its upper left corner
-     * then we have to move it as well.
+     * If the window isn't being positioned by its upper left corner then we
+     * have to move it as well.
      */
 
     if (wmPtr->flags & (WM_NEGATIVE_X | WM_NEGATIVE_Y)) {
@@ -4100,43 +4496,41 @@ TopLevelReqProc(dummy, tkwin)
  *
  * UpdateGeometryInfo --
  *
- *	This procedure is invoked when a top-level window is first
- *	mapped, and also as a when-idle procedure, to bring the
- *	geometry and/or position of a top-level window back into
- *	line with what has been requested by the user and/or widgets.
- *	This procedure doesn't return until the window manager has
- *	responded to the geometry change.
+ *	This function is invoked when a top-level window is first mapped, and
+ *	also as a when-idle function, to bring the geometry and/or position of
+ *	a top-level window back into line with what has been requested by the
+ *	user and/or widgets. This function doesn't return until the window
+ *	manager has responded to the geometry change.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	The size and location of both the toplevel window and its wrapper
- *	may change, unless the WM prevents that from happening.
+ *	The size and location of both the toplevel window and its wrapper may
+ *	change, unless the WM prevents that from happening.
  *
  *----------------------------------------------------------------------
  */
 
 static void
-UpdateGeometryInfo(clientData)
-    ClientData clientData;		/* Pointer to the window's record. */
+UpdateGeometryInfo(
+    ClientData clientData)	/* Pointer to the window's record. */
 {
     register TkWindow *winPtr = (TkWindow *) clientData;
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
-    int x, y, width, height;
+    int x, y, width, height, min, max;
     unsigned long serial;
 
     wmPtr->flags &= ~WM_UPDATE_PENDING;
 
     /*
-     * Compute the new size for the top-level window.  See the
-     * user documentation for details on this, but the size
-     * requested depends on (a) the size requested internally
-     * by the window's widgets, (b) the size requested by the
-     * user in a "wm geometry" command or via wm-based interactive
-     * resizing (if any), and (c) whether or not the window is
-     * gridded.  Don't permit sizes <= 0 because this upsets
-     * the X server.
+     * Compute the new size for the top-level window. See the user
+     * documentation for details on this, but the size requested depends on
+     * (a) the size requested internally by the window's widgets, (b) the size
+     * requested by the user in a "wm geometry" command or via wm-based
+     * interactive resizing (if any), (c) whether or not the window is
+     * gridded, and (d) the current min or max size for the toplevel. Don't
+     * permit sizes <= 0 because this upsets the X server.
      */
 
     if (wmPtr->width == -1) {
@@ -4150,6 +4544,30 @@ UpdateGeometryInfo(clientData)
     if (width <= 0) {
 	width = 1;
     }
+
+    /*
+     * Account for window max/min width
+     */
+
+    if (wmPtr->gridWin != NULL) {
+	min = winPtr->reqWidth
+		+ (wmPtr->minWidth - wmPtr->reqGridWidth)*wmPtr->widthInc;
+	if (wmPtr->maxWidth > 0) {
+	    max = winPtr->reqWidth
+		+ (wmPtr->maxWidth - wmPtr->reqGridWidth)*wmPtr->widthInc;
+	} else {
+	    max = 0;
+	}
+    } else {
+	min = wmPtr->minWidth;
+	max = wmPtr->maxWidth;
+    }
+    if (width < min) {
+	width = min;
+    } else if ((max > 0) && (width > max)) {
+	width = max;
+    }
+
     if (wmPtr->height == -1) {
 	height = winPtr->reqHeight;
     } else if (wmPtr->gridWin != NULL) {
@@ -4163,31 +4581,54 @@ UpdateGeometryInfo(clientData)
     }
 
     /*
+     * Account for window max/min height
+     */
+
+    if (wmPtr->gridWin != NULL) {
+	min = winPtr->reqHeight
+		+ (wmPtr->minHeight - wmPtr->reqGridHeight)*wmPtr->heightInc;
+	if (wmPtr->maxHeight > 0) {
+	    max = winPtr->reqHeight
+		+ (wmPtr->maxHeight - wmPtr->reqGridHeight)*wmPtr->heightInc;
+	} else {
+	    max = 0;
+	}
+    } else {
+	min = wmPtr->minHeight;
+	max = wmPtr->maxHeight;
+    }
+    if (height < min) {
+	height = min;
+    } else if ((max > 0) && (height > max)) {
+	height = max;
+    }
+
+    /*
      * Compute the new position for the upper-left pixel of the window's
-     * decorative frame.  This is tricky, because we need to include the
-     * border widths supplied by a reparented parent in this calculation,
-     * but can't use the parent's current overall size since that may
-     * change as a result of this code.
+     * decorative frame. This is tricky, because we need to include the border
+     * widths supplied by a reparented parent in this calculation, but can't
+     * use the parent's current overall size since that may change as a result
+     * of this code.
      */
 
     if (wmPtr->flags & WM_NEGATIVE_X) {
 	x = wmPtr->vRootWidth - wmPtr->x
 		- (width + (wmPtr->parentWidth - winPtr->changes.width));
     } else {
-	x =  wmPtr->x;
+	x = wmPtr->x;
     }
     if (wmPtr->flags & WM_NEGATIVE_Y) {
 	y = wmPtr->vRootHeight - wmPtr->y
 		- (height + (wmPtr->parentHeight - winPtr->changes.height));
     } else {
-	y =  wmPtr->y;
+	y = wmPtr->y;
     }
 
     /*
-     * If the window's size is going to change and the window is
-     * supposed to not be resizable by the user, then we have to
-     * update the size hints.  There may also be a size-hint-update
-     * request pending from somewhere else, too.
+     * If the window's size is going to change and the window is supposed to
+     * not be resizable by the user, then we have to update the size hints.
+     * There may also be a size-hint-update request pending from somewhere
+     * else, too.
      */
 
     if (((width != winPtr->changes.width)
@@ -4197,46 +4638,48 @@ UpdateGeometryInfo(clientData)
 	wmPtr->flags |= WM_UPDATE_SIZE_HINTS;
     }
     if (wmPtr->flags & WM_UPDATE_SIZE_HINTS) {
-	UpdateSizeHints(winPtr);
+	UpdateSizeHints(winPtr, width, height);
     }
 
     /*
-     * Reconfigure the wrapper if it isn't already configured correctly.
-     * A few tricky points:
+     * Reconfigure the wrapper if it isn't already configured correctly. A few
+     * tricky points:
      *
-     * 1. If the window is embeddedand the container is also in this
-     *    process, don't actually reconfigure the window; just pass the
-     *    desired size on to the container.  Also, zero out any position
-     *    information, since embedded windows are not allowed to move.
-     * 2. Sometimes the window manager will give us a different size
-     *    than we asked for (e.g. mwm has a minimum size for windows), so
-     *    base the size check on what we *asked for* last time, not what we
-     *    got.
+     * 1. If the window is embeddedand the container is also in this process,
+     *    don't actually reconfigure the window; just pass the desired size on
+     *    to the container. Also, zero out any position information, since
+     *    embedded windows are not allowed to move.
+     * 2. Sometimes the window manager will give us a different size than we
+     *    asked for (e.g. mwm has a minimum size for windows), so base the
+     *    size check on what we *asked for* last time, not what we got.
      * 3. Can't just reconfigure always, because we may not get a
      *    ConfigureNotify event back if nothing changed, so
      *    WaitForConfigureNotify will hang a long time.
-     * 4. Don't move window unless a new position has been requested for
-     *	  it.  This is because of "features" in some window managers (e.g.
-     *    twm, as of 4/24/91) where they don't interpret coordinates
-     *    according to ICCCM.  Moving a window to its current location may
-     *    cause it to shift position on the screen.
+     * 4. Don't move window unless a new position has been requested for it.
+     *	  This is because of "features" in some window managers (e.g. twm, as
+     *	  of 4/24/91) where they don't interpret coordinates according to
+     *	  ICCCM. Moving a window to its current location may cause it to shift
+     *	  position on the screen.
      */
 
     if ((winPtr->flags & (TK_EMBEDDED|TK_BOTH_HALVES))
 	    == (TK_EMBEDDED|TK_BOTH_HALVES)) {
+	TkWindow *childPtr = TkpGetOtherWindow(winPtr);
+
 	/*
-	 * This window is embedded and the container is also in this
-	 * process, so we don't need to do anything special about the
-	 * geometry, except to make sure that the desired size is known
-	 * by the container.  Also, zero out any position information,
-	 * since embedded windows are not allowed to move.
+	 * This window is embedded and the container is also in this process,
+	 * so we don't need to do anything special about the geometry, except
+	 * to make sure that the desired size is known by the container. Also,
+	 * zero out any position information, since embedded windows are not
+	 * allowed to move.
 	 */
 
 	wmPtr->x = wmPtr->y = 0;
 	wmPtr->flags &= ~(WM_NEGATIVE_X|WM_NEGATIVE_Y);
 	height += wmPtr->menuHeight;
-	Tk_GeometryRequest((Tk_Window) TkpGetOtherWindow(winPtr),
-		width, height);
+	if (childPtr != NULL) {
+	    Tk_GeometryRequest((Tk_Window) childPtr, width, height);
+	}
 	return;
     }
     serial = NextRequest(winPtr->display);
@@ -4247,9 +4690,9 @@ UpdateGeometryInfo(clientData)
 		&& (width == wmPtr->wrapperPtr->changes.width)
 		&& (height == wmPtr->wrapperPtr->changes.height)) {
 	    /*
-	     * The window already has the correct geometry, so don't bother
-	     * to configure it;  the X server appears to ignore these
-	     * requests, so we won't get back a ConfigureNotify and the
+	     * The window already has the correct geometry, so don't bother to
+	     * configure it; the X server appears to ignore these requests, so
+	     * we won't get back a ConfigureNotify and the
 	     * WaitForConfigureNotify call below will hang for a while.
 	     */
 
@@ -4259,8 +4702,8 @@ UpdateGeometryInfo(clientData)
 	wmPtr->configWidth = width;
 	wmPtr->configHeight = height;
 	if (winPtr->dispPtr->flags & TK_DISPLAY_WM_TRACING) {
-	   printf("UpdateGeometryInfo moving to %d %d, resizing to %d x %d,\n",
-                   x, y, width, height);
+	    printf("UpdateGeometryInfo moving to %d %d, resizing to %dx%d,\n",
+		    x, y, width, height);
 	}
 	XMoveResizeWindow(winPtr->display, wmPtr->wrapperPtr->window, x, y,
 		(unsigned) width, (unsigned) height);
@@ -4269,9 +4712,9 @@ UpdateGeometryInfo(clientData)
 	if ((width == wmPtr->wrapperPtr->changes.width)
 		&& (height == wmPtr->wrapperPtr->changes.height)) {
 	    /*
-	     * The window is already just the size we want, so don't bother
-	     * to configure it;  the X server appears to ignore these
-	     * requests, so we won't get back a ConfigureNotify and the
+	     * The window is already just the size we want, so don't bother to
+	     * configure it; the X server appears to ignore these requests, so
+	     * we won't get back a ConfigureNotify and the
 	     * WaitForConfigureNotify call below will hang for a while.
 	     */
 
@@ -4289,8 +4732,8 @@ UpdateGeometryInfo(clientData)
 	    && ((Tk_Width(wmPtr->menubar) != wmPtr->wrapperPtr->changes.width)
 	    || (Tk_Height(wmPtr->menubar) != wmPtr->menuHeight))) {
 	/*
-	 * It is possible that the window's overall size has not changed
-	 * but the menu size has.
+	 * It is possible that the window's overall size has not changed but
+	 * the menu size has.
 	 */
 
 	Tk_MoveResizeWindow(wmPtr->menubar, 0, 0,
@@ -4302,9 +4745,9 @@ UpdateGeometryInfo(clientData)
     }
 
     /*
-     * Wait for the configure operation to complete.  Don't need to do
-     * this, however, if the window is about to be mapped:  it will be
-     * taken care of elsewhere.
+     * Wait for the configure operation to complete. Don't need to do this,
+     * however, if the window is about to be mapped: it will be taken care of
+     * elsewhere.
      */
 
     if (!(wmPtr->flags & WM_ABOUT_TO_MAP)) {
@@ -4317,9 +4760,8 @@ UpdateGeometryInfo(clientData)
  *
  * UpdateSizeHints --
  *
- *	This procedure is called to update the window manager's
- *	size hints information from the information in a WmInfo
- *	structure.
+ *	This function is called to update the window manager's size hints
+ *	information from the information in a WmInfo structure.
  *
  * Results:
  *	None.
@@ -4331,8 +4773,10 @@ UpdateGeometryInfo(clientData)
  */
 
 static void
-UpdateSizeHints(winPtr)
-    TkWindow *winPtr;
+UpdateSizeHints(
+    TkWindow *winPtr,
+    int newWidth,
+    int newHeight)
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     XSizeHints *hintsPtr;
@@ -4346,9 +4790,8 @@ UpdateSizeHints(winPtr)
     }
 
     /*
-     * Compute the pixel-based sizes for the various fields in the
-     * size hints structure, based on the grid-based sizes in
-     * our structure.
+     * Compute the pixel-based sizes for the various fields in the size hints
+     * structure, based on the grid-based sizes in our structure.
      */
 
     GetMaxSize(wmPtr, &maxWidth, &maxHeight);
@@ -4389,79 +4832,294 @@ UpdateSizeHints(winPtr)
     hintsPtr->flags = wmPtr->sizeHintsFlags | PMinSize;
 
     /*
-     * If the window isn't supposed to be resizable, then set the
-     * minimum and maximum dimensions to be the same.
+     * If the window isn't supposed to be resizable, then set the minimum and
+     * maximum dimensions to be the same.
      */
 
     if (wmPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
-	if (wmPtr->width >= 0) {
-	    hintsPtr->min_width = wmPtr->width;
-	} else {
-	    hintsPtr->min_width = winPtr->reqWidth;
-	}
-	hintsPtr->max_width = hintsPtr->min_width;
+	hintsPtr->max_width = hintsPtr->min_width = newWidth;
+	hintsPtr->flags |= PMaxSize;
     }
     if (wmPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
-	if (wmPtr->height >= 0) {
-	    hintsPtr->min_height = wmPtr->height;
-	} else {
-	    hintsPtr->min_height = winPtr->reqHeight + wmPtr->menuHeight;
-	}
-	hintsPtr->max_height = hintsPtr->min_height;
+	hintsPtr->max_height = hintsPtr->min_height =
+		newHeight + wmPtr->menuHeight;
+	hintsPtr->flags |= PMaxSize;
     }
 
     XSetWMNormalHints(winPtr->display, wmPtr->wrapperPtr->window, hintsPtr);
 
     XFree((char *) hintsPtr);
 }
+/*
+ *--------------------------------------------------------------
+ *
+ * UpdateTitle --
+ *
+ *	This function is called to update the window title and icon name. It
+ *	sets the ICCCM-defined properties WM_NAME and WM_ICON_NAME for older
+ *	window managers, and the freedesktop.org-defined _NET_WM_NAME and
+ *	_NET_WM_ICON_NAME properties for newer ones. The ICCCM properties are
+ *	stored in the system encoding, the newer properties are stored in
+ *	UTF-8.
+ *
+ *	NOTE: the ICCCM specifies that WM_NAME and WM_ICON_NAME are stored in
+ *	ISO-Latin-1. Tk has historically used the default system encoding
+ *	(since 8.1). It's not clear whether this is correct or not.
+ *
+ * Side effects:
+ *	Properties get changed for winPtr.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+UpdateTitle(
+    TkWindow *winPtr)
+{
+    WmInfo *wmPtr = winPtr->wmInfoPtr;
+    Atom XA_UTF8_STRING = Tk_InternAtom((Tk_Window) winPtr, "UTF8_STRING");
+    const char *string;
+    Tcl_DString ds;
+
+    /*
+     * Set window title:
+     */
+
+    string = (wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid;
+    Tcl_UtfToExternalDString(NULL, string, -1, &ds);
+    XStoreName(winPtr->display, wmPtr->wrapperPtr->window,
+	    Tcl_DStringValue(&ds));
+    Tcl_DStringFree(&ds);
+
+    XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window,
+	    Tk_InternAtom((Tk_Window) winPtr, "_NET_WM_NAME"),
+	    XA_UTF8_STRING, 8, PropModeReplace,
+	    (const unsigned char*)string, (signed int)strlen(string));
+
+    /*
+     * Set icon name:
+     */
+
+    if (wmPtr->iconName != NULL) {
+	Tcl_UtfToExternalDString(NULL, wmPtr->iconName, -1, &ds);
+	XSetIconName(winPtr->display, wmPtr->wrapperPtr->window,
+		Tcl_DStringValue(&ds));
+	Tcl_DStringFree(&ds);
+
+	XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window,
+		Tk_InternAtom((Tk_Window) winPtr, "_NET_WM_ICON_NAME"),
+		XA_UTF8_STRING, 8, PropModeReplace,
+		(const unsigned char*)wmPtr->iconName,
+		(signed int)strlen(wmPtr->iconName));
+    }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * UpdatePhotoIcon --
+ *
+ *	This function is called to update the window photo icon. It sets the
+ *	EWMH-defined properties _NET_WM_ICON.
+ *
+ * Side effects:
+ *	Properties get changed for winPtr.
+ *
+ *--------------------------------------------------------------
+ */
+
+static void
+UpdatePhotoIcon(
+    TkWindow *winPtr)
+{
+    WmInfo *wmPtr = winPtr->wmInfoPtr;
+    unsigned char *data = wmPtr->iconDataPtr;
+    int size = wmPtr->iconDataSize;
+
+    if (data == NULL) {
+	data = winPtr->dispPtr->iconDataPtr;
+	size = winPtr->dispPtr->iconDataSize;
+    }
+    if (data != NULL) {
+	/*
+	 * Set icon:
+	 */
+
+	XChangeProperty(winPtr->display, wmPtr->wrapperPtr->window,
+		Tk_InternAtom((Tk_Window) winPtr, "_NET_WM_ICON"),
+		XA_CARDINAL, 32, PropModeReplace,
+		(unsigned char *) data, size);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetNetWmState --
+ *
+ * 	Sets the specified state property by sending a _NET_WM_STATE
+ * 	ClientMessage to the root window.
+ *
+ * Preconditions: 
+ *
+ * 	Wrapper window must be created.
+ *
+ * See also:
+ * 	UpdateNetWmState; EWMH spec, section _NET_WM_STATE.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#define _NET_WM_STATE_REMOVE    0l
+#define _NET_WM_STATE_ADD       1l
+#define _NET_WM_STATE_TOGGLE    2l
+
+static void SetNetWmState(TkWindow *winPtr, const char *atomName, int on)
+{
+    Tk_Window tkwin = (Tk_Window)winPtr;
+    Atom messageType = Tk_InternAtom(tkwin, "_NET_WM_STATE");
+    Atom action = on ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
+    Atom property = Tk_InternAtom(tkwin, atomName);
+    XEvent e;
+
+    if (!winPtr->wmInfoPtr->wrapperPtr) {
+	return;
+    }
+
+    e.xany.type = ClientMessage;
+    e.xany.window = winPtr->wmInfoPtr->wrapperPtr->window;
+    e.xclient.message_type = messageType;
+    e.xclient.format = 32;
+    e.xclient.data.l[0] = action;
+    e.xclient.data.l[1] = property;
+    e.xclient.data.l[2] = e.xclient.data.l[3] = e.xclient.data.l[4] = 0l;
+
+    XSendEvent(winPtr->display,
+	RootWindow(winPtr->display, winPtr->screenNum), 0,
+	SubstructureNotifyMask|SubstructureRedirectMask, &e);
+}
+
+/*
+ * CheckNetWmState --
+ *
+ * 	Updates the window attributes whenever the _NET_WM_STATE
+ * 	property changes.
+ *
+ * Notes:
+ * 	
+ * 	Tk uses a single -zoomed state, while the EWMH spec supports 
+ * 	separate vertical and horizontal maximization.  We consider
+ * 	the window to be "zoomed" if _NET_WM_STATE_MAXIMIZED_VERT 
+ * 	and _NET_WM_STATE_MAXIMIZED_HORZ are both set.
+ */
+static void CheckNetWmState(WmInfo *wmPtr, Atom *atoms, int numAtoms)
+{
+    Tk_Window tkwin = (Tk_Window)wmPtr->wrapperPtr;
+    int i;
+    Atom _NET_WM_STATE_ABOVE
+	    = Tk_InternAtom(tkwin, "_NET_WM_STATE_ABOVE"),
+	_NET_WM_STATE_MAXIMIZED_VERT 
+	    = Tk_InternAtom(tkwin, "_NET_WM_STATE_MAXIMIZED_VERT"),
+	_NET_WM_STATE_MAXIMIZED_HORZ 
+	    = Tk_InternAtom(tkwin, "_NET_WM_STATE_MAXIMIZED_HORZ"),
+	_NET_WM_STATE_FULLSCREEN 
+	    = Tk_InternAtom(tkwin, "_NET_WM_STATE_FULLSCREEN");
+
+    wmPtr->attributes.topmost = 0;
+    wmPtr->attributes.zoomed = 0;
+    wmPtr->attributes.fullscreen = 0;
+    for (i = 0; i < numAtoms; ++i) {
+	if (atoms[i] == _NET_WM_STATE_ABOVE) {
+	    wmPtr->attributes.topmost = 1;
+	} else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_VERT) {
+	    wmPtr->attributes.zoomed |= 1;
+	} else if (atoms[i] == _NET_WM_STATE_MAXIMIZED_HORZ) {
+	    wmPtr->attributes.zoomed |= 2;
+	} else if (atoms[i] == _NET_WM_STATE_FULLSCREEN) {
+	    wmPtr->attributes.fullscreen = 1;
+	}
+    }
+
+    wmPtr->attributes.zoomed = (wmPtr->attributes.zoomed == 3);
+
+    return;
+}
+
+/*
+ * UpdateNetWmState --
+ *
+ * 	Sets the _NET_WM_STATE property to match the requested attribute state
+ * 	just prior to mapping a withdrawn window.
+ */
+#define NET_WM_STATE_MAX_ATOMS 4
+static void UpdateNetWmState(WmInfo *wmPtr)
+{
+    Tk_Window tkwin = (Tk_Window)wmPtr->wrapperPtr;
+    Atom atoms[NET_WM_STATE_MAX_ATOMS];
+    long numAtoms = 0;
+
+    if (wmPtr->reqState.topmost) {
+	atoms[numAtoms++] = Tk_InternAtom(tkwin,"_NET_WM_STATE_ABOVE");
+    }
+    if (wmPtr->reqState.zoomed) {
+	atoms[numAtoms++] = Tk_InternAtom(tkwin,"_NET_WM_STATE_MAXIMIZED_VERT");
+	atoms[numAtoms++] = Tk_InternAtom(tkwin,"_NET_WM_STATE_MAXIMIZED_HORZ");
+    } 
+    if (wmPtr->reqState.fullscreen) {
+	atoms[numAtoms++] = Tk_InternAtom(tkwin, "_NET_WM_STATE_FULLSCREEN");
+    }
+
+    XChangeProperty(Tk_Display(tkwin), wmPtr->wrapperPtr->window, 
+	    Tk_InternAtom(tkwin, "_NET_WM_STATE"), XA_ATOM, 32, 
+	    PropModeReplace, (unsigned char *)atoms, numAtoms);
+}
 
 /*
  *----------------------------------------------------------------------
  *
  * WaitForConfigureNotify --
  *
- *	This procedure is invoked in order to synchronize with the
- *	window manager.  It waits for a ConfigureNotify event to
- *	arrive, signalling that the window manager has seen an attempt
- *	on our part to move or resize a top-level window.
+ *	This function is invoked in order to synchronize with the window
+ *	manager. It waits for a ConfigureNotify event to arrive, signalling
+ *	that the window manager has seen an attempt on our part to move or
+ *	resize a top-level window.
  *
  * Results:
  *	None.
  *
  * Side effects:
  *	Delays the execution of the process until a ConfigureNotify event
- *	arrives with serial number at least as great as serial.  This
- *	is useful for two reasons:
+ *	arrives with serial number at least as great as serial. This is useful
+ *	for two reasons:
  *
  *	1. It's important to distinguish ConfigureNotify events that are
  *	   coming in response to a request we've made from those generated
- *	   spontaneously by the user.  The reason for this is that if the
- *	   user resizes the window we take that as an order to ignore
- *	   geometry requests coming from inside the window hierarchy.  If
- *	   we accidentally interpret a response to our request as a
- *	   user-initiated action, the window will stop responding to
- *	   new geometry requests.  To make this distinction, (a) this
- *	   procedure sets a flag for TopLevelEventProc to indicate that
- *	   we're waiting to sync with the wm, and (b) all changes to
- *	   the size of a top-level window are followed by calls to this
- *	   procedure.
- *	2. Races and confusion can come about if there are multiple
- *	   operations outstanding at a time (e.g. two different resizes
- *	   of the top-level window:  it's hard to tell which of the
- *	   ConfigureNotify events coming back is for which request).
+ *	   spontaneously by the user. The reason for this is that if the user
+ *	   resizes the window we take that as an order to ignore geometry
+ *	   requests coming from inside the window hierarchy. If we
+ *	   accidentally interpret a response to our request as a
+ *	   user-initiated action, the window will stop responding to new
+ *	   geometry requests. To make this distinction, (a) this function sets
+ *	   a flag for TopLevelEventProc to indicate that we're waiting to sync
+ *	   with the wm, and (b) all changes to the size of a top-level window
+ *	   are followed by calls to this function.
+ *	2. Races and confusion can come about if there are multiple operations
+ *	   outstanding at a time (e.g. two different resizes of the top-level
+ *	   window: it's hard to tell which of the ConfigureNotify events
+ *	   coming back is for which request).
  *	While waiting, some events covered by StructureNotifyMask are
- *	processed (ConfigureNotify, MapNotify, and UnmapNotify)
- *	and all others are deferred.
+ *	processed (ConfigureNotify, MapNotify, and UnmapNotify) and all others
+ *	are deferred.
  *
  *----------------------------------------------------------------------
  */
 
 static void
-WaitForConfigureNotify(winPtr, serial)
-    TkWindow *winPtr;		/* Top-level window for which we want
-				 * to see a ConfigureNotify. */
-    unsigned long serial;	/* Serial number of resize request.  Want to
-				 * be sure wm has seen this. */
+WaitForConfigureNotify(
+    TkWindow *winPtr,		/* Top-level window for which we want to see a
+				 * ConfigureNotify. */
+    unsigned long serial)	/* Serial number of resize request. Want to be
+				 * sure wm has seen this. */
 {
     WmInfo *wmPtr = winPtr->wmInfoPtr;
     XEvent event;
@@ -4470,11 +5128,10 @@ WaitForConfigureNotify(winPtr, serial)
     Window window = (wmPtr->reparent != None) ? wmPtr->reparent : wmPtr->wrapperPtr->window;
 
     /*
-     * One more tricky detail about this procedure.  In some cases the
-     * window manager will decide to ignore a configure request (e.g.
-     * because it thinks the window is already in the right place).
-     * To avoid hanging in this situation, only wait for a few seconds,
-     * then give up.
+     * One more tricky detail about this function. In some cases the window
+     * manager will decide to ignore a configure request (e.g. because it
+     * thinks the window is already in the right place). To avoid hanging in
+     * this situation, only wait for a few seconds, then give up.
      */
 
     /*
@@ -4541,32 +5198,31 @@ WaitForConfigureNotify(winPtr, serial)
  *
  * WaitForEvent --
  *
- *	This procedure is used by WaitForConfigureNotify and
- *	WaitForMapNotify to wait for an event of a certain type
- *	to arrive.
+ *	This function is used by WaitForConfigureNotify and WaitForMapNotify
+ *	to wait for an event of a certain type to arrive.
  *
  * Results:
- *	Under normal conditions, TCL_OK is returned and an event for
- *	display and window that matches "mask" is stored in *eventPtr.
- *	This event  has already been processed by Tk before this procedure
- *	returns.  If a long time goes by with no event of the right type
- *	arriving, or if an error occurs while waiting for the event to
- *	arrive, then TCL_ERROR is returned.
+ *	Under normal conditions, TCL_OK is returned and an event for display
+ *	and window that matches "mask" is stored in *eventPtr. This event has
+ *	already been processed by Tk before this function returns. If a long
+ *	time goes by with no event of the right type arriving, or if an error
+ *	occurs while waiting for the event to arrive, then TCL_ERROR is
+ *	returned.
  *
  * Side effects:
  *	While waiting for the desired event to occur, Configurenotify,
- *	MapNotify, and UnmapNotify events for window are processed,
- *	as are all ReparentNotify events.
+ *	MapNotify, and UnmapNotify events for window are processed, as are all
+ *	ReparentNotify events.
  *
  *----------------------------------------------------------------------
  */
 
 static int
-WaitForEvent(display, wmInfoPtr, type, eventPtr)
-    Display *display;		/* Display event is coming from. */
-    WmInfo *wmInfoPtr;		/* Window for which event is desired. */
-    int type;			/* Type of event that is wanted. */
-    XEvent *eventPtr;		/* Place to store event. */
+WaitForEvent(
+    Display *display,		/* Display event is coming from. */
+    WmInfo *wmInfoPtr,		/* Window for which event is desired. */
+    int type,			/* Type of event that is wanted. */
+    XEvent *eventPtr)		/* Place to store event. */
 {
     WaitRestrictInfo info;
     Tk_RestrictProc *oldRestrictProc;
@@ -4574,9 +5230,9 @@ WaitForEvent(display, wmInfoPtr, type, e
     Tcl_Time timeout;
 
     /*
-     * Set up an event filter to select just the events we want, and
-     * a timer handler, then wait for events until we get the event
-     * we want or a timeout happens.
+     * Set up an event filter to select just the events we want, and a timer
+     * handler, then wait for events until we get the event we want or a
+     * timeout happens.
      */
 
     info.display = display;
@@ -4608,26 +5264,26 @@ WaitForEvent(display, wmInfoPtr, type, e
  *
  * WaitRestrictProc --
  *
- *	This procedure is a Tk_RestrictProc that is used to filter
- *	events while WaitForEvent is active.
+ *	This function is a Tk_RestrictProc that is used to filter events while
+ *	WaitForEvent is active.
  *
  * Results:
- *	Returns TK_PROCESS_EVENT if the right event is found.  Also
- *	returns TK_PROCESS_EVENT if any ReparentNotify event is found
- *	or if the event is a ConfigureNotify, MapNotify, or UnmapNotify
- *	for window.  Otherwise returns TK_DEFER_EVENT.
+ *	Returns TK_PROCESS_EVENT if the right event is found. Also returns
+ *	TK_PROCESS_EVENT if any ReparentNotify event is found or if the event
+ *	is a ConfigureNotify, MapNotify, or UnmapNotify for window. Otherwise
+ *	returns TK_DEFER_EVENT.
  *
  * Side effects:
- *	An event may get stored in the area indicated by the caller
- *	of WaitForEvent.
+ *	An event may get stored in the area indicated by the caller of
+ *	WaitForEvent.
  *
  *----------------------------------------------------------------------
  */
 
 static Tk_RestrictAction
-WaitRestrictProc(clientData, eventPtr)
-    ClientData clientData;	/* Pointer to WaitRestrictInfo structure. */
-    XEvent *eventPtr;		/* Event that is about to be handled. */
+WaitRestrictProc(
+    ClientData clientData,	/* Pointer to WaitRestrictInfo structure. */
+    XEvent *eventPtr)		/* Event that is about to be handled. */
 {
     WaitRestrictInfo *infoPtr = (WaitRestrictInfo *) clientData;
 
@@ -4647,9 +5303,8 @@ WaitRestrictProc(clientData, eventPtr)
 	infoPtr->foundEvent = 1;
 	return TK_PROCESS_EVENT;
     }
-    if (eventPtr->type == ConfigureNotify
-	   || eventPtr->type == MapNotify
-	   || eventPtr->type == UnmapNotify) {
+    if (eventPtr->type == ConfigureNotify || eventPtr->type == MapNotify
+	    || eventPtr->type == UnmapNotify) {
 	return TK_PROCESS_EVENT;
     }
     return TK_DEFER_EVENT;
@@ -4660,32 +5315,31 @@ WaitRestrictProc(clientData, eventPtr)
  *
  * WaitForMapNotify --
  *
- *	This procedure is invoked in order to synchronize with the
- *	window manager.  It waits for the window's mapped state to
- *	reach the value given by mapped.
+ *	This function is invoked in order to synchronize with the window
+ *	manager. It waits for the window's mapped state to reach the value
+ *	given by mapped.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	Delays the execution of the process until winPtr becomes mapped
- *	or unmapped, depending on the "mapped" argument.  This allows us
- *	to synchronize with the window manager, and allows us to
- *	identify changes in window size that come about when the window
- *	manager first starts managing the window (as opposed to those
- *	requested interactively by the user later).  See the comments
- *	for WaitForConfigureNotify and WM_SYNC_PENDING.  While waiting,
- *	some events covered by StructureNotifyMask are processed and all
- *	others are deferred.
+ *	Delays the execution of the process until winPtr becomes mapped or
+ *	unmapped, depending on the "mapped" argument. This allows us to
+ *	synchronize with the window manager, and allows us to identify changes
+ *	in window size that come about when the window manager first starts
+ *	managing the window (as opposed to those requested interactively by
+ *	the user later). See the comments for WaitForConfigureNotify and
+ *	WM_SYNC_PENDING. While waiting, some events covered by
+ *	StructureNotifyMask are processed and all others are deferred.
  *
  *----------------------------------------------------------------------
  */
 
 static void
-WaitForMapNotify(winPtr, mapped)
-    TkWindow *winPtr;		/* Top-level window for which we want
-				 * to see a particular mapping state. */
-    int mapped;			/* If non-zero, wait for window to become
+WaitForMapNotify(
+    TkWindow *winPtr,		/* Top-level window for which we want to see a
+				 * particular mapping state. */
+    int mapped)			/* If non-zero, wait for window to become
 				 * mapped, otherwise wait for it to become
 				 * unmapped. */
 {
@@ -4707,10 +5361,9 @@ WaitForMapNotify(winPtr, mapped)
 	wmPtr->flags &= ~WM_SYNC_PENDING;
 	if (code != TCL_OK) {
 	    /*
-	     * There are some bizarre situations in which the window
-	     * manager can't respond or chooses not to (e.g. if we've
-	     * got a grab set it can't respond).  If this happens then
-	     * just quit.
+	     * There are some bizarre situations in which the window manager
+	     * can't respond or chooses not to (e.g. if we've got a grab set
+	     * it can't respond). If this happens then just quit.
 	     */
 
 	    if (winPtr->dispPtr->flags & TK_DISPLAY_WM_TRACING) {
@@ -4731,9 +5384,8 @@ WaitForMapNotify(winPtr, mapped)
  *
  * UpdateHints --
  *
- *	This procedure is called to update the window manager's
- *	hints information from the information in a WmInfo
- *	structure.
+ *	This function is called to update the window manager's hints
+ *	information from the information in a WmInfo structure.
  *
  * Results:
  *	None.
@@ -4745,8 +5397,8 @@ WaitForMapNotify(winPtr, mapped)
  */
 
 static void
-UpdateHints(winPtr)
-    TkWindow *winPtr;
+UpdateHints(
+    TkWindow *winPtr)
 {
     WmInfo *wmPtr = winPtr->wmInfoPtr;
 
@@ -4761,13 +5413,12 @@ UpdateHints(winPtr)
  *
  * ParseGeometry --
  *
- *	This procedure parses a geometry string and updates
- *	information used to control the geometry of a top-level
- *	window.
+ *	This function parses a geometry string and updates information used to
+ *	control the geometry of a top-level window.
  *
  * Results:
- *	A standard Tcl return value, plus an error message in
- *	the interp's result if an error occurs.
+ *	A standard Tcl return value, plus an error message in the interp's
+ *	result if an error occurs.
  *
  * Side effects:
  *	The size and/or location of winPtr may change.
@@ -4776,12 +5427,12 @@ UpdateHints(winPtr)
  */
 
 static int
-ParseGeometry(interp, string, winPtr)
-    Tcl_Interp *interp;		/* Used for error reporting. */
-    char *string;		/* String containing new geometry.  Has the
+ParseGeometry(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    char *string,		/* String containing new geometry. Has the
 				 * standard form "=wxh+x+y". */
-    TkWindow *winPtr;		/* Pointer to top-level window whose
-				 * geometry is to be changed. */
+    TkWindow *winPtr)		/* Pointer to top-level window whose geometry
+				 * is to be changed. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     int x, y, width, height, flags;
@@ -4797,9 +5448,9 @@ ParseGeometry(interp, string, winPtr)
     }
 
     /*
-     * Parse the width and height, if they are present.  Don't
-     * actually update any of the fields of wmPtr until we've
-     * successfully parsed the entire geometry string.
+     * Parse the width and height, if they are present. Don't actually update
+     * any of the fields of wmPtr until we've successfully parsed the entire
+     * geometry string.
      */
 
     width = wmPtr->width;
@@ -4853,10 +5504,10 @@ ParseGeometry(interp, string, winPtr)
 	}
 
 	/*
-	 * Assume that the geometry information came from the user,
-	 * unless an explicit source has been specified.  Otherwise
-	 * most window managers assume that the size hints were
-	 * program-specified and they ignore them.
+	 * Assume that the geometry information came from the user, unless an
+	 * explicit source has been specified. Otherwise most window managers
+	 * assume that the size hints were program-specified and they ignore
+	 * them.
 	 */
 
 	if ((wmPtr->sizeHintsFlags & (USPosition|PPosition)) == 0) {
@@ -4866,9 +5517,9 @@ ParseGeometry(interp, string, winPtr)
     }
 
     /*
-     * Everything was parsed OK.  Update the fields of *wmPtr and
-     * arrange for the appropriate information to be percolated out
-     * to the window manager at the next idle moment.
+     * Everything was parsed OK. Update the fields of *wmPtr and arrange for
+     * the appropriate information to be percolated out to the window manager
+     * at the next idle moment.
      */
 
     wmPtr->width = width;
@@ -4884,9 +5535,8 @@ ParseGeometry(interp, string, winPtr)
     }
     return TCL_OK;
 
-    error:
-    Tcl_AppendResult(interp, "bad geometry specifier \"",
-	    string, "\"", (char *) NULL);
+  error:
+    Tcl_AppendResult(interp, "bad geometry specifier \"", string, "\"", NULL);
     return TCL_ERROR;
 }
 
@@ -4895,15 +5545,15 @@ ParseGeometry(interp, string, winPtr)
  *
  * Tk_GetRootCoords --
  *
- *	Given a token for a window, this procedure traces through the
- *	window's lineage to find the (virtual) root-window coordinates
- *	corresponding to point (0,0) in the window.
+ *	Given a token for a window, this function traces through the window's
+ *	lineage to find the (virtual) root-window coordinates corresponding to
+ *	point (0,0) in the window.
  *
  * Results:
- *	The locations pointed to by xPtr and yPtr are filled in with
- *	the root coordinates of the (0,0) point in tkwin.  If a virtual
- *	root window is in effect for the window, then the coordinates
- *	in the virtual root are returned.
+ *	The locations pointed to by xPtr and yPtr are filled in with the root
+ *	coordinates of the (0,0) point in tkwin. If a virtual root window is
+ *	in effect for the window, then the coordinates in the virtual root are
+ *	returned.
  *
  * Side effects:
  *	None.
@@ -4912,18 +5562,17 @@ ParseGeometry(interp, string, winPtr)
  */
 
 void
-Tk_GetRootCoords(tkwin, xPtr, yPtr)
-    Tk_Window tkwin;		/* Token for window. */
-    int *xPtr;			/* Where to store x-displacement of (0,0). */
-    int *yPtr;			/* Where to store y-displacement of (0,0). */
+Tk_GetRootCoords(
+    Tk_Window tkwin,		/* Token for window. */
+    int *xPtr,			/* Where to store x-displacement of (0,0). */
+    int *yPtr)			/* Where to store y-displacement of (0,0). */
 {
     int x, y;
     register TkWindow *winPtr = (TkWindow *) tkwin;
 
     /*
-     * Search back through this window's parents all the way to a
-     * top-level window, combining the offsets of each window within
-     * its parent.
+     * Search back through this window's parents all the way to a top-level
+     * window, combining the offsets of each window within its parent.
      */
 
     x = y = 0;
@@ -4933,10 +5582,9 @@ Tk_GetRootCoords(tkwin, xPtr, yPtr)
 	if ((winPtr->wmInfoPtr != NULL)
 		&& (winPtr->wmInfoPtr->menubar == (Tk_Window) winPtr)) {
 	    /*
-	     * This window is a special menubar; switch over to its
-	     * associated toplevel, compensate for their differences in
-	     * y coordinates, then continue with the toplevel (in case
-	     * it's embedded).
+	     * This window is a special menubar; switch over to its associated
+	     * toplevel, compensate for their differences in y coordinates,
+	     * then continue with the toplevel (in case it's embedded).
 	     */
 	    y -= winPtr->wmInfoPtr->menuHeight;
 	    winPtr = winPtr->wmInfoPtr->winPtr;
@@ -4950,8 +5598,8 @@ Tk_GetRootCoords(tkwin, xPtr, yPtr)
 	    otherPtr = TkpGetOtherWindow(winPtr);
 	    if (otherPtr == NULL) {
 		/*
-		 * The container window is not in the same application.
-		 * Query the X server.
+		 * The container window is not in the same application. Query
+		 * the X server.
 		 */
 
 		Window root, dummyChild;
@@ -4962,14 +5610,14 @@ Tk_GetRootCoords(tkwin, xPtr, yPtr)
 		    root = RootWindowOfScreen(Tk_Screen((Tk_Window)winPtr));
 		}
 		XTranslateCoordinates(winPtr->display, winPtr->window,
-		    root, 0, 0, &rootX, &rootY, &dummyChild);
+			root, 0, 0, &rootX, &rootY, &dummyChild);
 		x += rootX;
 		y += rootY;
 		break;
 	    } else {
 		/*
-		 * The container window is in the same application.
-		 * Let's query its coordinates.
+		 * The container window is in the same application. Let's
+		 * query its coordinates.
 		 */
 
 		winPtr = otherPtr;
@@ -4990,13 +5638,13 @@ Tk_GetRootCoords(tkwin, xPtr, yPtr)
  *
  * Tk_CoordsToWindow --
  *
- *	Given the (virtual) root coordinates of a point, this procedure
- *	returns the token for the top-most window covering that point,
- *	if there exists such a window in this application.
+ *	Given the (virtual) root coordinates of a point, this function returns
+ *	the token for the top-most window covering that point, if there exists
+ *	such a window in this application.
  *
  * Results:
- *	The return result is either a token for the window corresponding
- *	to rootX and rootY, or else NULL to indicate that there is no such
+ *	The return result is either a token for the window corresponding to
+ *	rootX and rootY, or else NULL to indicate that there is no such
  *	window.
  *
  * Side effects:
@@ -5006,13 +5654,13 @@ Tk_GetRootCoords(tkwin, xPtr, yPtr)
  */
 
 Tk_Window
-Tk_CoordsToWindow(rootX, rootY, tkwin)
-    int rootX, rootY;		/* Coordinates of point in root window.  If
-				 * a virtual-root window manager is in use,
+Tk_CoordsToWindow(
+    int rootX, int rootY,	/* Coordinates of point in root window. If a
+				 * virtual-root window manager is in use,
 				 * these coordinates refer to the virtual
 				 * root, not the real root. */
-    Tk_Window tkwin;		/* Token for any window in application;
-				 * used to identify the display. */
+    Tk_Window tkwin)		/* Token for any window in application; used
+				 * to identify the display. */
 {
     Window window, parent, child;
     int x, y, childX, childY, tmpx, tmpy, bd;
@@ -5022,16 +5670,16 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
     Tk_ErrorHandler handler = NULL;
 
     /*
-     * Step 1: scan the list of toplevel windows to see if there is a
-     * virtual root for the screen we're interested in.  If so, we have
-     * to translate the coordinates from virtual root to root
-     * coordinates.
+     * Step 1: scan the list of toplevel windows to see if there is a virtual
+     * root for the screen we're interested in. If so, we have to translate
+     * the coordinates from virtual root to root coordinates.
      */
 
     parent = window = RootWindowOfScreen(Tk_Screen(tkwin));
     x = rootX;
     y = rootY;
-    for (wmPtr = (WmInfo *) dispPtr->firstWmPtr; wmPtr != NULL; wmPtr = wmPtr->nextPtr) {
+    for (wmPtr = (WmInfo *) dispPtr->firstWmPtr; wmPtr != NULL;
+	    wmPtr = wmPtr->nextPtr) {
 	if (Tk_Screen(wmPtr->winPtr) != Tk_Screen(tkwin)) {
 	    continue;
 	}
@@ -5044,29 +5692,28 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
     }
 
     /*
-     * Step 2: work down through the window hierarchy starting at the
-     * root. For each window, find the child that contains the given
-     * point and then see if this child is either a wrapper for one of
-     * our toplevel windows or a window manager decoration window for
-     * one of our toplevels.  This approach handles several tricky
-     * cases:
+     * Step 2: work down through the window hierarchy starting at the root.
+     * For each window, find the child that contains the given point and then
+     * see if this child is either a wrapper for one of our toplevel windows
+     * or a window manager decoration window for one of our toplevels. This
+     * approach handles several tricky cases:
      *
-     * 1. There may be a virtual root window between the root and one of
-     *    our toplevels.
+     * 1. There may be a virtual root window between the root and one of our
+     *    toplevels.
      * 2. If a toplevel is embedded, we may have to search through the
-     *    windows of the container application(s) before getting to
-     *    the toplevel.
+     *    windows of the container application(s) before getting to the
+     *    toplevel.
      */
 
-    handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1,
-	    (Tk_ErrorProc *) NULL, (ClientData) NULL);
+    handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, NULL, NULL);
     while (1) {
 	if (XTranslateCoordinates(Tk_Display(tkwin), parent, window,
 		x, y, &childX, &childY, &child) == False) {
 	    /*
-	     * We can end up here when the window is in the middle of
-	     * being deleted
+	     * We can end up here when the window is in the middle of being
+	     * deleted
 	     */
+
 	    Tk_DeleteErrorHandler(handler);
 	    return NULL;
 	}
@@ -5075,7 +5722,7 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
 	    return NULL;
 	}
 	for (wmPtr = (WmInfo *) dispPtr->firstWmPtr; wmPtr != NULL;
-                wmPtr = wmPtr->nextPtr) {
+		wmPtr = wmPtr->nextPtr) {
 	    if (wmPtr->reparent == child) {
 		goto gotToplevel;
 	    }
@@ -5093,12 +5740,13 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
 	window = child;
     }
 
-    gotToplevel:
+  gotToplevel:
     if (handler) {
 	/*
-	 * Check value of handler, because we can reach this label
-	 * from above or below
+	 * Check value of handler, because we can reach this label from above
+	 * or below
 	 */
+
 	Tk_DeleteErrorHandler(handler);
 	handler = NULL;
     }
@@ -5110,10 +5758,9 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
     /*
      * Step 3: at this point winPtr and wmPtr refer to the toplevel that
      * contains the given coordinates, and childX and childY give the
-     * translated coordinates in the *parent* of the toplevel.  Now
-     * decide whether the coordinates are in the menubar or the actual
-     * toplevel, and translate the coordinates into the coordinate
-     * system of that window.
+     * translated coordinates in the *parent* of the toplevel. Now decide
+     * whether the coordinates are in the menubar or the actual toplevel, and
+     * translate the coordinates into the coordinate system of that window.
      */
 
     x = childX - winPtr->changes.x;
@@ -5134,17 +5781,18 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
     }
 
     /*
-     * Step 4: work down through the hierarchy underneath the current
-     * window. At each level, scan through all the children to find the
-     * highest one in the stacking order that contains the point.  Then
-     * repeat the whole process on that child.
+     * Step 4: work down through the hierarchy underneath the current window.
+     * At each level, scan through all the children to find the highest one in
+     * the stacking order that contains the point. Then repeat the whole
+     * process on that child.
      */
 
     while (1) {
 	nextPtr = NULL;
 	for (childPtr = winPtr->childList; childPtr != NULL;
 		childPtr = childPtr->nextPtr) {
-	    if (!Tk_IsMapped(childPtr) || (childPtr->flags & TK_TOP_HIERARCHY)) {
+	    if (!Tk_IsMapped(childPtr)
+		    || (childPtr->flags & TK_TOP_HIERARCHY)) {
 		continue;
 	    }
 	    if (childPtr->flags & TK_REPARENTED) {
@@ -5169,12 +5817,15 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
 		&& (winPtr->flags & TK_BOTH_HALVES)) {
 	    /*
 	     * The window containing the point is a container, and the
-	     * embedded application is in this same process.  Switch
-	     * over to the toplevel for the embedded application and
-	     * start processing that toplevel from scratch.
+	     * embedded application is in this same process. Switch over to
+	     * the toplevel for the embedded application and start processing
+	     * that toplevel from scratch.
 	     */
 
 	    winPtr = TkpGetOtherWindow(winPtr);
+	    if (winPtr == NULL) {
+		return NULL;
+	    }
 	    wmPtr = winPtr->wmInfoPtr;
 	    childX = x;
 	    childY = y;
@@ -5189,24 +5840,23 @@ Tk_CoordsToWindow(rootX, rootY, tkwin)
  *
  * UpdateVRootGeometry --
  *
- *	This procedure is called to update all the virtual root
- *	geometry information in wmPtr.
+ *	This function is called to update all the virtual root geometry
+ *	information in wmPtr.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	The vRootX, vRootY, vRootWidth, and vRootHeight fields in
- *	wmPtr are filled with the most up-to-date information.
+ *	The vRootX, vRootY, vRootWidth, and vRootHeight fields in wmPtr are
+ *	filled with the most up-to-date information.
  *
  *----------------------------------------------------------------------
  */
 
 static void
-UpdateVRootGeometry(wmPtr)
-    WmInfo *wmPtr;		/* Window manager information to be
-				 * updated.  The wmPtr->vRoot field must
-				 * be valid. */
+UpdateVRootGeometry(
+    WmInfo *wmPtr)		/* Window manager information to be updated.
+				 * The wmPtr->vRoot field must be valid. */
 {
     TkWindow *winPtr = wmPtr->winPtr;
     int bd;
@@ -5222,7 +5872,7 @@ UpdateVRootGeometry(wmPtr)
 
     wmPtr->flags &= ~WM_VROOT_OFFSET_STALE;
     if (wmPtr->vRoot == None) {
-	noVRoot:
+    noVRoot:
 	wmPtr->vRootX = wmPtr->vRootY = 0;
 	wmPtr->vRootWidth = DisplayWidth(winPtr->display, winPtr->screenNum);
 	wmPtr->vRootHeight = DisplayHeight(winPtr->display, winPtr->screenNum);
@@ -5233,8 +5883,7 @@ UpdateVRootGeometry(wmPtr)
      * Refresh the virtual root information if it's out of date.
      */
 
-    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1,
-	    (Tk_ErrorProc *) NULL, (ClientData) NULL);
+    handler = Tk_CreateErrorHandler(winPtr->display, -1, -1, -1, NULL, NULL);
     status = XGetGeometry(winPtr->display, wmPtr->vRoot,
 	    &dummy2, &wmPtr->vRootX, &wmPtr->vRootY,
 	    (unsigned int *) &wmPtr->vRootWidth,
@@ -5248,7 +5897,7 @@ UpdateVRootGeometry(wmPtr)
     Tk_DeleteErrorHandler(handler);
     if (status == 0) {
 	/*
-	 * The virtual root is gone!  Pretend that it never existed.
+	 * The virtual root is gone! Pretend that it never existed.
 	 */
 
 	wmPtr->vRoot = None;
@@ -5261,16 +5910,15 @@ UpdateVRootGeometry(wmPtr)
  *
  * Tk_GetVRootGeometry --
  *
- *	This procedure returns information about the virtual root
- *	window corresponding to a particular Tk window.
+ *	This function returns information about the virtual root window
+ *	corresponding to a particular Tk window.
  *
  * Results:
- *	The values at xPtr, yPtr, widthPtr, and heightPtr are set
- *	with the offset and dimensions of the root window corresponding
- *	to tkwin.  If tkwin is being managed by a virtual root window
- *	manager these values correspond to the virtual root window being
- *	used for tkwin;  otherwise the offsets will be 0 and the
- *	dimensions will be those of the screen.
+ *	The values at xPtr, yPtr, widthPtr, and heightPtr are set with the
+ *	offset and dimensions of the root window corresponding to tkwin. If
+ *	tkwin is being managed by a virtual root window manager these values
+ *	correspond to the virtual root window being used for tkwin; otherwise
+ *	the offsets will be 0 and the dimensions will be those of the screen.
  *
  * Side effects:
  *	Vroot window information is refreshed if it is out of date.
@@ -5279,12 +5927,13 @@ UpdateVRootGeometry(wmPtr)
  */
 
 void
-Tk_GetVRootGeometry(tkwin, xPtr, yPtr, widthPtr, heightPtr)
-    Tk_Window tkwin;		/* Window whose virtual root is to be
+Tk_GetVRootGeometry(
+    Tk_Window tkwin,		/* Window whose virtual root is to be
 				 * queried. */
-    int *xPtr, *yPtr;		/* Store x and y offsets of virtual root
+    int *xPtr, int *yPtr,	/* Store x and y offsets of virtual root
 				 * here. */
-    int *widthPtr, *heightPtr;	/* Store dimensions of virtual root here. */
+    int *widthPtr, int *heightPtr)
+				/* Store dimensions of virtual root here. */
 {
     WmInfo *wmPtr;
     TkWindow *winPtr = (TkWindow *) tkwin;
@@ -5294,7 +5943,8 @@ Tk_GetVRootGeometry(tkwin, xPtr, yPtr, w
      * information for that window.
      */
 
-    while (!(winPtr->flags & TK_TOP_HIERARCHY) && (winPtr->parentPtr != NULL)) {
+    while (!(winPtr->flags & TK_TOP_HIERARCHY)
+	    && (winPtr->parentPtr != NULL)) {
 	winPtr = winPtr->parentPtr;
     }
     wmPtr = winPtr->wmInfoPtr;
@@ -5306,10 +5956,9 @@ Tk_GetVRootGeometry(tkwin, xPtr, yPtr, w
 	*heightPtr = 0;
     }
 
-
     /*
-     * Make sure that the geometry information is up-to-date, then copy
-     * it out to the caller.
+     * Make sure that the geometry information is up-to-date, then copy it out
+     * to the caller.
      */
 
     if (wmPtr->flags & WM_VROOT_OFFSET_STALE) {
@@ -5326,33 +5975,31 @@ Tk_GetVRootGeometry(tkwin, xPtr, yPtr, w
  *
  * Tk_MoveToplevelWindow --
  *
- *	This procedure is called instead of Tk_MoveWindow to adjust
- *	the x-y location of a top-level window.  It delays the actual
- *	move to a later time and keeps window-manager information
- *	up-to-date with the move
+ *	This function is called instead of Tk_MoveWindow to adjust the x-y
+ *	location of a top-level window. It delays the actual move to a later
+ *	time and keeps window-manager information up-to-date with the move
  *
  * Results:
  *	None.
  *
  * Side effects:
  *	The window is eventually moved so that its upper-left corner
- *	(actually, the upper-left corner of the window's decorative
- *	frame, if there is one) is at (x,y).
+ *	(actually, the upper-left corner of the window's decorative frame, if
+ *	there is one) is at (x,y).
  *
  *----------------------------------------------------------------------
  */
 
 void
-Tk_MoveToplevelWindow(tkwin, x, y)
-    Tk_Window tkwin;		/* Window to move. */
-    int x, y;			/* New location for window (within
-				 * parent). */
+Tk_MoveToplevelWindow(
+    Tk_Window tkwin,		/* Window to move. */
+    int x, int y)		/* New location for window (within parent). */
 {
     TkWindow *winPtr = (TkWindow *) tkwin;
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
 
     if (!(winPtr->flags & TK_TOP_LEVEL)) {
-	panic("Tk_MoveToplevelWindow called with non-toplevel window");
+	Tcl_Panic("Tk_MoveToplevelWindow called with non-toplevel window");
     }
     wmPtr->x = x;
     wmPtr->y = y;
@@ -5365,9 +6012,8 @@ Tk_MoveToplevelWindow(tkwin, x, y)
 
     /*
      * If the window has already been mapped, must bring its geometry
-     * up-to-date immediately, otherwise an event might arrive from the
-     * server that would overwrite wmPtr->x and wmPtr->y and lose the
-     * new position.
+     * up-to-date immediately, otherwise an event might arrive from the server
+     * that would overwrite wmPtr->x and wmPtr->y and lose the new position.
      */
 
     if (!(wmPtr->flags & WM_NEVER_MAPPED)) {
@@ -5383,9 +6029,9 @@ Tk_MoveToplevelWindow(tkwin, x, y)
  *
  * UpdateWmProtocols --
  *
- *	This procedure transfers the most up-to-date information about
- *	window manager protocols from the WmInfo structure to the actual
- *	property on the top-level window.
+ *	This function transfers the most up-to-date information about window
+ *	manager protocols from the WmInfo structure to the actual property on
+ *	the top-level window.
  *
  * Results:
  *	None.
@@ -5397,8 +6043,8 @@ Tk_MoveToplevelWindow(tkwin, x, y)
  */
 
 static void
-UpdateWmProtocols(wmPtr)
-    register WmInfo *wmPtr;	/* Information about top-level window. */
+UpdateWmProtocols(
+    register WmInfo *wmPtr)	/* Information about top-level window. */
 {
     register ProtocolHandler *protPtr;
     Atom deleteWindowAtom;
@@ -5406,15 +6052,15 @@ UpdateWmProtocols(wmPtr)
     Atom *arrayPtr, *atomPtr;
 
     /*
-     * There are only two tricky parts here.  First, there could be any
-     * number of atoms for the window, so count them and malloc an array
-     * to hold all of their atoms.  Second, we *always* want to respond
-     * to the WM_DELETE_WINDOW protocol, even if no-one's officially asked.
+     * There are only two tricky parts here. First, there could be any number
+     * of atoms for the window, so count them and malloc an array to hold all
+     * of their atoms. Second, we *always* want to respond to the
+     * WM_DELETE_WINDOW protocol, even if no-one's officially asked.
      */
 
     for (protPtr = wmPtr->protPtr, count = 1; protPtr != NULL;
 	    protPtr = protPtr->nextPtr, count++) {
-	/* Empty loop body;  we're just counting the handlers. */
+	/* Empty loop body; we're just counting the handlers. */
     }
     arrayPtr = (Atom *) ckalloc((unsigned) (count * sizeof(Atom)));
     deleteWindowAtom = Tk_InternAtom((Tk_Window) wmPtr->winPtr,
@@ -5439,25 +6085,23 @@ UpdateWmProtocols(wmPtr)
  *
  * TkWmProtocolEventProc --
  *
- *	This procedure is called by the Tk_HandleEvent whenever a
- *	ClientMessage event arrives whose type is "WM_PROTOCOLS".
- *	This procedure handles the message from the window manager
- *	in an appropriate fashion.
+ *	This function is called by the Tk_HandleEvent whenever a ClientMessage
+ *	event arrives whose type is "WM_PROTOCOLS". This function handles the
+ *	message from the window manager in an appropriate fashion.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	Depends on what sort of handler, if any, was set up for the
- *	protocol.
+ *	Depends on what sort of handler, if any, was set up for the protocol.
  *
  *----------------------------------------------------------------------
  */
 
 void
-TkWmProtocolEventProc(winPtr, eventPtr)
-    TkWindow *winPtr;		/* Window to which the event was sent. */
-    XEvent *eventPtr;		/* X event. */
+TkWmProtocolEventProc(
+    TkWindow *winPtr,		/* Window to which the event was sent. */
+    XEvent *eventPtr)		/* X event. */
 {
     WmInfo *wmPtr;
     register ProtocolHandler *protPtr;
@@ -5473,11 +6117,11 @@ TkWmProtocolEventProc(winPtr, eventPtr)
     protocol = (Atom) eventPtr->xclient.data.l[0];
 
     /*
-     * Note: it's very important to retrieve the protocol name now,
-     * before invoking the command, even though the name won't be used
-     * until after the command returns.  This is because the command
-     * could delete winPtr, making it impossible for us to use it
-     * later in the call to Tk_GetAtomName.
+     * Note: it's very important to retrieve the protocol name now, before
+     * invoking the command, even though the name won't be used until after
+     * the command returns. This is because the command could delete winPtr,
+     * making it impossible for us to use it later in the call to
+     * Tk_GetAtomName.
      */
 
     protocolName = Tk_GetAtomName((Tk_Window) winPtr, protocol);
@@ -5485,8 +6129,8 @@ TkWmProtocolEventProc(winPtr, eventPtr)
 	    protPtr = protPtr->nextPtr) {
 	if (protocol == protPtr->protocol) {
 	    Tcl_Preserve((ClientData) protPtr);
-            interp = protPtr->interp;
-            Tcl_Preserve((ClientData) interp);
+	    interp = protPtr->interp;
+	    Tcl_Preserve((ClientData) interp);
 	    winPtr->dispPtr->lastEventTime = (Time) eventPtr->xclient.data.l[1];
 	    result = LangDoCallback(protPtr->interp, protPtr->command, 0, 0);
 	    if (result != TCL_OK) {
@@ -5496,15 +6140,15 @@ TkWmProtocolEventProc(winPtr, eventPtr)
 			"\" window manager protocol)");
 		Tcl_BackgroundError(interp);
 	    }
-            Tcl_Release((ClientData) interp);
+	    Tcl_Release((ClientData) interp);
 	    Tcl_Release((ClientData) protPtr);
 	    return;
 	}
     }
 
     /*
-     * No handler was present for this protocol.  If this is a
-     * WM_DELETE_WINDOW message then just destroy the window.
+     * No handler was present for this protocol. If this is a WM_DELETE_WINDOW
+     * message then just destroy the window.
      */
 
     if (protocol == Tk_InternAtom((Tk_Window) winPtr, "WM_DELETE_WINDOW")) {
@@ -5517,12 +6161,12 @@ TkWmProtocolEventProc(winPtr, eventPtr)
  *
  * TkWmStackorderToplevelWrapperMap --
  *
- *	This procedure will create a table that maps the reparent wrapper
- *	X id for a toplevel to the TkWindow structure that is wraps.
- *	Tk keeps track of a mapping from the window X id to the TkWindow
- *	structure but that does us no good here since we only get the X
- *	id of the wrapper window. Only those toplevel windows that are
- *	mapped have a position in the stacking order.
+ *	This function will create a table that maps the reparent wrapper X id
+ *	for a toplevel to the TkWindow structure that is wraps. Tk keeps track
+ *	of a mapping from the window X id to the TkWindow structure but that
+ *	does us no good here since we only get the X id of the wrapper window.
+ *	Only those toplevel windows that are mapped have a position in the
+ *	stacking order.
  *
  * Results:
  *	None.
@@ -5534,29 +6178,28 @@ TkWmProtocolEventProc(winPtr, eventPtr)
  */
 
 static void
-TkWmStackorderToplevelWrapperMap(winPtr, table)
-    TkWindow *winPtr;				/* TkWindow to recurse on */
-    Tcl_HashTable *table;			/* Maps X id to TkWindow */
+TkWmStackorderToplevelWrapperMap(
+    TkWindow *winPtr,		/* TkWindow to recurse on */
+    Display *display,		/* X display of parent window */
+    Tcl_HashTable *table)	/* Maps X id to TkWindow */
 {
     TkWindow *childPtr;
-    Tcl_HashEntry *hPtr;
-    Window wrapper;
-    int newEntry;
 
     if (Tk_IsMapped(winPtr) && Tk_IsTopLevel(winPtr) &&
-            !Tk_IsEmbedded(winPtr)) {
-        wrapper = (winPtr->wmInfoPtr->reparent != None)
-            ? winPtr->wmInfoPtr->reparent
-            : winPtr->wmInfoPtr->wrapperPtr->window;
-
-        hPtr = Tcl_CreateHashEntry(table,
-            (char *) wrapper, &newEntry);
-        Tcl_SetHashValue(hPtr, winPtr);
+	    !Tk_IsEmbedded(winPtr) && (winPtr->display == display)) {
+	Window wrapper = (winPtr->wmInfoPtr->reparent != None)
+		? winPtr->wmInfoPtr->reparent
+		: winPtr->wmInfoPtr->wrapperPtr->window;
+	Tcl_HashEntry *hPtr;
+	int newEntry;
+
+	hPtr = Tcl_CreateHashEntry(table, (char *) wrapper, &newEntry);
+	Tcl_SetHashValue(hPtr, winPtr);
     }
 
     for (childPtr = winPtr->childList; childPtr != NULL;
-            childPtr = childPtr->nextPtr) {
-        TkWmStackorderToplevelWrapperMap(childPtr, table);
+	    childPtr = childPtr->nextPtr) {
+	TkWmStackorderToplevelWrapperMap(childPtr, display, table);
     }
 }
 
@@ -5565,11 +6208,11 @@ TkWmStackorderToplevelWrapperMap(winPtr,
  *
  * TkWmStackorderToplevel --
  *
- *	This procedure returns the stack order of toplevel windows.
+ *	This function returns the stack order of toplevel windows.
  *
  * Results:
- *	An array of pointers to tk window objects in stacking order
- *	or else NULL if there was an error.
+ *	An array of pointers to tk window objects in stacking order or else
+ *	NULL if there was an error.
  *
  * Side effects:
  *	None.
@@ -5578,8 +6221,8 @@ TkWmStackorderToplevelWrapperMap(winPtr,
  */
 
 TkWindow **
-TkWmStackorderToplevel(parentPtr)
-    TkWindow *parentPtr;		/* Parent toplevel window. */
+TkWmStackorderToplevel(
+    TkWindow *parentPtr)	/* Parent toplevel window. */
 {
     Window dummy1, dummy2, vRoot;
     Window *children;
@@ -5594,53 +6237,54 @@ TkWmStackorderToplevel(parentPtr)
      */
 
     Tcl_InitHashTable(&table, TCL_ONE_WORD_KEYS);
-    TkWmStackorderToplevelWrapperMap(parentPtr, &table);
+    TkWmStackorderToplevelWrapperMap(parentPtr, parentPtr->display, &table);
 
-    window_ptr = windows = (TkWindow **) ckalloc((table.numEntries+1)
-        * sizeof(TkWindow *));
+    window_ptr = windows = (TkWindow **)
+	    ckalloc((table.numEntries+1) * sizeof(TkWindow *));
 
     /*
-     * Special cases: If zero or one toplevels were mapped
-     * there is no need to call XQueryTree.
+     * Special cases: If zero or one toplevels were mapped there is no need to
+     * call XQueryTree.
      */
 
     switch (table.numEntries) {
     case 0:
-        windows[0] = NULL;
-        goto done;
+	windows[0] = NULL;
+	goto done;
     case 1:
-        hPtr = Tcl_FirstHashEntry(&table, &search);
-        windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr);
-        windows[1] = NULL;
-        goto done;
+	hPtr = Tcl_FirstHashEntry(&table, &search);
+	windows[0] = (TkWindow *) Tcl_GetHashValue(hPtr);
+	windows[1] = NULL;
+	goto done;
     }
 
     vRoot = parentPtr->wmInfoPtr->vRoot;
     if (vRoot == None) {
-        vRoot = RootWindowOfScreen(Tk_Screen((Tk_Window) parentPtr));
+	vRoot = RootWindowOfScreen(Tk_Screen((Tk_Window) parentPtr));
     }
 
     if (XQueryTree(parentPtr->display, vRoot, &dummy1, &dummy2,
-            &children, &numChildren) == 0) {
-        ckfree((char *) windows);
-        windows = NULL;
+	    &children, &numChildren) == 0) {
+	ckfree((char *) windows);
+	windows = NULL;
     } else {
-        for (i = 0; i < numChildren; i++) {
-            hPtr = Tcl_FindHashEntry(&table, (char *) children[i]);
-            if (hPtr != NULL) {
-                childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr);
-                *window_ptr++ = childWinPtr;
-            }
-        }
-        if ((window_ptr - windows) != table.numEntries)
-            panic("num matched toplevel windows does not equal num children");
-        *window_ptr = NULL;
+	for (i = 0; i < numChildren; i++) {
+	    hPtr = Tcl_FindHashEntry(&table, (char *) children[i]);
+	    if (hPtr != NULL) {
+		childWinPtr = (TkWindow *) Tcl_GetHashValue(hPtr);
+		*window_ptr++ = childWinPtr;
+	    }
+	}
+	if ((window_ptr - windows) != table.numEntries) {
+	    Tcl_Panic("num matched toplevel windows does not equal num children");
+	}
+	*window_ptr = NULL;
 	if (numChildren) {
 	    XFree((char *) children);
 	}
     }
 
-    done:
+  done:
     Tcl_DeleteHashTable(&table);
     return windows;
 }
@@ -5650,25 +6294,25 @@ TkWmStackorderToplevel(parentPtr)
  *
  * TkWmRestackToplevel --
  *
- *	This procedure restacks a top-level window.
+ *	This function restacks a top-level window.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	WinPtr gets restacked  as specified by aboveBelow and otherPtr.
+ *	WinPtr gets restacked as specified by aboveBelow and otherPtr.
  *
  *----------------------------------------------------------------------
  */
 
 void
-TkWmRestackToplevel(winPtr, aboveBelow, otherPtr)
-    TkWindow *winPtr;		/* Window to restack. */
-    int aboveBelow;		/* Gives relative position for restacking;
+TkWmRestackToplevel(
+    TkWindow *winPtr,		/* Window to restack. */
+    int aboveBelow,		/* Gives relative position for restacking;
 				 * must be Above or Below. */
-    TkWindow *otherPtr;		/* Window relative to which to restack;
-				 * if NULL, then winPtr gets restacked
-				 * above or below *all* siblings. */
+    TkWindow *otherPtr)		/* Window relative to which to restack; if
+				 * NULL, then winPtr gets restacked above or
+				 * below *all* siblings. */
 {
     XWindowChanges changes;
     unsigned int mask;
@@ -5681,6 +6325,7 @@ TkWmRestackToplevel(winPtr, aboveBelow, 
     /*
      * Make sure that winPtr and its wrapper window have been created.
      */
+
     if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
 	TkWmMapWindow(winPtr);
     }
@@ -5691,6 +6336,7 @@ TkWmRestackToplevel(winPtr, aboveBelow, 
 	 * The window is to be restacked with respect to another toplevel.
 	 * Make sure it has been created as well.
 	 */
+
 	if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
 	    TkWmMapWindow(otherPtr);
 	}
@@ -5699,15 +6345,14 @@ TkWmRestackToplevel(winPtr, aboveBelow, 
     }
 
     /*
-     * Reconfigure the window.  Note that we use XReconfigureWMWindow
-     * instead of XConfigureWindow, in order to handle the case
-     * where the window is to be restacked with respect to another toplevel.
-     * See [ICCCM] 4.1.5 "Configuring the Window" and XReconfigureWMWindow(3)
-     * for details.
+     * Reconfigure the window. Note that we use XReconfigureWMWindow instead
+     * of XConfigureWindow, in order to handle the case where the window is to
+     * be restacked with respect to another toplevel. See [ICCCM] 4.1.5
+     * "Configuring the Window" and XReconfigureWMWindow(3) for details.
      */
 
     XReconfigureWMWindow(winPtr->display, wrapperPtr->window,
-	    Tk_ScreenNumber((Tk_Window) winPtr), mask,  &changes);
+	    Tk_ScreenNumber((Tk_Window) winPtr), mask, &changes);
 }
 
 
@@ -5716,28 +6361,27 @@ TkWmRestackToplevel(winPtr, aboveBelow, 
  *
  * TkWmAddToColormapWindows --
  *
- *	This procedure is called to add a given window to the
- *	WM_COLORMAP_WINDOWS property for its top-level, if it
- *	isn't already there.  It is invoked by the Tk code that
- *	creates a new colormap, in order to make sure that colormap
- *	information is propagated to the window manager by default.
+ *	This function is called to add a given window to the
+ *	WM_COLORMAP_WINDOWS property for its top-level, if it isn't already
+ *	there. It is invoked by the Tk code that creates a new colormap, in
+ *	order to make sure that colormap information is propagated to the
+ *	window manager by default.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	WinPtr's window gets added to the WM_COLORMAP_WINDOWS
- *	property of its nearest top-level ancestor, unless the
- *	colormaps have been set explicitly with the
- *	"wm colormapwindows" command.
+ *	WinPtr's window gets added to the WM_COLORMAP_WINDOWS property of its
+ *	nearest top-level ancestor, unless the colormaps have been set
+ *	explicitly with the "wm colormapwindows" command.
  *
  *----------------------------------------------------------------------
  */
 
 void
-TkWmAddToColormapWindows(winPtr)
-    TkWindow *winPtr;		/* Window with a non-default colormap.
-				 * Should not be a top-level window. */
+TkWmAddToColormapWindows(
+    TkWindow *winPtr)		/* Window with a non-default colormap. Should
+				 * not be a top-level window. */
 {
     TkWindow *wrapperPtr;
     TkWindow *topPtr;
@@ -5751,7 +6395,7 @@ TkWmAddToColormapWindows(winPtr)
     for (topPtr = winPtr->parentPtr; ; topPtr = topPtr->parentPtr) {
 	if (topPtr == NULL) {
 	    /*
-	     * Window is being deleted.  Skip the whole operation.
+	     * Window is being deleted. Skip the whole operation.
 	     */
 
 	    return;
@@ -5793,9 +6437,8 @@ TkWmAddToColormapWindows(winPtr)
     }
 
     /*
-     * Make a new bigger array and use it to reset the property.
-     * Automatically add the toplevel itself as the last element
-     * of the list.
+     * Make a new bigger array and use it to reset the property. Automatically
+     * add the toplevel itself as the last element of the list.
      */
 
     newPtr = (Window *) ckalloc((unsigned) ((count+2)*sizeof(Window)));
@@ -5820,26 +6463,26 @@ TkWmAddToColormapWindows(winPtr)
  *
  * TkWmRemoveFromColormapWindows --
  *
- *	This procedure is called to remove a given window from the
- *	WM_COLORMAP_WINDOWS property for its top-level.  It is invoked
- *	when windows are deleted.
+ *	This function is called to remove a given window from the
+ *	WM_COLORMAP_WINDOWS property for its top-level. It is invoked when
+ *	windows are deleted.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	WinPtr's window gets removed from the WM_COLORMAP_WINDOWS
- *	property of its nearest top-level ancestor, unless the
- *	top-level itself is being deleted too.
+ *	WinPtr's window gets removed from the WM_COLORMAP_WINDOWS property of
+ *	its nearest top-level ancestor, unless the top-level itself is being
+ *	deleted too.
  *
  *----------------------------------------------------------------------
  */
 
 void
-TkWmRemoveFromColormapWindows(winPtr)
-    TkWindow *winPtr;		/* Window that may be present in
+TkWmRemoveFromColormapWindows(
+    TkWindow *winPtr)		/* Window that may be present in
 				 * WM_COLORMAP_WINDOWS property for its
-				 * top-level.  Should not be a top-level
+				 * top-level. Should not be a top-level
 				 * window. */
 {
     TkWindow *wrapperPtr;
@@ -5866,8 +6509,8 @@ TkWmRemoveFromColormapWindows(winPtr)
     }
     if (topPtr->flags & TK_ALREADY_DEAD) {
 	/*
-	 * Top-level is being deleted, so there's no need to cleanup
-	 * the WM_COLORMAP_WINDOWS property.
+	 * Top-level is being deleted, so there's no need to cleanup the
+	 * WM_COLORMAP_WINDOWS property.
 	 */
 
 	return;
@@ -5894,8 +6537,7 @@ TkWmRemoveFromColormapWindows(winPtr)
     }
 
     /*
-     * Find the window and slide the following ones down to cover
-     * it up.
+     * Find the window and slide the following ones down to cover it up.
      */
 
     for (i = 0; i < count; i++) {
@@ -5919,10 +6561,10 @@ TkWmRemoveFromColormapWindows(winPtr)
  *	Fetch the position of the mouse pointer.
  *
  * Results:
- *	*xPtr and *yPtr are filled in with the (virtual) root coordinates
- *	of the mouse pointer for tkwin's display.  If the pointer isn't
- *	on tkwin's screen, then -1 values are returned for both
- *	coordinates.  The argument tkwin must be a toplevel window.
+ *	*xPtr and *yPtr are filled in with the (virtual) root coordinates of
+ *	the mouse pointer for tkwin's display. If the pointer isn't on tkwin's
+ *	screen, then -1 values are returned for both coordinates. The argument
+ *	tkwin must be a toplevel window.
  *
  * Side effects:
  *	None.
@@ -5931,10 +6573,10 @@ TkWmRemoveFromColormapWindows(winPtr)
  */
 
 void
-TkGetPointerCoords(tkwin, xPtr, yPtr)
-    Tk_Window tkwin;		/* Toplevel window that identifies screen
-				 * on which lookup is to be done. */
-    int *xPtr, *yPtr;		/* Store pointer coordinates here. */
+TkGetPointerCoords(
+    Tk_Window tkwin,		/* Toplevel window that identifies screen on
+				 * which lookup is to be done. */
+    int *xPtr, int *yPtr)	/* Store pointer coordinates here. */
 {
     TkWindow *winPtr = (TkWindow *) tkwin;
     WmInfo *wmPtr;
@@ -5960,16 +6602,15 @@ TkGetPointerCoords(tkwin, xPtr, yPtr)
  *
  * GetMaxSize --
  *
- *	This procedure computes the current maxWidth and maxHeight
- *	values for a window, taking into account the possibility
- *	that they may be defaulted.
+ *	This function computes the current maxWidth and maxHeight values for a
+ *	window, taking into account the possibility that they may be
+ *	defaulted.
  *
  * Results:
- *	The values at *maxWidthPtr and *maxHeightPtr are filled
- *	in with the maximum allowable dimensions of wmPtr's window,
- *	in grid units.  If no maximum has been specified for the
- *	window, then this procedure computes the largest sizes that
- *	will fit on the screen.
+ *	The values at *maxWidthPtr and *maxHeightPtr are filled in with the
+ *	maximum allowable dimensions of wmPtr's window, in grid units. If no
+ *	maximum has been specified for the window, then this function computes
+ *	the largest sizes that will fit on the screen.
  *
  * Side effects:
  *	None.
@@ -5978,13 +6619,13 @@ TkGetPointerCoords(tkwin, xPtr, yPtr)
  */
 
 static void
-GetMaxSize(wmPtr, maxWidthPtr, maxHeightPtr)
-    WmInfo *wmPtr;		/* Window manager information for the
+GetMaxSize(
+    WmInfo *wmPtr,		/* Window manager information for the
 				 * window. */
-    int *maxWidthPtr;		/* Where to store the current maximum
-				 * width of the window. */
-    int *maxHeightPtr;		/* Where to store the current maximum
-				 * height of the window. */
+    int *maxWidthPtr,		/* Where to store the current maximum width of
+				 * the window. */
+    int *maxHeightPtr)		/* Where to store the current maximum height
+				 * of the window. */
 {
     int tmp;
 
@@ -5992,15 +6633,15 @@ GetMaxSize(wmPtr, maxWidthPtr, maxHeight
 	*maxWidthPtr = wmPtr->maxWidth;
     } else {
 	/*
-	 * Must compute a default width.  Fill up the display, leaving a
-	 * bit of extra space for the window manager's borders.
+	 * Must compute a default width. Fill up the display, leaving a bit of
+	 * extra space for the window manager's borders.
 	 */
 
 	tmp = DisplayWidth(wmPtr->winPtr->display, wmPtr->winPtr->screenNum)
 	    - 15;
 	if (wmPtr->gridWin != NULL) {
 	    /*
-	     * Gridding is turned on;  convert from pixels to grid units.
+	     * Gridding is turned on; convert from pixels to grid units.
 	     */
 
 	    tmp = wmPtr->reqGridWidth
@@ -6026,8 +6667,8 @@ GetMaxSize(wmPtr, maxWidthPtr, maxHeight
  *
  * TkpMakeMenuWindow --
  *
- *	Configure the window to be either a pull-down (or pop-up)
- *	menu, or as a toplevel (torn-off) menu or palette.
+ *	Configure the window to be either a pull-down (or pop-up) menu, or as
+ *	a toplevel (torn-off) menu or palette.
  *
  * Results:
  *	None.
@@ -6039,12 +6680,12 @@ GetMaxSize(wmPtr, maxWidthPtr, maxHeight
  */
 
 void
-TkpMakeMenuWindow(tkwin, transient)
-    Tk_Window tkwin;		/* New window. */
-    int transient;		/* 1 means menu is only posted briefly as
-				 * a popup or pulldown or cascade.  0 means
-				 * menu is always visible, e.g. as a torn-off
-				 * menu.  Determines whether save_under and
+TkpMakeMenuWindow(
+    Tk_Window tkwin,		/* New window. */
+    int transient)		/* 1 means menu is only posted briefly as a
+				 * popup or pulldown or cascade. 0 means menu
+				 * is always visible, e.g. as a torn-off menu.
+				 * Determines whether save_under and
 				 * override_redirect should be set. */
 {
     WmInfo *wmPtr;
@@ -6068,13 +6709,13 @@ TkpMakeMenuWindow(tkwin, transient)
     }
 
     /*
-     * The override-redirect and save-under bits must be set on the
-     * wrapper window in order to have the desired effect.  However,
-     * also set the override-redirect bit on the window itself, so
-     * that the "wm overrideredirect" command will see it.
+     * The override-redirect and save-under bits must be set on the wrapper
+     * window in order to have the desired effect. However, also set the
+     * override-redirect bit on the window itself, so that the "wm
+     * overrideredirect" command will see it.
      */
 
-    if ((atts.override_redirect != Tk_Attributes(wrapperPtr)->override_redirect)
+    if ((atts.override_redirect!=Tk_Attributes(wrapperPtr)->override_redirect)
 	    || (atts.save_under != Tk_Attributes(wrapperPtr)->save_under)) {
 	Tk_ChangeWindowAttributes((Tk_Window) wrapperPtr,
 		CWOverrideRedirect|CWSaveUnder, &atts);
@@ -6091,9 +6732,9 @@ TkpMakeMenuWindow(tkwin, transient)
  *
  * CreateWrapper --
  *
- *	This procedure is invoked to create the wrapper window for a
- *	toplevel window.  It is called just before a toplevel is mapped
- *	for the first time.
+ *	This function is invoked to create the wrapper window for a toplevel
+ *	window. It is called just before a toplevel is mapped for the first
+ *	time.
  *
  * Results:
  *	None.
@@ -6105,8 +6746,8 @@ TkpMakeMenuWindow(tkwin, transient)
  */
 
 static void
-CreateWrapper(wmPtr)
-    WmInfo *wmPtr;		/* Window manager information for the
+CreateWrapper(
+    WmInfo *wmPtr)		/* Window manager information for the
 				 * window. */
 {
     TkWindow *winPtr, *wrapperPtr;
@@ -6120,12 +6761,12 @@ CreateWrapper(wmPtr)
     }
 
     /*
-     * The code below is copied from CreateTopLevelWindow,
-     * Tk_MakeWindowExist, and TkpMakeWindow; The idea is to create an
-     * "official" Tk window (so that we can get events on it), but to
-     * hide the window outside the official Tk hierarchy so that it
-     * isn't visible to the application.  See the comments for the other
-     * procedures if you have questions about this code.
+     * The code below is copied from CreateTopLevelWindow, Tk_MakeWindowExist,
+     * and TkpMakeWindow. The idea is to create an "official" Tk window (so
+     * that we can get events on it), but to hide the window outside the
+     * official Tk hierarchy so that it isn't visible to the application. See
+     * the comments for the other functions if you have questions about this
+     * code.
      */
 
     wmPtr->wrapperPtr = wrapperPtr = TkAllocWindow(winPtr->dispPtr,
@@ -6133,12 +6774,11 @@ CreateWrapper(wmPtr)
     wrapperPtr->dirtyAtts |= CWBorderPixel;
 
     /*
-     * Tk doesn't normally select for StructureNotifyMask events because
-     * the events are synthesized internally.  However, for wrapper
-     * windows we need to know when the window manager modifies the
-     * window configuration.  We also need to select on focus change
-     * events; these are the only windows for which we care about focus
-     * changes.
+     * Tk doesn't normally select for StructureNotifyMask events because the
+     * events are synthesized internally. However, for wrapper windows we need
+     * to know when the window manager modifies the window configuration. We
+     * also need to select on focus change events; these are the only windows
+     * for which we care about focus changes.
      */
 
     wrapperPtr->flags |= TK_WRAPPER;
@@ -6173,13 +6813,13 @@ CreateWrapper(wmPtr)
 	    0, 0);
 
     /*
-     * Tk must monitor structure events for wrapper windows in order
-     * to detect changes made by window managers such as resizing,
-     * mapping, unmapping, etc..
+     * Tk must monitor structure events for wrapper windows in order to detect
+     * changes made by window managers such as resizing, mapping, unmapping,
+     * etc..
      */
 
-    Tk_CreateEventHandler((Tk_Window) wmPtr->wrapperPtr, StructureNotifyMask,
-	    WrapperEventProc, (ClientData) wmPtr);
+    Tk_CreateEventHandler((Tk_Window) wmPtr->wrapperPtr, 
+	    WrapperEventMask, WrapperEventProc, (ClientData) wmPtr);
 }
 
 /*
@@ -6187,16 +6827,15 @@ CreateWrapper(wmPtr)
  *
  * TkWmFocusToplevel --
  *
- *	This is a utility procedure invoked by focus-management code.
- *	The focus code responds to externally generated focus-related
- *	events on wrapper windows but ignores those events for any other
- *	windows.  This procedure determines whether a given window is a
- *	wrapper window and, if so, returns the toplevel window
- *	corresponding to the wrapper.
+ *	This is a utility function invoked by focus-management code. The focus
+ *	code responds to externally generated focus-related events on wrapper
+ *	windows but ignores those events for any other windows. This function
+ *	determines whether a given window is a wrapper window and, if so,
+ *	returns the toplevel window corresponding to the wrapper.
  *
  * Results:
- *	If winPtr is a wrapper window, returns a pointer to the
- *	corresponding toplevel window; otherwise returns NULL.
+ *	If winPtr is a wrapper window, returns a pointer to the corresponding
+ *	toplevel window; otherwise returns NULL.
  *
  * Side effects:
  *	None.
@@ -6205,8 +6844,8 @@ CreateWrapper(wmPtr)
  */
 
 TkWindow *
-TkWmFocusToplevel(winPtr)
-    TkWindow *winPtr;		/* Window that received a focus-related
+TkWmFocusToplevel(
+    TkWindow *winPtr)		/* Window that received a focus-related
 				 * event. */
 {
     if (!(winPtr->flags & TK_WRAPPER)) {
@@ -6220,31 +6859,30 @@ TkWmFocusToplevel(winPtr)
  *
  * TkUnixSetMenubar --
  *
- *	This procedure is invoked by menu management code to specify the
- *	window to use as a menubar for a given toplevel window.
+ *	This function is invoked by menu management code to specify the window
+ *	to use as a menubar for a given toplevel window.
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	The window given by menubar will be mapped and positioned inside
- *	the wrapper for tkwin and above tkwin.  Menubar will
- *	automatically be resized to maintain the height specified by
- *	TkUnixSetMenuHeight the same width as tkwin.  Any previous
- *	menubar specified for tkwin will be unmapped and ignored from
- *	now on.
+ *	The window given by menubar will be mapped and positioned inside the
+ *	wrapper for tkwin and above tkwin. Menubar will automatically be
+ *	resized to maintain the height specified by TkUnixSetMenuHeight the
+ *	same width as tkwin. Any previous menubar specified for tkwin will be
+ *	unmapped and ignored from now on.
  *
  *----------------------------------------------------------------------
  */
 
 void
-TkUnixSetMenubar(tkwin, menubar)
-    Tk_Window tkwin;		/* Token for toplevel window. */
-    Tk_Window menubar;		/* Token for window that is to serve as
-				 * menubar for tkwin.  Must not be a
-				 * toplevel window.  If NULL, any
-				 * existing menubar is canceled and the
-				 * menu height is reset to 0. */
+TkUnixSetMenubar(
+    Tk_Window tkwin,		/* Token for toplevel window. */
+    Tk_Window menubar)		/* Token for window that is to serve as
+				 * menubar for tkwin. Must not be a toplevel
+				 * window. If NULL, any existing menubar is
+				 * canceled and the menu height is reset to
+				 * 0. */
 {
     WmInfo *wmPtr = ((TkWindow *) tkwin)->wmInfoPtr;
     Tk_Window parent;
@@ -6256,9 +6894,9 @@ TkUnixSetMenubar(tkwin, menubar)
 
     if (wmPtr->menubar != NULL) {
 	/*
-	 * There's already a menubar for this toplevel.  If it isn't the
-	 * same as the new menubar, unmap it so that it is out of the
-	 * way, and reparent it back to its original parent.
+	 * There's already a menubar for this toplevel. If it isn't the same
+	 * as the new menubar, unmap it so that it is out of the way, and
+	 * reparent it back to its original parent.
 	 */
 
 	if (wmPtr->menubar == menubar) {
@@ -6275,7 +6913,7 @@ TkUnixSetMenubar(tkwin, menubar)
 	}
 	Tk_DeleteEventHandler(wmPtr->menubar, StructureNotifyMask,
 		MenubarDestroyProc, (ClientData) wmPtr->menubar);
-	Tk_ManageGeometry(wmPtr->menubar, NULL, (ClientData) NULL);
+	Tk_ManageGeometry(wmPtr->menubar, NULL, NULL);
     }
 
     wmPtr->menubar = menubar;
@@ -6283,8 +6921,8 @@ TkUnixSetMenubar(tkwin, menubar)
 	wmPtr->menuHeight = 0;
     } else {
 	if ((menubarPtr->flags & TK_TOP_LEVEL)
-	     || (Tk_Screen(menubar) != Tk_Screen(tkwin))) {
-	    panic("TkUnixSetMenubar got bad menubar");
+		|| (Tk_Screen(menubar) != Tk_Screen(tkwin))) {
+	    Tcl_Panic("TkUnixSetMenubar got bad menubar");
 	}
 	wmPtr->menuHeight = Tk_ReqHeight(menubar);
 	if (wmPtr->menuHeight == 0) {
@@ -6317,24 +6955,24 @@ TkUnixSetMenubar(tkwin, menubar)
  *
  * MenubarDestroyProc --
  *
- *	This procedure is invoked by the event dispatcher whenever a
- *	menubar window is destroyed (it's also invoked for a few other
- *	kinds of events, but we ignore those).
+ *	This function is invoked by the event dispatcher whenever a menubar
+ *	window is destroyed (it's also invoked for a few other kinds of
+ *	events, but we ignore those).
  *
  * Results:
  *	None.
  *
  * Side effects:
- *	The association between the window and its toplevel is broken,
- *	so that the window is no longer considered to be a menubar.
+ *	The association between the window and its toplevel is broken, so that
+ *	the window is no longer considered to be a menubar.
  *
  *----------------------------------------------------------------------
  */
 
 static void
-MenubarDestroyProc(clientData, eventPtr)
-    ClientData clientData;		/* TkWindow pointer for menubar. */
-    XEvent *eventPtr;			/* Describes what just happened. */
+MenubarDestroyProc(
+    ClientData clientData,	/* TkWindow pointer for menubar. */
+    XEvent *eventPtr)		/* Describes what just happened. */
 {
     WmInfo *wmPtr;
 
@@ -6356,9 +6994,8 @@ MenubarDestroyProc(clientData, eventPtr)
  *
  * MenubarReqProc --
  *
- *	This procedure is invoked by the Tk geometry management code
- *	whenever a menubar calls Tk_GeometryRequest to request a new
- *	size.
+ *	This function is invoked by the Tk geometry management code whenever a
+ *	menubar calls Tk_GeometryRequest to request a new size.
  *
  * Results:
  *	None.
@@ -6370,10 +7007,10 @@ MenubarDestroyProc(clientData, eventPtr)
  */
 
 static void
-MenubarReqProc(clientData, tkwin)
-    ClientData clientData;	/* Pointer to the window manager
-				 * information for tkwin's toplevel. */
-    Tk_Window tkwin;		/* Handle for menubar window. */
+MenubarReqProc(
+    ClientData clientData,	/* Pointer to the window manager information
+				 * for tkwin's toplevel. */
+    Tk_Window tkwin)		/* Handle for menubar window. */
 {
     WmInfo *wmPtr = (WmInfo *) clientData;
 
@@ -6393,12 +7030,12 @@ MenubarReqProc(clientData, tkwin)
  *
  * TkpGetWrapperWindow --
  *
- *	Given a toplevel window return the hidden wrapper window for
- *	the toplevel window if available.
+ *	Given a toplevel window return the hidden wrapper window for the
+ *	toplevel window if available.
  *
  * Results:
- *	The wrapper window.  NULL is we were not passed a toplevel
- *	window or the wrapper has yet to be created.
+ *	The wrapper window. NULL is we were not passed a toplevel window or
+ *	the wrapper has yet to be created.
  *
  * Side effects:
  *	None.
@@ -6407,8 +7044,8 @@ MenubarReqProc(clientData, tkwin)
  */
 
 TkWindow *
-TkpGetWrapperWindow(winPtr)
-    TkWindow *winPtr;		/* A toplevel window pointer. */
+TkpGetWrapperWindow(
+    TkWindow *winPtr)		/* A toplevel window pointer. */
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
 
@@ -6565,8 +7202,8 @@ int imageHeight;
  *
  * UpdateCommand --
  *
- *	Update the WM_COMMAND property, taking care to translate
- *	the command strings into the external encoding.
+ *	Update the WM_COMMAND property, taking care to translate the command
+ *	strings into the external encoding.
  *
  * Results:
  *	None.
@@ -6578,8 +7215,8 @@ int imageHeight;
  */
 
 static void
-UpdateCommand(winPtr)
-    TkWindow  *winPtr;
+UpdateCommand(
+    TkWindow *winPtr)
 {
     register WmInfo *wmPtr = winPtr->wmInfoPtr;
     Tcl_DString cmds, ds;
@@ -6588,15 +7225,15 @@ UpdateCommand(winPtr)
     int  cmdArgc;
 
     /*
-     * Translate the argv strings into the external encoding.  To avoid
-     * allocating lots of memory, the strings are appended to a buffer
-     * with nulls between each string.
+     * Translate the argv strings into the external encoding. To avoid
+     * allocating lots of memory, the strings are appended to a buffer with
+     * nulls between each string.
      *
-     * This code is tricky because we need to pass and array of pointers
-     * to XSetCommand.  However, we can't compute the pointers as we go
-     * because the DString buffer space could get reallocated.  So, store
-     * offsets for each element as we go, then compute pointers from the
-     * offsets once the entire DString is done.
+     * This code is tricky because we need to pass and array of pointers to
+     * XSetCommand. However, we can't compute the pointers as we go because
+     * the DString buffer space could get reallocated. So, store offsets for
+     * each element as we go, then compute pointers from the offsets once the
+     * entire DString is done.
      */
 #ifdef _LANG
     Tcl_Obj **cmdObjv;
@@ -6639,8 +7276,8 @@ UpdateCommand(winPtr)
  *
  * TkpWmSetState --
  *
- *	Sets the window manager state for the wrapper window of a
- *	given toplevel window.
+ *	Sets the window manager state for the wrapper window of a given
+ *	toplevel window.
  *
  * Results:
  *	0 on error, 1 otherwise
@@ -6652,48 +7289,48 @@ UpdateCommand(winPtr)
  */
 
 int
-TkpWmSetState(winPtr, state)
-     TkWindow *winPtr;		/* Toplevel window to operate on. */
-     int state;			/* One of IconicState, NormalState,
-				 * or WithdrawnState. */
+TkpWmSetState(
+     TkWindow *winPtr,		/* Toplevel window to operate on. */
+     int state)			/* One of IconicState, NormalState, or
+				 * WithdrawnState. */
 {
     WmInfo *wmPtr = winPtr->wmInfoPtr;
 
     if (state == WithdrawnState) {
-        wmPtr->hints.initial_state = WithdrawnState;
-        wmPtr->withdrawn = 1;
-        if (wmPtr->flags & WM_NEVER_MAPPED) {
-            return 1;
-        }
-        if (XWithdrawWindow(winPtr->display, wmPtr->wrapperPtr->window,
-                winPtr->screenNum) == 0) {
-            return 0;
-        }
-        WaitForMapNotify(winPtr, 0);
+	wmPtr->hints.initial_state = WithdrawnState;
+	wmPtr->withdrawn = 1;
+	if (wmPtr->flags & WM_NEVER_MAPPED) {
+	    return 1;
+	}
+	if (XWithdrawWindow(winPtr->display, wmPtr->wrapperPtr->window,
+		winPtr->screenNum) == 0) {
+	    return 0;
+	}
+	WaitForMapNotify(winPtr, 0);
     } else if (state == NormalState) {
-        wmPtr->hints.initial_state = NormalState;
-        wmPtr->withdrawn = 0;
-        if (wmPtr->flags & WM_NEVER_MAPPED) {
-            return 1;
-        }
-        UpdateHints(winPtr);
-        Tk_MapWindow((Tk_Window) winPtr);
+	wmPtr->hints.initial_state = NormalState;
+	wmPtr->withdrawn = 0;
+	if (wmPtr->flags & WM_NEVER_MAPPED) {
+	    return 1;
+	}
+	UpdateHints(winPtr);
+	Tk_MapWindow((Tk_Window) winPtr);
     } else if (state == IconicState) {
-        wmPtr->hints.initial_state = IconicState;
-        if (wmPtr->flags & WM_NEVER_MAPPED) {
-            return 1;
-        }
-        if (wmPtr->withdrawn) {
-            UpdateHints(winPtr);
-            Tk_MapWindow((Tk_Window) winPtr);
-            wmPtr->withdrawn = 0;
-        } else {
-            if (XIconifyWindow(winPtr->display, wmPtr->wrapperPtr->window,
-                    winPtr->screenNum) == 0) {
-                return 0;
-            }
-            WaitForMapNotify(winPtr, 0);
-        }
+	wmPtr->hints.initial_state = IconicState;
+	if (wmPtr->flags & WM_NEVER_MAPPED) {
+	    return 1;
+	}
+	if (wmPtr->withdrawn) {
+	    UpdateHints(winPtr);
+	    Tk_MapWindow((Tk_Window) winPtr);
+	    wmPtr->withdrawn = 0;
+	} else {
+	    if (XIconifyWindow(winPtr->display, wmPtr->wrapperPtr->window,
+		    winPtr->screenNum) == 0) {
+		return 0;
+	    }
+	    WaitForMapNotify(winPtr, 0);
+	}
     }
 
     return 1;
diff -up '/usr/local/src/Tk-804.027/pTk/mTk/unix/tkUnixXft.c' '/home/e/eserte/work/svk-checkouts/Tk/pTk/mTk/unix/tkUnixXft.c'
Index: ./pTk/mTk/unix/tkUnixXft.c
Prereq:  1.5 
--- ./pTk/mTk/unix/tkUnixXft.c	Thu Sep 11 13:32:32 2003
+++ ./pTk/mTk/unix/tkUnixXft.c	Fri Nov  3 20:36:08 2006
@@ -27,6 +27,9 @@
 
 #ifdef USE_XFT_FONTS
 
+#ifdef NEED_FT2BUILD_H
+#include <ft2build.h>
+#endif
 #include <X11/Xft/Xft.h>
 #include <ctype.h>
 
diff -up '/usr/local/src/Tk-804.027/pTk/mTk/xlib/X11/Xlib.h' '/home/e/eserte/work/svk-checkouts/Tk/pTk/mTk/xlib/X11/Xlib.h'
Index: ./pTk/mTk/xlib/X11/Xlib.h
--- ./pTk/mTk/xlib/X11/Xlib.h	Sat Apr  3 19:57:55 2004
+++ ./pTk/mTk/xlib/X11/Xlib.h	Mon Oct 30 23:18:13 2006
@@ -1203,7 +1203,7 @@ _XFUNCPROTOBEGIN
 
 
 
-#include "../pTk/tkIntXlibDecls.h"
+#include "../../../pTk/tkIntXlibDecls.h"
 
 _XFUNCPROTOEND
 
diff -up '/usr/local/src/Tk-804.027/pod/Font.pod' '/home/e/eserte/work/svk-checkouts/Tk/pod/Font.pod'
Index: ./pod/Font.pod
--- ./pod/Font.pod	Sat Jul 19 10:39:40 2003
+++ ./pod/Font.pod	Sat Nov  4 16:18:22 2006
@@ -206,13 +206,13 @@ such as lower-case ``g'' stick below the
 
 The amount in pixels that the tallest letter sticks up above the baseline of
 the font, plus any extra blank space added by the designer of the font.
-(I<$font>-<gt>B<ascent> is provided for compatibility.)
+(I<$font>-E<gt>B<ascent> is provided for compatibility.)
 
 =item B<-descent>
 
 The largest amount in pixels that any letter sticks down below the baseline
 of the font, plus any extra blank space added by the designer of the font.
-(I<$font>-<gt>B<descent> is provided for compatibility.)
+(I<$font>-E<gt>B<descent> is provided for compatibility.)
 
 =item B<-linespace>
 
diff -up '/usr/local/src/Tk-804.027/pod/Widget.pod' '/home/e/eserte/work/svk-checkouts/Tk/pod/Widget.pod'
Index: ./pod/Widget.pod
--- ./pod/Widget.pod	Wed Mar 10 09:35:40 2004
+++ ./pod/Widget.pod	Mon Oct 30 23:18:08 2006
@@ -613,6 +613,12 @@ to user interactions.
 If an event handler invokes B<tkwait> again, the nested call
 to B<tkwait> must complete before the outer call can complete.
 
+=item I<$widget>-E<gt>B<Walk>(I<proc>?, I<arg, ...>?)
+
+Traverse a widget hierarchy starting at I<$widget> while executing the
+subroutine I<proc> to every visited widget. The arguments I<arg, ...>
+are supplied to the subroutine.
+
 =item I<$widget>-E<gt>B<width>
 
 Returns a decimal string giving I<$widget>'s width in pixels.
diff -up '/usr/local/src/Tk-804.027/pod/Wm.pod' '/home/e/eserte/work/svk-checkouts/Tk/pod/Wm.pod'
Index: ./pod/Wm.pod
--- ./pod/Wm.pod	Sat Feb 28 17:35:54 2004
+++ ./pod/Wm.pod	Sun Nov  5 21:07:18 2006
@@ -298,6 +298,29 @@ or an empty string if no icon name has b
 case the window manager will normally display the window's title,
 as specified with the B<title> method).
 
+=item I<$toplevel>-E<gt>B<iconphoto>(?-default? I<image1> ?I<image2>
+...?)
+
+Sets the titlebar icon for  window  based  on  the  named  photo
+images.  If -default is specified, this is applied to all future
+created toplevels as well.  The data in the images is taken as a
+snapshot  at  the  time  of invocation.  If the images are later
+changed, this is not reflected to the titlebar icons.   Multiple
+images  are  accepted to allow different images sizes (eg, 16x16
+and 32x32) to be provided.  The window manager  may  scale  pro-
+vided icons to an appropriate size.
+
+On Windows, the images are packed into a Windows icon structure.
+This will override an ico specified to wm iconbitmap,  and  vice
+versa. [NOTE: This is not implemented yet!]
+
+On  X, the images are arranged into the _NET_WM_ICON X property,
+which most modern window managers support.  A wm iconbitmap  may
+exist  simultaneously.  It is recommended to use not more than 2
+icons, placing the larger icon first.
+
+On Macintosh, this is currently does nothing.
+
 =item I<$toplevel>-E<gt>B<iconposition>(?I<x y>?)
 
 If I<x> and I<y> are specified, they are passed to the window
diff -up '/usr/local/src/Tk-804.027/ptksh' '/home/e/eserte/work/svk-checkouts/Tk/ptksh'
Index: ./ptksh
--- ./ptksh	Sun Jul 27 17:23:57 2003
+++ ./ptksh	Sat Nov  4 14:16:47 2006
@@ -31,6 +31,8 @@
 #  - Clarify <Up> in docs and help means "up arrow"
 #  - Use HOMEDRIVE/HOMEPATH on Win32
 #
+# For more history look at the various Changes files in the Perl/Tk
+# distribution.
 
 =head1 NAME
 
@@ -94,11 +96,13 @@ in perl/Tk widget easier:
 
 displays a short help summary.
 
-=item B<d> ?I<args>, ...?
+=item B<d>, or B<x> ?I<args>, ...?
 
 Dumps recursively arguments to stdout. (see L<Data::Dumper>).
 You must have <Data::Dumper> installed to support this feature.
 
+B<x> was introduced for perl debugger compatibility.
+
 =item B<p> ?I<arg>, ...?
 
 appends "|\n" to each of it's arguments and prints it.
@@ -194,7 +198,7 @@ L<perldebug|perldebug>
 
 =head1 VERSION
 
-VERSION 2.02
+VERSION 2.03
 
 =head1 AUTHORS
 
@@ -217,7 +221,7 @@ use Tk;
 use vars qw($NAME $VERSION $FONT @FONT $WIN32 $HOME $HISTFILE $HISTSAVE $PROMPT $INITFILE);
 
 $NAME = 'ptksh';
-$VERSION = '2.02';
+$VERSION = '2.03';
 $WIN32 = 1 if $^O =~ /Win32/;
 $HOME = $WIN32 ? ($ENV{HOMEDRIVE} . $ENV{HOMEPATH}) || 'C:\\' : $ENV{HOME} . "/";
 @FONT = ($WIN32 ? (-font => 'systemfixed') : () );
@@ -252,7 +256,12 @@ $st = $mw->Scrolled('Text', -scrollbars 
 				-width => 80, -height => 25, @FONT);
 $t = $st->Subwidget('scrolled');
 $st->pack(-fill => 'both', -expand => 'true');
-$mw->bind('<Map>', sub {Center($mw);} );
+# $mw_mapped assures that Center is only called exactly twice: first time
+# will determine geometry of window, second time centering will work.
+# I observed a couple of further <Map> events, which are now ignored
+# and thus window creation seems to be faster now.
+my $mw_mapped;
+$mw->bind('<Map>', sub {return if $mw_mapped && $mw_mapped>=2; Center($mw); $mw_mapped++;} );
 
 # Event bindings
 $t->bindtags([$t, ref($t), $t->toplevel, 'all']); # take first crack at events
@@ -264,9 +273,19 @@ $t->bind('<Control-a>', \&BeginLine);
 $t->bind('<Home>', \&BeginLine);
 $t->bind('<Any-KeyPress>', [\&Key, Tk::Ev('K'), Tk::Ev('A')]);
 
+my $default_font = $t->cget(-font);
+my %default_font = $t->fontActual($default_font);
+my $normal_font;
+if (!$t->fontMetrics($default_font, '-fixed')) {
+    $normal_font = $t->fontCreate(%default_font, -family => "courier");
+    $t->configure(-font => $normal_font);
+}
+my %normal_font = $t->fontActual($normal_font);
+my $bold_font = $t->fontCreate(%normal_font, -weight => "bold");
+
 # Set up different colors for the various window outputs
 #$t->tagConfigure('prompt', -underline => 'true');
-$t->tagConfigure('prompt', -foreground => 'blue');
+$t->tagConfigure('prompt', -foreground => 'blue', -font => $bold_font);
 $t->tagConfigure('result', -foreground => 'purple');
 $t->tagConfigure('error', -foreground => 'red');
 $t->tagConfigure('output', -foreground => 'blue');
@@ -331,6 +350,7 @@ $t->focus;
 #$mw->after(1000, sub {print STDERR "now\n"; $mw->focus; $t->focus;});
 
 ##### Now enter main loop
+#$mw->afterIdle(sub {Center($mw);});
 MainLoop();
 
 ####### Callbacks/etc.
@@ -446,11 +466,13 @@ sub History {
 	$hist->bind('<Double-1>', \&HistPick);
 	$hist->bind('<Return>', \&HistPick);
 	$hist->bind('<Escape>', \&HistKill);
-	$hist->bind('<Map>', sub {Center($hist);} );
+	my $hist_mapped; # see above for $mw_mapped
+	$hist->bind('<Map>', sub {return if $hist_mapped && $hist_mapped>=2; Center($hist); $hist_mapped++;} );
 	$hist->bind('<Destroy>', \&HistDestroy);
 	$hist->focus;
 	$list->focus;
 	$hist->grab;
+	#$mw->afterIdle(sub {Center($hist);});
 	Tk->break;
 }
 
@@ -642,7 +664,7 @@ sub _h
     print <<'EOT';
 
   ? or h          print this message
-  d arg,...       calls Data::Dumper::Dumper
+  d or x arg,...  calls Data::Dumper::Dumper
   p arg,...       print args, each on a line and "|\n"
   o $w /regexp/   print options of widget matching regexp
   o $w [opt ...]  print (all) options of widget
@@ -668,7 +690,7 @@ sub PtkshCommand {
 		last if s/^\?\s*$/Tk::ptksh::_h /;
 		last if s/^h\s*$/Tk::ptksh::_h /;
 		last if s/^u(\s+|$)/Tk::ptksh::_u /;
-		last if s/^d\s+/Tk::ptksh::_d /;
+		last if s/^[dx]\s+/Tk::ptksh::_d /;
 		last if s/^u\s+(\S+)/Tk::ptksh::_u('$1')/;
 		last if s/^p\s+(.*)$/Tk::ptksh::_p $1;/;
 		last if s/^o\s+(\S+)\s*?$/Tk::ptksh::_o $1;/;
diff -up /dev/null '/home/e/eserte/work/svk-checkouts/Tk/t/00wmcheck.t'
Index: ./t/00wmcheck.t
--- ./t/00wmcheck.t	Thu Jan  1 01:00:00 1970
+++ ./t/00wmcheck.t	Wed Nov  8 23:58:41 2006
@@ -0,0 +1,66 @@
+#!/usr/bin/perl -w
+# -*- perl -*-
+
+#
+# $Id: $
+# Author: Slaven Rezic
+#
+
+use strict;
+
+use Tk;
+
+BEGIN {
+    if (!eval q{
+	use Test::More;
+	1;
+    }) {
+	print "1..0 # skip: no Test::More module\n";
+	exit;
+    }
+}
+
+plan tests => 1;
+
+my $wm_name     = "<unknown>";
+my $wm_version  = "<unknown>";
+
+my $mw = MainWindow->new;
+$mw->withdraw;
+
+diag("Tk platform: $Tk::platform");
+
+SKIP: {
+    skip("window manager check only on X11", 1)
+	if $Tk::platform ne "unix";
+
+    my($type,$windowid) = eval { $mw->property('get', '_NET_SUPPORTING_WM_CHECK', 'root') };
+    if (defined $windowid) {
+	($wm_name) = eval { $mw->property('get', '_NET_WM_NAME', $windowid) };
+	if (!$wm_name) {
+	    if (eval { $mw->property('get', '_WINDOWMAKER_NOTICEBOARD', $windowid); 1 }
+		|| eval { $mw->property('get', '_WINDOWMAKER_ICON_TILE', $windowid); 1 }) {
+		$wm_name = "WindowMaker";
+	    } else {
+		$wm_name = "<unknown> (property _NET_SUPPORTING_WM_CHECK exists, but getting _NET_WM_NAME fails)";
+	    }
+	} else {
+	    if ($wm_name eq 'Metacity') {
+		($wm_version) = eval { $mw->property('get', '_METACITY_VERSION', $windowid) };
+	    } else {
+		# just guess the VERSION property
+		my($maybe_wm_version) = eval { $mw->property('get', '_'.$wm_name.'_VERSION', $windowid) };
+		if ($maybe_wm_version) {
+		    $wm_version = $maybe_wm_version;
+		}
+	    }
+	}
+    }
+
+    diag("window manager: $wm_name");
+    diag("version: $wm_version");
+
+    pass("window manager check done");
+}
+
+__END__
diff -up '/usr/local/src/Tk-804.027/t/JP.t' '/home/e/eserte/work/svk-checkouts/Tk/t/JP.t'
Index: ./t/JP.t
--- ./t/JP.t	Tue Mar 23 18:22:27 2004
+++ ./t/JP.t	Sun Nov  5 11:41:31 2006
@@ -1,14 +1,19 @@
 use Tk;
+use Tk::Config ();
 use Encode qw(FB_CROAK);
 BEGIN
 {
- my $enc = Tk::SystemEncoding();
- eval { $enc->encode("\x{30C8}",FB_CROAK) };
- if ($@)
+ my $Xft = $Tk::Config::xlib =~ /-lXft\b/;
+ if (!$Xft) # assume we have CJK charsets with ttf fonts available
   {
-   my $err = "$@";
-   print "1..0 # Skipped: locale's '",$enc->name,"' cannot represent Japanese.\n";
-   CORE::exit(0);
+   my $enc = Tk::SystemEncoding();
+   eval { $enc->encode("\x{30C8}",FB_CROAK) };
+   if ($@)
+    {
+     my $err = "$@";
+     print "1..0 # Skipped: locale's '",$enc->name,"' cannot represent Japanese.\n";
+     CORE::exit(0);
+    }
   }
 }
 use Test::More (tests => 294);
@@ -31,5 +36,5 @@ while (<$fh>)
   ok(1);
  }
 close($fh);
-$mw->after(2000,[ destroy => $mw ]);
+$mw->after(100,[ destroy => $mw ]);
 MainLoop;
diff -up '/usr/local/src/Tk-804.027/t/KR.t' '/home/e/eserte/work/svk-checkouts/Tk/t/KR.t'
Index: ./t/KR.t
--- ./t/KR.t	Tue Mar 23 18:29:35 2004
+++ ./t/KR.t	Sun Nov  5 11:40:27 2006
@@ -1,14 +1,19 @@
 use Tk;
+use Tk::Config ();
 use Encode qw(FB_CROAK);
 BEGIN
 {
- my $enc = Tk::SystemEncoding();
- eval { $enc->encode("\x{AC00}",FB_CROAK) };
- if ($@)
+ my $Xft = $Tk::Config::xlib =~ /-lXft\b/;
+ if (!$Xft) # assume we have CJK charsets with ttf fonts available
   {
-   my $err = "$@";
-   print "1..0 # Skipped: locale's '",$enc->name,"' cannot represent Korean.\n";
-   CORE::exit(0);
+   my $enc = Tk::SystemEncoding();
+   eval { $enc->encode("\x{AC00}",FB_CROAK) };
+   if ($@)
+    {
+     my $err = "$@";
+     print "1..0 # Skipped: locale's '",$enc->name,"' cannot represent Korean.\n";
+     CORE::exit(0);
+    }
   }
 }
 use Test::More (tests => 271);
@@ -30,5 +35,5 @@ while (<$fh>)
   ok(1);
  }
 close($fh);
-$mw->after(2000,[ destroy => $mw ]);
+$mw->after(100,[ destroy => $mw ]);
 MainLoop;
diff -up '/usr/local/src/Tk-804.027/t/TkTest.pm' '/home/e/eserte/work/svk-checkouts/Tk/t/TkTest.pm'
Index: ./t/TkTest.pm
--- ./t/TkTest.pm	Tue Dec 23 11:30:13 2003
+++ ./t/TkTest.pm	Wed Nov  8 21:45:06 2006
@@ -9,15 +9,15 @@ use vars qw(@EXPORT $eps $VERSION);
 $VERSION = sprintf '4.%03d', q$Revision: #3 $ =~ /\D(\d+)\s*$/;
 
 use base qw(Exporter);
-@EXPORT = qw(ok_float);
+@EXPORT = qw(is_float);
 
 use POSIX qw(DBL_EPSILON);
-use Test qw(ok);
 $eps = DBL_EPSILON;
 
 
-sub ok_float ($$;$) {
-    my($value, $expected, $diag) = @_;
+sub is_float ($$;$) {
+    my($value, $expected, $testname) = @_;
+    local $Test::Builder::Level = $Test::Builder::Level+1;
     my @value    = split /[\s,]+/, $value;
     my @expected = split /[\s,]+/, $expected;
     my $ok = 1;
@@ -35,11 +35,9 @@ sub ok_float ($$;$) {
 	}
     }
     if ($ok) {
-	@_ = (1, 1, $diag);
-	goto &ok;
+	Test::More::pass($testname);
     } else {
-	@_ = ($value, $expected, $diag);
-	goto &ok;
+	Test::More::is($value, $expected, $testname); # will fail
     }
 }
 
diff -up /dev/null '/home/e/eserte/work/svk-checkouts/Tk/t/canvas.t'
Index: ./t/canvas.t
--- ./t/canvas.t	Thu Jan  1 01:00:00 1970
+++ ./t/canvas.t	Fri Nov  3 22:00:45 2006
@@ -0,0 +1,515 @@
+#!/usr/bin/perl -w
+# -*- perl -*-
+
+#
+# $Id: $
+# Translated by: Slaven Rezic
+#
+# Original copyright from tk/tests/canvas.test, version 1.23 from
+# tktoolkit CVS on sourceforge:
+
+# This file is a Tcl script to test out the procedures in tkCanvas.c,
+# which implements generic code for canvases.  It is organized in the
+# standard fashion for Tcl tests.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+# All rights reserved.
+#
+# RCS: @(#) $Id: canvas.test,v 1.23 2004/12/07 21:22:19 dgp Exp $
+
+use strict;
+
+use Getopt::Long;
+use Tk;
+
+BEGIN {
+    if (!eval q{
+	use Test::More;
+	1;
+    }) {
+	print "1..0 # skip: no Test::More module\n";
+	exit;
+    }
+}
+
+plan tests => 158;
+
+use_ok("Tk::Canvas");
+
+my $verbose = 0;
+GetOptions("v" => \$verbose)
+    or die "usage: $0 [-v]";
+
+# XXX - This test file is woefully incomplete.  At present, only a
+# few of the features are tested.
+
+my $mw = MainWindow->new;
+$mw->geometry("+10+10");
+my $c = $mw->Canvas;
+isa_ok($c, "Tk::Canvas");
+isa_ok($c, "Tk::Widget");
+$c->pack;
+$c->update;
+
+sub deleteWindows () {
+    eval { $_->destroy } for $mw->children;
+}
+
+use constant SKIP_CGET    => 5;
+use constant SKIP_CONF    => 6;
+use constant SKIP_ERROR   => 7;
+use constant SKIP_RESTORE => 8;
+
+my @tests =
+   (
+    ['-background', '#ff0000', '#ff0000', 'non-existent',
+     'unknown color name "non-existent"'],
+    ['-bg', '#ff0000', '#ff0000', 'non-existent',
+     'unknown color name "non-existent"'],
+    [qw(-bd 4 4 badValue), 'bad screen distance "badValue"'],
+    [qw(-borderwidth 1.3 1 badValue), 'bad screen distance "badValue"'],
+    [qw(-closeenough 24 24 bogus), q{'bogus' isn't numeric}],
+    [qw(-confine true 1 silly), 'expected boolean value but got "silly"', 0,0,1,0], # probably auto-converted to some boolean value?
+    [qw(-cursor arrow arrow badValue), 'bad cursor spec "badValue"'],
+    [qw(-height 2.1 2 x42), 'bad screen distance "x42"'],
+    [qw(-highlightbackground), '#112233', '#112233', 'ugly', 'unknown color name "ugly"'],
+    [qw(-highlightcolor), '#110022', '#110022',	'bogus', 'unknown color name "bogus"'],
+    [qw(-highlightthickness 18 18 badValue), 'bad screen distance "badValue"'],
+    [qw(-insertbackground), '#110022', '#110022', 'bogus', 'unknown color name "bogus"'],
+    [qw(-insertborderwidth 1.3 1 2.6x), 'bad screen distance "2.6x"'],
+    [qw(-insertofftime 100 100 3.2), q{expected integer but got "3.2"}, 0,0,1,0], # probably auto-converted to integer?
+    [qw(-insertontime 100 100 3.2), q{expected integer but got "3.2"}, 0,0,1,0], # probably auto-converted to integer?
+    [qw(-insertwidth 1.3 1 6x), q{bad screen distance "6x"}],
+    [qw(-relief groove groove 1.5), q{bad relief type "1.5": must be flat, groove, raised, ridge, solid, or sunken}],
+    [qw(-selectbackground), '#110022', '#110022', 'bogus', q{unknown color name "bogus"}],
+    [qw(-selectborderwidth 1.3 1 badValue), q{bad screen distance "badValue"}],
+    [qw(-selectforeground), '#654321', '#654321', 'bogus', q{unknown color name "bogus"}],
+    [qw(-takefocus), "any string", "any string", undef, undef],
+    [qw(-width 402 402 xyz), q{bad screen distance "xyz"}],
+    [qw(-xscrollcommand), q{Some command}, q{Some command}, undef, undef, 1],
+    [qw(-yscrollcommand), q{Another command}, q{Another command}, undef, undef, 1],
+);
+
+foreach my $test (@tests) {
+    my $name = $test->[0];
+    $c->configure($name, $test->[1]);
+    if (!$test->[SKIP_CGET]) {
+	is($c->cget($name), $test->[2], "cget $name");
+    }
+    if (!$test->[SKIP_CONF]) {
+	is(($c->configure($name))[4], $c->cget($name), "Comparing configure and cget values for $name");
+    }
+
+    if (defined $test->[4]) {
+	if (!$test->[SKIP_ERROR]) {
+	    eval { $c->configure($name, $test->[3]) };
+	    like($@, qr/$test->[4]/, "Expected error message for $name");
+	}
+    }
+    if (!$test->[SKIP_RESTORE]) {
+	$c->configure($name, ($c->configure($name))[3]);
+    }
+}
+
+eval { $c->configure(-gorp => "foo") };
+like($@, qr{Bad option `-gorp'}, "configure throws error on bad option");
+$c->create("rect",10,10,100,100);
+eval { $c->configure(-gorp => "foo") };
+like($@, qr{Bad option `-gorp'}, "configure throws error on bad option");
+
+eval { $c->destroy };
+$c = $mw->Canvas(qw(-width 60 -height 40),
+		 -scrollregion => [qw(0 0 200 150)],
+		 -bd => 0,
+		 -highlightthickness => 0,
+		)->pack;
+$c->update;
+
+{
+    my $i = $c->createRectangle(10,10,100,100);
+    eval { $c->bind($i, "<a>") };
+    is($@, "", "bind method");
+}
+
+{
+    my $i = $c->create('rect',10,10,100,100);
+    eval { $c->bind($i, "<") };
+    like($@, qr{no event type or button # or keysym}, "bind method with failure");
+}
+
+{
+    $c->configure(-xscrollincrement => 40, -yscrollincrement => 5);
+    $c->xview('moveto', 0);
+    $c->update;
+    is_deeply([$c->xview], [0, 0.3], "xview method");
+    $c->xview('scroll', 2, 'units');
+    $c->update;
+    is_deeply([$c->xview], [0.4, 0.7], "xview method after scroll");
+}
+
+{
+    # Tcl/Tk comment:
+    # This test gives slightly different results on platforms such
+    # as NetBSD.  I don't know why...
+    # Perl/Tk comment:
+    # Everything's ok on a FreeBSD machine.
+    $c->configure(-xscrollincrement => 0, -yscrollincrement => 5);
+    $c->xviewMoveto(0.6);
+    $c->update;
+    is_deeply([$c->xview], [0.6, 0.9], "xview method (2)");
+    $c->xviewScroll(2, 'units');
+    $c->update;
+    is_deeply([$c->xview], [0.66, 0.96], "xview method after scroll (2)");
+}
+
+eval { $c->destroy };
+$c = $mw->Canvas(qw(-width 60 -height 40),
+		 -scrollregion => [qw(0 0 200 80)],
+		 -borderwidth => 0,
+		 -highlightthickness => 0,
+		)->pack;
+$c->update;
+
+{
+    $c->configure(qw(-xscrollincrement 40 -yscrollincrement 5));
+    $c->yview('moveto', 0);
+    $c->update;
+    is_deeply([$c->yview], [0, 0.5], "yview method");
+    $c->yview('scroll', 3, 'units');
+    $c->update;
+    is_deeply([$c->yview], [0.1875, 0.6875], "yview method after scroll");
+}
+
+{
+    $c->configure(qw(-xscrollincrement 40 -yscrollincrement 0));
+    $c->yviewMoveto(0);
+    $c->update;
+    is_deeply([$c->yview], [0, 0.5], "yview method (2)");
+    $c->yviewScroll(2, 'units');
+    $c->update;
+    is_deeply([$c->yview], [0.1, 0.6], "yview method after scroll (2)");
+}
+
+{
+    eval { $c->destroy };
+    $c = $mw->Canvas(qw(-width 100 -height 50),
+		     -scrollregion => [qw(-200 -100 305 102)],
+		     -borderwidth => 2,
+		     -highlightthickness => 3,
+		    )->pack;
+    $c->update;
+    $c->configure(qw(-xscrollincrement 0 -yscrollincrement 0));
+    $c->xview('moveto', 0);
+    $c->yview('moveto', 0);
+    $c->update;
+    is($c->canvasx(0), -205, "canvasx after scrolling to origin");
+    is($c->canvasy(0), -105, "canvasy after scrolling to origin");
+}
+
+{
+    $c->configure(qw(-xscrollincrement 20 -yscrollincrement 10));
+    my @x;
+    for my $i (qw(.08 .10 .48 .50)) {
+	$c->xviewMoveto($i);
+	$c->update;
+	push @x, $c->canvasx(0);
+    }
+    is_deeply(\@x, [-165, -145, 35, 55], "canvasx after multiple scroll");
+}
+
+{
+    $c->configure(qw(-xscrollincrement 20 -yscrollincrement 10));
+    my @x;
+    for my $i (qw(.06 .08 .70 .72)) {
+	$c->yviewMoveto($i);
+	$c->update;
+	push @x, $c->canvasy(0);
+    }
+    is_deeply(\@x, [-95, -85, 35, 45], "canvasy after multiple scroll");
+}
+
+{
+    $c->configure(qw(-xscrollincrement 20 -yscrollincrement 10));
+    $c->xview('moveto', 1.0);
+    is($c->canvasx(0), 215);
+}
+
+{
+    $c->configure(qw(-xscrollincrement 20 -yscrollincrement 10));
+    $c->yview(moveto => 1.0);
+    is($c->canvasy(0), 55);
+}
+
+deleteWindows;
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test dumps SV contents ...
+    $c = $mw->Canvas;
+    $c->create(qw(arc -100 10 100 210 -start 10 -extent 50 -style arc -tags arc1));
+    is_deeply([$c->bbox("arc1")], [qw(48 21 100 94)], "BBox of arc");
+    $c->createArc(qw(100 10 300 210 -start 10 -extent 50 -style chord -tags arc2));
+    is_deeply([$c->bbox("arc2")], [qw(248 21 300 94)], "BBox of chord");
+    $c->create(qw(arc 300 10 500 210 -start 10 -extent 50 -style pieslice -tags arc3));
+    is_deeply([$c->bbox("arc3")], [qw(398 21 500 112)], "BBox of pieslice");
+}
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test dumps SV contents ...
+    $c = $mw->Canvas;
+
+    # With Tk 8.0.4 the ids are now stored in a hash table.  You
+    # can use this test as a performance test with older versions
+    # by changing the value of size.
+    my $size = 15;
+
+    for my $i (0 .. $size-1) {
+	my $x = -10 + 3*$i;
+	for(my $j = 0, my $y = -10; $j < 10; $j++, $y+=3) {
+	    $c->create('rect', "${x}c", "${y}c", ($x+2)."c", ($y+2)."c",
+		       qw(-outline black -fill blue -tags rect));
+	    $c->create('text', ($x+1)."c", ($y+1)."c", -text => "$i,$j",
+		       qw(-anchor center -tags text));
+	}
+    }
+
+    # The actual bench mark - this code also exercises all the hash
+    # table changes.
+
+    my $time = Tk::timeofday();
+    foreach my $id ($c->find(withtag => "all")) {
+	$c->lower($id);
+	$c->raise($id);
+	$c->find(withtag => $id);
+	$c->bind('<Return>', $id, '');
+	$c->delete($id);
+    }
+    my $delta = Tk::timeofday() - $time;
+    diag "Canvas creation and deletion test needed $delta s"
+	if $verbose;
+}
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test dumps SV contents ...
+    $c = $mw->Canvas;
+
+    $c->create(qw(oval 20 20 40 40 -fill red -tag) , [qw(a b c d)]);
+    $c->create(qw(oval 20 60 40 80 -fill yellow -tag), [qw(b a)]);
+    $c->create(qw(oval 20 100 40 120 -fill green -tag), [qw(c b)]);
+    $c->create(qw(oval 20 140 40 160 -fill blue -tag), [qw(b)]);
+    $c->create(qw(oval 20 180 40 200 -fill bisque -tag), [qw(a d e)]);
+    $c->create(qw(oval 20 220 40 240 -fill bisque -tag b));
+    $c->create(qw(oval 20 260 40 280 -fill bisque -tag), ['d', "tag with spaces"]);
+
+    is_deeply([$c->find(withtag => q{!a})],[qw(3 4 6 7)], "Tag expressions");
+    is_deeply([$c->find(withtag => q{b&&c})],[qw(1 3)]);
+    is_deeply([$c->find(withtag => q{b||c})],[qw(1 2 3 4 6)]);
+    is_deeply([$c->find(withtag => q{a&&!b})],[qw(5)]);
+    is_deeply([$c->find(withtag => q{!b&&!c})],[qw(5 7)]);
+    is_deeply([$c->find(withtag => q{d&&a&&c&&b})],[qw(1)]);
+    is_deeply([$c->find(withtag => q{b^a})],[qw(3 4 5 6)]);
+    is_deeply([$c->find(withtag => q{(a&&!b)||(!a&&b)})],[qw(3 4 5 6)]);
+    is_deeply([$c->find(withtag => q{ ( a && ! b ) || ( ! a && b ) })],[qw(3 4 5 6)]);
+    is_deeply([$c->find(withtag => q{a&&!(c||d)})],[qw(2)]);
+    is_deeply([$c->find(withtag => q{d&&"tag with spaces"})],[qw(7)], "Tag with spaces");
+    is_deeply([$c->find(withtag => q"tag with spaces")],[qw(7)]);
+}
+
+for my $testdef (
+		 [q{&&c}, qr{Unexpected operator in tag search expression}],
+		 [q{!!c}, qr{Too many '!' in tag search expression}],
+		 [q{b||}, qr{Missing tag in tag search expression}],
+		 [q{b&&(c||)}, qr{Unexpected operator in tag search expression}],
+		 [q{d&&""}, qr{Null quoted tag string in tag search expression}],
+		 [q"d&&\"tag with spaces", qr{Missing endquote in tag search expression}],
+		 [q{a&&"tag with spaces"z}, qr{Invalid boolean operator in tag search expression}],
+		 [q{a&&b&c}, qr{Singleton '&' in tag search expression}],
+		 [q{a||b|c}, qr{Singleton '|' in tag search expression}],
+		) {
+    my($tag_expr, $error_rx) = @$testdef;
+
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas;
+
+    $c->create(qw(oval 20 20 40 40 -fill red -tag), [qw(a b c d)]);
+    $c->create(qw(oval 20 260 40 280 -fill bisque -tag), ['d', "tag with spaces"]);
+    eval { $c->find(withtag => $tag_expr) };
+    like($@, $error_rx, "Tag expression error ($tag_expr)");
+}
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas;
+
+    $c->create(qw(oval 20 20 40 40 -fill red -tag), [q{ strange tag(xxx&yyy|zzz) " && \" || ! ^ " }]);
+    ok($c->find(withtag => q{ strange tag(xxx&yyy|zzz) " && \" || ! ^ " }), 
+       q{backward compatility - strange tags that are not expressions});
+} 
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas;
+
+    $c->bind(q{a && b}, '<Enter>' => sub {warn "Enter"});
+    $c->bind(q{a && b}, '<Leave>' => sub {warn "Leave"});
+
+    pass(q{multple events bound to same tag expr});
+}
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas->pack;
+
+    # This would crash in 8.3.0 and 8.3.1
+    $c->create(qw(polygon 0 0 100 100 200 50),
+	       -fill => undef,
+	       qw(-stipple gray50 -outline black));
+    pass(q{canvas poly fill check, bug 5783});
+}
+   
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas->pack;
+
+    $c->create(qw(poly 30 30 90 90 30 90 90 30));
+    ok($c->find(qw(over 40 40 45 45)), "rect region inc. edge; canvas poly overlap fill check, bug 226357");
+    ok($c->find(qw(over 60 40 60 40)), "top-center point");
+    ok(!$c->find(qw(over 0 0 0 0)), "not on poly");
+    ok($c->find(qw(over 60 60 60 60)), "center-point");
+    ok(!$c->find(qw(over 45 50 45 50)), "outside poly");
+
+    $c->itemconfigure(1, -fill => "", -outline => "black");
+    ok($c->find(qw(over 40 40 45 45)), "rect region inc. edge");
+    ok($c->find(qw(over 60 40 60 40)), "top-center point");
+    ok(!$c->find(qw(over 0 0 0 0)), "not on poly");
+    ok($c->find(qw(over 60 60 60 60)), "center-point");
+    ok(!$c->find(qw(over 45 50 45 50)), "outside poly");
+
+    $c->itemconfigure(1, -width => 8);
+    ok($c->find(qw(over 45 50 45 50)), "outside poly?");
+}
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas->pack;
+
+    my $qx = 1.+1.;
+    # qx has type double and no string representation (in Tcl?)
+    $c->scale('all', $qx, 0, 1., 1.);
+    # qx has now type MMRep and no string representation (in Tcl?);
+    is($qx, 2, q{canvas mm obj, patch SF-403327, 102471});
+}
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas->pack;
+
+    my $val = 10;
+    $val++;
+    # qx has type double and no string representation (in Tcl?)
+    $c->scale('all', $val, 0, 1, 1);
+    # qx has now type MMRep and no string representation (in Tcl?)
+    $val++;
+    is($val, 12, q{canvas mm obj, patch SF-403327, 102471});
+}
+
+{
+    my $x = "";
+    
+    my $kill_canvas = sub {
+	my $w = shift;
+	$w->destroy;
+	$w = $mw->Canvas(qw(-height 200 -width 200))->pack(qw(-fill both -expand yes));
+	$mw->idletasks;
+	$w->create('rectangle', qw(80 80 120 120 -fill blue -tags blue));
+	# bind a button press to re-build the canvas
+	$w->bind('blue', '<ButtonRelease-1>' => sub { $x .= "ok" });
+	$w;
+    };
+
+    $c = $kill_canvas->($c);
+
+    # do this many times to improve chances of triggering the crash
+    for my $i (0 .. 29) {
+	$c->eventGenerate('<1>', qw(-x 100 -y 100));
+	$c->eventGenerate('<ButtonRelease-1>', qw(-x 100 -y 100));
+    }
+    is($x, "okokokokokokokokokokokokokokokokokokokokokokokokokokokokokok",
+       q{canvas delete during event, SF bug-228024});
+}
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas->pack;
+
+    eval { $c->scan };
+    like($@, qr{\Qwrong # args: should be ".canvas scan mark|dragto x y ?dragGain?"\E},
+	 qr{canvas scan SF bug 581560});
+
+    eval { $c->scan("bogus") };
+    like($@, qr{\Qwrong # args: should be ".canvas scan mark|dragto x y ?dragGain?"\E},
+	 "canvas scan");
+
+    eval { $c->scan("mark") };
+    like($@, qr{\Qwrong # args: should be ".canvas scan mark|dragto x y ?dragGain?"\E});
+
+    $c->scan(qw(mark 10 10));
+    pass("correct canvas scan mark");
+
+    eval { $c->scan(qw(mark 10 10 5)) };
+    like($@, qr{wrong # args: should be ".canvas scan mark x y"});
+
+    $c->scan(qw(dragto 10 10 5));
+    pass("correct canvas scan dragto");
+}
+
+{
+    foreach my $type (qw{arc bitmap image line oval polygon rect text window}) {
+	eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+	$c = $mw->Canvas->pack;
+
+	eval { $c->create($type) };
+	like($@, qr{wrong # args: should be ".canvas create $type coords \Q?arg arg ...?"\E},
+	     "basic types check: $type requires coords");
+
+	eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+	$c = $mw->Canvas->pack;
+
+	eval { $c->create($type, 0) };
+	like($@, qr{wrong # coordinates: expected},
+	     "basic coords check: $type coords are paired");
+    }
+}
+
+{
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas->pack;
+
+    my $id = $c->createArc(qw(0 10 20 30 -start 33));
+    is($c->itemcget($id, "-start"), 33, "arc coords check");
+}
+
+{
+    local $TODO = "Decide whether test failures are expected or not...";
+
+    eval { $c->destroy } if Tk::Exists($c); # without existence test may dump SV contents ...
+    $c = $mw->Canvas->pack;
+
+    my $id = $c->createLine(qw{0 0 1 1 2 2 3 3 4 4 5 5 6 6});
+    is($c->itemcget($id, '-smooth'), 0);
+
+    foreach my $smoothtest (
+			    ['yes', 'true'],
+			    [1, 'true'],
+			    ['bezier', 'true'],
+			    ['raw', 'raw'],
+			    ['r', 'raw'],
+			    ['b', 'b']
+			   ) {
+	my($smoother, $expected) = @$smoothtest;
+	$c->itemconfigure($id, -smooth => $smoother);
+	is($c->itemcget($id, '-smooth'), $expected, "smooth test");
+    }
+}
+
+__END__
diff -up '/usr/local/src/Tk-804.027/t/entry.t' '/home/e/eserte/work/svk-checkouts/Tk/t/entry.t'
Index: ./t/entry.t
--- ./t/entry.t	Thu Mar 18 21:34:01 2004
+++ ./t/entry.t	Wed Nov  1 22:55:32 2006
@@ -21,10 +21,10 @@ my $Xft = $Tk::Config::xlib =~ /-lXft\b/
 
 BEGIN {
     if (!eval q{
-	use Test;
+	use Test::More;
 	1;
     }) {
-	print "# tests only work with installed Test module\n";
+	print "# tests only work with installed Test::More module\n";
 	print "1..1\n";
 	print "ok 1\n";
 	exit;
@@ -39,12 +39,25 @@ BEGIN {
         todo => \@fragile
       }
 
+use Getopt::Long;
+
+my $do_wm_test   = (defined($ENV{WINDOWMANAGER}) &&
+		    $ENV{WINDOWMANAGER} eq '/usr/X11R6/bin/kde');
+my $do_font_test = 1;
+
+GetOptions("wmtest!" => \$do_wm_test)
+    or die "usage: $0 [-wmtest]";
+
+my $skip_wm_test = "window manager dependent tests";
+my $skip_font_test = "font-related tests";
+my $skip_wm_font_test = "window manager and/or font-related tests";
+
 my $mw = Tk::MainWindow->new();
 $mw->geometry('+10+10');
 
 my $e0 = $mw->Entry;
-ok(Tk::Exists($e0), 1);
-ok(ref $e0, "Tk::Entry");
+ok(Tk::Exists($e0), "Entry widget exists");
+isa_ok($e0, "Tk::Entry");
 
 my @scrollInfo;
 sub scroll {
@@ -59,19 +72,23 @@ $sel->insert("end", "This is some sample
 # Font names
 
 my $big   = $Xft ? '{Adobe Helvetica} -24' : "-adobe-helvetica-medium-r-normal--24-240-75-75-p-*-iso8859-1";
-my $fixed = $Xft ? '{Adobe Courier} -12' : "-adobe-courier-medium-r-normal--12-120-75-75-m-*-iso8859-1";
+## Always use the X11 font, even with Xft, otherwise the measurements would
+## be wrong.
+#my $fixed = $Xft ? '{Adobe Courier} -12' : "-adobe-courier-medium-r-normal--12-120-75-75-m-*-iso8859-1";
+my $fixed = "-adobe-courier-medium-r-normal--12-120-75-75-m-*-iso8859-1";
 
 # Create entries in the option database to be sure that geometry options
 # like border width have predictable values.
 
 $mw->option("add", "*Entry.borderWidth", 2);
 $mw->option("add", "*Entry.highlightThickness", 2);
-$mw->option("add", "*Entry.font", $Xft ? '{Adobe Helvetica} -12' : "Helvetica -12");
+## Again, prefer the X11 font.
+#$mw->option("add", "*Entry.font", $Xft ? '{Adobe Helvetica} -12' : "Helvetica -12");
+$mw->option("add", "*Entry.font", "Helvetica -12");
 
 my $e = $mw->Entry(qw(-bd 2 -relief sunken))->pack;
 $mw->update;
 
-my $skip_font_test;
 if (!$Xft) { # XXX Is this condition necessary?
     my %fa = $mw->fontActual($e->cget(-font));
     my %expected = (
@@ -84,16 +101,11 @@ if (!$Xft) { # XXX Is this condition nec
 		   );
     while(my($k,$v) = each %expected) {
 	if ($v ne $fa{$k}) {
-	    $skip_font_test = "font-related tests";
+	    $do_font_test = 0;
 	    last;
 	}
     }
 }
-my $skip_wm_test;
-unless (defined($ENV{WINDOWMANAGER}) &&
-        $ENV{WINDOWMANAGER} eq '/usr/X11R6/bin/kde') {
-    $skip_wm_test = "window manager dependent tests";
-}
 
 my $i;
 
@@ -140,43 +152,35 @@ my @tests = (
 foreach my $test (@tests) {
     my $name = $test->[0];
     $e->configure($name, $test->[1]);
-    if ($test->[SKIP_CGET]) {
-	skip(1,1);
-    } else {
-	ok($e->cget($name), $test->[2], "Failed to cget $name");
+    if (!$test->[SKIP_CGET]) {
+	is($e->cget($name), $test->[2], "cget $name");
     }
-    if ($test->[SKIP_CONF]) {
-	skip(1,1);
-    } else {
-	ok(($e->configure($name))[4], $e->cget($name), "Failed comparing configure and cget values for $name");
+    if (!$test->[SKIP_CONF]) {
+	is(($e->configure($name))[4], $e->cget($name), "Comparing configure and cget values for $name");
     }
 
     if (defined $test->[4]) {
-	if ($test->[SKIP_ERROR]) {
-	    skip(1,1);
-	} else {
+	if (!$test->[SKIP_ERROR]) {
 	    eval { $e->configure($name, $test->[3]) };
-	    ok($@ =~ /$test->[4]/, 1, "Error message for $name: Got $@, expected $test->[4]");
+	    like($@, qr/$test->[4]/, "Expected error message for $name");
 	}
     }
-    if ($test->[SKIP_RESTORE]) {
-	skip(1,1);
-    } else {
+    if (!$test->[SKIP_RESTORE]) {
 	$e->configure($name, ($e->configure($name))[3]);
     }
 }
 
 eval { $e->destroy };
 $e = $mw->Entry;
-ok(Tk::Exists($e), 1);
-ok($e->class, 'Entry');
-ok(ref $e, 'Tk::Entry');
+ok(Tk::Exists($e));
+is($e->class, 'Entry', "Tk class name");
+isa_ok($e, 'Tk::Entry');
 
 eval { $e->destroy; undef $e };
 eval { $e = $mw->Entry(-gorp => 'foo') };
-ok($@ =~ /unknown option "-gorp"/, 1, $@);
-ok(!Tk::Exists($e), 1);
-ok(!defined $e, 1);
+like($@, qr/unknown option "-gorp"/);
+ok(!Tk::Exists($e), "Expected failure while creating entry widget with bad options");
+ok(!defined $e);
 
 eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed)->pack;
@@ -184,188 +188,180 @@ $e->update;
 
 my $cx = $mw->fontMeasure($fixed, 'a');
 my $cy = $mw->fontMetrics($fixed, '-linespace');
-my $ux = $mw->fontMeasure($fixed, "\x{4e4e}"); # XXX no unicode yet
+my $ux = $mw->fontMeasure($fixed, "\x{4e4e}");
 
 eval { $e->bbox };
-ok($@ =~ /wrong \# args: should be ".* bbox index"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* bbox index"/, "bbox error message");
 
 eval { $e->bbox(qw(a b)) };
-ok($@ =~ /wrong \# args: should be ".* bbox index"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* bbox index"/);
 
 eval { $e->bbox(qw(bogus)) };
-ok($@ =~ /bad entry index "bogus"/, 1, $@);
+like($@, qr/bad entry index "bogus"/);
 
 $e->delete(0,"end");
-ok(join(",",$e->bbox(0)),"5,5,0,$cy");
+is_deeply([$e->bbox(0)],[5,5,0,$cy], "Expected bbox");
 
 $e->delete(0,"end");
 $e->insert(0,"abc");
-ok(join(",",$e->bbox(3)),join(",",5+2*$cx,5,$cx,$cy));
-ok(join(",",$e->bbox("end")), join(",",$e->bbox(3)));
+is_deeply([$e->bbox(3)],[5+2*$cx,5,$cx,$cy]);
+is_deeply([$e->bbox("end")],[$e->bbox(3)]);
 
-# XXX no unicode yet
-#  test entry-3.7 {EntryWidgetCmd procedure, "bbox" widget command} {
-#      # Tcl_UtfAtIndex(): utf at end
-#      .e delete 0 end
-#      .e insert 0 "ab\u4e4e"
-#      .e bbox end
-#  } "[expr 5+2*$cx] 5 $ux $cy"
-#  test entry-3.8 {EntryWidgetCmd procedure, "bbox" widget command} {
-#      # Tcl_UtfAtIndex(): utf before index
-#      .e delete 0 end
-#      .e insert 0 "ab\u4e4ec"
-#      .e bbox 3
-#  } "[expr 5+2*$cx+$ux] 5 $cx $cy"
+$e->delete(0,"end");
+$e->insert(0,"ab\x{4e4e}");
+is_deeply([$e->bbox("end")],[5+2*$cx,5,$ux,$cy], "Bbox check with unicode char (at end)");
 
 $e->delete(0,"end");
-ok("5,5,0,$cy",join(",",$e->bbox("end")));
+$e->insert(0,"ab\x{4e4e}c");
+is_deeply([$e->bbox(3)],[5+2*$cx+$ux,5,$cx,$cy], "Bbox check with unicode char (before index)");
 
-# XXX no unicode yet
-#  test entry-3.10 {EntryWidgetCmd procedure, "bbox" widget command} {
-#      .e delete 0 end
-#      .e insert 0 "abcdefghij\u4e4eklmnop"
-#      list [.e bbox 0] [.e bbox 1] [.e bbox 10] [.e bbox end]
-#  } [list "5 5 $cx $cy" "[expr 5+$cx] 5 $cx $cy" "[expr 5+10*$cx] 5 $ux $cy" "[expr 5+$ux+15*$cx] 5 $cx $cy"]
+$e->delete(0,"end");
+is_deeply([5,5,0,$cy],[$e->bbox("end")]);
+
+$e->delete(0,"end");
+$e->insert(0,"abcdefghij\x{4e4e}klmnop");
+is_deeply([[$e->bbox(0)],
+	   [$e->bbox(1)],
+	   [$e->bbox(10)],
+	   [$e->bbox("end")]],
+	  [[5,5,$cx,$cy],
+	   [5+$cx,5,$cx,$cy],
+	   [5+10*$cx,5,$ux,$cy],
+	   [5+$ux+15*$cx,5,$cx,$cy]], "More bbox checks with unicode char");
 
 eval { $e->cget };
-ok($@ =~ /wrong \# args: should be ".* cget option"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* cget option"/, "cget error message");
 
 eval { $e->cget(qw(a b)) };
-ok($@ =~ /wrong \# args: should be ".* cget option"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* cget option"/);
 
 eval { $e->cget(-gorp) };
-ok($@ =~ /unknown option "-gorp"/, 1, $@);
+like($@, qr/unknown option "-gorp"/);
 
 $e->configure(-bd => 4);
-ok($e->cget(-bd), 4);
-ok(scalar @{$e->configure}, 36);
+is($e->cget(-bd), 4);
+is(scalar @{$e->configure}, 36);
 
 eval { $e->configure('-foo') };
-ok($@ =~ /unknown option "-foo"/, 1, $@);
+like($@, qr/unknown option "-foo"/, "Unknown option error message");
 
 $e->configure(-bd => 4);
 $e->configure(-bg => '#ffffff');
-ok(($e->configure(-bd))[4], 4);
+is(($e->configure(-bd))[4], 4);
 
 eval { $e->delete };
-ok($@ =~ /wrong \# args: should be ".* delete firstIndex \?lastIndex\?"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* delete firstIndex \?lastIndex\?"/, "delete error message");
 
 eval { $e->delete(qw(a b c)) };
-ok($@ =~ /wrong \# args: should be ".* delete firstIndex \?lastIndex\?"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* delete firstIndex \?lastIndex\?"/);
 
 eval { $e->delete("foo") };
-ok($@ =~ /bad entry index "foo"/, 1, $@);
+like($@, qr/bad entry index "foo"/);
 
 eval { $e->delete(0, "bar") };
-ok($@ =~ /bad entry index "bar"/, 1, $@);
+like($@, qr/bad entry index "bar"/);
 
 $e->delete(0, "end");
 $e->insert("end", "01234567890");
 $e->delete(2, 4);
-ok($e->get, "014567890");
+is($e->get, "014567890", "Expected get after insert");
 
 $e->delete(0, "end");
 $e->insert("end", "01234567890");
 $e->delete(6);
-ok($e->get, "0123457890");
+is($e->get, "0123457890");
 
-#  test entry-3.24 {EntryWidgetCmd procedure, "delete" widget command} {
-#      # UTF
-#      set x {}
-#      .e delete 0 end
-#      .e insert end "01234\u4e4e67890"
-#      .e delete 6
-#      lappend x [.e get]
-#      .e delete 0 end
-#      .e insert end "012345\u4e4e7890"
-#      .e delete 6
-#      lappend x [.e get]
-#      .e delete 0 end
-#      .e insert end "0123456\u4e4e890"
-#      .e delete 6
-#      lappend x [.e get]
-#  } [list "01234\u4e4e7890" "0123457890" "012345\u4e4e890"]
+$e->delete(0, "end");
+$e->insert("end", "01234\x{4e4e}67890");
+$e->delete(6);
+is($e->get, "01234\x{4e4e}7890", "Delete with unicode character before");
+
+$e->delete(0, "end");
+$e->insert("end", "012345\x{4e4e}7890");
+$e->delete(6);
+is($e->get, "0123457890", "Delete unicode character");
 
+$e->delete(0, "end");
+$e->insert("end", "0123456\x{4e4e}890");
+$e->delete(6);
+is($e->get, "012345\x{4e4e}890", "Delete with unicode character after");
 
 $e->delete(0,"end");
 $e->insert("end", "01234567890");
 $e->delete(6, 5);
-ok($e->get, "01234567890");
+is($e->get, "01234567890", "Delete reversed range");
 
 $e->delete(0,"end");
 $e->insert("end", "01234567890");
 $e->configure(-state => 'disabled');
 $e->delete(2, 8);
 $e->configure(-state => 'normal');
-ok($e->get, "01234567890");
+is($e->get, "01234567890", "Delete while disabled state");
 
 eval { $e->get("foo") };
-ok($@ =~ /wrong \# args: should be ".* get"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* get"/, "get error message");
 
 eval { $e->icursor };
-ok($@ =~ /wrong \# args: should be ".* icursor pos"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* icursor pos"/);
 
 eval { $e->icursor("foo") };
-ok($@ =~ /bad entry index "foo"/, 1, $@);
+like($@, qr/bad entry index "foo"/);
 
 $e->delete(0,"end");
 $e->insert("end", "01234567890");
 $e->icursor(4);
-ok($e->index('insert'), 4);
+is($e->index('insert'), 4, "Index method");
 
 eval { $e->in };
-ok($@ =~ /Can\'t locate(?: file)? auto\/Tk\/Entry\/in\.al/, 1, $@);
+like($@, qr/Can\'t locate(?: file)? auto\/Tk\/Entry\/in\.al/, "Invalid abbreviated method name (index)");
 
 eval { $e->index };
-ok($@ =~ /wrong \# args: should be ".* index string"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* index string"/, "index error message");
 
 eval { $e->index("foo") };
-ok($@ =~ /bad entry index "foo"/, 1, $@);
+like($@, qr/bad entry index "foo"/);
 
-ok($e->index(0), 0);
+is($e->index(0), 0);
 
-#  test entry-3.35 {EntryWidgetCmd procedure, "index" widget command} {
-#      # UTF
-#      .e delete 0 end
-#      .e insert 0 abc\u4e4e\u0153def
-#      list [.e index 3] [.e index 4] [.e index end]
-#  } {3 4 8}
+$e->delete(0,"end");
+$e->insert(0, "abc\x{4e4e}\x{0153}def");
+is_deeply([$e->index(3), $e->index(4), $e->index("end")],[3,4,8], "Index with unicode characters");
 
 eval { $e->insert(qw(a)) };
-ok($@ =~ /wrong \# args: should be ".* insert index text"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* insert index text"/, "insert error message");
 
 eval { $e->insert(qw(a b c)) };
-ok($@ =~ /wrong \# args: should be ".* insert index text"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* insert index text"/);
 
 eval { $e->insert(qw(foo Text)) };
-ok($@ =~ /bad entry index "foo"/, 1, $@);
+like($@, qr/bad entry index "foo"/);
 
 $e->delete(0,"end");
 $e->insert("end", "01234567890");
 $e->insert(3, "xxx");
-ok($e->get, '012xxx34567890');
+is($e->get, '012xxx34567890', "get after insert method call");
 
 $e->delete(0,"end");
 $e->insert("end", "01234567890");
 $e->configure(qw(-state disabled));
 $e->insert(qw(3 xxx));
 $e->configure(qw(-state normal));
-ok($e->get, "01234567890");
+is($e->get, "01234567890");
 
 eval { $e->insert(qw(a b c)) };
-ok($@ =~ /wrong \# args: should be ".* insert index text"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* insert index text"/);
 
 eval { $e->scan(qw(a)) };
-ok($@ =~ /wrong \# args: should be ".* scan mark\|dragto x"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* scan mark\|dragto x"/, "scan error message");
 
 eval { $e->scan(qw(a b c)) };
-ok($@ =~ /wrong \# args: should be ".* scan mark\|dragto x"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* scan mark\|dragto x"/);
 
 eval { $e->scan(qw(foobar 20)) };
-ok($@ =~ /bad scan option "foobar": must be mark or dragto/, 1, $@);
+like($@, qr/bad scan option "foobar": must be mark or dragto/);
 
 eval { $e->scan(qw(mark 20.1)) };
-ok($@, '');
+is($@, '', "Correct mark method call");
 
 # This test is non-portable because character sizes vary.
 
@@ -375,19 +371,19 @@ $e->insert(end => "This is quite a long 
 $e->insert(end => "very very long string");
 $e->scan(qw(mark 30));
 $e->scan(qw(dragto 28));
-ok($e->index('@0'), 2);
+is($e->index('@0'), 2, "Index of a scrolled string");
 
 eval {$e->select };
-ok($@ =~ /Can\'t locate(?: file)? auto\/Tk\/Entry\/select\.al/, 1, $@);
+like($@, qr/Can\'t locate(?: file)? auto\/Tk\/Entry\/select\.al/, "Invalid abbreviated method name (selection)");
 
 eval {$e->selection };
-ok($@ =~ /wrong \# args: should be ".* selection option \?index\?"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* selection option \?index\?"/, "selection error message");
 
 eval {$e->selection('foo') };
-ok($@ =~ /bad selection option "foo": must be adjust, clear, from, present, range, or to/, 1, $@);
+like($@, qr/bad selection option "foo": must be adjust, clear, from, present, range, or to/);
 
 eval { $e->selection("clear", "gorp") };
-ok($@ =~ /wrong \# args: should be ".* selection clear"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* selection clear"/);
 
 $e->delete(0, "end");
 $e->insert("end", "01234567890");
@@ -396,24 +392,24 @@ $e->selection("to", 4);
 $e->update;
 $e->selection("clear");
 eval { $mw->SelectionGet };
-ok($@ =~ /PRIMARY selection doesn\'t exist or form "(UTF8_)?STRING" not defined/, 1, $@);
-ok($mw->SelectionOwner, $e);
+like($@, qr/PRIMARY selection doesn\'t exist or form "(UTF8_)?STRING" not defined/);
+is($mw->SelectionOwner, $e, "Expected selection owner");
 
 eval { $e->selection("present", "foo") };
-ok($@ =~ /wrong \# args: should be ".* selection present"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* selection present"/);
 
 $e->delete(0, "end");
 $e->insert("end", "01234567890");
 $e->selectionFrom(3);
 $e->selectionTo(6);
-ok($e->selectionPresent,1);
+ok($e->selectionPresent, "Selection is now present");
 
 $e->delete(0, "end");
 $e->insert("end", "01234567890");
 $e->selectionFrom(3);
 $e->selectionTo(6);
 $e->configure(-exportselection => 0);
-ok($e->selection('present'), 1);
+ok($e->selection('present'), "Selection is also present with no exportselection");
 
 $e->configure(-exportselection => 1);
 
@@ -422,13 +418,13 @@ $e->insert("end", "01234567890");
 $e->selectionFrom(3);
 $e->selectionTo(6);
 $e->delete(0,"end");
-ok($e->selectionPresent, 0);
+ok(!$e->selectionPresent, "Selection is not present, -exportselection set to true");
 
 eval { $e->selectionAdjust("x") };
-ok($@ =~ /bad entry index "x"/, 1, $@);
+like($@, qr/bad entry index "x"/, "selectionAdjust error message");
 
 eval { $e->selection(qw(adjust 2 3)) };
-ok($@ =~ /wrong \# args: should be ".* selection adjust index"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* selection adjust index"/);
 
 $e->delete(0, "end");
 $e->insert("end", "01234567890");
@@ -436,7 +432,7 @@ $e->selectionFrom(1);
 $e->selection(qw(to 5));
 $e->update;
 $e->selectionAdjust(4);
-ok($mw->SelectionGet, "123");
+is($mw->SelectionGet, "123", "Expected result with selectionGet");
 
 $e->delete(0, "end");
 $e->insert("end", "01234567890");
@@ -444,16 +440,16 @@ $e->selectionFrom(1);
 $e->selection(qw(to 5));
 $e->update;
 $e->selectionAdjust(2);
-ok($mw->SelectionGet, "234");
+is($mw->SelectionGet, "234");
 
 eval { $e->selectionFrom(qw(2 3)) };
-ok($@ =~ /wrong \# args: should be ".* selection from index"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* selection from index"/, "selectionFrom error message");
 
 eval { $e->selection(qw(range 2)) };
-ok($@ =~ /wrong \# args: should be ".* selection range start end"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* selection range start end"/, "selectionRange error message");
 
 eval { $e->selection(qw(range 2 3 4)) };
-ok($@ =~ /wrong \# args: should be ".* selection range start end"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* selection range start end"/);
 
 $e->delete(0, "end");
 $e->insert("end", "01234567890");
@@ -461,100 +457,99 @@ $e->selectionFrom(1);
 $e->selection(qw(to 5));
 $e->selection(qw(range 4 4 ));
 eval { $e->index("sel.first") };
-ok($@ =~ /selection isn\'t in widget/, 1, $@);
+like($@, qr/selection isn\'t in widget/);
 
 $e->delete(0, "end");
 $e->insert("end", "0123456789");
 $e->selectionFrom(3);
 $e->selection(qw(to 7));
 $e->selection(qw(range 2 9));
-ok($e->index("sel.first"), 2);
-ok($e->index("sel.last"), 9);
-ok($e->index("anchor"), 3);
+is($e->index("sel.first"), 2, "Index of selection");
+is($e->index("sel.last"), 9);
+is($e->index("anchor"), 3);
 
 $e->delete(qw(0 end));
 $e->insert(end => "This is quite a long text string, so long that it ");
 $e->insert(end => "runs off the end of the window quite a bit.");
 
 eval { $e->selectionTo(2,3) };
-ok($@ =~ /wrong \# args: should be ".* selection to index"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* selection to index"/);
 
 $e->xview(5);
-ok(join(",", map { substr($_, 0, 8) } $e->xview), "0.053763,0.268817");
+is_deeply([map { substr($_, 0, 8) } $e->xview],["0.053763","0.268817"], "Expected xview result");
 
 eval { $e->xview(qw(gorp)) };
-ok($@ =~ /bad entry index "gorp"/, 1, $@);
+like($@, qr/bad entry index "gorp"/, "xview error message");
 
 $e->xview(0);
 $e->icursor(10);
 $e->xview('insert');
-ok(join(",", map { substr($_, 0, 7) } $e->xview), "0.10752,0.32258");
+is_deeply([map { substr($_, 0, 7) } $e->xview],["0.10752","0.32258"]);
 
 eval { $e->xviewMoveto(qw(foo bar)) };
-ok($@ =~ /wrong \# args: should be ".* xview moveto fraction"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* xview moveto fraction"/);
 
 eval { $e->xview(qw(moveto foo)) };
-ok($@ =~ /\'foo\' isn\'t numeric/, 1, $@);
+like($@, qr/\'foo\' isn\'t numeric/);
 
 $e->xviewMoveto(0.5);
-ok(join(",", map { substr($_, 0, 7) } $e->xview), "0.50537,0.72043");
+is_deeply([map { substr($_, 0, 7) } $e->xview],["0.50537","0.72043"]);
 
 eval { $e->xviewScroll(24) };
-ok($@ =~ /wrong \# args: should be ".* xview scroll number units\|pages"/, 1, $@);
+like($@, qr/wrong \# args: should be ".* xview scroll number units\|pages"/, "xviewScroll error message");
 
 eval { $e->xviewScroll(qw(gorp units)) };
-ok($@ =~ /\'gorp\' isn\'t numeric/, 1, $@);
+like($@, qr/\'gorp\' isn\'t numeric/);
 
 $e->xviewMoveto(0);
 $e->xview(qw(scroll 1 pages));
-ok(join(",", map { substr($_, 0, 7) } $e->xview), "0.19354,0.40860");
+is_deeply([map { substr($_, 0, 7) } $e->xview],["0.19354","0.40860"]);
 
 $e->xview(qw(moveto .9));
 $e->update;
 $e->xview(qw(scroll -2 p));
-ok(join(",", map { substr($_, 0, 7) } $e->xview), "0.39784,0.61290");
+is_deeply([map { substr($_, 0, 7) } $e->xview],["0.39784","0.61290"]);
 
 $e->xview(30);
 $e->update;
 $e->xview(qw(scroll 2 units));
-ok($e->index('@0'), 32);
+is($e->index('@0'), 32);
 
 $e->xview(30);
 $e->update;
 $e->xview(qw(scroll -1 units));
-ok($e->index('@0'), 29);
+is($e->index('@0'), 29);
 
 eval { $e->xviewScroll(23,"foobars") };
-ok($@ =~ /bad argument "foobars": must be units or pages/, 1, $@);
+like($@, qr/bad argument "foobars": must be units or pages/);
 
 eval { $e->xview(qw(eat 23 hamburgers)) };
-ok($@ =~ /unknown option "eat": must be moveto or scroll/, 1, $@);
+like($@, qr/unknown option "eat": must be moveto or scroll/);
 
 $e->xview(0);
 $e->update;
 $e->xview(-4);
-ok($e->index('@0'), 0);
+is($e->index('@0'), 0);
 
 $e->xview(300);
-ok($e->index('@0'), 73);
+is($e->index('@0'), 73);
+
+{
+    $e->insert(10, "\x{4e4e}");
 
-#  .e insert 10 \u4e4e
-#  test entry-3.81 {EntryWidgetCmd procedure, "xview" widget command} {
-#      # UTF
-#      # If Tcl_NumUtfChars wasn't used, wrong answer would be:
-#      # 0.106383 0.117021 0.117021
-
-#      set x {}
-#      .e xview moveto .1
-#      lappend x [lindex [.e xview] 0]
-#      .e xview moveto .11
-#      lappend x [lindex [.e xview] 0]
-#      .e xview moveto .12
-#      lappend x [lindex [.e xview] 0]
-#  } {0.0957447 0.106383 0.117021}
+    my @x;
+    $e->xviewMoveto(0.1);
+    push @x, ($e->xview)[0];
+    $e->xviewMoveto(0.11);
+    push @x, ($e->xview)[0];
+    $e->xviewMoveto(0.12);
+    push @x, ($e->xview)[0];
+
+    is_deeply([map { substr($_, 0, 7) } @x],["0.09574","0.10638","0.11702"], "xviewMoveto with unicode character");
+}
 
 eval { $e->gorp };
-ok($@ =~ /Can\'t locate(?: file)? auto\/Tk\/Entry\/gorp\.al/, 1, $@);
+like($@, qr/Can\'t locate(?: file)? auto\/Tk\/Entry\/gorp\.al/, "Invalid method");
 
 # The test below doesn't actually check anything directly, but if run
 # with Purify or some other memory-allocation-checking program it will
@@ -573,7 +568,7 @@ my $f = $mw->Frame(qw(-width 200 -height
 #eval { $e->destroy };
 $x = 12345;
 $e = $mw->Entry(-textvariable => \$x);
-ok($e->get, "12345");
+is($e->get, "12345", "-textvariable check");
 
 eval { $e->destroy };
 $x = "12345";
@@ -581,21 +576,21 @@ $e = $mw->Entry(-textvariable => \$x);
 my $y = "abcde";
 $e->configure(-textvariable => \$y);
 $x = 54321;
-ok($e->get, "abcde");
+is($e->get, "abcde");
 
 eval { $e->destroy };
 undef $x;
 $e = $mw->Entry;
 $e->configure(-textvariable => \$x);
 $e->insert(0, "Some text");
-ok($x, "Some text");
+is($x, "Some text");
 
 eval { $e->destroy };
 undef $x;
 $e = $mw->Entry;
 $e->insert(0, "Some text");
 $e->configure(-textvariable => \$x);
-#ok($x, "Some text"); # XXX does not work with Perl/Tk!
+#is($x, "Some text"); # XXX does not work with Perl/Tk!
 
 sub override {
     $x = 12345;
@@ -610,20 +605,20 @@ $e->configure(-textvariable => \$x);
 $e->insert('0', "Some text");
 my @result = ($x,$e->get);
 undef $x;
-ok($result[0], "12345");
-ok($result[1], "12345");
+is($result[0], "12345", "-textvariable with traceVariable");
+is($result[1], "12345");
 
 eval { $e->destroy };
 $e = $mw->Entry(-exportselection => 0)->pack;
 $e->insert(qw(end 0123456789));
 $sel->selectionFrom(0);
 $sel->selectionTo(10);
-ok($mw->SelectionGet, "This is so");
+is($mw->SelectionGet, "This is so");
 $e->selectionFrom(1);
 $e->selectionTo(5);
-ok($mw->SelectionGet, "This is so");
+is($mw->SelectionGet, "This is so");
 $e->configure(-exportselection => 1);
-ok($mw->SelectionGet, "1234");
+is($mw->SelectionGet, "1234");
 
 eval { $e->destroy };
 $e = $mw->Entry->pack;
@@ -632,16 +627,16 @@ $e->selectionFrom(1);
 $e->selectionTo(5);
 $e->configure(-exportselection => 0);
 eval { $mw->SelectionGet };
-ok($@ =~ /PRIMARY selection doesn\'t exist or form "(UTF8_)?STRING" not defined/, 1, $@);
-ok($e->index("sel.first"), 1);
-ok($e->index("sel.last"), 5);
+like($@, qr/PRIMARY selection doesn\'t exist or form "(UTF8_)?STRING" not defined/);
+is($e->index("sel.first"), 1);
+is($e->index("sel.last"), 5);
 
 eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed, qw(-width 4 -xscrollcommand), \&scroll)->pack;
 $e->insert(qw(end 01234567890));
 $e->update;
 $e->configure(qw(-width 5));
-ok(join(",", map { substr($_, 0, 8) } @scrollInfo), "0,0.363636");
+is_deeply([map { substr($_, 0, 8) } @scrollInfo], [0,0.363636]);
 
 eval { $e->destroy };
 
@@ -650,25 +645,29 @@ $e->insert(end => "0123");
 $e->update;
 $e->configure(-font => $big);
 $e->update;
-skip($skip_wm_test, $e->geometry, qr/62x3\d\+0\+0/);
+SKIP: {
+    skip($skip_wm_test, 1)
+	if !$do_wm_test;
+    like($e->geometry, qr/62x3\d\+0\+0/, "Geometry check");
+}
 
 eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed, -bd => 2, -relief => "raised")->pack;
 $e->insert(end => "0123");
 $e->update;
-ok($e->index('@10'), 0);
-ok($e->index('@11'), 0);
-ok($e->index('@12'), 1);
-ok($e->index('@13'), 1);
+is($e->index('@10'), 0, "index with raised relief");
+is($e->index('@11'), 0);
+is($e->index('@12'), 1);
+is($e->index('@13'), 1);
 
 eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed, -bd => 2, -relief => "flat")->pack;
 $e->insert(end => "0123");
 $e->update;
-ok($e->index('@10'), 0);
-ok($e->index('@11'), 0);
-ok($e->index('@12'), 1);
-ok($e->index('@13'), 1);
+is($e->index('@10'), 0, "index with flat relief");
+is($e->index('@11'), 0);
+is($e->index('@12'), 1);
+is($e->index('@13'), 1);
 
 # If "0" in selected font had 0 width, caused divide-by-zero error.
 
@@ -683,85 +682,90 @@ eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed, -bd => 2, -relief => "raised", -width => 20, -highlightthickness => 3)->pack;
 $e->insert("end", "012\t45");
 $e->update;
-ok($e->index('@61'), 3);
-ok($e->index('@62'), 4);
+is($e->index('@61'), 3, "index with highlightthickness");
+is($e->index('@62'), 4);
 
 eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed, qw(-bd 2 -relief raised -width 20 -justify center -highlightthickness 3))->pack;
 $e->insert("end", "012\t45");
 $e->update;
-ok($e->index('@96'), 3);
-ok($e->index('@97'), 4);
+is($e->index('@96'), 3, "index with center justify");
+is($e->index('@97'), 4);
 
 eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed, qw(-bd 2 -relief raised -width 20 -justify right -highlightthickness 3))->pack;
 $e->insert("end", "012\t45");
 $e->update;
-ok($e->index('@131'), 3);
-ok($e->index('@132'), 4);
+is($e->index('@131'), 3, "index with right justify");
+is($e->index('@132'), 4);
 
 eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed, qw(-bd 2 -relief raised -width 5))->pack;
 $e->insert(qw(end 01234567890));
 $e->update;
 $e->xview(6);
-ok($e->index('@0'), 6);
+is($e->index('@0'), 6);
 
 eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed, qw(-bd 2 -relief raised -width 5))->pack;
 $e->insert(qw(end 01234567890));
 $e->update;
 $e->xview(7);
-ok($e->index('@0'), 6);
+is($e->index('@0'), 6);
 
 eval { $e->destroy };
 $e = $mw->Entry(-font => $fixed, qw(-bd 2 -relief raised -width 10))->pack;
 $e->insert(qw(end), "01234\t67890");
 $e->update;
 $e->xview(3);
-ok($e->index('@39'), 5);
-ok($e->index('@40'), 6);
-
-eval { $e->destroy };
-$e = $mw->Entry(-font => $big, qw(-bd 3 -relief raised -width 5))->pack;
-$e->insert(qw(end), "01234567");
-$e->update;
-skip($skip_font_test, $e->reqwidth, 77);
-skip($skip_font_test, $e->reqheight, 39);
+is($e->index('@39'), 5, "index with tabulator in entry");
+is($e->index('@40'), 6);
 
-eval { $e->destroy };
-$e = $mw->Entry(-font => $big, qw(-bd 3 -relief raised -width 0))->pack;
-$e->insert(qw(end), "01234567");
-$e->update;
-skip($skip_font_test, $e->reqwidth, 116);
-skip($skip_font_test, $e->reqheight, 39);
+SKIP: {
+    skip($skip_wm_test, 10)
+	if !$do_wm_test;
+
+    eval { $e->destroy };
+    $e = $mw->Entry(-font => $big, qw(-bd 3 -relief raised -width 5))->pack;
+    $e->insert(qw(end), "01234567");
+    $e->update;
+    is($e->reqwidth, 77, "Expected reqwidth");
+    is($e->reqheight, 39, "Expected reqheight");
 
-eval { $e->destroy };
-$e = $mw->Entry(-font => $big, qw(-bd 3 -relief raised -width 0 -highlightthickness 2))->pack;
-$e->update;
-skip($skip_font_test, $e->reqwidth, 25);
-skip($skip_font_test, $e->reqheight, 39);
+    eval { $e->destroy };
+    $e = $mw->Entry(-font => $big, qw(-bd 3 -relief raised -width 0))->pack;
+    $e->insert(qw(end), "01234567");
+    $e->update;
+    is($e->reqwidth, 116);
+    is($e->reqheight, 39);
 
-eval { $e->destroy };
-$e = $mw->Entry(qw(-bd 1 -relief raised -width 0 -show .))->pack;
-$e->insert(0, "12345");
-$e->update;
-skip($skip_font_test, $e->reqwidth, 23);
-$e->configure(-show => 'X');
-skip($skip_font_test, $e->reqwidth, 53);
-#$e->configure(-show => '');
-#skip($skip_font_test, $e->reqwidth, 43);
+    eval { $e->destroy };
+    $e = $mw->Entry(-font => $big, qw(-bd 3 -relief raised -width 0 -highlightthickness 2))->pack;
+    $e->update;
+    is($e->reqwidth, 25);
+    is($e->reqheight, 39);
 
-eval { $e->destroy };
-$e = $mw->Entry(qw(-bd 1 -relief raised -width 0 -show .),
-		-font => 'helvetica 12')->pack;
-$e->insert(0, "12345");
-$e->update;
-skip($skip_font_test, $e->reqwidth, 8+5*$mw->fontMeasure("helvetica 12", "."));
-$e->configure(-show => 'X');
-skip($skip_font_test, $e->reqwidth, 8+5*$mw->fontMeasure("helvetica 12", "X"));
-#$e->configure(-show => '');
-#ok($e->reqwidth, 8+$mw->fontMeasure("helvetica 12", "12345"));
+    eval { $e->destroy };
+    $e = $mw->Entry(qw(-bd 1 -relief raised -width 0 -show .))->pack;
+    $e->insert(0, "12345");
+    $e->update;
+    is($e->reqwidth, 23);
+    $e->configure(-show => 'X');
+    is($e->reqwidth, 53);
+    #$e->configure(-show => '');
+    #is($e->reqwidth, 43);
+
+    eval { $e->destroy };
+    $e = $mw->Entry(qw(-bd 1 -relief raised -width 0 -show .),
+		    -font => 'helvetica 12')->pack;
+    $e->insert(0, "12345");
+    $e->update;
+    is($e->reqwidth, 8+5*$mw->fontMeasure("helvetica 12", "."));
+    $e->configure(-show => 'X');
+    is($e->reqwidth, 8+5*$mw->fontMeasure("helvetica 12", "X"));
+    #$e->configure(-show => '');
+    #is($e->reqwidth, 8+$mw->fontMeasure("helvetica 12", "12345"));
+}
 
 eval { $e->destroy };
 my $contents;
@@ -772,120 +776,120 @@ $e->delete(0, "end");
 $e->insert(0, "abcde");
 $e->insert(2, "XXX");
 $e->update;
-ok($e->get, "abXXXcde");
-ok($contents, "abXXXcde");
-ok(join(" ", @scrollInfo), "0 1");
+is($e->get, "abXXXcde");
+is($contents, "abXXXcde");
+is(join(" ", @scrollInfo), "0 1", "Result collected in -xscrollcommand callback");
 
 $e->delete(0, "end");
 $e->insert(0, "abcde");
 $e->insert(500, "XXX");
 $e->update;
-ok($e->get, "abcdeXXX");
-ok($contents, "abcdeXXX");
-ok(join(" ", @scrollInfo), "0 1");
+is($e->get, "abcdeXXX");
+is($contents, "abcdeXXX");
+is(join(" ", @scrollInfo), "0 1");
 
 $e->delete(0, "end");
 $e->insert(0, "0123456789");
 $e->selectionFrom(2);
 $e->selectionTo(6);
 $e->insert(2, "XXX");
-ok($e->index("sel.first"), 5);
-ok($e->index("sel.last"), 9);
+is($e->index("sel.first"), 5);
+is($e->index("sel.last"), 9);
 $e->selectionTo(8);
-ok($e->index("sel.first"), 5);
-ok($e->index("sel.last"), 8);
+is($e->index("sel.first"), 5);
+is($e->index("sel.last"), 8);
 
 $e->delete(0, "end");
 $e->insert(0, "0123456789");
 $e->selectionFrom(2);
 $e->selectionTo(6);
 $e->insert(3, "XXX");
-ok($e->index("sel.first"), 2);
-ok($e->index("sel.last"), 9);
+is($e->index("sel.first"), 2);
+is($e->index("sel.last"), 9);
 $e->selectionTo(8);
-ok($e->index("sel.first"), 2);
-ok($e->index("sel.last"), 8);
+is($e->index("sel.first"), 2);
+is($e->index("sel.last"), 8);
 
 $e->delete(0, "end");
 $e->insert(0, "0123456789");
 $e->selectionFrom(2);
 $e->selectionTo(6);
 $e->insert(5, "XXX");
-ok($e->index("sel.first"), 2);
-ok($e->index("sel.last"), 9);
+is($e->index("sel.first"), 2);
+is($e->index("sel.last"), 9);
 $e->selectionTo(8);
-ok($e->index("sel.first"), 2);
-ok($e->index("sel.last"), 8);
+is($e->index("sel.first"), 2);
+is($e->index("sel.last"), 8);
 
 $e->delete(0, "end");
 $e->insert(0, "0123456789");
 $e->selectionFrom(2);
 $e->selectionTo(6);
 $e->insert(6, "XXX");
-ok($e->index("sel.first"), 2);
-ok($e->index("sel.last"), 6);
+is($e->index("sel.first"), 2);
+is($e->index("sel.last"), 6);
 $e->selectionTo(5);
-ok($e->index("sel.first"), 2);
-ok($e->index("sel.last"), 5);
+is($e->index("sel.first"), 2);
+is($e->index("sel.last"), 5);
 
 $e->delete(0, "end");
 $e->insert(0, "0123456789");
 $e->icursor(4);
 $e->insert(4, "XXX");
-ok($e->index("insert"), 7);
+is($e->index("insert"), 7);
 
 $e->delete(0, "end");
 $e->insert(0, "0123456789");
 $e->icursor(4);
 $e->insert(5, "XXX");
-ok($e->index("insert"), 4);
+is($e->index("insert"), 4);
 
 $e->delete(0, "end");
 $e->insert(0, "This is a very long string");
 $e->update;
 $e->xview(4);
 $e->insert(qw(3 XXX));
-ok($e->index('@0'), 7);
+is($e->index('@0'), 7);
 
 $e->delete(0, "end");
 $e->insert(0, "This is a very long string");
 $e->update;
 $e->xview(4);
 $e->insert(qw(4 XXX));
-ok($e->index('@0'), 4);
+is($e->index('@0'), 4);
 
 $e->delete(0, "end");
 $e->insert(0, "xyzzy");
 $e->update;
 $e->insert(2, "00");
-## XXX ok($e->reqwidth, 59);
+## XXX is($e->reqwidth, 59);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 abcde));
 $e->delete(qw(2 4));
 $e->update;
-ok($e->get, "abe");
-ok($contents, "abe");
-ok($scrollInfo[0], 0);
-ok($scrollInfo[1], 1);
+is($e->get, "abe");
+is($contents, "abe");
+is($scrollInfo[0], 0);
+is($scrollInfo[1], 1);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 abcde));
 $e->delete(qw(-2 2));
 $e->update;
-ok($e->get, "cde");
-ok($contents, "cde");
-ok($scrollInfo[0], 0);
-ok($scrollInfo[1], 1);
+is($e->get, "cde");
+is($contents, "cde");
+is($scrollInfo[0], 0);
+is($scrollInfo[1], 1);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 abcde));
 $e->delete(qw(3 1000));
 $e->update;
-ok($e->get, "abc");
-ok($contents, "abc");
-ok($scrollInfo[0], 0);
-ok($scrollInfo[1], 1);
+is($e->get, "abc");
+is($contents, "abc");
+is($scrollInfo[0], 0);
+is($scrollInfo[1], 1);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
@@ -893,11 +897,11 @@ $e->selection(qw(from 3));
 $e->selection(qw(to 8));
 $e->delete(qw(1 3));
 $e->update;
-ok($e->index("sel.first"), 1);
-ok($e->index("sel.last"), 6);
+is($e->index("sel.first"), 1);
+is($e->index("sel.last"), 6);
 $e->selectionTo(5);
-ok($e->index("sel.first"), 1);
-ok($e->index("sel.last"), 5);
+is($e->index("sel.first"), 1);
+is($e->index("sel.last"), 5);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
@@ -905,11 +909,11 @@ $e->selection(qw(from 3));
 $e->selection(qw(to 8));
 $e->delete(qw(1 4));
 $e->update;
-ok($e->index("sel.first"), 1);
-ok($e->index("sel.last"), 5);
+is($e->index("sel.first"), 1);
+is($e->index("sel.last"), 5);
 $e->selectionTo(4);
-ok($e->index("sel.first"), 1);
-ok($e->index("sel.last"), 4);
+is($e->index("sel.first"), 1);
+is($e->index("sel.last"), 4);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
@@ -917,11 +921,11 @@ $e->selection(qw(from 3));
 $e->selection(qw(to 8));
 $e->delete(qw(1 7));
 $e->update;
-ok($e->index("sel.first"), 1);
-ok($e->index("sel.last"), 2);
+is($e->index("sel.first"), 1);
+is($e->index("sel.last"), 2);
 $e->selectionTo(5);
-ok($e->index("sel.first"), 1);
-ok($e->index("sel.last"), 5);
+is($e->index("sel.first"), 1);
+is($e->index("sel.last"), 5);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
@@ -929,7 +933,7 @@ $e->selection(qw(from 3));
 $e->selection(qw(to 8));
 $e->delete(qw(1 8));
 eval { $e->index("sel.first") };
-ok($@ =~ /selection isn\'t in widget/, 1, $@);
+like($@, qr/selection isn\'t in widget/, "Expected error, no selection");
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
@@ -937,11 +941,11 @@ $e->selection(qw(from 3));
 $e->selection(qw(to 8));
 $e->delete(qw(3 7));
 $e->update;
-ok($e->index("sel.first"), 3);
-ok($e->index("sel.last"), 4);
+is($e->index("sel.first"), 3);
+is($e->index("sel.last"), 4);
 $e->selectionTo(8);
-ok($e->index("sel.first"), 3);
-ok($e->index("sel.last"), 8);
+is($e->index("sel.first"), 3);
+is($e->index("sel.last"), 8);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
@@ -949,7 +953,7 @@ $e->selection(qw(from 3));
 $e->selection(qw(to 8));
 $e->delete(qw(3 8));
 eval { $e->index("sel.first") };
-ok($@ =~ /selection isn\'t in widget/, 1, $@);
+like($@, qr/selection isn\'t in widget/);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
@@ -957,11 +961,11 @@ $e->selection(qw(from 8));
 $e->selection(qw(to 3));
 $e->delete(qw(5 8));
 $e->update;
-ok($e->index("sel.first"), 3);
-ok($e->index("sel.last"), 5);
+is($e->index("sel.first"), 3);
+is($e->index("sel.last"), 5);
 $e->selectionTo(8);
-ok($e->index("sel.first"), 5);
-ok($e->index("sel.last"), 8);
+is($e->index("sel.first"), 5);
+is($e->index("sel.last"), 8);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
@@ -969,47 +973,47 @@ $e->selection(qw(from 8));
 $e->selection(qw(to 3));
 $e->delete(qw(8 10));
 $e->update;
-ok($e->index("sel.first"), 3);
-ok($e->index("sel.last"), 8);
+is($e->index("sel.first"), 3);
+is($e->index("sel.last"), 8);
 $e->selectionTo(4);
-ok($e->index("sel.first"), 4);
-ok($e->index("sel.last"), 8);
+is($e->index("sel.first"), 4);
+is($e->index("sel.last"), 8);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
 $e->icursor(4);
 $e->delete(qw(1 4));
-ok($e->index("insert"), 1);
+is($e->index("insert"), 1);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
 $e->icursor(4);
 $e->delete(qw(1 5));
-ok($e->index("insert"), 1);
+is($e->index("insert"), 1);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcde));
 $e->icursor(4);
 $e->delete(qw(4 6));
-ok($e->index("insert"), 4);
+is($e->index("insert"), 4);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0), "This is a very long string");
 $e->xview(4);
 $e->delete(qw(1 4));
-ok($e->index('@0'), 1);
+is($e->index('@0'), 1);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0), "This is a very long string");
 $e->xview(4);
 $e->delete(qw(1 5));
-ok($e->index("\@0"), 1);
+is($e->index("\@0"), 1);
 
 $e->delete(qw(0 end));
 $e->insert(qw(0), "This is a very long string");
 $e->xview(4);
 $e->delete(qw(4 6));
-ok($e->index("\@0"), 4);
+is($e->index("\@0"), 4);
 
 $e->configure(qw(-width 0));
 
@@ -1017,7 +1021,7 @@ $e->delete(qw(0 end));
 $e->insert(0, "xyzzy");
 $e->update;
 $e->delete(qw(2 4));
-ok($e->reqwidth, 31);
+is($e->reqwidth, 31);
 
 eval { $e->destroy };
 
@@ -1028,8 +1032,8 @@ undef $x;
 $mw->traceVariable(\$x, 'w', \&_override2);
 $e = $mw->Entry(-textvariable => \$x);
 $e->insert(0, "foo");
-ok($x, 12345);
-ok($e->get, 12345);
+is($x, 12345);
+is($e->get, 12345);
 undef $x;
 
 Tk::catch {$e->destroy};
@@ -1042,8 +1046,8 @@ $e->configure(-textvariable => \$x);
 $e->update;
 $e->configure(-textvariable => \$y);
 $e->update;
-ok($e->get, "ab");
-ok($e->reqwidth, 24);
+is($e->get, "ab");
+is($e->reqwidth, 24);
 
 $mw->traceVdelete(\$x); # XXX why?
 
@@ -1053,23 +1057,23 @@ $e->insert(0, "abcdefghjklmnopqrstu");
 $e->selection(qw(range 4 10));
 $x = "a";
 eval { $e->index("sel.first") };
-ok($@ =~ /selection isn\'t in widget/, 1, $@);
+like($@, qr/selection isn\'t in widget/);
 
 Tk::catch {$e->destroy};
 $e = $mw->Entry(-textvariable => \$x);
 $e->insert(0, "abcdefghjklmnopqrstu");
 $e->selection(qw(range 4 10));
 $x = "abcdefg";
-ok($e->index("sel.first"), 4);
-ok($e->index("sel.last"), 7);
+is($e->index("sel.first"), 4);
+is($e->index("sel.last"), 7);
 
 Tk::catch {$e->destroy};
 $e = $mw->Entry(-textvariable => \$x);
 $e->insert(0, "abcdefghjklmnopqrstu");
 $e->selection(qw(range 4 10));
 $x = "abcdefghijklmn";
-ok($e->index("sel.first"), 4);
-ok($e->index("sel.last"), 10);
+is($e->index("sel.first"), 4);
+is($e->index("sel.last"), 10);
 
 Tk::catch {$e->destroy};
 $e = $mw->Entry(-textvariable => \$x)->pack;
@@ -1078,7 +1082,7 @@ $e->xview(10);
 $e->update;
 $x = "abcdefg";
 $e->update;
-ok($e->index('@0'), 0);
+is($e->index('@0'), 0);
 
 Tk::catch {$e->destroy};
 $e = $mw->Entry(-font => $fixed, -width => 10, -textvariable => \$x)->pack;
@@ -1087,21 +1091,21 @@ $e->xview(10);
 $e->update;
 $x = "1234567890123456789012";
 $e->update;
-ok($e->index('@0'), 10);
+is($e->index('@0'), 10);
 
 Tk::catch {$e->destroy};
 $e = $mw->Entry(-font => $fixed, -width => 10, -textvariable => \$x)->pack;
 $e->insert(0, "abcdefghjklmnopqrstu");
 $e->icursor(5);
 $x = "123";
-ok($e->index("insert"), 3);
+is($e->index("insert"), 3);
 
 Tk::catch {$e->destroy};
 $e = $mw->Entry(-font => $fixed, -width => 10, -textvariable => \$x)->pack;
 $e->insert(0, "abcdefghjklmnopqrstuvwxyz");
 $e->icursor(5);
 $x = "123456";
-ok($e->index("insert"), 5);
+is($e->index("insert"), 5);
 
 Tk::catch {$e->destroy};
 $e = $mw->Entry;
@@ -1111,45 +1115,45 @@ $mw->update;
 
 $_->destroy for ($mw->children);
 my $e1 = $mw->Entry(-fg => '#112233');
-ok(($mw->children)[0], $e1);
+is(($mw->children)[0], $e1);
 $e1->destroy;
-ok(scalar($mw->children), undef); # XXX why not 0?
+is(scalar($mw->children), undef); # XXX why not 0?
 
 $e = $mw->Entry(-font => $fixed, qw(-width 5 -bd 2 -relief sunken))->pack;
 $e->insert(qw(0 012345678901234567890));
 $e->xview(4);
 $e->update;
-ok($e->index("end"), 21);
+is($e->index("end"), 21);
 
 eval { $e->index("abogus") };
-ok($@ =~ /bad entry index "abogus"/, 1, $@);
+like($@, qr/bad entry index "abogus"/);
 
 $e->selection(qw(from 1));
 $e->selection(qw(to 6));
-ok($e->index(qw(anchor)), 1);
+is($e->index(qw(anchor)), 1);
 
 $e->selection(qw(from 4));
 $e->selection(qw(to 1));
-ok($e->index(qw(anchor)), 4);
+is($e->index(qw(anchor)), 4);
 
 $e->selection(qw(from 3));
 $e->selection(qw(to 15));
 $e->selection(qw(adjust 4));
-ok($e->index(qw(anchor)), 15);
+is($e->index(qw(anchor)), 15);
 
 eval { $e->index("ebogus") };
-ok($@ =~ /bad entry index "ebogus"/, 1, $@);
+like($@, qr/bad entry index "ebogus"/);
 
 $e->icursor(2);
-ok($e->index('insert'), 2);
+is($e->index('insert'), 2);
 
 eval { $e->index("ibogus") };
-ok($@ =~ /bad entry index "ibogus"/, 1, $@);
+like($@, qr/bad entry index "ibogus"/);
 
 $e->selectionFrom(1);
 $e->selectionTo(6);
-ok($e->index("sel.first"), 1);
-ok($e->index("sel.last"), 6);
+is($e->index("sel.first"), 1);
+is($e->index("sel.last"), 6);
 
 $mw->SelectionClear($e);
 
@@ -1158,49 +1162,54 @@ if ($^O ne 'MSWin32') {
     # selection range is reset.
 
     eval { $e->index("sel.first") };
-    skip("Test only for MSWin32", $@ =~ /selection isn\'t in widget/, 1, $@) for (1..2);
+    like($@, qr/selection isn\'t in widget/);
+    pass("Dummy to align number of tests with MSWin32");
 
 } else {
     # On mac and pc, when selection is cleared, entry widget remembers
     # last selected range.  When selection ownership is restored to
     # entry, the old range will be rehighlighted.
 
-    ok($e->getSelected, '12345');
-    ok($e->index("sel.first"), 1);
+    is($e->getSelected, '12345');
+    is($e->index("sel.first"), 1);
 }
 
 if ($^O ne 'MSWin32') {
     eval { $e->index("sbogus") };
-    ok($@ =~ /selection isn\'t in widget/, 1, $@);
+    like($@, qr/selection isn\'t in widget/);
 } else {
     eval { $e->index("sbogus") };
-    ok($@ =~ /bad entry index "sbogus"/, 1, $@);
+    like($@, qr/bad entry index "sbogus"/);
 }
 
 eval { $e->index('@xyz') };
-ok($@ =~ /bad entry index "\@xyz"/, 1, $@);
+like($@, qr/bad entry index "\@xyz"/);
 
-ok($e->index('@4'), 4);
-ok($e->index('@11'), 4);
-ok($e->index('@12'), 5);
-ok($e->index('@' . ($e->width-6)), 8);
-ok($e->index('@' . ($e->width-5)), 9);
-ok($e->index('@1000'), 9);
+is($e->index('@4'), 4);
+is($e->index('@11'), 4);
+is($e->index('@12'), 5);
+is($e->index('@' . ($e->width-6)), 8);
+is($e->index('@' . ($e->width-5)), 9);
+is($e->index('@1000'), 9);
 
 eval { $e->index('1xyz') };
-ok($@ =~ /bad entry index "1xyz"/, 1, $@);
+like($@, qr/bad entry index "1xyz"/);
 
-ok($e->index(-10), 0);
-ok($e->index(12), 12);
-ok($e->index(49), 21);
+is($e->index(-10), 0);
+is($e->index(12), 12);
+is($e->index(49), 21);
 
 Tk::catch { $e->destroy };
 $e = $mw->Entry(-show => ".");
 $e->insert(qw(0 XXXYZZY));
 $e->pack;
 $e->update;
-skip($skip_font_test, $e->index('@7'), 0);
-skip($skip_font_test, $e->index('@8'), 1);
+SKIP: {
+    skip($skip_font_test, 2)
+	if !$do_font_test;
+    is($e->index('@7'), 0);
+    is($e->index('@8'), 1);
+}
 
 # XXX Still need to write tests for EntryScanTo and EntrySelectTo.
 
@@ -1214,32 +1223,32 @@ $e = $mw->Entry;
 $e->insert(end => "This is a test string");
 $e->selection(qw(from 1));
 $e->selection(qw(to 18));
-ok($mw->SelectionGet, "his is a test str");
+is($mw->SelectionGet, "his is a test str");
 
 Tk::catch { $e->destroy };
 $e = $mw->Entry(-show => "*");
 $e->insert(end => "This is a test string");
 $e->selection(qw(from 1));
 $e->selection(qw(to 18));
-ok($mw->SelectionGet, "*****************");
+is($mw->SelectionGet, "*****************");
 
 Tk::catch { $e->destroy };
 $e = $mw->Entry;
 $e->insert("end", $x);
 $e->selectionFrom(0);
 $e->selectionTo("end");
-ok($mw->SelectionGet, $x);
+is($mw->SelectionGet, $x);
 
 Tk::catch { $e->destroy };
 $e = $mw->Entry;
 $e->insert(0, "Text");
 $e->selectionFrom(0);
 $e->selectionTo(4);
-ok($mw->SelectionGet, "Text");
+is($mw->SelectionGet, "Text");
 $mw->SelectionClear;
 $e->selectionFrom(0);
 $e->selectionTo(4);
-ok($mw->SelectionGet, "Text");
+is($mw->SelectionGet, "Text");
 
 # No tests for EventuallyRedraw.
 
@@ -1249,7 +1258,11 @@ $e->update;
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 .............................));
-skip($skip_font_test || $skip_wm_test, join(" ", map { substr($_, 0, 8) } $e->xview), "0 0.827586");
+SKIP: {
+    skip($skip_wm_font_test, 1)
+	if !$do_font_test || !$do_wm_test;
+    is_deeply([map { substr($_, 0, 8) } $e->xview], [0, 0.827586]);
+}
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXX));
@@ -1258,16 +1271,20 @@ my $Xw = join(" ", map { substr($_, 0, 8
 $e->configure(-show => 'X');
 $e->delete(qw(0 end));
 $e->insert(qw(0 .............................));
-ok(join(" ", map { substr($_, 0, 8) } $e->xview), $Xw);
+is(join(" ", map { substr($_, 0, 8) } $e->xview), $Xw);
 
 $e->configure(-show => '.');
 $e->delete(qw(0 end));
 $e->insert(qw(0 XXXXXXXXXXXXXXXXXXXXXXXXXXXXX));
-skip($skip_font_test || $skip_wm_test, join(" ", map { substr($_, 0, 8) } $e->xview), "0 0.827586");
+SKIP: {
+    skip($skip_wm_font_test, 1)
+	if !$do_font_test || !$do_wm_test;
+    is_deeply([map { substr($_, 0, 8) } $e->xview], [0, 0.827586]);
+}
 
 $e->configure(-show => "");
 $e->delete(qw(0 end));
-ok(($e->xview)[$_], $_) for (0 .. 1);
+is(($e->xview)[$_], $_) for (0 .. 1);
 
 Tk::catch {$e->destroy};
 $e = $mw->Entry(qw(-width 10 -xscrollcommand), \&scroll, -font => $fixed)->pack;
@@ -1276,19 +1293,27 @@ $e->update;
 $e->delete(qw(0 end));
 $e->insert(qw(0 123));
 $e->update;
-ok(join(" ",@scrollInfo),"0 1");
+is(join(" ",@scrollInfo),"0 1");
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 0123456789abcdef));
 $e->xview(3);
 $e->update;
-skip($skip_font_test || $skip_wm_test, join(" ",@scrollInfo),"0.1875 0.8125");
+SKIP: {
+    skip($skip_wm_font_test, 1)
+	if !$do_font_test || !$do_wm_test;
+    is_deeply([@scrollInfo],[0.1875, 0.8125]);
+}
 
 $e->delete(qw(0 end));
 $e->insert(qw(0 abcdefghijklmnopqrs));
 $e->xview(6);
 $e->update;
-skip($skip_font_test || $skip_wm_test, join(" ",map { sprintf "%8f", $_ } @scrollInfo),"0.315789 0.842105");
+SKIP: {
+    skip($skip_wm_font_test, 1)
+	if !$do_font_test || !$do_wm_test;
+    is_deeply([map { sprintf "%8f", $_ } @scrollInfo],[0.315789, 0.842105]);
+}
 
 Tk::catch {$e->destroy};
 my $err;
@@ -1297,7 +1322,7 @@ eval {
     $e = $mw->Entry(qw(-width 5 -xscrollcommand thisisnotacommand))->pack;
     $e->update;
 };
-ok($err =~ /Undefined subroutine &main::thisisnotacommand/);
+like($err, qr/Undefined subroutine &main::thisisnotacommand/, "Expected invalid -xscrollcommand callback");
 
 #      pack .e
 #      update
@@ -1323,7 +1348,7 @@ ok($err =~ /Undefined subroutine &main::
 # Additional tests
 
 $e->validate; # check whether validate method is defined
-ok(1);
+pass("validate method seems to be defined");
 
 __END__
 
diff -up '/usr/local/src/Tk-804.027/t/fork.t' '/home/e/eserte/work/svk-checkouts/Tk/t/fork.t'
Index: ./t/fork.t
--- ./t/fork.t	Fri Apr  9 11:13:37 2004
+++ ./t/fork.t	Tue Nov  7 23:39:07 2006
@@ -7,6 +7,7 @@ use Tk;
 plan tests => 1;
 
 my $mw = tkinit;
+$mw->geometry("+10+10");
 
 if ($^O ne 'MSWin32' && fork == 0) {
     print "# Child $$\n";
diff -up '/usr/local/src/Tk-804.027/t/listbox.t' '/home/e/eserte/work/svk-checkouts/Tk/t/listbox.t'
Index: ./t/listbox.t
Prereq:  1.2 
--- ./t/listbox.t	Sun Dec 21 21:03:05 2003
+++ ./t/listbox.t	Thu Nov  9 00:37:00 2006
@@ -25,26 +25,28 @@ use FindBin;
 use lib "$FindBin::RealBin";
 use TkTest;
 
+use Getopt::Long;
+
 BEGIN {
     $Listbox = "Listbox";
     #$Listbox = "TextList";
+    GetOptions("listboxclass=s" => \$Listbox)
+	or die "usage: $0 [-listboxclass baseclass]";
+
     eval "use Tk::$Listbox";
 }
 
 BEGIN {
     if (!eval q{
-	use Test;
+	use Test::More;
 	1;
     }) {
-	print "# tests only work with installed Test module:\n";
-	print join("\n", map { "## $_" } split(/\n/, $@)), "\n";
-	print "1..1\n";
-	print "is 1\n";
+	print "1..0 # skip: no Test::More module\n";
 	exit;
     }
 }
 
-BEGIN { plan tests => 437 , todo => [274 .. 276] }
+plan tests => 537;
 
 my $partial_top;
 my $partial_lb;
@@ -52,19 +54,24 @@ my $partial_lb;
 my $mw = new MainWindow;
 $mw->geometry('+10+10');
 $mw->raise;
-my $fixed = $Xft ? '{Adobe Courier} -12' : 'Courier -12';
-ok(Tk::Exists($mw), 1);
+## Always use the X11 font, even with Xft, otherwise the measurements would
+## be wrong.
+#my $fixed = $Xft ? '{Adobe Courier} -12' : 'Courier -12';
+my $fixed = "-adobe-courier-medium-r-normal--12-120-75-75-m-*-iso8859-1";
+ok(Tk::Exists($mw));
 
 # Create entries in the option database to be sure that geometry options
 # like border width have predictable values.
 $mw->optionAdd("*$Listbox.borderWidth",2);
 $mw->optionAdd("*$Listbox.highlightThickness",2);
-$mw->optionAdd("*$Listbox.font",
-                $Xft ? '{Adobe Helvetica} -12 bold' :'Helvetica -12 bold');
+## Again, prefer the X11 font.
+#$mw->optionAdd("*$Listbox.font",
+#                $Xft ? '{Adobe Helvetica} -12 bold' :'Helvetica -12 bold');
+$mw->optionAdd("*$Listbox.font", 'Helvetica -12 bold');
 
 my $lb = $mw->$Listbox->pack;
-ok(Tk::Exists($lb), 1);
-ok($lb->isa("Tk::$Listbox"), 1);
+ok(Tk::Exists($lb), "Listbox exists");
+isa_ok($lb, "Tk::$Listbox");
 $lb->update;
 
 my $skip_font_test;
@@ -89,30 +96,33 @@ if (!$Xft) { # XXX Is this condition nec
 my $skip_fixed_font_test;
 {
     my $fixed_lb = $mw->$Listbox(-font => $fixed);
-    if (!$Xft) { # XXX Is this condition necessary?
-	my %fa = $mw->fontActual($fixed_lb->cget(-font));
-	my %expected = (
-			"-weight" => "normal",
-			"-underline" => 0,
-			"-family" => "courier",
-			"-slant" => "roman",
-			"-size" => -12,
-			"-overstrike" => 0,
-		       );
-	while(my($k,$v) = each %expected) {
-	    if ($v ne $fa{$k}) {
-		$skip_fixed_font_test = "font-related tests (fixed font)";
-		last;
-	    }
+    my %fa = $mw->fontActual($fixed_lb->cget(-font));
+    my %expected = (
+		    "-weight" => "normal",
+		    "-underline" => 0,
+		    "-family" => "courier", # with $Xft, this would be "Courier"
+		    "-slant" => "roman",
+		    "-size" => -12,
+		    "-overstrike" => 0,
+		   );
+    while(my($k,$v) = each %expected) {
+	if ($v ne $fa{$k}) {
+	    $skip_fixed_font_test = "font-related tests (fixed font)";
+	    last;
 	}
-	$fixed_lb->destroy;
     }
+    $fixed_lb->destroy;
 }
 
 resetGridInfo();
 
 $mw->Photo("testimage", -file => Tk->findINC("Xcamel.gif"));
 
+use constant SKIP_CGET    => 5;
+use constant SKIP_CONF    => 6;
+
+my $testVariable;
+
 foreach my $test
     (
      ['-activestyle', 'under', 'underline', 'foo',
@@ -124,16 +134,12 @@ foreach my $test
       'unknown color name "non-existent"'],
      [qw{-borderwidth 1.3 1 badValue}, q{bad screen distance "badValue"}],
      [qw{-cursor arrow arrow badValue}, q{bad cursor spec "badValue"}],
-# XXX error test skipped...
-     [qw{-exportselection yes 1}, "", #"xyzzy",
-      q{expected boolean value but got "xyzzy"}],
+     [qw{-exportselection yes 1}, ""], # Perl/Tk thinks different about booleans: "xyzzy", q{expected boolean value but got "xyzzy"}],
      ['-fg', '#110022', '#110022', 'bogus', q{unknown color name "bogus"}],
-# XXX should test perl font object
-#     ['-font', 'Helvetica 12', 'Helvetica 12', '', "font \"\" doesn't exist"],
+     ['-font', 'Helvetica 12', 'Helvetica 12', '', "font \"\" doesn't exist", 1, 1],
      ['-foreground', '#110022', '#110022', 'bogus',
       q{unknown color name "bogus"}],
-# XXX q{expected integer but got "20p"}
-     [qw{-height 30 30 20p}, "'20p' isn't numeric"],
+     [qw{-height 30 30 20p}, "'20p' isn't numeric"], # in Tcl/Tk nowadays: expected integer but got "20p"
      ['-highlightbackground', '#112233', '#112233', 'ugly',
       q{unknown color name "ugly"}],
      ['-highlightcolor', '#123456', '#123456', 'bogus',
@@ -143,9 +149,12 @@ foreach my $test
      ['-offset', '1,1', '1,1', 'wrongside',
       'bad offset "wrongside": expected "x,y", n, ne, e, se, s, sw, w, nw, or center'],
      [qw{-relief groove groove 1.5},
-      ($Tk::VERSION < 803
+      ($Listbox eq 'TextList'
        ? q{bad relief type "1.5": must be flat, groove, raised, ridge, solid, or sunken}
-       : q{bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken})],
+       : ($Tk::VERSION < 803
+	  ? q{bad relief type "1.5": must be flat, groove, raised, ridge, solid, or sunken}
+	  : q{bad relief "1.5": must be flat, groove, raised, ridge, solid, or sunken})
+      )],
      ['-selectbackground', '#110022', '#110022', 'bogus',
       q{unknown color name "bogus"}],
      [qw{-selectborderwidth 1.3 1 badValue},
@@ -153,131 +162,129 @@ foreach my $test
      ['-selectforeground', '#654321', '#654321', 'bogus',
       q{unknown color name "bogus"}],
      [qw{-selectmode string string}, '', ''],
-     [qw{-setgrid false 0}, "", # XXX "lousy",
+     [qw{-setgrid false 0}, "", "lousy",
       q{expected boolean value but got "lousy"}],
      ['-state', 'disabled', 'disabled', 'foo',
-      'bad state "foo": must be disabled, or normal'],
+      ($Listbox eq 'TextList'
+       ? q{bad state value "foo": must be normal or disabled}
+       : 'bad state "foo": must be disabled, or normal'
+      )],
      ['-takefocus', "any string", "any string", '', ''],
      ['-tile', 'testimage', 'testimage', 'non-existant',
       'image "non-existant" doesn\'t exist'],
-     [qw{-width 45 45 3p}, "'3p' isn't numeric"],
-      #XXXq{expected integer but got "3p"}],
-#XXX Callback object      ['-xscrollcommand', 'Some command', 'Some command', '', ''],
-#XXX     ['-yscrollcommand', 'Another command', 'Another command', '', ''],
-#XXX not yet in 800.022     [qw{-listvar}, \$testVariable,  testVariable {}}, q{}],
+     [qw{-width 45 45 3p}, "'3p' isn't numeric"], # In Tcl/Tk nowadays q{expected integer but got "3p"}
+     [qw(-xscrollcommand), q{Some command}, q{Some command}, '', undef, 1, 1],
+     [qw(-yscrollcommand), q{Another command}, q{Another command}, '', undef, 1, 1],
+     [qw{-listvar}, \$testVariable,  \$testVariable, '', undef],
     ) {
 	my $name = $test->[0];
 
-	if ($Listbox eq 'TextList' &&
-	    $name =~ /^-(activestyle|bg|fg|foreground|height|selectborderwidth)$/) {
-	    my $skip = "$name test not supported for $Listbox";
-	    skip($skip,1);
-	    if ($test->[3] ne "") {
-		skip($skip,1);
+    SKIP: {
+	    skip("$name test not supported for $Listbox", 3)
+		if ($Listbox eq 'TextList' &&
+		    $name =~ /^-(activestyle|bg|fg|foreground|height|selectborderwidth|listvar)$/);
+
+	    skip("$name not implemented on $Tk::VERSION", 3)
+		if ($Listbox eq 'Listbox' && $Tk::VERSION < 804 &&
+		    $name =~ /^-(activestyle)$/);
+
+	    skip("*TODO* $name not yet implemented on $Tk::VERSION", 3)
+		if ($Tk::VERSION >= 804 &&
+		    $name =~ /^-(tile|offset)$/);
+
+	    $lb->configure($name, $test->[1]);
+	    pass("configure set for $name");
+	SKIP: {
+		skip("configure test for $name", 1) if $test->[SKIP_CONF];
+		is(($lb->configure($name))[4],$test->[2], "configuration option $name");
 	    }
-	    next;
-	}
-
-	if ($Listbox eq 'Listbox' && $Tk::VERSION < 804 &&
-	    $name =~ /^-(activestyle)$/) {
-	    my $skip = "$name not implemented on $Tk::VERSION";
-	    skip($skip,1);
-	    if ($test->[3] ne "") {
-		skip($skip,1);
+	SKIP: {
+		skip("cget test for $name", 1) if $test->[SKIP_CGET];
+		is($lb->cget($name), $test->[2], "cget call with $name");
 	    }
-	    next;
-	}
-
-	if ($Listbox eq 'Listbox' && $Tk::VERSION >= 804 &&
-	    $name =~ /^-(tile|offset)$/) {
-	    my $skip = "*TODO* $name not yet implemented on $Tk::VERSION";
-	    skip($skip,1);
-	    if ($test->[3] ne "") {
-		skip($skip,1);
+	SKIP: {
+		skip("error test for $name", 1) if $test->[3] eq "";
+		eval {
+		    $lb->configure($name, $test->[3]);
+		};
+		like($@,qr/$test->[4]/,"error message for $name");
 	    }
-	    next;
-	}
 
-	$lb->configure($name, $test->[1]);
-	ok(($lb->configure($name))[4], $test->[2], "configuration option $name");
-	ok($lb->cget($name), $test->[2], "cget call with $name");
-	if ($test->[3] ne "") {
-	    eval {
-		$lb->configure($name, $test->[3]);
-	    };
-	    ok($@,qr/$test->[4]/,"wrong error message for $name");
+	    $lb->configure($name, ($lb->configure($name))[3]);
 	}
-	$lb->configure($name, ($lb->configure($name))[3]);
     }
 
-if ($Listbox ne 'Listbox') {
-    skip(1, 1);
-} else {
+SKIP: {
+    skip("only for Listbox, not for $Listbox", 1)
+	if ($Listbox ne 'Listbox');
+
     eval { Tk::listbox() };
-    ok($@,qr/Usage \$widget->listbox(...)/, "wrong error message");
+    like($@,qr/Usage \$widget->listbox(...)/, "error message");
 }
 
-eval {
-    $lb->destroy;
-    $lb = $mw->$Listbox;
-};
-ok(Tk::Exists($lb), 1);
-ok($lb->class, "$Listbox");
+{
+    eval {
+	$lb->destroy;
+	$lb = $mw->$Listbox;
+    };
+    ok(Tk::Exists($lb));
+    is($lb->class, "$Listbox", "Tk class $Listbox");
+}
 
-eval {
-    $lb->destroy;
-    $lb = $mw->$Listbox(-gorp => "foo");
-};
-ok($@,
-     ($Tk::VERSION < 803)
-       ? qr/Bad option \`-gorp\'/
-       : qr/unknown option \"-gorp\"/,
-      "wrong error message");
+{
+    eval {
+	$lb->destroy;
+	$lb = $mw->$Listbox(-gorp => "foo");
+    };
+    like($@,
+	 ($Tk::VERSION < 803)
+	 ? qr/Bad option \`-gorp\'/
+	 : qr/unknown option \"-gorp\"/,
+	 "error message");
+}
 
-ok(Tk::Exists($lb), 0);
+ok(!Tk::Exists($lb));
 
 $lb = $mw->$Listbox(-width => 20, -height => 5, -bd => 4,
-		   -highlightthickness => 1,
-		   -selectborderwidth => 2)->pack;
+		    -highlightthickness => 1,
+		    -selectborderwidth => 2)->pack;
 $lb->insert(0,
 	    'el0','el1','el2','el3','el4','el5','el6','el7','el8','el9','el10',
 	    'el11','el12','el13','el14','el15','el16','el17');
 $lb->update;
 eval { $lb->activate };
-ok($@,qr/wrong \# args: should be "\.listbox.* activate index"/,
-   "wrong error message");
+like($@,qr/wrong \# args: should be "\.listbox.* activate index"/,
+     "Listbox activate error message");
 
 eval { $lb->activate("fooey") };
-ok($@,qr/bad listbox index "fooey": must be active, anchor, end, \@x,y, or a number/,
-     "wrong error message");
+like($@,qr/bad listbox index "fooey": must be active, anchor, end, \@x,y, or a number/);
 
 $lb->activate(3);
-ok($lb->index("active"), 3);
+is($lb->index("active"), 3, "Listbox activate");
 
 $lb->activate(-1);
-ok($lb->index("active"), 0);
+is($lb->index("active"), 0);
 
 $lb->activate(30);
-ok($lb->index("active"), 17);
+is($lb->index("active"), 17);
 
 $lb->activate("end");
-ok($lb->index("active"), 17);
+is($lb->index("active"), 17);
 
 eval { $lb->bbox };
-ok($@, qr/wrong \# args: should be "\.listbox.* bbox index"/,
-   "wrong error message");
+like($@, qr/wrong \# args: should be "\.listbox.* bbox index"/,
+     "Listbox bbox error message");
 
 eval { $lb->bbox(qw/a b/) };
-ok($@, qr/wrong \# args: should be "\.listbox.* bbox index"/,
-   "wrong error message");
+like($@, qr/wrong \# args: should be "\.listbox.* bbox index"/);
 
 eval { $lb->bbox("fooey") };
-ok($@,qr/bad listbox index "fooey": must be active, anchor, end, \@x,y, or a number/, "wrong error message");
+like($@,qr/bad listbox index "fooey": must be active, anchor, end, \@x,y, or a number/);
 
 $lb->yview(3);
 $lb->update;
-ok($lb->bbox(2), undef);
-ok($lb->bbox(8), undef);
+is($lb->bbox(2), undef, "Listbox bbox");
+is($lb->bbox(8), undef);
 
 # Used to generate a core dump before a bug was fixed (the last
 # element would be on-screen if it existed, but it doesn't exist).
@@ -288,26 +295,32 @@ eval {
     my $x = $l2->bbox(0);
     $l2->destroy;
 };
-ok($@, '', "wrong error message");
+is($@, '', "No core dump with bbox");
 
 $lb->yview(3);
 $lb->update;
-skip($skip_font_test, join(" ", $lb->bbox(3)), "7 7 17 14");
-ok(scalar @{[$lb->bbox(3)]}, 4);
-skip($skip_font_test, ($lb->bbox(3))[0], 7);
-skip($skip_font_test, ($lb->bbox(3))[-1], 14);
-skip($skip_font_test, join(" ", $lb->bbox(4)), "7 26 17 14");
+SKIP: {
+    skip($skip_font_test, 2) if $skip_font_test;
+    is_deeply([$lb->bbox(3)], [qw(7 7 17 14)]);
+    is_deeply([$lb->bbox(4)], [qw(7 26 17 14)]);
+}
 
 $lb->yview(0);
 $lb->update;
-ok($lb->bbox(-1), undef);
-skip($skip_font_test, join(" ", $lb->bbox(0)), "7 7 17 14");
+is($lb->bbox(-1), undef);
+SKIP: {
+    skip($skip_font_test, 1) if $skip_font_test;
+    is_deeply([$lb->bbox(0)], [qw(7 7 17 14)]);
+}
 
 $lb->yview("end");
 $lb->update;
-skip($skip_font_test, join(" ", $lb->bbox(17)), "7 83 24 14");
-skip($skip_font_test, join(" ", $lb->bbox("end")), "7 83 24 14");
-ok($lb->bbox(18), undef);
+SKIP: {
+    skip($skip_font_test, 2) if $skip_font_test;
+    is_deeply([$lb->bbox(17)], [qw(7 83 24 14)]);
+    is_deeply([$lb->bbox("end")], [qw(7 83 24 14)]);
+}
+is($lb->bbox(18), undef);
 
 {
     my $t = $mw->Toplevel;
@@ -320,81 +333,84 @@ ok($lb->bbox(18), undef);
     $lb->pack;
     $lb->update;
     $lb->xview(moveto => 0.2);
-    skip($skip_font_test, join(" ", $lb->bbox(2)), '-72 39 393 14');
-    $t->destroy;
+ SKIP: {
+	skip($skip_font_test, 1) if $skip_font_test;
+	is_deeply([$lb->bbox(2)], [qw(-72 39 393 14)]);
+	$t->destroy;
+    }
 }
 
 mkPartial();
-skip($skip_font_test, join(" ", $partial_lb->bbox(3)), "5 56 24 14");
-skip($skip_font_test, join(" ", $partial_lb->bbox(4)), "5 73 23 14");
+SKIP: {
+    skip($skip_font_test, 2) if $skip_font_test;
+    is_deeply([$partial_lb->bbox(3)], [qw(5 56 24 14)]);
+    is_deeply([$partial_lb->bbox(4)], [qw(5 73 23 14)]);
+}
 
 eval { $lb->cget };
-ok($@,qr/wrong \# args: should be \"\.listbox.* cget option\"/,
-   "wrong error message");
+like($@,qr/wrong \# args: should be \"\.listbox.* cget option\"/,
+     "Listbox cget message");
 
 eval { $lb->cget(qw/a b/) };
-ok($@,qr/wrong \# args: should be \"\.listbox.* cget option\"/,
-   "wrong error message");
+like($@,qr/wrong \# args: should be \"\.listbox.* cget option\"/);
 
 eval { $lb->cget(-gorp) };
-ok($@,qr/unknown option "-gorp"/, "wrong error message");
+like($@,qr/unknown option "-gorp"/);
 
-ok($lb->cget(-setgrid), 0);
-# XXX why 25 in Tk800?
-ok(scalar @{[$lb->configure]}, ($Tk::VERSION < 803 ? 25 : 27));
-ok(join(" ", $lb->configure(-setgrid)),
-   "-setgrid setGrid SetGrid 0 0");
+is($lb->cget(-setgrid), 0);
+# XXX why 25 in Tk800? probably because of less configuration options!
+is(scalar @{[$lb->configure]}, ($Tk::VERSION < 803 ? 25 : 27), "Listbox configure");
+is_deeply([$lb->configure(-setgrid)],
+	  [qw(-setgrid setGrid SetGrid 0 0)]);
 eval { $lb->configure(-gorp) };
-ok($@,qr/unknown option "-gorp"/, "wrong error message");
+like($@,qr/unknown option "-gorp"/);
 
 {
     my $oldbd = $lb->cget(-bd);
     my $oldht = $lb->cget(-highlightthickness);
     $lb->configure(-bd => 3, -highlightthickness => 0);
-    ok($lb->cget(-bd), 3);
-    ok($lb->cget(-highlightthickness), 0);
+    is($lb->cget(-bd), 3);
+    is($lb->cget(-highlightthickness), 0);
     $lb->configure(-bd => $oldbd);
     $lb->configure(-highlightthickness => $oldht);
 }
 
 eval { $lb->curselection("a") };
-ok($@,qr/wrong \# args: should be \"\.listbox.* curselection\"/,
-   "wrong error message");
+like($@,qr/wrong \# args: should be \"\.listbox.* curselection\"/,
+     "Listbox curselection error message");
 
 $lb->selection("clear", 0, "end");
 $lb->selection("set", 3, 6);
 $lb->selection("set", 9);
-ok(join(" ", $lb->curselection), "3 4 5 6 9");
+is_deeply([$lb->curselection], [qw(3 4 5 6 9)],
+	  "Listbox curselection");
 
 # alternative perl/Tk methods
 $lb->selectionClear(0, "end");
 $lb->selectionSet(3, 6);
 $lb->selectionSet(9);
-ok(join(" ", $lb->curselection), "3 4 5 6 9");
+is_deeply([$lb->curselection], [qw(3 4 5 6 9)]);
 
 eval { $lb->delete };
-ok($@,qr/wrong \# args: should be \"\.listbox.* delete firstIndex \?lastIndex\?\"/,
-   "wrong error message");
+like($@,qr/wrong \# args: should be \"\.listbox.* delete firstIndex \?lastIndex\?\"/,
+   "Listbox delete error message");
 
 eval { $lb->delete(qw/a b c/) };
-ok($@,qr/wrong \# args: should be \"\.listbox.* delete firstIndex \?lastIndex\?\"/,
-   "wrong error message");
+like($@,qr/wrong \# args: should be \"\.listbox.* delete firstIndex \?lastIndex\?\"/);
 
 eval { $lb->delete("badindex") };
-ok($@,qr/bad listbox index "badindex": must be active, anchor, end, \@x,y, or a number/,
-   "wrong error message");
+like($@,qr/bad listbox index "badindex": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->delete(2, "123ab") };
-ok($@,qr/bad listbox index "123ab": must be active, anchor, end, \@x,y, or a number/,
-   "wrong error message");
+like($@,qr/bad listbox index "123ab": must be active, anchor, end, \@x,y, or a number/);
 
 {
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7));
     $l2->delete(3);
-    ok($l2->get(2), "el2");
-    ok($l2->get(3), "el4");
-    ok($l2->index("end"), "7");
+    is($l2->get(2), "el2", "Listbox delete element");
+    is($l2->get(3), "el4");
+    is($l2->index("end"), "7");
     $l2->destroy;
 }
 
@@ -402,9 +418,9 @@ ok($@,qr/bad listbox index "123ab": must
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7));
     $l2->delete(2, 4);
-    ok($l2->get(1), "el1");
-    ok($l2->get(2), "el5");
-    ok($l2->index("end"), "5");
+    is($l2->get(1), "el1");
+    is($l2->get(2), "el5");
+    is($l2->index("end"), "5");
     $l2->destroy;
 }
 
@@ -412,7 +428,7 @@ ok($@,qr/bad listbox index "123ab": must
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7));
     $l2->delete(-3, 2);
-    ok(join(" ", $l2->get(0, "end")), "el3 el4 el5 el6 el7");
+    is_deeply([$l2->get(0, "end")], [qw(el3 el4 el5 el6 el7)]);
     $l2->destroy;
 }
 
@@ -420,8 +436,8 @@ ok($@,qr/bad listbox index "123ab": must
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7));
     $l2->delete(-3, -1);
-    ok(join(" ", $l2->get(0, "end")), join(" ", map { "el$_" } (0 .. 7)));
-    ok(scalar @{[$l2->get(0, "end")]}, 8);
+    is_deeply([$l2->get(0, "end")], [map { "el$_" } (0 .. 7)]);
+    is(scalar @{[$l2->get(0, "end")]}, 8);
     $l2->destroy;
 }
 
@@ -429,8 +445,8 @@ ok($@,qr/bad listbox index "123ab": must
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7));
     $l2->delete(2, "end");
-    ok(join(" ", $l2->get(0, "end")), "el0 el1");
-    ok(scalar @{[$l2->get(0, "end")]}, 2);
+    is_deeply([$l2->get(0, "end")], [qw(el0 el1)]);
+    is(scalar @{[$l2->get(0, "end")]}, 2);
     $l2->destroy;
 }
 
@@ -438,8 +454,8 @@ ok($@,qr/bad listbox index "123ab": must
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7));
     $l2->delete(5, 20);
-    ok(join(" ", $l2->get(0, "end")), "el0 el1 el2 el3 el4");
-    ok(scalar @{[$l2->get(0, "end")]}, 5);
+    is_deeply([$l2->get(0, "end")], [qw(el0 el1 el2 el3 el4)]);
+    is(scalar @{[$l2->get(0, "end")]}, 5);
     $l2->destroy;
 }
 
@@ -447,8 +463,8 @@ ok($@,qr/bad listbox index "123ab": must
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7));
     $l2->delete("end", 20);
-    ok(join(" ", $l2->get(0, "end")), "el0 el1 el2 el3 el4 el5 el6");
-    ok(scalar @{[$l2->get(0, "end")]}, 7);
+    is_deeply([$l2->get(0, "end")], [qw(el0 el1 el2 el3 el4 el5 el6)]);
+    is(scalar @{[$l2->get(0, "end")]}, 7);
     $l2->destroy;
 }
 
@@ -456,107 +472,96 @@ ok($@,qr/bad listbox index "123ab": must
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7));
     $l2->delete(8, 20);
-    ok(join(" ", $l2->get(0, "end")), "el0 el1 el2 el3 el4 el5 el6 el7");
-    ok(scalar @{[$l2->get(0, "end")]}, 8);
+    is_deeply([$l2->get(0, "end")], [qw(el0 el1 el2 el3 el4 el5 el6 el7)]);
+    is(scalar @{[$l2->get(0, "end")]}, 8);
     $l2->destroy;
 }
 
 eval { $lb->get };
-ok($Tk::VERSION < 803
-   ? $@ =~ /wrong \# args: should be \"\.listbox.* get first \?last\?\"/
-   : $@ =~ /wrong \# args: should be \"\.listbox.* get firstIndex \?lastIndex\?\"/,
-   1,
-   "wrong error message");
+like($@, $Tk::VERSION < 803
+     ? qr/wrong \# args: should be \"\.listbox.* get first \?last\?\"/
+     : qr/wrong \# args: should be \"\.listbox.* get firstIndex \?lastIndex\?\"/,
+     "Listbox get error message");
 
 eval { $lb->get(qw/a b c/) };
-ok($Tk::VERSION < 803
-   ? $@ =~ /wrong \# args: should be \"\.listbox.* get first \?last\?\"/
-   : $@ =~ /wrong \# args: should be \"\.listbox.* get firstIndex \?lastIndex\?\"/,
-   1,
-   "wrong error message");
-
-# XXX is in perl/Tk
-#  eval { $lb->get("2.4") };
-#  ok($@ ,qr/bad listbox index "2.4": must be active, anchor, end, \@x,y, or a number/,
-#     "wrong error message");
+like($@, $Tk::VERSION < 803
+     ? qr/wrong \# args: should be \"\.listbox.* get first \?last\?\"/
+     : qr/wrong \# args: should be \"\.listbox.* get firstIndex \?lastIndex\?\"/);
 
 eval { $lb->get("badindex") };
-ok($@ ,qr/bad listbox index "badindex": must be active, anchor, end, \@x,y, or a number/,
-   "wrong error message");
+like($@ ,qr/bad listbox index "badindex": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->get("end", "bogus") };
-ok($@ ,qr/bad listbox index "bogus": must be active, anchor, end, \@x,y, or a number/,
-   "wrong error message");
+like($@ ,qr/bad listbox index "bogus": must be active, anchor, end, \@x,y, or a number/);
 
 {
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7));
-    ok($l2->get(0), "el0");
-    ok($l2->get(3), "el3");
-    ok($l2->get("end"), "el7");
+    is($l2->get(0), "el0");
+    is($l2->get(3), "el3");
+    # This is valid in perl/Tk, but not Tcl/Tk
+    is($lb->get("3.4"), "el3", "get with float");
+    is($l2->get("end"), "el7");
     $l2->destroy;
 }
 
 {
     my $l2 = $mw->$Listbox;
-    ok($l2->get(0), undef);
-    ok($l2->get("end"), undef);
+    is($l2->get(0), undef);
+    is($l2->get("end"), undef);
     $l2->destroy;
 }
 
 {
     my $l2 = $mw->$Listbox;
     $l2->insert(0, qw(el0 el1 el2), "two words", qw(el4 el5 el6 el7));
-    ok($l2->get(3), "two words");
-    ok(($l2->get(3, "end"))[0], "two words");
-    ok(join(" ", $l2->get(3, "end")), "two words el4 el5 el6 el7");
-}
-
-ok($lb->get(-1), undef);
-ok($lb->get(-2, -1), undef);
-ok(join(" ", $lb->get(-2, 3)), "el0 el1 el2 el3");
-ok(scalar @{[ $lb->get(-2, 3) ]}, 4);
-
-ok(join(" ", $lb->get(12, "end")), "el12 el13 el14 el15 el16 el17");
-ok(scalar @{[ $lb->get(12, "end") ]}, 6);
-ok(join(" ", $lb->get(12, 20)), "el12 el13 el14 el15 el16 el17");
-ok(scalar @{[ $lb->get(12, 20) ]}, 6);
-
-ok($lb->get("end"), "el17");
-ok($lb->get(30), undef);
-ok($lb->get(30, 35), ());
+    is($l2->get(3), "two words");
+    is(($l2->get(3, "end"))[0], "two words");
+    is_deeply([$l2->get(3, "end")], ['two words', qw(el4 el5 el6 el7)]);
+}
+
+is($lb->get(-1), undef);
+is($lb->get(-2, -1), undef);
+is_deeply([$lb->get(-2, 3)], [qw(el0 el1 el2 el3)]);
+is(scalar @{[ $lb->get(-2, 3) ]}, 4);
+
+is_deeply([$lb->get(12, "end")], [qw(el12 el13 el14 el15 el16 el17)]);
+is(scalar @{[ $lb->get(12, "end") ]}, 6);
+is_deeply([$lb->get(12, 20)], [qw(el12 el13 el14 el15 el16 el17)]);
+is(scalar @{[ $lb->get(12, 20) ]}, 6);
+
+is($lb->get("end"), "el17");
+is($lb->get(30), undef);
+is_deeply([$lb->get(30, 35)], []);
 
 eval { $lb->index };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* index index\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* index index\"/,
+     "Listbox index error message");
 
 eval { $lb->index(qw/a b/) };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* index index\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* index index\"/);
 
 eval { $lb->index(qw/@/) };
-ok($@ ,qr/bad listbox index "\@": must be active, anchor, end, \@x,y, or a number/,
-   "wrong error message");
+like($@ ,qr/bad listbox index "\@": must be active, anchor, end, \@x,y, or a number/);
 
-ok($lb->index(2), 2);
-ok($lb->index(-1), -1);
-ok($lb->index("end"), 18);
-ok($lb->index(34), 34);
+is($lb->index(2), 2);
+is($lb->index(-1), -1);
+is($lb->index("end"), 18);
+is($lb->index(34), 34);
 
 eval { $lb->insert };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* insert index \?element element \.\.\.\?\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* insert index \?element element \.\.\.\?\"/,
+     "Listbox insert error message");
 
 eval { $lb->insert("badindex") };
-ok($@ ,qr/bad listbox index "badindex": must be active, anchor, end, \@x,y, or a number/,
-   "wrong error message");
+like($@ ,qr/bad listbox index "badindex": must be active, anchor, end, \@x,y, or a number/);
 
 {
     my $l2 = $mw->$Listbox;
     $l2->insert("end", qw/a b c d e/);
     $l2->insert(3, qw/x y z/);
-    ok(join(" ", $l2->get(0, "end")), 'a b c x y z d e');
-    ok(scalar @{[ $l2->get(0, "end") ]}, 8);
+    is_deeply([$l2->get(0, "end")], [qw(a b c x y z d e)], "Listbox insert");
+    is(scalar @{[ $l2->get(0, "end") ]}, 8);
     $l2->destroy;
 }
 
@@ -564,8 +569,8 @@ ok($@ ,qr/bad listbox index "badindex": 
     my $l2 = $mw->$Listbox;
     $l2->insert("end", qw/a b c/);
     $l2->insert(-1, qw/x/);
-    ok(join(" ", $l2->get(0, "end")), 'x a b c');
-    ok(scalar @{[ $l2->get(0, "end") ]}, 4);
+    is_deeply([$l2->get(0, "end")], [qw(x a b c)]);
+    is(scalar @{[ $l2->get(0, "end") ]}, 4);
     $l2->destroy;
 }
 
@@ -573,8 +578,8 @@ ok($@ ,qr/bad listbox index "badindex": 
     my $l2 = $mw->$Listbox;
     $l2->insert("end", qw/a b c/);
     $l2->insert("end", qw/x/);
-    ok(join(" ", $l2->get(0, "end")), 'a b c x');
-    ok(scalar @{[ $l2->get(0, "end") ]}, 4);
+    is_deeply([$l2->get(0, "end")], [qw(a b c x)]);
+    is(scalar @{[ $l2->get(0, "end") ]}, 4);
     $l2->destroy;
 }
 
@@ -582,55 +587,50 @@ ok($@ ,qr/bad listbox index "badindex": 
     my $l2 = $mw->$Listbox;
     $l2->insert("end", qw/a b c/);
     $l2->insert(43, qw/x/);
-    ok(join(" ", $l2->get(0, "end")), 'a b c x');
-    ok(scalar @{[ $l2->get(0, "end") ]}, 4);
+    is_deeply([$l2->get(0, "end")], [qw(a b c x)]);
+    is(scalar @{[ $l2->get(0, "end") ]}, 4);
     $l2->insert(4, qw/y/);
-    ok(join(" ", $l2->get(0, "end")), 'a b c x y');
+    is_deeply([$l2->get(0, "end")], [qw(a b c x y)]);
     $l2->insert(6, qw/z/);
-    ok(join(" ", $l2->get(0, "end")), 'a b c x y z');
+    is_deeply([$l2->get(0, "end")], [qw(a b c x y z)]);
     $l2->destroy;
 }
 
-eval { $lb->nearest };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* nearest y\"/,
-   "wrong error message");
+SKIP: {
+    skip("nearest not yet implemented", 4)
+	if $Listbox eq 'TextList';
+
+    eval { $lb->nearest };
+    like($@ ,qr/wrong \# args: should be \"\.listbox.* nearest y\"/,
+	 "Listbox nearest error message");
 
-eval { $lb->nearest(qw/a b/) };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* nearest y\"/,
-   "wrong error message");
+    eval { $lb->nearest(qw/a b/) };
+    like($@ ,qr/wrong \# args: should be \"\.listbox.* nearest y\"/);
 
-eval { $lb->nearest("badindex") };
-ok($@ ,qr/\'badindex\' isn\'t numeric/,
-   "wrong error message");
+    eval { $lb->nearest("badindex") };
+    like($@ ,qr/\'badindex\' isn\'t numeric/);
 
-$lb->yview(3);
-ok($lb->nearest(1000), 7);
+    $lb->yview(3);
+    is($lb->nearest(1000), 7, "Listbox nearest");
+}
 
 eval { $lb->scan };
-ok($@,qr/wrong \# args: should be \"\.listbox.* scan mark\|dragto x y\"/,
-   "wrong error message");
+like($@,qr/wrong \# args: should be \"\.listbox.* scan mark\|dragto x y\"/,
+     "Listbox scan error message");
 
 eval { $lb->scan(qw/a b/) };
-ok($@,qr/wrong \# args: should be \"\.listbox.* scan mark\|dragto x y\"/,
-   "wrong error message");
+like($@,qr/wrong \# args: should be \"\.listbox.* scan mark\|dragto x y\"/);
 
 eval { $lb->scan(qw/a b c d/) };
-ok( $@,qr/wrong \# args: should be \"\.listbox.* scan mark\|dragto x y\"/,
-   "wrong error message");
+like($@,qr/wrong \# args: should be \"\.listbox.* scan mark\|dragto x y\"/);
 
 eval { $lb->scan(qw/foo bogus 2/) };
-ok($@ ,qr/\'bogus\' isn\'t numeric/, "wrong error message");
-
-## is in perl
-#  eval { $lb->scan(qw/foo 2 2.3/) };
-#  ok($@ ,qr/'2.3' isn't numeric/,
-#     "wrong error message");
+like($@ ,qr/\'bogus\' isn\'t numeric/);
 
 eval { $lb->scan(qw/foo 2 3/) };
-ok($Tk::VERSION < 803
-   ? $@ =~ /bad scan option \"foo\": must be mark or dragto/
-   : $@ =~ /bad option \"foo\": must be mark, or dragto/,
-   1, "wrong error message");
+like($@, $Tk::VERSION < 803
+     ? qr/bad scan option \"foo\": must be mark or dragto/
+     : qr/bad option \"foo\": must be mark, or dragto/);
 
 {
     my $t = $mw->Toplevel;
@@ -643,167 +643,165 @@ ok($Tk::VERSION < 803
     $lb->update;
     $lb->scan("mark", 100, 140);
     $lb->scan("dragto", 90, 137);
+    $lb->scan("dragto", "90.1", "137.1"); # ok in Perl/Tk, an error in Tcl/Tk
     $lb->update;
-    skip($skip_font_test,
-	 join(",",$lb->xview) ,qr/^0\.24936.*,0\.42748.*$/,
-	 join(",",$lb->xview));
-    skip($skip_font_test,
-	 join(",",$lb->yview) ,qr/^0\.071428.*,0\.428571.*$/,
-	 join(",",$lb->yview));
+ SKIP: {
+	skip($skip_font_test, 2) if $skip_font_test;
+	like(join(",",$lb->xview), qr/^0\.24936.*,0\.42748.*$/, "Listbox scan");
+	like(join(",",$lb->yview), qr/^0\.071428.*,0\.428571.*$/);
+    }
     $t->destroy;
 }
 
 eval { $lb->see };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* see index\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* see index\"/,
+     "Listbox see error message");
 
 eval { $lb->see("a","b") };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* see index\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* see index\"/);
 
 eval { $lb->see("badindex") };
-ok($@ ,qr/bad listbox index "badindex": must be active, anchor, end, \@x,y, or a number/,
-   "wrong error message");
+like($@ ,qr/bad listbox index "badindex": must be active, anchor, end, \@x,y, or a number/);
 
 $lb->yview(7);
 $lb->see(7);
-ok($lb->index('@0,0'), 7);
+is($lb->index('@0,0'), 7, "Listbox see");
 
 $lb->yview(7);
 $lb->see(11);
-ok($lb->index('@0,0'), 7);
+is($lb->index('@0,0'), 7);
 
 $lb->yview(7);
 $lb->see(6);
-ok($lb->index('@0,0'), 6);
+is($lb->index('@0,0'), 6);
 
 $lb->yview(7);
 $lb->see(5);
-ok($lb->index('@0,0'), 3);
+is($lb->index('@0,0'), 3);
 
 $lb->yview(7);
 $lb->see(12);
-ok($lb->index('@0,0'), 8);
+is($lb->index('@0,0'), 8);
 
 $lb->yview(7);
 $lb->see(13);
-ok($lb->index('@0,0'), 11);
+is($lb->index('@0,0'), 11);
 
 $lb->yview(7);
 $lb->see(-1);
-ok($lb->index('@0,0'), 0);
+is($lb->index('@0,0'), 0);
 
 $lb->yview(7);
 $lb->see("end");
-ok($lb->index('@0,0'), 13);
+is($lb->index('@0,0'), 13);
 
 $lb->yview(7);
 $lb->see(322);
-ok($lb->index('@0,0'), 13);
+is($lb->index('@0,0'), 13);
 
 mkPartial();
 $partial_lb->see(4);
-ok($partial_lb->index('@0,0'), 1);
+is($partial_lb->index('@0,0'), 1);
 
 eval { $lb->selection };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* selection option index \?index\?\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* selection option index \?index\?\"/,
+     "Listbox selection error message");
 
 eval { $lb->selection("a") };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* selection option index \?index\?\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* selection option index \?index\?\"/);
 
 eval { $lb->selection(qw/a b c d/) };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* selection option index \?index\?\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* selection option index \?index\?\"/);
 
 eval { $lb->selection(qw/a bogus/) };
-ok($@ ,qr/bad listbox index \"bogus\": must be active, anchor, end, \@x,y, or a number/,
-   "wrong error message");
+like($@ ,qr/bad listbox index \"bogus\": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->selection(qw/a 0 lousy/) };
-ok($@ ,qr/bad listbox index \"lousy\": must be active, anchor, end, \@x,y, or a number/,
-   "wrong error message");
+like($@ ,qr/bad listbox index \"lousy\": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->selection(qw/anchor 0 0/) };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* selection anchor index\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* selection anchor index\"/);
 
-$lb->selection("anchor", 5);
-ok($lb->index("anchor"), 5);
-$lb->selectionAnchor(0);
-ok($lb->index("anchor"), 0);
-
-$lb->selectionAnchor(-1);
-ok($lb->index("anchor"), 0);
-$lb->selectionAnchor("end");
-ok($lb->index("anchor"), 17);
-$lb->selectionAnchor(44);
-ok($lb->index("anchor"), 17);
+SKIP: {
+    skip("anchor index not yet implemented", 5)
+	if $Listbox eq 'TextList';
+
+    $lb->selection("anchor", 5);
+    is($lb->index("anchor"), 5, "Listbox selection");
+    $lb->selectionAnchor(0);
+    is($lb->index("anchor"), 0);
+
+    $lb->selectionAnchor(-1);
+    is($lb->index("anchor"), 0);
+    $lb->selectionAnchor("end");
+    is($lb->index("anchor"), 17);
+    $lb->selectionAnchor(44);
+    is($lb->index("anchor"), 17);
+}
 
 $lb->selection("clear", 0, "end");
 $lb->selection("set", 2, 8);
 $lb->selection("clear", 3, 4);
-ok(join(",",$lb->curselection), "2,5,6,7,8");
+is_deeply([$lb->curselection], [2,5,6,7,8]);
 
 $lb->selectionClear(0, "end");
 $lb->selectionSet(2, 8);
 $lb->selectionClear(3, 4);
-ok(join(",",$lb->curselection), "2,5,6,7,8");
+is_deeply([$lb->curselection], [2,5,6,7,8]);
 
 eval { $lb->selection(qw/includes 0 0/) };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* selection includes index\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* selection includes index\"/,
+     "Tk selection includes error message");
 
 $lb->selectionClear(0, "end");
 $lb->selectionSet(2,8);
 $lb->selectionClear(4);
-ok($lb->selection("includes", 3), 1);
-ok($lb->selection("includes", 4), 0);
-ok($lb->selection("includes", 5), 1);
-ok($lb->selectionIncludes(3), 1);
+is($lb->selection("includes", 3), 1, "Listbox selection includes");
+is($lb->selection("includes", 4), 0);
+is($lb->selection("includes", 5), 1);
+is($lb->selectionIncludes(3), 1);
 
 $lb->selectionSet(0, "end");
-ok($lb->selectionIncludes(-1), 0);
+is($lb->selectionIncludes(-1), 0);
 
 $lb->selectionClear(0, "end");
 $lb->selectionSet("end");
-ok($lb->selection("includes", "end"), 1);
+is($lb->selection("includes", "end"), 1);
 
 $lb->selectionClear(0, "end");
 $lb->selectionSet("end");
-ok($lb->selection("includes", 44), 0);
+is($lb->selection("includes", 44), 0);
 
 {
     my $l2 = $mw->$Listbox;
-    ok($l2->selectionIncludes(0), 0);
+    is($l2->selectionIncludes(0), 0);
     $l2->destroy;
 }
 
 $lb->selection(qw(clear 0 end));
 $lb->selection(qw(set 2));
 $lb->selection(qw(set 5 7));
-ok(join(" ", $lb->curselection), "2 5 6 7");
-ok(scalar @{[$lb->curselection]}, 4);
+is_deeply([$lb->curselection], [qw(2 5 6 7)]);
+is(scalar @{[$lb->curselection]}, 4);
 $lb->selection(qw(set 5 7));
-ok(join(" ", $lb->curselection), "2 5 6 7");
-ok(scalar @{[$lb->curselection]}, 4);
+is_deeply([$lb->curselection], [qw(2 5 6 7)]);
+is(scalar @{[$lb->curselection]}, 4);
 
 eval { $lb->selection(qw/badOption 0 0/) };
-ok($@, qr/bad option \"badOption\": must be anchor, clear, includes, or set/,
-   "wrong error message");
+like($@, qr/bad option \"badOption\": must be anchor, clear, includes, or set/,
+     "Listbox selection error message");
 
 eval { $lb->size(qw/a/) };
-ok($@ ,qr/wrong \# args: should be \"\.listbox.* size\"/,
-   "wrong error message");
+like($@ ,qr/wrong \# args: should be \"\.listbox.* size\"/,
+     "Listbox size error message");
 
-ok($lb->size, 18);
+is($lb->size, 18, "Listbox size");
 
 {
     my $l2 = $mw->$Listbox;
     $l2->update;
-    ok(($l2->xview)[0], 0);
-    ok(($l2->xview)[1], 1);
+    is(($l2->xview)[0], 0, "xview, first value");
+    is(($l2->xview)[1], 1, "xview, second value");
     $l2->destroy;
 }
 
@@ -812,8 +810,8 @@ $lb = $mw->$Listbox(-width => 10, -heigh
 $lb->insert(qw/0 a b c d e f g h i j k l m n o p q r s t/);
 $lb->pack;
 $lb->update;
-ok(($lb->xview)[0], 0);
-ok(($lb->xview)[1], 1);
+is(($lb->xview)[0], 0);
+is(($lb->xview)[1], 1);
 
 eval { $lb->destroy };
 $lb = $mw->$Listbox(-width => 10, -height => 5, -font => $fixed);
@@ -822,52 +820,61 @@ $lb->insert(qw/1 0123456789a123456789b12
 $lb->pack;
 $lb->update;
 
-$lb->xview(4);
-ok_float(join(",",$lb->xview), "0.08,0.28");
+SKIP: {
+    skip("xview not fully implemented", 1)
+	if $Listbox eq 'TextList';
+
+    $lb->xview(4);
+    is_float(join(",",$lb->xview), "0.08,0.28", "Listbox xview with floats");
+}
 
 eval { $lb->xview("foo") };
-ok($@ ,qr/\'foo\' isn\'t numeric/,
-   "wrong error message");
+like($@ ,qr/\'foo\' isn\'t numeric/,
+     "Listbox xview error message");
 
 eval { $lb->xview("zoom", "a", "b") };
-ok($@ ,qr/unknown option \"zoom\": must be moveto or scroll/,
-   "wrong error message");
+like($@ ,qr/unknown option \"zoom\": must be moveto or scroll/);
 
-$lb->xview(0);
-$lb->xview(moveto => 0.4);
-$lb->update;
-ok_float(($lb->xview)[0], 0.4);
-ok_float(($lb->xview)[1], 0.6);
+SKIP: {
+    skip("xview not fully implemented", 5)
+	if $Listbox eq 'TextList';
 
-$lb->xview(0);
-$lb->xview(scroll => 2, "units");
-$lb->update;
-ok_float("@{[ $lb->xview ]}", '0.04 0.24');
+    $lb->xview(0);
+    $lb->xview(moveto => 0.4);
+    $lb->update;
+    is_float(($lb->xview)[0], 0.4);
+    is_float(($lb->xview)[1], 0.6);
 
-$lb->xview(30);
-$lb->xview(scroll => -1, "pages");
-$lb->update;
-ok_float("@{[ $lb->xview ]}", '0.44 0.64');
+    $lb->xview(0);
+    $lb->xview(scroll => 2, "units");
+    $lb->update;
+    is_float("@{[ $lb->xview ]}", '0.04 0.24');
 
-$lb->configure(-width => 1);
-$lb->update;
-$lb->xview(30);
-$lb->xview("scroll", -4, "pages");
-$lb->update;
-ok_float("@{[ $lb->xview ]}", '0.52 0.54');
+    $lb->xview(30);
+    $lb->xview(scroll => -1, "pages");
+    $lb->update;
+    is_float("@{[ $lb->xview ]}", '0.44 0.64');
+
+    $lb->configure(-width => 1);
+    $lb->update;
+    $lb->xview(30);
+    $lb->xview("scroll", -4, "pages");
+    $lb->update;
+    is_float("@{[ $lb->xview ]}", '0.52 0.54');
+}
 
 eval { $lb->destroy };
 $lb = $mw->$Listbox->pack;
 $lb->update;
-ok(($lb->yview)[0], 0);
-ok(($lb->yview)[1], 1);
+is(($lb->yview)[0], 0);
+is(($lb->yview)[1], 1);
 
 eval { $lb->destroy };
 $lb = $mw->$Listbox->pack;
 $lb->insert(0, "el1");
 $lb->update;
-ok(($lb->yview)[0], 0);
-ok(($lb->yview)[1], 1);
+is(($lb->yview)[0], 0);
+is(($lb->yview)[1], 1);
 
 eval { $lb->destroy };
 $lb = $mw->$Listbox(-width => 10, -height => 5, -font => $fixed);
@@ -877,39 +884,38 @@ $lb->pack;
 $lb->update;
 $lb->yview(4);
 $lb->update;
-ok_float(($lb->yview)[0], 0.2);
-ok_float(($lb->yview)[1], 0.45);
+is_float(($lb->yview)[0], 0.2);
+is_float(($lb->yview)[1], 0.45);
 
 mkPartial();
-ok(($partial_lb->yview)[0], 0);
-ok(($partial_lb->yview)[1] ,qr/^0\.\d+$/,
-   "got " . (($partial_lb->yview)[1]));
+is(($partial_lb->yview)[0], 0);
+like(($partial_lb->yview)[1] ,qr/^0\.\d+$/,
+     "yview returned " . (($partial_lb->yview)[1]));
+
+eval { $lb->yview("foo") };
+like($@ ,qr/\Qbad listbox index "foo": must be active, anchor, end, \E\@\Qx,y, or a number/,
+     "Listbox yview error message");
 
-eval { $lb->xview("foo") };
-ok($@ ,qr/\'foo\' isn\'t numeric/,
-   "wrong error message");
-
-eval { $lb->xview("foo", "a", "b") };
-ok($@ ,qr/unknown option \"foo\": must be moveto or scroll/,
-   "wrong error message");
+eval { $lb->yview("foo", "a", "b") };
+like($@ ,qr/unknown option \"foo\": must be moveto or scroll/);
 
 $lb->yview(0);
 $lb->yview(moveto => 0.31);
-ok_float("@{[ $lb->yview ]}", "0.3 0.55");
+is_float("@{[ $lb->yview ]}", "0.3 0.55");
 
 $lb->yview(2);
 $lb->yview(scroll => 2 => "pages");
-ok_float("@{[ $lb->yview ]}", "0.4 0.65");
+is_float("@{[ $lb->yview ]}", "0.4 0.65");
 
 $lb->yview(10);
 $lb->yview(scroll => -3 => "units");
-ok_float("@{[ $lb->yview ]}", "0.35 0.6");
+is_float("@{[ $lb->yview ]}", "0.35 0.6");
 
 $lb->configure(-height => 2);
 $lb->update;
 $lb->yview(15);
 $lb->yview(scroll => -4 => "pages");
-ok_float("@{[ $lb->yview ]}", "0.55 0.65");
+is_float("@{[ $lb->yview ]}", "0.55 0.65");
 
 # No tests for DestroyListbox:  I can't come up with anything to test
 # in this procedure.
@@ -918,22 +924,22 @@ eval { $lb->destroy };
 $lb = $mw->$Listbox(-setgrid => 1, -width => 25, -height => 15);
 $lb->pack;
 $mw->update;
-ok(getsize($mw), qr/^\d+x\d+$/);
+like(getsize($mw), qr/^\d+x\d+$/);
 $lb->configure(-setgrid => 0);
 $mw->update;
-ok(getsize($mw), qr/^\d+x\d+$/);
+like(getsize($mw), qr/^\d+x\d+$/);
 
 resetGridInfo();
 
 $lb->configure(-highlightthickness => -3);
-ok($lb->cget(-highlightthickness), 0);
+is($lb->cget(-highlightthickness), 0);
 
 $lb->configure(-exportselection => 0);
 $lb->delete(0, "end");
 $lb->insert(0, qw(el0 el1 el2 el3 el4 el5 el6 el7 el8));
 $lb->selection("set", 3, 5);
 $lb->configure(-exportselection => 1);
-ok($mw->SelectionGet, "el3\nel4\nel5");
+is($mw->SelectionGet, "el3\nel4\nel5");
 
 my $e = $mw->Entry;
 $e->insert(0, "abc");
@@ -945,8 +951,8 @@ $lb->insert(0, qw(el0 el1 el2 el3 el4 el
 $lb->selectionSet(3, 5);
 $lb->selectionClear(3, 5);
 $lb->configure(-exportselection => 1);
-ok($mw->SelectionOwner, $e);
-ok($mw->SelectionGet, "ab");
+is($mw->SelectionOwner, $e);
+is($mw->SelectionGet, "ab");
 $e->destroy;
 
 $mw->SelectionClear;
@@ -954,26 +960,24 @@ $lb->configure(-exportselection => 1);
 $lb->delete(0, "end");
 $lb->insert(qw(0 el0 el1 el2 el3 el4 el5 el6 el7 el8));
 $lb->selection("set", 1, 1);
-ok($mw->SelectionGet, "el1");
-ok(join(',',$lb->curselection), "1"); # join forces list context
+is($mw->SelectionGet, "el1");
+is(join(',',$lb->curselection), "1"); # join forces list context
 $lb->configure(-exportselection => 0);
 eval { $mw->SelectionGet };
-ok($@ ,qr/PRIMARY selection doesn\'t exist or form \"(UTF8_)?STRING\" not defined/,
-   "wrong error message: $@");
-ok(join(',',$lb->curselection), "1"); # join forces list context
+like($@ ,qr/PRIMARY selection doesn\'t exist or form \"(UTF8_)?STRING\" not defined/,
+     "SelectionGet, error message");
+is(join(',',$lb->curselection), "1"); # join forces list context
 $lb->selection("clear", 0, "end");
 eval { $mw->SelectionGet };
-ok($@ ,qr/PRIMARY selection doesn\'t exist or form \"(UTF8_)?STRING\" not defined/,
-   "wrong error message: $@");
-ok($lb->curselection, ());
+like($@ ,qr/PRIMARY selection doesn\'t exist or form \"(UTF8_)?STRING\" not defined/);
+is($lb->curselection, undef, "Empty curselection");
 $lb->selection("set", 1, 3);
 eval { $mw->SelectionGet };
-ok($@ ,qr/PRIMARY selection doesn\'t exist or form \"(UTF8_)?STRING\" not defined/,
-   "wrong error message: $@");
-ok("@{[$lb->curselection]}", "1 2 3");
+like($@ ,qr/PRIMARY selection doesn\'t exist or form \"(UTF8_)?STRING\" not defined/);
+is_deeply([$lb->curselection], [qw(1 2 3)]);
 $lb->configure(-exportselection => 1);
-ok($mw->SelectionGet, "el1\nel2\nel3");
-ok("@{[$lb->curselection]}", "1 2 3");
+is($mw->SelectionGet, "el1\nel2\nel3");
+is_deeply([$lb->curselection], [qw(1 2 3)]);
 
 $lb->destroy;
 $mw->geometry("300x300");
@@ -984,10 +988,10 @@ $lb = $mw->$Listbox(-font => $fixed, -wi
 $lb->pack;
 $lb->update;
 $mw->deiconify;
-ok(getsize($mw), qr/^\d+x\d+$/);
+like(getsize($mw), qr/^\d+x\d+$/);
 $lb->configure(-setgrid => 1);
 $mw->update;
-ok(getsize($mw), qr/^\d+x\d+$/);
+like(getsize($mw), qr/^\d+x\d+$/);
 
 $lb->destroy;
 $mw->withdraw;
@@ -997,13 +1001,17 @@ $mw->geometry("+0+0");
 $lb->pack;
 $mw->update;
 $mw->deiconify;
-ok(getsize($mw), "30x20"); # TODO
-$mw->geometry("26x15");
-$mw->update;
-ok(getsize($mw), "26x15"); # TODO
-$lb->configure(-setgrid => 1);
-$lb->update;
-ok(getsize($mw), "26x15"); # TODO
+{
+    local $TODO = "Tests may fail (window-manager related?)";
+
+    is(getsize($mw), "30x20");
+    $mw->geometry("26x15");
+    $mw->update;
+    is(getsize($mw), "26x15");
+    $lb->configure(-setgrid => 1);
+    $lb->update;
+    is(getsize($mw), "26x15");
+}
 
 $mw->geometry("");
 $lb->destroy;
@@ -1019,122 +1027,169 @@ $lb->update;
 $lb->configure(-fg => "black");
 @log = ();
 $lb->update;
-ok($log[0], "y 0 1");
-ok($log[1], "x 0 1");
+is($log[0], "y 0 1");
+is($log[1], "x 0 1");
 
 $lb->destroy;
-my @x = qw/a b c d/;
-#XXX these are missing: -listvar tests, because 800.023 do not know this option
-# $lb = $mw->$Listbox(-listvar => \@x);
-# ok(join(",",$lb->get(0, "end")), "a,b,c,d");
-
-#test listbox-4.10 {ConfigureListbox, no listvar -> existing listvar} {
-#    catch {destroy $_lb}
-#    set x [list a b c d]
-#    listbox $_lb
-#    $_lb insert end 1 2 3 4
-#    $_lb configure -listvar x
-#    $_lb get 0 end
-#} [list a b c d]
-#test listbox-4.11 {ConfigureListbox procedure, listvar -> no listvar} {
-#    catch {destroy $_lb}
-#    set x [list a b c d]
-#    listbox $_lb -listvar x
-#    $_lb configure -listvar {}
-#    $_lb insert end 1 2 3 4
-#    list $x [$_lb get 0 end]
-#} [list [list a b c d] [list a b c d 1 2 3 4]]
-#test listbox-4.12 {ConfigureListbox procedure, listvar -> different listvar} {
-#    catch {destroy $_lb}
-#    set x [list a b c d]
-#    set y [list 1 2 3 4]
-#    listbox $_lb
-#    $_lb configure -listvar x
-#    $_lb configure -listvar y
-#    $_lb insert end 5 6 7 8
-#    list $x $y
-#} [list [list a b c d] [list 1 2 3 4 5 6 7 8]]
-#test listbox-4.13 {ConfigureListbox, no listvar -> non-existant listvar} {
-#    catch {destroy $_lb}
-#    catch {unset x}
-#    listbox $_lb
-#    $_lb insert end a b c d
-#    $_lb configure -listvar x
-#    set x
-#} [list a b c d]
-#test listbox-4.14 {ConfigureListbox, non-existant listvar} {
-#    catch {destroy $_lb}
-#    catch {unset x}
-#    listbox $_lb -listvar x
-#    list [info exists x] $x
-#} [list 1 {}]
-#test listbox-4.15 {ConfigureListbox, listvar -> non-existant listvar} {
-#    catch {destroy $_lb}
-#    catch {unset y}
-#    set x [list a b c d]
-#    listbox $_lb -listvar x
-#    $_lb configure -listvar y
-#    list [info exists y] $y
-#} [list 1 [list a b c d]]
-#test listbox-4.16 {ConfigureListbox, listvar -> same listvar} {
-#    catch {destroy $_lb}
-#    set x [list a b c d]
-#    listbox $_lb -listvar x
-#    $_lb configure -listvar x
-#    set x
-#} [list a b c d]
-#test listbox-4.17 {ConfigureListbox, no listvar -> no listvar} {
-#    catch {destroy $_lb}
-#    listbox $_lb
-#    $_lb insert end a b c d
-#    $_lb configure -listvar {}
-#    $_lb get 0 end
-#} [list a b c d]
-#test listbox-4.18 {ConfigureListbox, no listvar -> bad listvar} {
-#    catch {destroy $_lb}
-#    listbox $_lb
-#    $_lb insert end a b c d
-#    set x {this is a " bad list}
-#    catch {$_lb configure -listvar x} result
-#    list [$_lb get 0 end] [$_lb cget -listvar] $result
-#} [list [list a b c d] {} \
-#	"unmatched open quote in list: invalid listvar value"]
+
+SKIP: {
+    skip("no -listvar in older Tks", 12)
+	if $Tk::VERSION < 804;
+    {
+	my @x = qw/a b c d/;
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	is_deeply([$lb->get(0, "end")], [qw(a b c d)], "-listvar after initial setting");
+	$lb->destroy;
+    }
+
+    {
+	my @x = qw(a b c d);
+	my $lb = $mw->$Listbox;
+	$lb->insert(qw(end 1 2 3 4));
+	$lb->configure(-listvar => \@x);
+	is_deeply([$lb->get(qw(0 end))], [qw(a b c d)],
+		  q{ConfigureListbox, no listvar -> existing listvar});
+	$lb->destroy;
+    }
+
+    {
+ 	local $TODO = "Not yet implemented in Perl/Tk";
+
+ 	my @x = qw(a b c d);
+ 	my $lb = $mw->$Listbox(-listvar => \@x);
+ 	$lb->configure(-listvar => undef);
+ 	$lb->insert(qw(end 1 2 3 4));
+ 	is_deeply([@x], [qw(a b c d)],
+ 		  q{ConfigureListbox procedure, listvar -> no listvar});
+ 	is_deeply([$lb->get(qw(0 end))], [qw(a b c d 1 2 3 4)]);
+ 	$lb->destroy;
+    }
+    
+    if (0) { # TODO: dumps core!!!
+	my @x = qw(a b c d);
+	my @y = (1..4);
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	$lb->configure(-listvar => \@x);
+	$lb->configure(-listvar => \@y);
+	$lb->insert(qw(end 5 6 7 8));
+	is_deeply(\@x, [qw(a b c d)],
+		  q{ConfigureListbox procedure, listvar -> different listvar});
+	is_deeply(\@y, [qw(1 2 3 4 5 6 7 8)]);
+	$lb->destroy;
+    }
+
+    {
+ 	local $TODO = "Not yet implemented in Perl/Tk";
+
+	my @x;
+	my $lb = $mw->$Listbox;
+	$lb->insert(qw(end a b c d));
+	$lb->configure(-listvar => \@x);
+	is_deeply(\@x, [qw(a b c d)],
+		  q{ConfigureListbox, no listvar -> non-existant listvar});
+	$lb->destroy;
+    }
+
+    {
+	my @x;
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	is_deeply(\@x, [], q{ConfigureListbox, non-existant listvar});
+    }
+
+    {
+ 	local $TODO = "Not yet implemented in Perl/Tk";
+
+	my @x = qw(a b c d);
+	my @y;
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	$lb->configure(-listvar => \@y);
+	is_deeply(\@y, [qw(a b c d)],
+		  q{ConfigureListbox, listvar -> non-existant listvar});
+	$lb->destroy;
+    }
+
+
+    {
+	my @x = qw(a b c d);
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	$lb->configure(-listvar => \@x);
+	is_deeply(\@x, [qw(a b c d)],
+		  q{ConfigureListbox, listvar -> same listvar});
+	$lb->destroy;
+    }
+
+    {
+	my $lb = $mw->$Listbox;
+	$lb->insert(qw(end a b c d));
+	$lb->configure(-listvar => undef);
+	is_deeply([$lb->get(qw(0 end))], [qw(a b c d)],
+		  q{ConfigureListbox, no listvar -> no listvar});
+    }
+
+    {
+	local $TODO = "Not yet implemented in Perl/Tk";
+
+	my $lb = $mw->$Listbox;
+	$lb->insert(qw(end a b c d));
+	my $x = "this is not an array";
+	eval { $lb->configure(-listvar => \$x) };
+	like($@, qr{Should have an error message about invalid type});
+	is_deeply([$lb->get(qw(0 end))], [qw(a b c d)],
+		  q{ConfigureListbox, no listvar -> bad listvar});
+	is($lb->cget(-listvar), undef);
+    }
+}
 
 # No tests for DisplayListbox:  I don't know how to test this procedure.
 
 Tk::catch { $lb->destroy if Tk::Exists($lb) };
 $lb = $mw->$Listbox(-font => $fixed, -width => 15, -height => 20)->pack;
-skip($skip_fixed_font_test, $lb->reqwidth, 115);
-skip($skip_fixed_font_test, $lb->reqheight, 328);
+SKIP: {
+    skip($skip_fixed_font_test, 2) if $skip_fixed_font_test;
+    is($lb->reqwidth, 115, "Reqwidth with fixed font");
+    is($lb->reqheight, 328, "Reqheight with fixed font");
+}
 
 eval { $lb->destroy };
 $lb = $mw->$Listbox(-font => $fixed, -width => 0, -height => 10)->pack;
 $lb->update;
-skip($skip_fixed_font_test, $lb->reqwidth, 17);
-skip($skip_fixed_font_test, $lb->reqheight, 168);
+SKIP: {
+    skip($skip_fixed_font_test, 2) if $skip_fixed_font_test;
+    is($lb->reqwidth, 17);
+    is($lb->reqheight, 168);
+}
 
 eval { $lb->destroy };
 $lb = $mw->$Listbox(-font => $fixed, -width => 0, -height => 10,
 		   -bd => 3)->pack;
 $lb->insert(0, "Short", "Really much longer", "Longer");
 $lb->update;
-skip($skip_fixed_font_test, $lb->reqwidth, 138);
-skip($skip_fixed_font_test, $lb->reqheight, 170);
+SKIP: {
+    skip($skip_fixed_font_test, 2) if $skip_fixed_font_test;
+    is($lb->reqwidth, 138);
+    is($lb->reqheight, 170);
+}
 
 eval { $lb->destroy };
 $lb = $mw->$Listbox(-font => $fixed, -width => 10, -height => 0,
 		  )->pack;
 $lb->update;
-skip($skip_fixed_font_test, $lb->reqwidth, 80);
-skip($skip_fixed_font_test, $lb->reqheight, 24);
+SKIP: {
+    skip($skip_fixed_font_test, 2) if $skip_fixed_font_test;
+    is($lb->reqwidth, 80);
+    is($lb->reqheight, 24);
+}
 
 eval { $lb->destroy };
 $lb = $mw->$Listbox(-font => $fixed, -width => 10, -height => 0,
 		   -highlightthickness => 0)->pack;
 $lb->insert(0, "Short", "Really much longer", "Longer");
 $lb->update;
-skip($skip_fixed_font_test, $lb->reqwidth, 76);
-skip($skip_fixed_font_test, $lb->reqheight, 52);
+SKIP: {
+    skip($skip_fixed_font_test, 2) if $skip_fixed_font_test;
+    is($lb->reqwidth, 76);
+    is($lb->reqheight, 52);
+}
 
 eval { $lb->destroy };
 # If "0" in selected font had 0 width, caused divide-by-zero error.
@@ -1152,53 +1207,53 @@ $lb->insert(qw/end a b c d/);
 $lb->insert(qw/5 x y z/);
 $lb->insert(qw/2 A/);
 $lb->insert(qw/0 q r s/);
-ok(join(" ",$lb->get(qw/0 end/)), 'q r s a b A c d x y z');
+is_deeply([$lb->get(qw/0 end/)], [qw(q r s a b A c d x y z)]);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->selection(qw/anchor 2/);
 $lb->insert(qw/2 A B/);
-ok($lb->index(qw/anchor/), 4);
+is($lb->index(qw/anchor/), 4);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->selection(qw/anchor 2/);
 $lb->insert(qw/3 A B/);
-ok($lb->index(qw/anchor/), 2);
+is($lb->index(qw/anchor/), 2);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->yview(qw/3/);
 $lb->update;
 $lb->insert(qw/2 A B/);
-ok($lb->index(q/@0,0/), 5);
+is($lb->index(q/@0,0/), 5);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->yview(qw/3/);
 $lb->update;
 $lb->insert(qw/3 A B/);
-ok($lb->index(q/@0,0/), 3);
+is($lb->index(q/@0,0/), 3);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->activate(qw/5/);
 $lb->insert(qw/5 A B/);
-ok($lb->index(qw/active/), 7);
+is($lb->index(qw/active/), 7);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->activate(qw/5/);
 $lb->insert(qw/6 A B/);
-ok($lb->index(qw/active/), 5);
+is($lb->index(qw/active/), 5);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c/);
-ok($lb->index(qw/active/), 2);
+is($lb->index(qw/active/), 2);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0/);
-ok($lb->index(qw/active/), 0);
+is($lb->index(qw/active/), 0);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b/, "two words", qw/c d e f g h i j/);
@@ -1206,8 +1261,7 @@ $lb->update;
 @log = ();
 $lb->insert(qw/0 word/);
 $lb->update;
-print "# @log\n";
-ok("@log",qr/^y 0 0\.\d+/);
+like("@log",qr/^y 0 0\.\d+/);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b/, "two words", qw/c d e f g h i j/);
@@ -1215,31 +1269,31 @@ $lb->update;
 @log = ();
 $lb->insert(0, "much longer entry");
 $lb->update;
-print "# @log\n";
-ok("$log[0]",qr/^y 0 0\.\d+/);
-ok("$log[1]", qr/x 0 \d[\d\.]*/);
+like("$log[0]",qr/^y 0 0\.\d+/);
+like("$log[1]", qr/x 0 \d[\d\.]*/);
 
-{
+SKIP: {
+    skip($skip_font_test, 4) if $skip_font_test;
     my $l2 = $mw->$Listbox(-width => 0, -height => 0)->pack(-side => "top");
     $l2->insert(0, "a", "b", "two words", "c", "d");
-    skip($skip_font_test, $l2->reqwidth, 80);
-    skip($skip_font_test, $l2->reqheight, 93);
+    is($l2->reqwidth, 80);
+    is($l2->reqheight, 93);
     $l2->insert(0, "much longer entry");
-    skip($skip_font_test, $l2->reqwidth, 122);
-    skip($skip_font_test, $l2->reqheight, 110);
+    is($l2->reqwidth, 122);
+    is($l2->reqheight, 110);
     $l2->destroy;
 }
 
-{
-      my @x = qw(a b c d);
-    ## -listvar XXX
-#      my $l2 = $mw->$Listbox(-listvar => \@x);
-#      $l2->insert(0, 1 .. 4);
-#      ok(join(" ", @x), "1 2 3 4 a b c d");
-#      ok(scalar @x, 8);
-#      ok($x[0], 1);
-#      ok($x[-1], "d");
-#      $l2->destroy;
+SKIP: {
+    skip("-listvar not implemented in older Tks", 1)
+	if $Tk::VERSION < 804;
+    skip("dumps core *TODO*", 1);
+
+    my @x = qw(a b c d);
+    my $l2 = $mw->$Listbox(-listvar => \@x);
+    $l2->insert(0, 1 .. 4);
+    is_deeply([@x], [qw(1 2 3 4 a b c d)]);
+    $l2->destroy;
 }
 
 {
@@ -1247,8 +1301,8 @@ ok("$log[1]", qr/x 0 \d[\d\.]*/);
     $l2->insert(0, 0 .. 4);
     $l2->selection("set", 2, 4);
     $l2->insert(0, "a");
-    ok("@{[ $l2->curselection ]}", "3 4 5");
-    ok(scalar @{[ $l2->curselection ]}, 3);
+    is_deeply([ $l2->curselection ], [qw(3 4 5)]);
+    is(scalar @{[ $l2->curselection ]}, 3);
     $l2->destroy;
 }
 
@@ -1256,8 +1310,8 @@ $lb->delete(0, "end");
 $lb->insert(0, qw/a b c d e f g h i j/);
 $lb->selectionSet(1, 6);
 $lb->delete(4, 3);
-ok($lb->size, 10);
-ok($mw->SelectionGet, "b
+is($lb->size, 10);
+is($mw->SelectionGet, "b
 c
 d
 e
@@ -1268,107 +1322,107 @@ $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->selection(qw/set 3 6/);
 $lb->delete(qw/4 4/);
-ok($lb->size, 9);
-ok($lb->get(4), "f");
-ok("@{[ $lb->curselection ]}", "3 4 5");
-ok(scalar @{[ $lb->curselection ]}, 3);
-ok(($lb->curselection)[0], 3);
-ok(($lb->curselection)[-1], 5);
+is($lb->size, 9);
+is($lb->get(4), "f");
+is_deeply([ $lb->curselection ], [3,4,5]);
+is(scalar @{[ $lb->curselection ]}, 3);
+is(($lb->curselection)[0], 3);
+is(($lb->curselection)[-1], 5);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->delete(qw/0 3/);
-ok($lb->size, 6);
-ok($lb->get(0), "e");
-ok($lb->get(1), "f");
+is($lb->size, 6);
+is($lb->get(0), "e");
+is($lb->get(1), "f");
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->delete(qw/8 1000/);
-ok($lb->size, 8);
-ok($lb->get(7), "h");
+is($lb->size, 8);
+is($lb->get(7), "h");
 
 $lb-> delete(0, qw/end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->selection(qw/anchor 2/);
 $lb->delete(qw/0 1/);
-ok($lb->index(qw/anchor/), 0);
+is($lb->index(qw/anchor/), 0);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->selection(qw/anchor 2/);
 $lb->delete(qw/2/);
-ok($lb->index(qw/anchor/), 2);
+is($lb->index(qw/anchor/), 2);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->selection(qw/anchor 4/);
 $lb->delete(qw/2 5/);
-ok($lb->index(qw/anchor/), 2);
+is($lb->index(qw/anchor/), 2);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->selection(qw/anchor 3/);
 $lb->delete(qw/4 5/);
-ok($lb->index(qw/anchor/), 3);
+is($lb->index(qw/anchor/), 3);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->yview(qw/3/);
 $lb->update;
 $lb->delete(qw/1 2/);
-ok($lb->index(q/@0,0/), 1);
+is($lb->index(q/@0,0/), 1);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->yview(qw/3/);
 $lb->update;
 $lb->delete(qw/3 4/);
-ok($lb->index(q/@0,0/), 3);
+is($lb->index(q/@0,0/), 3);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->yview(qw/3/);
 $lb->update;
 $lb->delete(qw/4 6/);
-ok($lb->index(q/@0,0/), 3);
+is($lb->index(q/@0,0/), 3);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->yview(qw/3/);
 $lb->update;
 $lb->delete(qw/3 end/);
-ok($lb->index(q/@0,0/), qr/^[12]$/);
+like($lb->index(q/@0,0/), qr/^[12]$/);
 
 mkPartial();
 $partial_lb->yview(8);
 $mw->update;
 $partial_lb->delete(10, 13);
-ok($partial_lb->index('@0,0'), qr/^[67]$/);
+like($partial_lb->index('@0,0'), qr/^[67]$/);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->activate(qw/6/);
 $lb->delete(qw/3 4/);
-ok($lb->index(qw/active/), 4);
+is($lb->index(qw/active/), 4);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->activate(qw/6/);
 $lb->delete(qw/5 7/);
-ok($lb->index(qw/active/), 5);
+is($lb->index(qw/active/), 5);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->activate(qw/6/);
 $lb->delete(qw/5 end/);
-ok($lb->index(qw/active/), 4);
+is($lb->index(qw/active/), 4);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->activate(qw/6/);
 $lb->delete(qw/0 end/);
-ok($lb->index(qw/active/), 0);
+is($lb->index(qw/active/), 0);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c/, "two words", qw/d e f g h i j/);
@@ -1376,7 +1430,7 @@ $lb->update;
 @log = ();
 $lb->delete(qw/4 6/);
 $lb->update;
-ok($log[0], qr/y 0 0\.\d+/);
+like($log[0], qr/y 0 0\.\d+/);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c/, "two words", qw/d e f g h i j/);
@@ -1384,37 +1438,40 @@ $lb->update;
 @log = ();
 $lb->delete(qw/3/);
 $lb->update;
-ok($log[0], qr/^y 0 0\.\d+$/);
-ok($log[1], "x 0 1");
+like($log[0], qr/^y 0 0\.\d+$/);
+is($log[1], "x 0 1");
 
-{
+SKIP: {
+    skip($skip_font_test, 4) if $skip_font_test;
     my $l2 = $mw->$Listbox(-width => 0, -height => 0)->pack(-side => "top");
     $l2->insert(0, "a", "b", "two words", qw/c d e f g/);
-    skip($skip_font_test, $l2->reqwidth, 80);
-    skip($skip_font_test, $l2->reqheight, 144);
+    is($l2->reqwidth, 80);
+    is($l2->reqheight, 144);
     $l2->delete(2, 4);
-    skip($skip_font_test, $l2->reqwidth, 17);
-    skip($skip_font_test, $l2->reqheight, 93);
+    is($l2->reqwidth, 17);
+    is($l2->reqheight, 93);
     $l2->destroy;
 }
 
-## -listvar
-#  catch {destroy .l2}
-#  test listbox-7.21 {DeleteEls procedure, check -listvar update} {
-#      catch {destroy .l2}
-#      set x [list a b c d]
-#      listbox .l2 -listvar x
-#      .l2 delete 0 1
-#      set x
-#  } [list c d]
+SKIP: {
+    skip("-listvar not implemented in older Tks", 1)
+	if $Tk::VERSION < 804;
+    skip("dumps core *TODO*", 1);
+
+    my @x = qw(a b c d);
+    my $l2 = $mw->Listbox(-listvar => \@x);
+    $l2->delete(0, 1);
+    is_deeply(\@x, ["c","d"],
+	      q{DeleteEls procedure, check -listvar update});
+}
 
 $lb->destroy;
 $lb = $mw->$Listbox(-setgrid => 1)->pack;
 $lb->update;
-ok(getsize($mw), qr/^\d+x\d+$/); # still worth it ?
+like(getsize($mw), qr/^\d+x\d+$/); # still worth it ?
 $lb->destroy;
-ok(getsize($mw), qr/^\d+x\d+$/); # still worth it ?
-ok(Tk::Exists($lb), 0);
+like(getsize($mw), qr/^\d+x\d+$/); # still worth it ?
+ok(!Tk::Exists($lb));
 
 resetGridInfo();
 
@@ -1425,14 +1482,17 @@ $lb->pack;
 $lb->update;
 $lb->place(qw/-width 50 -height 80/);
 $lb->update;
-skip($skip_font_test, join(" ", $lb->xview), qr/^0 0\.2222/);
-skip($skip_font_test, join(" ", $lb->yview), qr/^0 0\.3333/);
+SKIP: {
+    skip($skip_font_test, 2) if $skip_font_test;
+    like(join(" ", $lb->xview), qr/^0 0\.2222/);
+    like(join(" ", $lb->yview), qr/^0 0\.3333/);
+}
 
 map { $_->destroy } $mw->children;
 my $l1 = $mw->$Listbox(-bg => "#543210");
 my $l2 = $l1;
-ok(join(",", map { $_->PathName } $mw->children) ,qr/^\.listbox\d*$/);
-ok($l2->cget(-bg), "#543210");
+like(join(",", map { $_->PathName } $mw->children) ,qr/^\.listbox\d*$/);
+is($l2->cget(-bg), "#543210");
 $l2->destroy;
 
 my $top = $mw->Toplevel;
@@ -1441,94 +1501,97 @@ my $top_lb = $top->$Listbox(-setgrid => 
 			    -width => 20,
 			    -height => 10)->pack;
 $top_lb->update;
-ok($top->geometry, qr/20x10\+\d+\+\d+/);
+like($top->geometry, qr/20x10\+\d+\+\d+/);
 $top_lb->destroy;
-skip($skip_font_test, $top->geometry, qr/150x178\+\d+\+\d+/);
+SKIP: {
+    skip($skip_font_test, 1) if $skip_font_test;
+    like($top->geometry, qr/150x178\+\d+\+\d+/, "Geometry");
+}
 
 $lb = $mw->$Listbox->pack;
 $lb->delete(0, "end");
 $lb->insert(qw/0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11/);
 $lb->activate(3);
-ok($lb->index("active"), 3);
+is($lb->index("active"), 3);
 $lb->activate(6);
-ok($lb->index("active"), 6);
+is($lb->index("active"), 6);
 
 $lb->selection(qw/anchor 2/);
-ok($lb->index(qw/anchor/), 2);
+is($lb->index(qw/anchor/), 2);
 
 $lb->insert(qw/end A B C D E/);
 $lb->selection(qw/anchor end/);
 $lb->delete(qw/12 end/);
-ok($lb->index("anchor"), 12);
-ok($lb->index("end"), 12);
+is($lb->index("anchor"), 12);
+is($lb->index("end"), 12);
 
 eval { $lb->index("a") };
-ok($@ ,qr/bad listbox index \"a\": must be active, anchor, end, \@x,y, or a number/, "wrong error message $@");
+like($@ ,qr/bad listbox index \"a\": must be active, anchor, end, \@x,y, or a number/, "Listbox index error message");
 
 eval { $lb->index("\@") };
-ok($@ ,qr/bad listbox index \"\@\": must be active, anchor, end, \@x,y, or a number/, "wrong error message $@");
+like($@ ,qr/bad listbox index \"\@\": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->index("\@foo") };
-ok($@ ,qr/bad listbox index \"\@foo\": must be active, anchor, end, \@x,y, or a number/, "wrong error message $@");
+like($@ ,qr/bad listbox index \"\@foo\": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->index("\@1x3") };
-ok($@ ,qr/bad listbox index \"\@1x3\": must be active, anchor, end, \@x,y, or a number/, "wrong error message $@");
+like($@ ,qr/bad listbox index \"\@1x3\": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->index("\@1,") };
-ok($@ ,qr/bad listbox index \"\@1,\": must be active, anchor, end, \@x,y, or a number/, "wrong error message $@");
+like($@ ,qr/bad listbox index \"\@1,\": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->index("\@1,foo") };
-ok($@ ,qr/bad listbox index \"\@1,foo\": must be active, anchor, end, \@x,y, or a number/, "wrong error message $@");
+like($@ ,qr/bad listbox index \"\@1,foo\": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->index("\@1,2x") };
-ok($@ ,qr/bad listbox index \"\@1,2x\": must be active, anchor, end, \@x,y, or a number/, "wrong error message $@");
+like($@ ,qr/bad listbox index \"\@1,2x\": must be active, anchor, end, \@x,y, or a number/);
 
 eval { $lb->index("1xy") };
-ok($@ ,qr/bad listbox index \"1xy\": must be active, anchor, end, \@x,y, or a number/, "wrong error message $@");
+like($@ ,qr/bad listbox index \"1xy\": must be active, anchor, end, \@x,y, or a number/);
 
-ok($lb->index("end"), 12);
+is($lb->index("end"), 12);
 
-ok($lb->get(qw/end/), "el11");
+is($lb->get(qw/end/), "el11");
 
 $lb->delete(qw/0 end/);
-ok($lb->index(qw/end/), 0);
+is($lb->index(qw/end/), 0);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 el0 el1 el2 el3 el4 el5 el6 el7 el8 el9 el10 el11/);
 $lb->update;
 
-ok($lb->index(q/@5,57/), 3);
-ok($lb->index(q/@5,58/), 3);
+is($lb->index(q/@5,57/), 3);
+is($lb->index(q/@5,58/), 3);
 
-ok($lb->index(qw/3/), 3);
-ok($lb->index(qw/20/), 20);
+is($lb->index(qw/3/), 3);
+is($lb->index(qw/20/), 20);
 
-ok($lb->get(qw/20/), undef);
+is($lb->get(qw/20/), undef);
 
-ok($lb->index(qw/-2/), -2);
+is($lb->index(qw/-2/), -2);
 
 $lb->delete(qw/0 end/);
-ok($lb->index(qw/1/), 1);
+is($lb->index(qw/1/), 1);
 
 $lb->destroy;
 $lb = $mw->$Listbox(-height => 5)->pack;
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->yview(qw/3/);
 $lb->update;
-ok($lb->index(q/@0,0/), 3);
+is($lb->index(q/@0,0/), 3);
 $lb->yview(qw/-1/);
 $lb->update;
-ok($lb->index(q/@0,0/), 0);
+is($lb->index(q/@0,0/), 0);
 
 $lb->destroy;
 $lb = $mw->$Listbox(qw/-height 5/)->pack;
 $lb->insert(qw/0 a b c d e f g h i j/);
 $lb->yview(qw/3/);
 $lb->update;
-ok($lb->index(q/@0,0/), 3);
+is($lb->index(q/@0,0/), 3);
 $lb->yview(qw/20/);
 $lb->update;
-ok($lb->index(q/@0,0/), 5);
+is($lb->index(q/@0,0/), 5);
 
 $lb->destroy;
 $lb = $mw->$Listbox(qw/-height 5 -yscrollcommand/, [qw/record y/])->pack;
@@ -1537,8 +1600,8 @@ $lb->update;
 @log = ();
 $lb->yview(qw/2/);
 $lb->update;
-ok_float("@{[ $lb->yview ]}", "0.2 0.7");
-ok_float($log[0], "y 0.2 0.7");
+is_float("@{[ $lb->yview ]}", "0.2 0.7");
+is_float($log[0], "y 0.2 0.7");
 
 $lb->destroy;
 $lb = $mw->$Listbox(qw/-height 5 -yscrollcommand/, [qw/record y/])->pack;
@@ -1547,8 +1610,8 @@ $lb->update;
 @log = ();
 $lb->yview(qw/8/);
 $lb->update;
-ok_float("@{[ $lb->yview ]}", "0.5 1");
-ok_float($log[0], "y 0.5 1");
+is_float("@{[ $lb->yview ]}", "0.5 1");
+is_float($log[0], "y 0.5 1");
 
 $lb->destroy;
 $lb = $mw->$Listbox(qw/-height 5 -yscrollcommand/, [qw/record y/])->pack;
@@ -1558,12 +1621,12 @@ $lb->update;
 @log = ();
 $lb->yview(qw/3/);
 $lb->update;
-ok_float("@{[ $lb->yview ]}", "0.3 0.8");
-ok(scalar @log, 0);
+is_float("@{[ $lb->yview ]}", "0.3 0.8");
+is(scalar @log, 0);
 
 mkPartial();
 $partial_lb->yview(13);
-ok($partial_lb->index('@0,0'), qr/^1[01]$/);
+like($partial_lb->index('@0,0'), qr/^1[01]$/);
 
 $lb->destroy;
 $lb = $mw->$Listbox(-font => $fixed,
@@ -1576,24 +1639,24 @@ $lb->update;
 @log = ();
 $lb->xview(qw/99/);
 $lb->update;
-ok_float("@{[ $lb->xview ]}", "0.9 1");
-ok_float(($lb->xview)[0], 0.9);
-ok(($lb->xview)[1], 1);
-ok_float($log[0], "x 0.9 1");
+is_float("@{[ $lb->xview ]}", "0.9 1");
+is_float(($lb->xview)[0], 0.9);
+is(($lb->xview)[1], 1);
+is_float($log[0], "x 0.9 1");
 
 @log = ();
 $lb->xview(qw/moveto -.25/);
 $lb->update;
-ok_float("@{[ $lb->xview ]}", "0 0.1");
-ok_float($log[0], "x 0 0.1");
+is_float("@{[ $lb->xview ]}", "0 0.1");
+is_float($log[0], "x 0 0.1");
 
 $lb->xview(qw/10/);
 $lb->update;
 @log = ();
 $lb->xview(qw/10/);
 $lb->update;
-ok_float("@{[ $lb->xview ]}", "0.1 0.2");
-ok(scalar @log, 0);
+is_float("@{[ $lb->xview ]}", "0.1 0.2");
+is(scalar @log, 0);
 
 $lb->destroy;
 $lb = $mw->$Listbox(-font => $fixed, -width => 10, -height => 5)->pack;
@@ -1608,38 +1671,38 @@ $lb->xview(qw/0/);
 $lb->scan(qw/mark 10 20/);
 $lb->scan(qw/dragto/, 10-$width, 20-$height);
 $lb->update;
-ok_float("@{[ $lb->xview ]}", "0.2 0.4");
-ok_float("@{[ $lb->yview ]}", "0.5 0.75");
+is_float("@{[ $lb->xview ]}", "0.2 0.4");
+is_float("@{[ $lb->yview ]}", "0.5 0.75");
 
 $lb->yview(qw/5/);
 $lb->xview(qw/10/);
 $lb->scan(qw/mark 10 20/);
 $lb->scan(qw/dragto 20 40/);
 $lb->update;
-ok_float("@{[ $lb->xview ]}", "0 0.2");
-ok_float("@{[ $lb->yview ]}", "0 0.25");
+is_float("@{[ $lb->xview ]}", "0 0.2");
+is_float("@{[ $lb->yview ]}", "0 0.25");
 
 $lb->scan(qw/dragto/, 20-$width, 40-$height);
 $lb->update;
-ok_float("@{[ $lb->xview ]}", "0.2 0.4");
-ok_float(join(',',$lb->xview), "0.2,0.4");  # just to prove it is a list
-ok_float("@{[ $lb->yview ]}", "0.5 0.75");
-ok_float(join(',',$lb->yview), "0.5,0.75"); # just to prove it is a list
+is_float("@{[ $lb->xview ]}", "0.2 0.4");
+is_float(join(',',$lb->xview), "0.2,0.4");  # just to prove it is a list
+is_float("@{[ $lb->yview ]}", "0.5 0.75");
+is_float(join(',',$lb->yview), "0.5,0.75"); # just to prove it is a list
 
 $lb->yview(qw/moveto 1.0/);
 $lb->xview(qw/moveto 1.0/);
 $lb->scan(qw/mark 10 20/);
 $lb->scan(qw/dragto 5 10/);
 $lb->update;
-ok_float("@{[ $lb->xview ]}", "0.8 1");
-ok_float("@{[ $lb->yview ]}", "0.75 1");
+is_float("@{[ $lb->xview ]}", "0.8 1");
+is_float("@{[ $lb->yview ]}", "0.75 1");
 $lb->scan(qw/dragto/, 5+$width, 10+$height);
 $lb->update;
-ok_float("@{[ $lb->xview ]}", "0.64 0.84");
-ok_float("@{[ $lb->yview ]}", "0.25 0.5");
+is_float("@{[ $lb->xview ]}", "0.64 0.84");
+is_float("@{[ $lb->yview ]}", "0.25 0.5");
 
 mkPartial();
-ok($partial_lb->nearest($partial_lb->height), 4);
+is($partial_lb->nearest($partial_lb->height), 4);
 
 $lb->destroy;
 $lb = $mw->$Listbox(-font => $fixed,
@@ -1650,19 +1713,22 @@ $lb->yview(qw/4/);
 $lb->pack;
 $lb->update;
 
-skip($skip_fixed_font_test, $lb->index(q/@50,0/), 4);
+SKIP: {
+    skip($skip_fixed_font_test, 3) if $skip_fixed_font_test;
 
-skip($skip_fixed_font_test, $lb->index(q/@50,35/), 5);
-skip($skip_fixed_font_test, $lb->index(q/@50,36/), 6);
+    is($lb->index(q/@50,0/), 4);
+    is($lb->index(q/@50,35/), 5);
+    is($lb->index(q/@50,36/), 6);
+}
 
-ok($lb->index(q/@50,200/), qr/^\d+/);
+like($lb->index(q/@50,200/), qr/^\d+/);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j k l m n o p/);
 $lb->selection(qw/set 2 4/);
 $lb->selection(qw/set 7 12/);
 $lb->selection(qw/clear 4 7/);
-ok("@{[ $lb->curselection ]}", "2 3 8 9 10 11 12");
+is_deeply([ $lb->curselection ], [qw(2 3 8 9 10 11 12)]);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f g h i j k l m n o p/);
@@ -1672,76 +1738,76 @@ $e->insert(0, "This is some text");
 $e->selection(qw/from 0/);
 $e->selection(qw/to 7/);
 $lb->selection(qw/clear 2 4/);
-ok($mw->SelectionOwner, $e);
+is($mw->SelectionOwner, $e);
 $lb->selection(qw/set 3/);
-ok($mw->SelectionOwner, $lb);
-ok($mw->SelectionGet, "d");
+is($mw->SelectionOwner, $lb);
+is($mw->SelectionGet, "d");
 
 $lb->delete(qw/0 end/);
 $lb->selection(qw/clear 0 end/);
 $lb->selection(qw/set 0 end/);
-ok($lb->curselection, ());
+is($lb->curselection, undef);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f/);
 $lb->selection(qw/clear 0 end/);
 $lb->selection(qw/set -2 -1/);
-ok($lb->curselection, ());
+is($lb->curselection, undef);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f/);
 $lb->selection(qw/clear 0 end/);
 $lb->selection(qw/set -1 3/);
-ok(join(",",$lb->curselection), "0,1,2,3");
+is_deeply([$lb->curselection], [0,1,2,3]);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f/);
 $lb->selection(qw/clear 0 end/);
 $lb->selection(qw/set 2 4/);
-ok(join(" ", $lb->curselection), "2 3 4");
+is_deeply([$lb->curselection], [qw(2 3 4)]);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f/);
 $lb->selection(qw/clear 0 end/);
 $lb->selection(qw/set 4 end/);
-ok(join(" ", $lb->curselection), "4 5");
+is_deeply([$lb->curselection], [4, 5]);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f/);
 $lb->selection(qw/clear 0 end/);
 $lb->selection(qw/set 4 30/);
-ok(join(",", $lb->curselection), "4,5");
+is_deeply([$lb->curselection], [4, 5]);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f/);
 $lb->selection(qw/clear 0 end/);
 $lb->selection(qw/set end 30/);
-ok(join(",", $lb->curselection), 5);
-ok(scalar @{[ $lb->curselection ]}, 1);
+is(join(",", $lb->curselection), 5);
+is(scalar @{[ $lb->curselection ]}, 1);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e f/);
 $lb->selection(qw/clear 0 end/);
 $lb->selection(qw/set 20 25/);
-ok($lb->curselection, ());
+is($lb->curselection, undef);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c/, "two words", qw/ e f g h i \ k l m n o p/);
 $lb->selection(qw/set 2 4/);
 $lb->selection(qw/set 9/);
 $lb->selection(qw/set 11 12/);
-ok($mw->SelectionGet, "c\ntwo words\ne\n\\\nl\nm");
+is($mw->SelectionGet, "c\ntwo words\ne\n\\\nl\nm");
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c/, "two words", qw/ e f g h i \ k l m n o p/);
 $lb->selection(qw/set 3/);
-ok($mw->SelectionGet, "two words");
+is($mw->SelectionGet, "two words");
 
 my $long = "This is quite a long string\n" x 11;
 $lb->delete(qw/0 end/);
 $lb->insert(0, "1$long", "2$long", "3$long", "4$long", "5$long");
 $lb->selection(qw/set 0 end/);
-ok($mw->SelectionGet, "1$long\n2$long\n3$long\n4$long\n5$long");
+is($mw->SelectionGet, "1$long\n2$long\n3$long\n4$long\n5$long");
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e/);
@@ -1751,7 +1817,7 @@ $e = $mw->Entry;
 $e->insert(0, "This is some text");
 $e->selection(qw/from 0/);
 $e->selection(qw/to 5/);
-ok($lb->curselection, ());
+is($lb->curselection, undef);
 
 $lb->delete(qw/0 end/);
 $lb->insert(qw/0 a b c d e/);
@@ -1762,7 +1828,7 @@ $e = $top->Entry;
 $e->insert(0, "This is some text");
 $e->selection(qw/from 0/);
 $e->selection(qw/to 5/);
-ok(join(" ", $lb->curselection), "0 1 2 3 4");
+is_deeply([$lb->curselection], [qw(0 1 2 3 4)]);
 
 $lb->destroy;
 $lb = $mw->$Listbox(-font => $fixed, -width => 10, -height => 5);
@@ -1777,18 +1843,18 @@ $lb->insert(qw/end d e f g h/);
 $lb->update;
 $lb->delete(qw/0 end/);
 $lb->update;
-ok($log[0], "y 0 1");
-ok_float($log[1], "y 0 0.625");
-ok($log[2], "y 0 1");
+is($log[0], "y 0 1");
+is_float($log[1], "y 0 0.625");
+is($log[2], "y 0 1");
 
 mkPartial();
 $partial_lb->configure(-yscrollcommand => ["record", "y"]);
 @log = ();
 $partial_lb->yview(3);
 $partial_lb->update;
-ok($log[0], qr/^y 0\.2(0000+\d+)? 0\.\d+/);
+like($log[0], qr/^y 0\.2(0000+\d+)? 0\.\d+/);
 
-@x = ();
+my @x = ();
 
 sub Tk::Error {
     push @x, @_;
@@ -1798,7 +1864,7 @@ sub Tk::Error {
 $lb->configure(qw/-yscrollcommand gorp/);
 $lb->insert(qw/0 foo/);
 $lb->update;
-ok("@x" ,qr/Undefined subroutine &main::gorp called.*vertical scrolling command executed by listbox/s, "x is @x");
+like("@x" ,qr/Undefined subroutine &main::gorp called.*vertical scrolling command executed by listbox/s);
 
 $lb->destroy;
 $lb = $mw->$Listbox(-font => $fixed, qw/-width 10 -height 5/)->pack;
@@ -1812,82 +1878,89 @@ $lb->insert(qw/0/, "This is a much longe
 $lb->update;
 $lb->delete(qw/0 end/);
 $lb->update;
-ok($log[0], "x 0 1");
-ok($log[1] ,qr/^x 0 0\.32258/, "expected: x 0 0.32258 in $log[1]");
-ok($log[2], "x 0 1");
+is($log[0], "x 0 1");
+like($log[1] ,qr/^x 0 0\.32258/);
+is($log[2], "x 0 1");
 
 @x = ();
 $lb->configure(qw/-xscrollcommand bogus/);
 $lb->insert(qw/0 foo/);
 $lb->update;
-ok("@x" ,qr/Undefined subroutine &main::bogus.*horizontal scrolling command executed by listbox/s, "x is @x");
+like("@x" ,qr/Undefined subroutine &main::bogus.*horizontal scrolling command executed by listbox/s);
 
 foreach ($mw->children) { $_->destroy }
 
-## XXX not yet
-#  # tests for ListboxListVarProc
-#  test listbox-21.1 {ListboxListVarProc} {
-#      catch {destroy $_lb}
-#      catch {unset x}
-#      listbox $_lb -listvar x
-#      set x [list a b c d]
-#      $_lb get 0 end
-#  } [list a b c d]
-#  test listbox-21.2 {ListboxListVarProc} {
-#      catch {destroy $_lb}
-#      set x [list a b c d]
-#      listbox $_lb -listvar x
-#      unset x
-#      set x
-#  } [list a b c d]
-#  test listbox-21.3 {ListboxListVarProc} {
-#      catch {destroy $_lb}
-#      set x [list a b c d]
-#      listbox $_lb -listvar x
-#      $_lb configure -listvar {}
-#      unset x
-#      info exists x
-#  } 0
-#  test listbox-21.4 {ListboxListVarProc} {
-#      catch {destroy $_lb}
-#      set x [list a b c d]
-#      listbox $_lb -listvar x
-#      lappend x e f g
-#      $_lb size
-#  } 7
-#  test listbox-21.5 {ListboxListVarProc, test selection after listvar mod} {
-#      catch {destroy $_lb}
-#      set x [list a b c d e f g]
-#      listbox $_lb -listvar x
-#      $_lb selection set end
-#      set x [list a b c d]
-#      set x [list 0 1 2 3 4 5 6]
-#      $_lb curselection
-#  } {}
-#  test listbox-21.6 {ListboxListVarProc, test selection after listvar mod} {
-#      catch {destroy $_lb}
-#      set x [list a b c d]
-#      listbox $_lb -listvar x
-#      $_lb selection set 3
-#      lappend x e f g
-#      $_lb curselection
-#  } 3
-#  test listbox-21.7 {ListboxListVarProc, test selection after listvar mod} {
-#      catch {destroy $_lb}
-#      set x [list a b c d]
-#      listbox $_lb -listvar x
-#      $_lb selection set 0
-#      set x [linsert $x 0 1 2 3 4]
-#      $_lb curselection
-#  } 0
-#  test listbox-21.8 {ListboxListVarProc, test selection after listvar mod} {
-#      catch {destroy $_lb}
-#      set x [list a b c d]
-#      listbox $_lb -listvar x
-#      $_lb selection set 2
-#      set x [list a b c]
-#      $_lb curselection
-#  } 2
+SKIP: {
+    skip("no -listvar in older Tks", 12)
+	if $Tk::VERSION < 804;
+
+    {
+	my @x;
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	@x = qw(a b c d);
+	is_deeply([$lb->get(0, "end")], [qw(a b c d)],
+		  "ListboxListVarProc");
+	$lb->destroy;
+    }
+
+    {
+	my @x;
+	@x = qw(a b c d);
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	$lb->configure(-listvar => undef);
+	@x = ();
+	is_deeply(\@x, []);
+	$lb->destroy;
+    }
+
+    {
+	my @x = qw(a b c d);
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	push @x, qw(e f g);
+	is(scalar(@x), 7);
+	$lb->destroy;
+    }
+
+    {
+	my @x = qw(a b c d e f g);
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	$lb->selection(qw(set end));
+	@x = qw(a b c d);
+	@x = (0..6);
+	is($lb->curselection, undef,
+	   q{ListboxListVarProc, test selection after listvar mod});
+	$lb->destroy;
+    }
+
+    {
+	my @x = qw(a b c d);
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	$lb->selection(qw(set 3));
+	push @x, qw(e f g);
+	is_deeply([$lb->curselection], [3]);
+	$lb->destroy;
+    }
+
+    {
+	my @x = qw(a b c d);
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	$lb->selection(qw(set 0));
+	splice @x, 0, 0, (1, 2, 3, 4); # not sure if this is the correct linsert translation
+	is_deeply([$lb->curselection], [0]);
+	$lb->destroy;
+    }
+
+    {
+	local $TODO = "Not yet implemented in Perl/Tk";
+
+	my @x = qw(a b c d);
+	my $lb = $mw->$Listbox(-listvar => \@x);
+	$lb->selection(qw(set 2));
+	@x = qw(a b c);
+	is_deeply([$lb->curselection], [2]);
+	$lb->destroy;
+    }
+
 #  test listbox-21.9 {ListboxListVarProc, test hscrollbar after listvar mod} {
 #      catch {destroy $_lb}
 #      catch {unset x}
@@ -1989,6 +2062,7 @@ foreach ($mw->children) { $_->destroy }
 #      lappend result [$_lb yview]
 #      set result
 #  } [list {0.5 1} {0 1}]
+}
 
 # UpdateHScrollbar
 
@@ -1999,132 +2073,152 @@ $lb->insert("end", "0000000000");
 $mw->update;
 $lb->insert("end", "00000000000000000000");
 $mw->update;
-ok($log[0], "x 0 1");
-ok($log[1], "x 0 1");
-ok($log[2], "x 0 0.5");
-
-## no itemconfigure in Tk800.x
-#  # ConfigureListboxItem
-#  test listbox-23.1 {ConfigureListboxItem} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      catch {$_lb itemconfigure 0} result
-#      set result
-#  } {item number "0" out of range}
-#  test listbox-23.2 {ConfigureListboxItem} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      $_lb insert end a b c d
-#      $_lb itemconfigure 0
-#  } [list {-background background Background {} {}} \
-#  	{-bg -background} \
-#  	{-fg -foreground} \
-#  	{-foreground foreground Foreground {} {}} \
-#  	{-selectbackground selectBackground Foreground {} {}} \
-#  	{-selectforeground selectForeground Background {} {}}]
-#  test listbox-23.3 {ConfigureListboxItem, itemco shortcut} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      $_lb insert end a b c d
-#      $_lb itemco 0 -background
-#  } {-background background Background {} {}}
-#  test listbox-23.4 {ConfigureListboxItem, wrong num args} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      $_lb insert end a
-#      catch {$_lb itemco} result
-#      set result
-#  } {wrong # args: should be "$_lb itemconfigure index ?option? ?value? ?option value ...?"}
-#  test listbox-23.5 {ConfigureListboxItem, multiple calls} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      set i 0
-#      foreach color {red orange yellow green blue darkblue violet} {
-#  	$_lb insert end $color
-#  	$_lb itemconfigure $i -bg $color
-#  	incr i
-#      }
-#      pack $_lb
-#      update
-#      list [$_lb itemcget 0 -bg] [$_lb itemcget 1 -bg] [$_lb itemcget 2 -bg] \
-#  	    [$_lb itemcget 3 -bg] [$_lb itemcget 4 -bg] [$_lb itemcget 5 -bg] \
-#  	    [$_lb itemcget 6 -bg]
-#  } {red orange yellow green blue darkblue violet}
-#  catch {destroy $_lb}
-#  listbox $_lb
-#  $_lb insert end a b c d
-#  set i 6
-#  #      {-background #ff0000 #ff0000 non-existent
-#  #  	    {unknown color name "non-existent"}}
-#  #      {-bg #ff0000 #ff0000 non-existent {unknown color name "non-existent"}}
-#  #      {-fg #110022 #110022 bogus {unknown color name "bogus"}}
-#  #      {-foreground #110022 #110022 bogus {unknown color name "bogus"}}
-#  #      {-selectbackground #110022 #110022 bogus {unknown color name "bogus"}}
-#  #      {-selectforeground #654321 #654321 bogus {unknown color name "bogus"}}
-#  #XXX
-#  foreach test { A } {
-#      set name [lindex $test 0]
-#      test listbox-23.$i {configuration options} {
-#  	$_lb itemconfigure 0 $name [lindex $test 1]
-#  	list [lindex [$_lb itemconfigure 0 $name] 4] [$_lb itemcget 0 $name]
-#      } [list [lindex $test 2] [lindex $test 2]]
-#      incr i
-#      if {[lindex $test 3] != ""} {
-#  	test listbox-1.$i {configuration options} {
-#  	    list [catch {$_lb configure $name [lindex $test 3]} msg] $msg
-#  	} [list 1 [lindex $test 4]]
-#      }
-#      $_lb configure $name [lindex [$_lb configure $name] 3]
-#      incr i
-#  }
+is($log[0], "x 0 1");
+is($log[1], "x 0 1");
+is($log[2], "x 0 0.5");
+
+SKIP: {
+    skip("no itemconfigure in Tk800.x", 35)
+	if $Tk::VERSION < 804;
+
+    {
+	my $lb = $mw->$Listbox;
+	eval { $lb->itemconfigure(0) };
+	like($@, qr{item number "0" out of range},
+	     "ConfigureListboxItem error");
+	$lb->destroy;
+    }
 
-#  # ListboxWidgetObjCmd, itemcget
-#  test listbox-24.1 {itemcget} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      $_lb insert end a b c d
-#      $_lb itemcget 0 -fg
-#  } {}
-#  test listbox-24.2 {itemcget} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      $_lb insert end a b c d
-#      $_lb itemconfigure 0 -fg red
-#      $_lb itemcget 0 -fg
-#  } red
-#  test listbox-24.3 {itemcget} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      $_lb insert end a b c d
-#      catch {$_lb itemcget 0} result
-#      set result
-#  } {wrong # args: should be "$_lb itemcget index option"}
-#  test listbox-24.3 {itemcget, itemcg shortcut} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      $_lb insert end a b c d
-#      catch {$_lb itemcg 0} result
-#      set result
-#  } {wrong # args: should be "$_lb itemcget index option"}
+    {
+	my $lb = $mw->$Listbox;
+	$lb->insert(qw(end a b c d));
+	is_deeply([$lb->itemconfigure(0)],
+		  [[qw(-background background Background), undef, undef],
+		   [qw(-bg -background)],
+		   [qw(-fg -foreground)],
+		   [qw(-foreground foreground Foreground), undef, undef],
+		   [qw(-selectbackground selectBackground Foreground), undef, undef],
+		   [qw(-selectforeground selectForeground Background), undef, undef],
+		  ], "itemconfigure options");
+	$lb->destroy;
+    }
 
-#  # General item configuration issues
-#  test listbox-25.1 {listbox item configurations and widget based deletions} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      $_lb insert end a
-#      $_lb itemconfigure 0 -fg red
-#      $_lb delete 0 end
-#      $_lb insert end a
-#      $_lb itemcget 0 -fg
-#  } {}
-#  test listbox-25.2 {listbox item configurations and widget based inserts} {
-#      catch {destroy $_lb}
-#      listbox $_lb
-#      $_lb insert end a b c
-#      $_lb itemconfigure 0 -fg red
-#      $_lb insert 0 1 2 3 4
-#      list [$_lb itemcget 0 -fg] [$_lb itemcget 4 -fg]
-#  } [list {} red]
+    {
+	my $lb = $mw->$Listbox;
+	$lb->insert(qw(end a b c d));
+	is_deeply([$lb->itemconfigure(0, -background)],[qw(-background background Background),undef,undef],
+		  "itemconfigure with just one option"
+		 );
+	$lb->destroy;
+    }
+
+    {
+	my $lb = $mw->$Listbox(Name => "lb");
+	$lb->insert(qw(end a));
+	eval { $lb->itemconfigure };
+	like($@, qr{\Qwrong # args: should be ".lb itemconfigure index ?option? ?value? ?option value ...?"},
+	     q{ConfigureListboxItem, wrong num args});
+	$lb->destroy;
+    }
+
+    {
+	my $lb = $mw->$Listbox(Name => "lb");
+	my $i = 0;
+	my @colors = qw(red orange yellow green blue darkblue violet);
+	for my $color (@colors) {
+	    $lb->insert(end => $color);
+	    $lb->itemconfigure($i, -bg => $color);
+	    $i++;
+	}
+	$lb->pack;
+	$lb->update;
+	for my $i (0 .. 6) {
+	    is($lb->itemcget($i, -bg), $colors[$i],
+	       q{ConfigureListboxItem, multiple calls, } . $colors[$i]);
+	}
+	$lb->destroy;
+    }
+
+    {
+	my $lb = $mw->$Listbox;
+	$lb->insert(qw(end a b c d));
+
+	no warnings 'qw';
+
+	foreach my $test
+	    (
+	     [qw(-background #ff0000 #ff0000 non-existent),
+	      qr{unknown color name "non-existent"}],
+	     [qw(-bg #ff0000 #ff0000 non-existent),
+	      qr{unknown color name "non-existent"}],
+	     [qw(-fg #110022 #110022 bogus),
+	      qr{unknown color name "bogus"}],
+	     [qw(-foreground #110022 #110022 bogus),
+	      qr{unknown color name "bogus"}],
+	     [qw(-selectbackground #110022 #110022 bogus),
+	      qr{unknown color name "bogus"}],
+	     [qw(-selectforeground #654321 #654321 bogus),
+	      qr{unknown color name "bogus"}],
+	    ) {
+		my($name, $set_val, $get_val, $err_val, $err_msg) = @$test;
+		$lb->itemconfigure(0, $name, $set_val);
+		is($lb->itemcget(0, $name), $get_val, "itemconfigure $name");
+		eval { $lb->itemconfigure(0, $name, $err_val) };
+		like($@, $err_msg, "itemconfigure $name error ");
+		is($lb->itemcget(0, $name), $get_val, "still same value after error");
+	    }
+	$lb->destroy;
+    }
+
+    {
+	my $lb = $mw->$Listbox;
+	$lb->insert(qw(end a b c d));
+	is($lb->itemcget(0, -fg), undef, "itemcget with undef value");
+	$lb->destroy;
+    }
+
+    {
+	my $lb = $mw->$Listbox;
+	$lb->insert(qw(end a b c d));
+	$lb->itemconfigure(0, -fg => "red");
+	is($lb->itemcget(0, -fg), "red");
+	$lb->destroy;
+    }
+
+    {
+	my $lb = $mw->$Listbox(Name => "lb");
+	$lb->insert(qw(end a b c d));
+	eval { $lb->itemcget(0) };
+	like($@, qr{\Qwrong # args: should be ".lb itemcget index option"},
+	     "itemcget error");
+	$lb->destroy;
+    }
+
+    # No shortcuts in Perl/Tk, skipping shortcut test
+
+    # General item configuration issues
+    {
+	my $lb = $mw->$Listbox(Name => "lb");
+	$lb->insert(qw(end a));
+	$lb->itemconfigure(0, -fg => "red");
+	$lb->delete(0, "end");
+	$lb->insert("end", "a");
+	is($lb->itemcget(0, -fg), undef,
+	   q{listbox item configurations and widget based deletions});
+	$lb->destroy;
+    }
+
+    {
+	my $lb = $mw->$Listbox(Name => "lb");
+	$lb->insert(end => a => b => "c");
+	$lb->itemconfigure(0 => -fg => "red");
+	$lb->insert(0, 1, 2, 3, 4);
+	is($lb->itemcget(0, -fg), undef,
+	   q{listbox item configurations and widget based inserts});
+	is($lb->itemcget(4, -fg), "red");
+	$lb->destroy;
+    }
+}
 
 resetGridInfo();
 
diff -up /dev/null '/home/e/eserte/work/svk-checkouts/Tk/t/wm-tcl.t'
Index: ./t/wm-tcl.t
--- ./t/wm-tcl.t	Thu Jan  1 01:00:00 1970
+++ ./t/wm-tcl.t	Thu Nov  9 00:05:19 2006
@@ -0,0 +1,2234 @@
+#!/usr/bin/perl -w
+# -*- perl -*-
+
+# This file is a Tcl script to test out Tk's interactions with
+# the window manager, including the "wm" command.  It is organized
+# in the standard fashion for Tcl tests.
+#
+# Copyright (c) 1992-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+#
+# RCS: @(#) $Id$
+
+# This file tests window manager interactions that work across
+# platforms. Window manager tests that only work on a specific
+# platform should be placed in unixWm.test or winWm.test.
+
+#
+# Translated by Slaven Rezic (2006-11, from CVS version 1.36)
+#
+
+# Some tests are marked as TODO because they fail with
+# some window managers.
+#
+# Window managers passing all tests: 
+# * fvwm 2.4.19
+# * twm
+# * windowmaker 0.92.0
+#
+# Window managers with test failures
+# * metacity 2.16.3
+# * metacity 2.10.3 (even more failures)
+# * fvwm 2.5.18
+# * blackbox 0.70.1
+# * KWin: 3.0
+
+use strict;
+
+use Tk;
+use Getopt::Long;
+
+BEGIN {
+    if (!eval q{
+	use Test::More;
+	1;
+    }) {
+	print "1..0 # skip: no Test::More module\n";
+	exit;
+    }
+}
+
+plan tests => 315;
+
+my $mw = MainWindow->new;
+
+my $poswin = 1;
+my $netwm = 0;
+GetOptions("poswin!" => \$poswin,
+	   "trace!"  => sub { $mw->wmTracing(1) },
+	   "netwm!"  => \$netwm,
+	  )
+    or die "usage: $0 [-poswin] [-trace] [-netwm]
+-noposwin: turn off fixed geometry setting (fixed geometry setting is needed
+           for some window managers like twm with default manual positioning)
+-trace:    turns wmTracing on
+-netwm:    set this is using modern opendesktop compliant X11 window manager
+";
+
+
+$mw->geometry("+10+10");
+
+$mw->deiconify;
+if (!$mw->ismapped) {
+    $mw->waitVisibility;
+}
+
+my $t;
+
+sub stdWindow () {
+    $t->destroy if Tk::Exists($t);
+    $t = $mw->Toplevel(qw(-width 100 -height 50));
+    $t->geometry("+0+0");
+    $t->update
+}
+
+sub deleteWindows () {
+    eval { $_->destroy } for $mw->children;
+}
+
+# [raise] and [lower] may return before the window manager
+# has completed the operation.  The raiseDelay procedure
+# idles for a while to give the operation a chance to complete.
+#
+
+sub raiseDelay () {
+    $mw->after(100);
+    $mw->update;
+}
+
+sub poswin ($;@) {
+    if ($poswin) {
+	for (@_) {
+	    $_->geometry("+0+0");
+	}
+    }
+}
+
+deleteWindows;
+stdWindow;
+
+{
+    my $b = $mw->Button(-text => "hello");
+    eval { Tk::Wm::geometry($b) }; # one shouldn't do this anyway
+    like($@, qr{window ".button" isn't a top-level window},
+	 q{Tk_WmObjCmd procedure, miscellaneous errors});
+    $b->destroy;
+}
+
+### wm aspect ###
+{
+    eval { $mw->aspect("_") };
+    like($@, qr{\Qwrong # args: should be "wm aspect window ?minNumer minDenom maxNumer maxDenom?"\E},
+	 "wm aspect usage");
+
+    eval { $mw->aspect("_", "_", "_") };
+    like($@, qr{\Qwrong # args: should be "wm aspect window ?minNumer minDenom maxNumer maxDenom?"\E});
+
+    eval { $mw->aspect("_", "_", "_", "_", "_") };
+    like($@, qr{\Qwrong # args: should be "wm aspect window ?minNumer minDenom maxNumer maxDenom?"\E});
+
+    eval { $mw->aspect(qw(bad 14 15 16)) };
+    like($@, qr{'bad' isn't numeric});
+
+    eval { $mw->aspect(qw(13 foo 15 16)) };
+    like($@, qr{'foo' isn't numeric});
+
+    eval { $mw->aspect(qw(13 14 bar 16)) };
+    like($@, qr{'bar' isn't numeric});
+
+    eval { $mw->aspect(qw(13 14 15 baz)) };
+    like($@, qr{'baz' isn't numeric});
+
+    eval { $mw->aspect(qw(0 14 15 16)) };
+    like($@, qr{\Qaspect number can't be <= 0});
+
+    eval { $mw->aspect(qw(13 0 15 16)) };
+    like($@, qr{\Qaspect number can't be <= 0});
+
+    eval { $mw->aspect(qw(13 14 0 16)) };
+    like($@, qr{\Qaspect number can't be <= 0});
+
+    eval { $mw->aspect(qw(13 14 15 0)) };
+    like($@, qr{\Qaspect number can't be <= 0});
+}
+
+{
+    is_deeply([$mw->aspect], [], "setting and reading aspect values");
+    $mw->aspect(qw(3 4 10 2));
+    is_deeply([$mw->aspect], [qw(3 4 10 2)]);
+    $mw->aspect(undef,undef,undef,undef);
+    is_deeply([$mw->aspect],[]);
+}
+
+### wm attributes ###
+{
+    eval { $mw->attributes(-alpha => 1.0, '-disabled') };
+    like($@, qr{\Qwrong # args: should be "wm attributes window ?-attribute ?value ...??});
+
+ SKIP: {
+	skip("works only on windows", 1)
+	    if $Tk::platform ne 'MSWin32';
+	eval { $mw->attributes('-to') };
+	like($@, qr{\Qwrong # args: should be "wm attributes window ?-alpha ?double?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"});
+    }
+    
+ SKIP: {
+	skip("works only on unix", 1)
+	    if $Tk::platform ne 'unix';
+	eval { $mw->attributes("_") };
+	like($@, qr{\Qbad attribute "_": must be -alpha, -topmost, -zoomed, or -fullscreen},
+	     "wm attributes usage");
+    }
+
+ SKIP: {
+	skip("works only on aqua", 1)
+	    if $Tk::platform ne 'aqua';
+	die <<EOF;
+not yet translated:
+test wm-attributes-1.2.5 {usage} aqua {
+    list [catch {wm attributes . _} err] \$err
+} {1 {bad attribute "_": must be -alpha, -modified, -notify, or -titlepath}}
+EOF
+    }
+}
+
+{
+    ### wm client ###
+    is($t->client, undef, "wm client, setting and reading values");
+    $t->client('Miffo');
+    is($t->client, 'Miffo');
+    $t->client(undef);
+    is($t->client, undef);
+}
+
+SKIP: {
+    skip("fullscreen tests only on windows", 38)
+ 	if $Tk::platform ne 'MSWin32';
+## Getting fullscreen attribute is not yet implemented for X11
+#     skip("fullscreen tests only on windows or on X11 with option -netwm", 38)
+# 	if !($Tk::platform eq 'MSWin32' || ($Tk::platform eq 'unix' && $netwm));
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	is($t->attributes(-fullscreen), 0,
+	   "default -fullscreen value");
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	$t->attributes(-fullscreen => 1);
+	is($t->attributes(-fullscreen), 1,
+	   q{change -fullscreen before map});
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$t->attributes(-fullscreen => 1);
+	$mw->update;
+	is($t->attributes(-fullscreen), 1,
+	   q{change -fullscreen before map});
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$mw->update;
+	$t->attributes(-fullscreen => 1);
+	is($t->attributes(-fullscreen), 1,
+	   q{change -fullscreen after map});
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$mw->update;
+	is($t->attributes(-fullscreen), 0,
+	   q{change -fullscreen after map});
+	$t->attributes(-fullscreen => 1);
+	is($t->attributes(-fullscreen), 1);
+	# Query above should not clear fullscreen state
+	is($t->attributes(-fullscreen), 1);
+	$t->attributes(-fullscreen => 0);
+	is($t->attributes(-fullscreen), 0);
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	my $normal_geom = "301x302+101+102";
+	my $fullscreen_geom = $mw->screenwidth . "x" . $mw->screenheight . "+0+0";
+	$t->geometry($normal_geom);
+	$mw->update;
+	is($t->geometry, $normal_geom, q{change -fullscreen after map});
+	$t->attributes(-fullscreen => 1);
+	is($t->geometry, $fullscreen_geom);
+	$t->attributes(-fullscreen => 0);
+	is($t->geometry, $normal_geom);
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$mw->update;
+	$t->attributes(-fullscreen => 1);
+	$t->withdraw;
+	$t->deiconify;
+	is($t->attributes(-fullscreen), 1,
+	   q{state change does not change -fullscreen});
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	$mw->update;
+	$t->attributes(-fullscreen => 1);
+	$t->iconify;
+	$t->deiconify;
+	is($t->attributes(-fullscreen), 1,
+	   q{state change (iconify) does not change -fullscreen});
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$mw->update;
+	$t->overrideredirect(1);
+	eval { $t->attributes(-fullscreen => 1) };
+	like($@, qr{\Qcan't set fullscreen attribute for ".t": override-redirect flag is set},
+	     q{override-redirect not compatible with fullscreen attribute});
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$mw->update;
+	$t->maxsize(5000, 450);
+	eval { $t->attributes(-fullscreen => 1) };
+	like($@, qr{\Qcan't set fullscreen attribute for ".t": max width/height is too small},
+	     q{max height too small});
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$mw->update;
+	$t->maxsize(450, 5000);
+	eval { $t->attributes(-fullscreen => 1) };
+	like($@, qr{\Qcan't set fullscreen attribute for ".t": max width/height is too small},
+	     q{max width too small});
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$mw->update;
+	$t->attributes(-alpha => 1.0, -fullscreen => 1);
+	is($t->attributes(-fullscreen), 1,
+	   q{another attribute, then -fullscreen});
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$mw->update;
+	# This was originally -toolwindow instead of -alpha; changed
+	# this to make the test runnable under X11
+	$t->attributes(-alpha => 0.1, -fullscreen => 1, -topmost => 0);
+	is($t->attributes(-fullscreen), 1,
+	   q{another attribute, then -fullscreen, then another});
+    }
+
+    {
+	deleteWindows;
+	$mw->focusForce;
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$t->lower;
+	$mw->update;
+	is($mw->focus, $mw,
+	   q{setting/unsetting fullscreen does not change the focus});
+
+	my $done;
+	$t->attributes(-fullscreen => 1);
+	$mw->after(200, sub { $done = 1 });
+	$mw->waitVariable(\$done);
+	is($mw->focus, $mw);
+
+	$done = 0;
+	$t->attributes(-fullscreen => 0);
+	$mw->after(200, sub { $done = 1 });
+	$mw->waitVariable(\$done);
+	is($mw->focus, $mw);
+    }
+
+    {
+	deleteWindows;
+	my(@focusin, $done);
+	$mw->focusForce;
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	my $te = $t->Entry(Name => "e")->pack;
+	$t->lower;
+	$t->bind("<FocusIn>", [sub {push @focusin, $_[0]}, Ev('W')]);
+	$mw->after(200, sub { $done = 1 });
+	$mw->waitVariable(\$done);
+
+	push @focusin, 1;
+	$te->focusForce;
+	$mw->after(200, sub { $done = 2 });
+	$mw->waitVariable(\$done);
+
+	push @focusin, 2;
+	$t->attributes(-fullscreen => 1);
+	$mw->after(200, sub { $done = 3 });
+	$mw->waitVariable(\$done);
+
+	push @focusin, 3;
+	$t->attributes(-fullscreen => 0);
+	$mw->after(200, sub { $done = 4 });
+	$mw->waitVariable(\$done);
+
+	push @focusin, "final";
+
+	$mw->bind("<FocusIn>" => '');
+	$t->bind("<FocusIn>" => '');
+	
+	is_deeply(\@focusin, [1, $t, $te, 2, 3, "final", $te],
+		  q{setting fullscreen does not generate FocusIn on wrapper create});
+    }
+	
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel(Name => "t");
+	is_deeply([$mw->stackorder], ["."],
+		  "fullscreen stackorder");
+	my $done;
+	$mw->after(200, sub { $done = 1 });
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".", ".t"]);
+
+	# Default stacking is on top of other windows
+	# on the display. Setting the fullscreen attribute
+	# does not change this.
+	$t->attributes(qw(-fullscreen 1));
+	$mw->after(200, sub { $done = 2 });
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".", ".t"]);
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$t->lower;
+	my $done;
+	$mw->after(200, sub { $done = 1 });
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".t", "."],
+		  q{fullscreen stackorder});
+    
+	# If stacking order is explicitly set, then
+	# setting the fullscreen attribute should
+	# not change it.
+	$t->attributes(-fullscreen => 1);
+	$mw->after(200, sub { $done = 2 });
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".t", "."]);
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	# lower forces the window to be mapped, it would not be otherwise
+	$t->lower;
+	is_deeply([$mw->stackorder], [".t", "."]);
+
+	# If stacking order is explicitly set
+	# for an unmapped window, then setting
+	# the fullscreen attribute should
+	# not change it.
+	$t->attributes(qw(-fullscreen 1));
+	my $done;
+	$mw->after(200 => sub { $done = 1 });
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".t", "."]);
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel(Name => "t");
+	my $done;
+	$mw->after(200, sub { $done = 1});
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".", ".t"],
+		  q{fullscreen stackorder});
+
+	$t->attributes(qw(-fullscreen 1));
+	$mw->after(200, sub { $done = 2});
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".", ".t"]);
+
+	# Unsetting the fullscreen attribute
+	# should not change the stackorder.
+	$t->attributes(qw(-fullscreen 0));
+	$mw->after(200, sub { $done = 3 });
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".", ".t"]);
+    }
+
+    {
+	deleteWindows;
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$t->lower;
+	my $done;
+	$mw->after(200, sub { $done = 1 });
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".t", "."]);
+
+	$t->attributes(qw(-fullscreen 1));
+	$mw->after(200, sub { $done = 2 });
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".t", "."]);
+
+	# Unsetting the fullscreen attribute
+	# should not change the stackorder.
+	$t->attributes(qw(-fullscreen 0));
+	$mw->after(200, sub { $done = 3});
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".t", "."]);
+    }
+
+    {
+	deleteWindows;
+	my $a = $mw->Toplevel(Name => "a");
+	my $b = $mw->Toplevel(Name => "b");
+	my $c = $mw->Toplevel(Name => "c");
+	poswin $a, $b, $c;
+	$a->raise;
+	$b->raise;
+	$c->raise;
+	my $done;
+	$mw->after(200, sub { $done = 1});
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".", ".a", ".b", ".c"]);
+
+	$b->attributes(-fullscreen => 1);
+	$mw->after(200, sub { $done = 2});
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".", ".a", ".b", ".c"]);
+
+	# Unsetting the fullscreen attribute
+	# should not change the stackorder.
+	$b->attributes(qw(-fullscreen 0));
+	$mw->after(200, sub { $done = 3});
+	$mw->waitVariable(\$done);
+	is_deeply([$mw->stackorder], [".", ".a", ".b", ".c"]);
+    }
+}
+
+deleteWindows;
+stdWindow;
+
+{
+    ### wm colormapwindows ###
+    eval { $mw->colormapwindows("_","_") };
+    like($@, qr{\Qwrong # args: should be "wm colormapwindows window ?windowList?"},
+	 "wm colormapwindows usage");
+
+    eval { $mw->colormapwindows("foo") };
+    like($@, qr{bad window path name "foo"});
+}
+
+{
+    my $t1 = $mw->Toplevel(qw(Name toplevel1 -width 200 -height 200 -colormap new));
+    poswin $t1;
+    my $t1a = $t1->Frame(qw(-width 100 -height 30));
+    my $t1b = $t1->Frame(qw(-width 100 -height 30 -colormap new));
+    Tk::pack($t1a, $t1b, qw(-side top));
+    $mw->update;
+
+    is_deeply([$t1->colormapwindows], [".toplevel1.frame1", ".toplevel1"],
+	      "wm colormapwindows reading values");
+
+    my $t1c = $t1->Frame(qw(-width 100 -height 30 -colormap new))->pack(-side => "top");
+    $mw->update;
+    is_deeply([$t1->colormapwindows], [".toplevel1.frame1", ".toplevel1.frame2", ".toplevel1"]);
+
+    $t1->destroy;
+}
+
+{
+    my $t1 = $mw->Toplevel(qw(Name toplevel2 -width 200 -height 200));
+    poswin $t1;
+    my @f;
+    for (1 .. 3) {
+	push @f, $t1->Frame(qw(-width 100 -height 30))->pack(-side => "top");
+    }
+    $t1->colormapwindows([$f[1], $f[0]]);
+    is_deeply([$t1->colormapwindows], [".toplevel2.frame1", ".toplevel2.frame"],
+	      "wm colormapwindows, setting and reading values");
+}
+
+{
+    ### wm command ###
+    eval { $mw->command("_", "_") };
+    like($@, qr{\Qwrong # args: should be "wm command window ?value?"},
+	 "wm command usage");
+
+    is_deeply([$t->command],[], "wm command, setting and reading values");
+    $t->command([qw(Miffo Foo)]);
+    is_deeply([$t->command],[qw(Miffo Foo)]);
+    $t->command(undef);
+    is_deeply([$t->command],[]);
+}
+
+{
+    ### wm deiconify ###
+    my $icon = $mw->Toplevel(qw(Name icon -width 50 -height 50 -bg red));
+    $t->iconwindow($icon);
+    eval { $icon->deiconify };
+    like($@, qr{can't deiconify .icon: it is an icon for .t}, "wm deiconify");
+    $icon->destroy;
+}
+
+{
+    if ($Tk::platform eq 'MSWin32') {
+	# test embedded window for Windows
+	my $tf = $t->Frame(-container => 1);
+	my $embed = $mw->Toplevel(Name => "embed", -use => $tf->id);
+	eval { $embed->deiconify };
+	like($@, qr{\Qcan't deiconify .embed: the container does not support the request},
+	     "wm deiconify embedded window");
+	$embed->destroy;
+	$tf->destroy;
+    } else {
+	my $tf = $t->Frame(-container => 1);
+	my $embed = $mw->Toplevel(Name => "embed", -use => $tf->id);
+	eval { $embed->deiconify };
+	like($@, qr{\Qcan't deiconify .embed: it is an embedded window},
+	     "wm deiconify embedded window");
+	$embed->destroy;
+	$tf->destroy;
+    }
+}
+
+{
+    deleteWindows;
+    $t = $mw->Toplevel;
+    $t->deiconify;
+    ok(!$t->ismapped,
+       q{a window that has never been mapped should not be mapped by deiconify()});
+}
+
+{
+    deleteWindows;
+    $t = $mw->Toplevel;
+    poswin $t;
+    $mw->idletasks;
+    $t->withdraw;
+    $t->deiconify;
+    ok($t->ismapped,
+       q{a window that has already been mapped should be mapped by deiconify()});
+}
+
+{
+    deleteWindows;
+    $t = $mw->Toplevel(qw(-width 200 -height 200));
+    is($t->geometry, "1x1+0+0");
+    $t->deiconify;
+    is($t->geometry, "1x1+0+0",
+       q{geometry for an unmapped window should not be calculated by deiconify()});
+    poswin $t;
+    $mw->idletasks;
+    like($t->geometry, qr{^200x200},
+	 q{... it should be done at idle time});
+}
+
+{
+    deleteWindows;
+    $t = $mw->Toplevel;
+    $t->withdraw;
+    $t->deiconify;
+    $t->destroy;
+    $mw->update;
+    pass(q{invoking destroy after a deiconify should not result in a crash});
+    # ... because of a callback set on the toplevel
+}
+
+{
+    ### wm focusmodel ###
+    eval { $mw->focusmodel("_", "_") };
+    like($@, qr{\Qwrong # args: should be "wm focusmodel window ?active|passive?"},
+	 "wm focusmodel usage");
+
+    eval { $mw->focusmodel("bogus") };
+    like($@, qr{\Qbad argument "bogus": must be active, or passive});
+}
+
+stdWindow;
+
+{
+    is($t->focusmodel, "passive",
+       "wm focusmodel, setting and reading values");
+    $t->focusmodel("active");
+    is($t->focusmodel, "active");
+    $t->focusmodel("passive");
+    is($t->focusmodel, "passive");
+}
+
+{
+    ### wm frame ###
+    ok(defined $mw->frame, "wm frame");
+}
+
+{
+    ### wm geometry ###
+    eval { $mw->geometry("_", "_") };
+    like($@, qr{\Qwrong # args: should be "wm geometry window ?newGeometry?"},
+	 "wm geometry usage");
+
+    eval { $mw->geometry("bogus") };
+    like($@, qr{\Qbad geometry specifier "bogus"});
+}
+
+{
+    $t->geometry("150x150+50+50");
+    $t->update;
+    is($t->geometry, "150x150+50+50",
+       "wm geometry, setting and getting values");
+    $t->geometry(undef);
+    $t->update;
+    isnt($t->geometry, "150x150+50+50", "geometry should change and is now " . $t->geometry);
+}
+
+{
+    ### wm grid ###
+    for my $args (1, 3, 5) {
+	eval { $mw->wmGrid(("_")x$args) };
+	like($@, qr{\Qwrong # args: should be "wm grid window ?baseWidth baseHeight widthInc heightInc?"},
+	     "wm grid usage (tried $args args)");
+    }
+
+    eval { $mw->wmGrid(qw(bad 14 16 16)) };
+    like($@, qr{'bad' isn't numeric});
+
+    eval { $mw->wmGrid(qw(13 foo 16 16)) };
+    like($@, qr{'foo' isn't numeric});
+
+    eval { $mw->wmGrid(qw(13 14 bar 16)) };
+    like($@, qr{'bar' isn't numeric});
+
+    eval { $mw->wmGrid(qw(13 14 15 baz)) };
+    like($@, qr{'baz' isn't numeric});
+
+    eval { $mw->wmGrid(qw(-1 14 15 16)) };
+    like($@, qr{baseWidth can't be < 0});
+
+    eval { $mw->wmGrid(qw(13 -1 15 16)) };
+    like($@, qr{baseHeight can't be < 0});
+
+    eval { $mw->wmGrid(qw(13 14 -1 16)) };
+    like($@, qr{widthInc can't be <= 0});
+
+    eval { $mw->wmGrid(qw(13 14 15 -1)) };
+    like($@, qr{heightInc can't be <= 0});
+
+    is_deeply([$t->wmGrid],[], "wm grid, setting and reading values");
+    $t->wmGrid(qw(3 4 10 2));
+    is_deeply([$t->wmGrid],[qw(3 4 10 2)]);
+    $t->wmGrid((undef)x4);
+    is_deeply([$t->wmGrid],[]);
+}
+
+{
+    ### wm group ###
+    eval { $mw->group(12, 13) };
+    like($@, qr{\Qwrong # args: should be "wm group window ?pathName?"},
+	 q{wm group usage});
+
+    eval { $mw->group("bogus") };
+    like($@, qr{bad window path name "bogus"});
+
+    is($t->group, undef, "wm group, setting and reading values");
+    $t->group($mw);
+    is($t->group, ".");
+    $t->group(undef);
+    is($t->group, undef);
+}
+
+{
+    ### wm iconbitmap ###
+ SKIP: {
+	skip("test only for unix", 1)
+	    if $Tk::platform ne "unix";
+	eval { $mw->iconbitmap(12, 13) };
+	like($@, qr{\Qwrong # args: should be "wm iconbitmap window ?bitmap?"},
+	     "wm iconbitmap usage on unix");
+    }
+
+ SKIP: {
+	skip("test only for windows", 2)
+	    if $Tk::platform ne "MSWin32";
+
+	eval { $mw->iconbitmap(12, 13, 14) };
+	like($@, qr{\Qwrong # args: should be "wm iconbitmap window ?-default? ?image?"},
+	     "wm iconbitmap usage on windows");
+
+	eval { $mw->iconbitmap(12, 13) };
+	like($@, qr{\Qillegal option "12" must be "-default"});
+    }
+
+    eval { $mw->iconbitmap("bad-bitmap") };
+    like($@, qr{bitmap "bad-bitmap" not defined});
+
+    is($t->iconbitmap, undef, "wm iconbitmap, setting and reading values");
+    $t->iconbitmap("hourglass");
+    is($t->iconbitmap, "hourglass");
+    $t->iconbitmap(undef);
+    is($t->iconbitmap, undef);
+}
+
+{
+    ### wm iconify ###
+    my $t2 = $mw->Toplevel(qw(Name toplevel2));
+    $t2->geometry("+10+10");
+    $t2->overrideredirect(1);
+    eval { $t2->iconify };
+    like($@, qr{\Qcan't iconify ".toplevel2": override-redirect flag is set},
+	 "wm iconify, misc errors");
+    $t2->destroy;
+}
+
+{
+    my $t2 = $mw->Toplevel(qw(Name toplevel2));
+    poswin $t2;
+    $t2->transient($t);
+    eval { $t2->iconify };
+    like($@, qr{\Qcan't iconify ".toplevel2": it is a transient});
+    $t2->destroy;
+}
+
+{
+    my $t2 = $mw->Toplevel(qw(Name toplevel2));
+    poswin $t2;
+    $t->iconwindow($t2);
+    eval { $t2->iconify };
+    like($@, qr{can't iconify .toplevel2: it is an icon for .toplevel});
+    $t2->destroy;
+}
+
+{
+    if ($Tk::platform eq 'MSWin32') {
+	# test embedded window for Windows
+	my $tf = $t->Frame(qw(Name f -container 1));
+	my $t2 = $mw->Toplevel(qw(Name toplevel2), -use => $tf->id);
+	eval { $t2->iconify };
+	like($@, qr{\Qcan't iconify .toplevel2: the container does not support the request});
+	$t2->destroy;
+    } else {
+	# test embedded window for other platforms
+	my $tf = $t->Frame(qw(Name f -container 1));
+	my $t2 = $mw->Toplevel(qw(Name toplevel2), -use => $tf->id);
+	eval { $t2->iconify };
+	like($@, qr{\Qcan't iconify .toplevel2: it is an embedded window});
+	$t2->destroy;
+    }
+}
+
+{
+    my $t2 = $mw->Toplevel;
+    $t2->geometry("-0+0");
+    $mw->update;
+    ok($t2->ismapped);
+    $t2->iconify;
+    $mw->update;
+    ok(!$t2->ismapped);
+}
+
+{
+    ### wm iconmask ###
+    eval { $mw->iconmask(12, 13) };
+    like($@, qr{\Qwrong # args: should be "wm iconmask window ?bitmap?"},
+	 q{wm iconmask usage});
+
+    eval { $mw->iconmask("bad-bitmap") };
+    like($@, qr{\Qbitmap "bad-bitmap" not defined});
+
+    is($t->iconmask, undef, "wm iconmask, setting and reading values");
+    $t->iconmask("hourglass");
+    is($t->iconmask, "hourglass");
+    $t->iconmask(undef);
+    is($t->iconmask, undef);
+}
+
+{
+    ### wm iconname ###
+    eval { $mw->iconname(12, 13) };
+    like($@, qr{\Qwrong # args: should be "wm iconname window ?newName?"},
+	 q{wm iconname usage});
+
+    # This is somewhat inconsistent ('' vs. undef)
+    is($t->iconname, '', "wm iconname, setting and reading values");
+    $t->iconname("ThisIconHasAName");
+    is($t->iconname, "ThisIconHasAName");
+    $t->iconname(undef);
+    is($t->iconname, '');
+}
+
+{
+    ### wm iconphoto ###
+    eval { $mw->iconphoto };
+    like($@, qr{\Qwrong # args: should be "wm iconphoto window ?-default? image1 ?image2 ...?"},
+	 "wm iconphoto usage");
+
+    eval { $mw->iconphoto("notanimage") };
+    like($@, qr{\Qcan't use "notanimage" as iconphoto: not a photo image});
+
+    eval { $mw->iconphoto("-default") };
+    like($@, qr{\Qwrong # args: should be "wm iconphoto window ?-default? image1 ?image2 ...?"});
+
+    my $photo = $mw->Photo(-file => Tk->findINC("icon.gif"));
+    $mw->iconphoto($photo);
+    pass("Set iconphoto");
+
+    # All other iconphoto tests are platform specific
+}
+
+{
+    ### wm iconposition ###
+    eval { $mw->iconposition(12) };
+    like($@, qr{\Qwrong # args: should be "wm iconposition window ?x y?"},
+	 "wm iconposition usage");
+
+    eval { $mw->iconposition(12,13,14) };
+    like($@, qr{\Qwrong # args: should be "wm iconposition window ?x y?"});
+
+    eval { $mw->iconposition('bad', 13) };
+    like($@, qr{\Q'bad' isn't numeric});
+
+    eval { $mw->iconposition(13, 'lousy') };
+    like($@, qr{\Q'lousy' isn't numeric});
+
+    is_deeply([$mw->iconposition], [], "wm iconposition, setting and reading values");
+    $mw->iconposition(10, 20);
+    is_deeply([$mw->iconposition], [10, 20]);
+    $mw->iconposition(undef, undef);
+    is_deeply([$mw->iconposition], []);
+}
+
+{
+    ### wm iconwindow ###
+    eval { $mw->iconwindow(12, 13) };
+    like($@, qr{\Qwrong # args: should be "wm iconwindow window ?pathName?"},
+	 q{wm iconwindow usage});
+
+    eval { $mw->iconwindow("bogus") };
+    like($@, qr{bad window path name "bogus"});
+}
+
+{
+    my $b = $mw->Button(Name => "b", -text => "Help");
+    eval { $t->iconwindow($b) };
+    like($@, qr{\Qcan't use .b as icon window: not at top level});
+    $b->destroy;
+}
+
+{
+    my $icon = $mw->Toplevel(Name => "icon",
+			     qw(-width 50 -height 50 -bg green));
+    my $t2 = $mw->Toplevel(Name => "t2");
+    poswin $t2;
+    $t2->iconwindow($icon);
+    eval { $t->iconwindow($icon) };
+    like($@, qr{\Q.icon is already an icon for .t2});
+
+    $t2->destroy;
+    $icon->destroy;
+}
+
+{
+    is($t->iconwindow, undef, "wm iconwindow, setting and reading values");
+    my $icon = $mw->Toplevel(Name => "icon",
+			     qw(-width 50 -height 50 -bg green));
+    $t->iconwindow($icon);
+    is($t->iconwindow, $icon);
+    $t->iconwindow(undef);
+    is($t->iconwindow, undef);
+}
+
+{
+    ### wm maxsize ###
+    eval { $mw->maxsize("a") };
+    like($@, qr{\Qwrong # args: should be "wm maxsize window ?width height?"},
+	 q{wm maxsize usage});
+
+    eval { $mw->maxsize(qw(a b c)) };
+    like($@, qr{\Qwrong # args: should be "wm maxsize window ?width height?"});
+
+    eval { $mw->maxsize(qw(x 100)) };
+    like($@, qr{'x' isn't numeric});
+
+    eval { $mw->maxsize(qw(100 bogus)) };
+    like($@, qr{'bogus' isn't numeric});
+}
+
+{
+    my $t2 = $mw->Toplevel;
+    poswin $t2;
+    $t2->maxsize(300, 200);
+    is_deeply([$t2->maxsize], [300,200]);
+    $t2->destroy;
+}
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    my($t_width, $t_height) = $t->maxsize;
+    my($s_width, $s_height) = ($t->screenwidth, $t->screenheight);
+    cmp_ok($t_width, "<=", $s_width, 
+	   "maxsize must be <= screen size");
+    cmp_ok($t_height, "<=", $s_height);
+    $t->destroy;
+}
+
+{
+    my $t = $mw->Toplevel(qw(-width 300 -height 300));
+    poswin $t;
+    $t->update;
+    $t->maxsize(200, 150);
+    # UpdateGeometryInfo invoked at idle
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 200, q{setting the maxsize to a smaller value will resize a toplevel});
+    is($h, 150);
+    $t->destroy;
+}
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $t->wmGrid(0,0,50,50);
+    $t->geometry("6x6");
+    $t->update;
+    $t->maxsize(4, 3);
+    # UpdateGeometryInfo invoked at idle
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 4, q{setting the maxsize to a smaller value will resize a gridded toplevel});
+    is($h, 3);
+    $t->destroy;
+}
+
+{
+    my $t = $mw->Toplevel(qw(-width 200 -height 200));
+    poswin $t;
+    $t->maxsize(300, 250);
+    $t->update;
+    $t->geometry("400x300");
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 300, q{attempting to resize to a value bigger than the current maxsize});
+    # ... will set it to the max size
+    is($h, 250);
+    $t->destroy;
+}    
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $t->wmGrid(qw(1 1 50 50));
+    $t->geometry("4x4");
+    $t->maxsize(6, 5);
+    $t->update;
+    $t->geometry("8x6");
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 6, q{attempting to resize a gridded toplevel to a value bigger});
+    # ... than the current maxsize will set it to the max size
+    is($h, 5);
+    $t->destroy;
+}
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    my $tf = $t->Frame(qw(-width 400 -height 400))->pack;
+    $t->idletasks;
+    is($t->reqwidth, 400);
+    is($t->reqheight, 400);
+    $t->maxsize(300, 300);
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 300, q{Use max size if window size is not explicitly set});
+    # ... and the reqWidth/reqHeight are bigger than the max size
+    is($h, 300);
+}    
+
+{
+    ### wm minsize ###
+    eval { $mw->minsize("a") };
+    like($@, qr{\Qwrong # args: should be "wm minsize window ?width height?"},
+	 q{wm minsize usage});
+
+    eval { $mw->minsize(qw(a b c)) };
+    like($@, qr{\Qwrong # args: should be "wm minsize window ?width height?"});
+
+    eval { $mw->minsize(qw(x 100)) };
+    like($@, qr{'x' isn't numeric});
+
+    eval { $mw->minsize(qw(100 bogus)) };
+    like($@, qr{'bogus' isn't numeric});
+}
+
+{
+    my $t2 = $mw->Toplevel;
+    poswin $t2;
+    $t2->minsize(300, 200);
+    is_deeply([$t2->minsize], [300,200]);
+    $t2->destroy;
+}
+
+{
+    my $t = $mw->Toplevel(qw(-width 200 -height 200));
+    poswin $t;
+    $t->update;
+    $t->minsize(400, 300);
+    # UpdateGeometryInfo invoked at idle
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 400, q{setting the minsize to a larger value will resize a toplevel});
+    is($h, 300);
+    $t->destroy;
+}
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $t->wmGrid(qw(1 1 50 50));
+    $t->geometry("4x4");
+    $t->update;
+    $t->minsize(8,8);
+    # UpdateGeometryInfo invoked at idle
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 8, q{setting the minsize to a larger value will resize a gridded toplevel});
+    is($h, 8);
+    $t->destroy;
+}    
+
+{
+    my $t = $mw->Toplevel(qw(-width 400 -height 400));
+    poswin $t;
+    $t->minsize(300, 300);
+    $t->update;
+    $t->geometry("200x200");
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 300, q{attempting to resize to a value smaller than the current minsize});
+    # ... will set it to the minsize
+    is($h, 300);
+    $t->destroy;
+}
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $t->wmGrid(qw(1 1 50 50));
+    $t->geometry("8x8");
+    $t->minsize(6, 6);
+    $t->update;
+    $t->geometry("4x4");
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 6, q{attempting to resize a gridded toplevel to a value smaller});
+    # than the current minsize will set it to the minsize when gridded
+    is($h, 6);
+    $t->destroy;
+}
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    my $tf = $t->Frame(qw(-width 250 -height 250))->pack;
+    $t->idletasks;
+    is($t->reqwidth, 250);
+    is($t->reqheight, 250);
+    $t->minsize(300, 300);
+    $t->update;
+    my($w,$h) = $t->geometry =~ m{(\d+)x(\d+)};
+    is($w, 300, q{Use min size if window size is not explicitly set});
+    # ... and the reqWidth/reqHeight are smaller than the min size
+    is($h, 300);
+    $t->destroy;
+}
+
+{
+    ### wm overrideredirect ###
+    eval { $mw->overrideredirect(1, 2) };
+    like($@, qr{\Qwrong # args: should be "wm overrideredirect window ?boolean?"},
+	 "wm overrideredirect usage");
+
+    ## In Perl probably interpreted as a true value
+    #eval { $mw->overrideredirect("boo") };
+    #like($@, qr{\Qexpected boolean value but got "boo"});
+
+    is($mw->overrideredirect, 0, "wm overrideredirect, setting and reading values");
+    $mw->overrideredirect(1);
+    is($mw->overrideredirect, 1);
+    $mw->overrideredirect(0);
+    is($mw->overrideredirect, 0);
+}
+
+{
+    ### wm positionfrom ###
+    eval { $mw->positionfrom(1, 2) };
+    like($@, qr{\Qwrong # args: should be "wm positionfrom window ?user/program?"},
+	 "wm positionfrom usage");
+
+    eval { $mw->positionfrom("none") };
+    like($@, qr{bad argument "none": must be program, or user});
+}
+
+{
+    my $t2 = $mw->Toplevel;
+    poswin $t2;
+    $t2->positionfrom("user");
+    is($t2->positionfrom, "user", "wm positionfrom, setting and reading values");
+    $t2->positionfrom("program");
+    is($t2->positionfrom, "program");
+    $t2->positionfrom(undef);
+    is($t2->positionfrom, undef);    
+    $t2->destroy;
+}
+
+{
+    ### wm protocol ###
+    eval { $mw->protocol(1, 2, 3) };
+    like($@, qr{\Qwrong # args: should be "wm protocol window ?name? ?command?"},
+	 "wm protocol usage");
+}
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $t->protocol("foo a", "a b c");
+    $t->protocol("bar", "test script for bar");
+    is_deeply([$t->protocol], ["bar", "foo a"],
+	      "wm protocol, setting and reading values");
+    $t->protocol("foo a", undef);
+    $t->protocol("bar", undef);
+    is_deeply([$t->protocol], []);
+    $t->destroy;
+}
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $t->protocol("foo", "a b c");
+    $t->protocol("bar", "test script for bar");
+    isa_ok($t->protocol("foo"), "Tk::Callback");
+    isa_ok($t->protocol("bar"), "Tk::Callback");
+    $t->protocol("foo", undef);
+    $t->protocol("bar", undef);
+    is($t->protocol("foo"), undef);
+    is($t->protocol("bar"), undef);
+    $t->destroy;
+}
+
+{
+    my $t = $mw->Toplevel;
+    poswin $t;
+    my $code1 = sub { "a b c" };
+    $t->protocol("foo", $code1);
+    my $code2 = sub { "test script" };
+    $t->protocol("foo", $code2);
+    is($t->protocol("foo")->[0], $code2);
+    $t->protocol("foo", ["bla"]);
+    isa_ok($t->protocol("foo"), "Tk::Callback");
+    is($t->protocol("foo")->[0], "bla");
+    $t->destroy;
+}
+
+{
+    ### wm resizable ###
+    eval { $mw->resizable(1) };
+    like($@, qr{\Qwrong # args: should be "wm resizable window ?width height?"},
+	 "wm resizable usage");
+
+    eval { $mw->resizable(1,2,3) };
+    like($@, qr{\Qwrong # args: should be "wm resizable window ?width height?"});
+
+    ## Valid in Perl, "bad" is a boolean value
+    #eval { $mw->resizable("bad", 0) };
+
+    $mw->resizable(0, 1);
+    is_deeply([$mw->resizable], [0, 1], "wm resizable, setting and reading values");
+    $mw->resizable(1, 0);
+    is_deeply([$mw->resizable], [1, 0]);
+    $mw->resizable(1, 1);
+    is_deeply([$mw->resizable], [1, 1]);
+}
+
+{
+    ### wm sizefrom ###
+    eval { $mw->sizefrom(1, 2) };
+    like($@, qr{\Qwrong # args: should be "wm sizefrom window ?user|program?"},
+	 "wm sizefrom usage");
+
+    eval { $mw->sizefrom("bad") };
+    like($@, qr{bad argument "bad": must be program, or user});
+
+    $t->sizefrom("user");
+    is($t->sizefrom, "user", "wm sizefrom, setting and reading values");
+    $t->sizefrom("program");
+    is($t->sizefrom, "program");
+    $t->sizefrom(undef);
+    is($t->sizefrom, undef);
+}
+
+{
+    ### wm stackorder ###
+    eval { $mw->stackorder("_") };
+    like($@, qr{\Qwrong # args: should be "wm stackorder window ?isabove|isbelow window?"},
+	 "wm stackorder usage");
+
+    eval { $mw->stackorder("_", "_", "_") };
+    like($@, qr{\Qwrong # args: should be "wm stackorder window ?isabove|isbelow window?"});
+
+    eval { $mw->stackorder("is", ".") };
+    like($@, qr{\Qambiguous argument "is": must be isabove, or isbelow});
+
+    eval { $mw->stackorder("isabove", "_") };
+    like($@, qr{\Qbad window path name "_"});
+}
+
+for my $is ("isabove", "isbelow") {
+    my $t = $mw->Toplevel(Name => "t");
+    poswin $t;
+    my $tb = $t->Button(Name => "b")->pack;
+    $mw->update;
+    eval { $mw->stackorder($is, $tb) };
+    like($@, qr{\Qwindow ".t.b" isn't a top-level window});
+    $t->destroy;
+}
+
+for my $is ("isabove", "isbelow") {
+    my $t = $mw->Toplevel(Name => "t");
+    poswin $t;
+    $t->update;
+    $t->withdraw;
+    eval { $t->stackorder($is, $mw) };
+    like($@, qr{\Qwindow ".t" isn't mapped},
+	 "wm stackorder usage, isabove|isbelow toplevels must be mapped");
+    $t->destroy;
+}
+    
+deleteWindows;
+
+# stackorder was not defined before Tk804.027_001
+eval {
+    {
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$t->update;
+	is_deeply([$mw->stackorder], [".", ".t"]);
+	$t->destroy;
+    }
+
+    {
+	local $TODO = "May fail sometimes on some older window managers (e.g. metacity 2.10.x)";
+
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$t->update;
+	$mw->raise;
+	raiseDelay;
+	is_deeply([$mw->stackorder], [".t", "."]);
+	$t->destroy;
+    }
+
+    {
+	local $TODO = "May fail sometimes on some window managers (e.g. metacity)";
+
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$t->update;
+	my $t2 = $mw->Toplevel(Name => "t2");
+	poswin $t2;
+	$t2->update;
+	$mw->raise;
+	$t2->raise;
+	raiseDelay;
+	is_deeply([$mw->stackorder], [".t", ".", ".t2"]);
+	Tk::destroy($t, $t2);
+    }
+
+    {
+	local $TODO = "May fail sometimes on some window managers (e.g. metacity)";
+
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$t->update;
+	my $t2 = $mw->Toplevel(Name => "t2");
+	poswin $t2;
+	$t2->update;
+	$mw->raise;
+	$t2->lower;
+	raiseDelay;
+	is_deeply([$mw->stackorder], [".t2", ".t", "."]);
+	Tk::destroy($t, $t2);
+    }
+
+    {
+	local $TODO = "May fail sometimes on some window managers (e.g. metacity)";
+
+	my $parent = $mw->Toplevel(Name => "parent");
+	poswin $parent;
+	$parent->update;
+	my $parent_child1 = $parent->Toplevel(Name => "child1");
+	poswin $parent_child1;
+	$parent_child1->update;
+	my $parent_child2 = $parent->Toplevel(Name => "child2");
+	poswin $parent_child2;
+	$parent_child2->update;
+	my $extra = $mw->Toplevel(Name => "extra");
+	poswin $extra;
+	$extra->update;
+	$parent->raise;
+	$parent_child2->lower;
+	raiseDelay;
+	is_deeply([$parent->stackorder], [qw(.parent.child2 .parent.child1 .parent)]);
+    }
+
+    deleteWindows;
+
+    {
+	my $t1 = $mw->Toplevel(Name => "t1");
+	poswin $t1;
+	my $t1b = $t1->Button->pack;
+	$mw->update;
+	is_deeply([$mw->stackorder], [".", ".t1"],
+		  q{non-toplevel widgets ignored});
+    }
+
+    deleteWindows;
+
+    {
+	is_deeply([$mw->stackorder], ["."],
+		  q{no children returns self});
+    }
+
+    deleteWindows;
+
+    {
+	my $t1 = $mw->Toplevel(Name => "t1");
+	poswin $t1;
+	$t1->update;
+	my $t2 = $mw->Toplevel(Name => "t2");
+	poswin $t2;
+	$t2->update;
+	$t1->iconify;
+	is_deeply([$mw->stackorder], [".", ".t2"],
+		  "unmapped toplevel");
+	$t2->destroy;
+	$t1->destroy;
+    }
+
+    {
+	my $t1 = $mw->Toplevel(Name => "t1");
+	poswin $t1;
+	$t1->update;
+	my $t2 = $mw->Toplevel(Name => "t2");
+	poswin $t2;
+	$t2->update;
+	$t2->withdraw;
+	is_deeply([$mw->stackorder], [".", ".t1"]);
+	$t2->destroy;
+	$t1->destroy;
+    }
+
+    {
+	my $t1 = $mw->Toplevel(Name => "t1");
+	poswin $t1;
+	$t1->update;
+	my $t2 = $mw->Toplevel(Name => "t2");
+	poswin $t2;
+	$t2->update;
+	$t2->withdraw;
+	is_deeply([$t2->stackorder], []);
+	$t2->destroy;
+	$t1->destroy;
+    }
+
+    {
+	my $t1 = $mw->Toplevel(Name => "t1");
+	poswin $t1;
+	$t1->update;
+	my $t1t2 = $t1->Toplevel(Name => "t2");
+	poswin $t1t2;
+	$t1t2->update;
+	$t1t2->withdraw;
+	is_deeply([$t1->stackorder], [".t1"]);
+	$t1t2->destroy;
+	$t1->destroy;
+    }
+
+    {
+	my $t1 = $mw->Toplevel(Name => "t1");
+	poswin $t1;
+	$t1->update;
+	my $t1t2 = $t1->Toplevel(Name => "t2");
+	poswin $t1t2;
+	$t1t2->update;
+	$t1->withdraw;
+	is_deeply([$t1->stackorder], [".t1.t2"]);
+	$t1t2->destroy;
+	$t1->destroy;
+    }
+
+    {
+	my $t1 = $mw->Toplevel(Name => "t1");
+	poswin $t1;
+	$t1->update;
+	my $t1t2 = $t1->Toplevel(Name => "t2");
+	poswin $t1t2;
+	$t1t2->update;
+	my $t1t2t3 = $t1t2->Toplevel(Name => "t3");
+	poswin $t1t2t3;
+	$t1t2t3->update;
+	$t1t2->withdraw;
+	is_deeply([$t1->stackorder],[".t1", ".t1.t2.t3"]);
+	$t1t2t3->destroy;
+	$t1t2->destroy;
+	$t1->destroy;
+    }
+
+    {
+	my $t1 = $mw->Toplevel(Name => "t1");
+	poswin $t1;
+	$t1->update;
+	my $t1t2 = $t1->Toplevel(Name => "t2");
+	poswin $t1t2;
+	$t1t2->update;
+	$t1->withdraw;
+	is_deeply([$t1->stackorder], [".t1.t2"],
+		  q{unmapped toplevel, mapped children returned});
+	$t1t2->destroy;
+	$t1->destroy;
+    }
+
+    {
+	my $t1 = $mw->Toplevel;
+	is_deeply([$mw->stackorder], ["."],
+		  q{toplevel mapped in idle callback});
+	$t1->destroy;
+    }
+
+    deleteWindows;
+
+    {
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$t->update;
+	$t->raise;
+	is($mw->stackorder("isabove", $t), 0,
+	   q{wm stackorder isabove|isbelow});
+	$t->destroy;
+    }
+
+    {
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$t->update;
+	$t->raise;
+	is($mw->stackorder("isbelow", $t), 1);
+	$t->destroy;
+    }
+
+    {
+	local $TODO = "May fail sometimes on some older window managers (e.g. metacity 2.10.x)";
+
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$t->update;
+	$mw->raise;
+	raiseDelay;
+	is($t->stackorder("isa", $mw), 0);
+	$t->destroy;
+    }
+
+    {
+	local $TODO = "May fail sometimes on some older window managers (e.g. metacity 2.10.x)";
+
+	my $t = $mw->Toplevel;
+	poswin $t;
+	$t->update;
+	$mw->raise;
+	raiseDelay;
+	is($t->stackorder("isb", $mw), 1);
+	$t->destroy;
+    }
+
+    deleteWindows;
+
+    {
+	local $TODO = "May fail sometimes on some older window managers (e.g. metacity 2.10.x)";
+
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	my $tm = $t->Menu(-type => "menubar");
+	$tm->add("cascade", -label => "File");
+	$t->configure(-menu => $tm);
+	$mw->update;
+	$mw->raise;
+	raiseDelay;
+	is_deeply([$mw->stackorder], [".t", "."],
+		  q{a menu is not a toplevel});
+	$t->destroy;
+    }
+
+    {
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$t->overrideredirect(1);
+	$mw->raise;
+	$mw->update;
+	raiseDelay;
+	is($mw->stackorder("isabove", $t), 0,
+	   q{A normal toplevel can't be raised above an overrideredirect toplevel});
+	$t->destroy;
+    }
+
+    {
+	my $t = $mw->Toplevel(Name => "t");
+	poswin $t;
+	$t->overrideredirect(1);
+	$mw->lower;
+	$mw->update;
+	raiseDelay;
+	is($mw->stackorder("isbelow", $t), 1,
+	   q{A normal toplevel can be explicitely lowered});
+	$t->destroy;
+    }
+
+    {
+	my $real = $mw->Toplevel(Name => "real", -container => 1);
+	poswin $real;
+	my $embd = $mw->Toplevel(Name => "embd",
+				 -bg => "blue", -use => $real->id);
+	poswin $embd;
+	$mw->update;
+	is_deeply([$mw->stackorder], [".", ".real"],
+		  q{An embedded toplevel does not appear in the stacking order});
+	$embd->destroy;
+	$real->destroy;
+    }
+};
+if ($@) {
+    fail("stackorder tests failed: $@");
+}
+
+stdWindow;
+
+{
+    ### wm title ###
+    eval { $mw->title("1", "2") };
+    like($@, qr{\Qwrong # args: should be "wm title window ?newTitle?"},
+	 "wm title usage");
+
+    my $t = $mw->Toplevel;
+    is($t->title, "Toplevel", "wm title, setting and reading values");
+    $t->title("Apa");
+    is($t->title, "Apa");
+    $t->title(undef);
+    is($t->title, "");
+    $t->destroy;
+}
+
+{
+    ### wm transient ###
+    my $t = $mw->Toplevel(Name => "t");
+    eval { $t->transient(1, 2) };
+    like($@, qr{\Qwrong # args: should be "wm transient window ?master?"},
+	 "wm transient usage");
+
+    eval { $t->transient("foo") };
+    like($@, qr{bad window path name "foo"});    
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel(Name => "master");
+    my $subject = $mw->Toplevel(Name => "subject");
+    $subject->transient($master);
+    eval { $subject->iconify };
+    like($@, qr{\Qcan't iconify ".subject": it is a transient});
+}
+
+{
+    deleteWindows;
+    my $icon = $mw->Toplevel(Name => "icon", -bg => "blue");
+    my $top = $mw->Toplevel(Name => "top");
+    $top->iconwindow($icon);
+    my $dummy = $mw->Toplevel;
+    eval { $icon->transient($dummy) };
+    like($@, qr{\Qcan't make ".icon" a transient: it is an icon for .top});
+}
+
+{
+    deleteWindows;
+    my $icon = $mw->Toplevel(Name => "icon", -bg => "blue");
+    my $top = $mw->Toplevel(Name => "top");
+    $top->iconwindow($icon);
+    my $dummy = $mw->Toplevel;
+    eval { $dummy->transient($icon) };
+    like($@, qr{\Qcan't make ".icon" a master: it is an icon for .top});
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel(Name => "master");
+    eval { $master->transient($master) };
+    like($@, qr{\Qcan't make ".master" its own master});
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel(Name => "master");
+    my $f = $master->Frame(Name => "f");
+    eval { $master->transient($f) };
+    like($@, qr{\Qcan't make ".master" its own master});
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel(Name => "master");
+    my $subject = $mw->Toplevel(Name => "subject");
+    is($subject->transient, undef, "basic get/set of master");
+    $subject->transient($master);
+    is($subject->transient, $master);
+    $subject->transient(undef);
+    is($subject->transient, undef);
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel(Name => "master");
+    my $f = $master->Frame;
+    my $subject = $mw->Toplevel(Name => "subject");
+    $subject->transient($f);
+    is($subject->transient, $master,
+       "first toplevel parent of non-toplevel master is used");
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel(Name => "master");
+    poswin $master;
+    $master->withdraw;
+    $mw->update;
+    my $subject = $mw->Toplevel(Name => "subject");
+    poswin $subject;
+    $subject->transient($master);
+    $mw->update;
+    is($subject->state, "withdrawn",
+       "transient toplevel is withdrawn when mapped if master is withdrawn");
+    is($subject->ismapped, 0);
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel(Name => "master");
+    poswin $master;
+    $master->withdraw;
+    $mw->update;
+    my $subject = $mw->Toplevel(Name => "subject");
+    poswin $subject;
+    $mw->update;
+    $subject->transient($master);
+    $mw->update;
+    is($subject->state, "withdrawn",
+       q{already mapped transient toplevel takes on withdrawn state of master});
+    is($subject->ismapped, 0);
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    my $subject = $mw->Toplevel;
+    poswin $master, $subject;
+    $mw->update;
+    $subject->transient($master);
+    $master->withdraw;
+    $mw->update;
+    is($subject->state, "withdrawn",
+       q{withdraw on the master also does a withdraw on the transient});
+    is($subject->ismapped, 0);
+    $master->deiconify;
+    $mw->update;
+
+    local $TODO = "May fail on some window managers (e.g. fvwm 2.5.x)";
+
+    is($subject->state, "normal",
+       q{deiconify on the master also does a deiconify on the transient});
+    is($subject->ismapped, 1);
+}
+
+{
+    local $TODO = "May fail on some window managers (e.g. metacity)";
+
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    poswin $master;
+    $master->iconify;
+    $mw->update;
+    my $subject = $mw->Toplevel;
+    poswin $subject;
+    $subject->transient($master);
+    $mw->update;
+    is($subject->state, "withdrawn",
+       q{transient toplevel is withdrawn when mapped if master is iconic});
+    is($subject->ismapped, 0);
+}
+
+{
+    local $TODO = "May fail on some window managers (e.g. metacity)";
+
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    poswin $master;
+    $master->iconify;
+    $mw->update;
+    my $subject = $mw->Toplevel;
+    poswin $subject;
+    $mw->update;
+    $subject->transient($master);
+    $mw->update;
+    is($subject->state, "withdrawn",
+       q{already mapped transient toplevel is withdrawn if master is iconic});
+    is($subject->ismapped, 0);
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    my $subject = $mw->Toplevel;
+    poswin $master, $subject;
+    $mw->update;
+    $subject->transient($master);
+    $master->iconify;
+    $mw->update;
+    is($subject->state, "withdrawn",
+       q{iconify on the master does a withdraw on the transient});
+    is($subject->ismapped, 0);
+    $master->deiconify;
+    $mw->update;
+    is($subject->state, "normal",
+       q{deiconify on the master does a deiconify on the transient});
+    is($subject->ismapped, 1);
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    my $subject = $mw->Toplevel;
+    poswin $master, $subject;
+    $mw->update;
+    $subject->transient($master);
+    eval { $subject->transient(".bad") };
+    ok($@, q{error during transient should not cause deletion of map/unmap binding});
+    $master->withdraw;
+    $mw->update;
+
+    local $TODO = "May fail on some window managers (e.g. fvwm 2.5.x)";
+
+    is($subject->state, "withdrawn");
+    $master->deiconify;
+    $mw->update;
+    is($subject->state, "normal");
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    my $subject = $mw->Toplevel;
+    poswin $master, $subject;
+    $subject->transient($master);
+    $mw->update;
+    $master->destroy;
+    $mw->update;
+    is($subject->transient, undef,
+       q{remove transient property when master is destroyed});
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    my $subject = $mw->Toplevel;
+    $subject->transient($master);
+    $master->destroy;
+    is($subject->transient, undef,
+       q{remove transient property from unmapped window when master is destroyed});
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    my $subject = $mw->Toplevel;
+    poswin $master, $subject;
+    $mw->update;
+    $subject->transient($master);
+    $subject->withdraw;
+    $master->withdraw;
+    $master->deiconify;
+    # idle handler should not map the transient
+    $mw->update;
+    is($subject->state, q{withdrawn},
+       q{a withdrawn transient does not track state changes in the master});
+}
+
+{
+    local $TODO = "May fail on some window managers (e.g. fvwm 2.5.x)";
+
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    my $subject = $mw->Toplevel;
+    poswin $master, $subject;
+    $mw->update;
+    $subject->transient($master);
+    $subject->withdraw;
+    $master->withdraw;
+    $master->deiconify;
+    # idle handler should not map the transient
+    $mw->update;
+    is($subject->state, "withdrawn",
+       q{a withdrawn transient does not track state changes in the master});
+    $subject->deiconify;
+    is($subject->state, "normal");
+    $master->withdraw;
+    is($subject->state, "withdrawn");
+    $master->deiconify;
+    # idle handler should map transient
+    $mw->update;
+    is($subject->state, "normal");
+}
+
+{
+    deleteWindows;
+    my $master = $mw->Toplevel;
+    my $subject = $mw->Toplevel;
+    poswin $master, $subject;
+    $mw->update;
+    # withdraw before making window a transient
+    $subject->withdraw;
+    $subject->transient($master);
+    $master->withdraw;
+    $master->deiconify;
+    # idle handler should not map the transient
+    $mw->update;
+    is($subject->state, q{withdrawn},
+       q{a withdrawn transient does not track state changes in the master});
+}
+
+{
+    # wm-transient-7.*: See SF Tk Bug #592201 "wm transient fails with two masters"
+    # wm-transient-7.3 through 7.5 all caused panics on Unix in Tk 8.4b1.
+    # 7.1 and 7.2 added to catch (potential) future errors.
+
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    my $transient = $mw->Toplevel;
+    $transient->transient($t);
+    $transient->destroy;
+    $t->destroy;
+    pass("Destroying transient did not cause a panic");
+}
+
+{
+    my $t = $mw->Toplevel;
+    my $transient = $mw->Toplevel;
+    $transient->transient($t);
+    $t->destroy;
+    is($transient->transient, undef);
+    $transient->destroy;
+    pass("Destroying master did not cause a panic");
+}
+
+{
+    deleteWindows;
+    my $t1 = $mw->Toplevel;
+    my $t2 = $mw->Toplevel;
+    my $transient = $mw->Toplevel;
+    $transient->transient($t1);
+    $transient->transient($t2);
+    $t1->destroy; # Caused panic in 8.4b1
+    $t2->destroy;
+    $transient->destroy;
+    pass(q{Reassign transient, destroy old master});
+}
+
+{
+    deleteWindows;
+    my $t1 = $mw->Toplevel;
+    my $t2 = $mw->Toplevel;
+    my $transient = $mw->Toplevel;
+    $transient->transient($t1);
+    $transient->transient($t2);
+    $t2->destroy; # caused panic in 8.4b1
+    $t1->destroy;
+    $transient->destroy;
+    pass(q{Reassign transient, destroy new master});
+}
+
+{
+    my $t1 = $mw->Toplevel;
+    my $t2 = $mw->Toplevel;
+    my $transient = $mw->Toplevel;
+    $transient->transient($t1);
+    $transient->transient($t2);
+    $transient->destroy;
+    $t2->destroy; # caused panic in 8.4b1
+    $t1->destroy; # so did this
+    pass(q{Reassign transient, destroy transient});
+}
+
+{
+    ### wm state ###
+    eval { $mw->state("_", "_") };
+    like($@, qr{\Qwrong # args: should be "wm state window ?state?"},
+	 "wm state usage");
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    is($t->state, "normal", "initial state");
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    $t->state("withdrawn");
+    is($t->state, "withdrawn",
+       q{state change before map});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    $t->withdraw;
+    is($t->state, "withdrawn",
+       q{state change before map});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $mw->update;
+    $t->state("withdrawn");
+    is($t->state, "withdrawn",
+       q{state change after map});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $mw->update;
+    $t->withdraw;
+    is($t->state, "withdrawn",
+       q{state change after map});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    $t->state("iconic");
+    is($t->state, q{iconic},
+       q{state change before map, iconic});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    $t->iconify;
+    is($t->state, q{iconic},
+       q{state change before map, iconic});
+}
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $mw->update;
+    $t->state("iconic");
+    is($t->state, q{iconic},
+       q{state change after map, iconic});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $mw->update;
+    $t->iconify;
+    is($t->state, q{iconic},
+       q{state change after map, iconic});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    $t->withdraw;
+    $t->state("normal");
+    is($t->state, "normal",
+       q{state change before map, normal});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    $t->withdraw;
+    $t->deiconify;
+    is($t->state, "normal",
+       q{state change before map, normal});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $mw->update;
+    $t->withdraw;
+    $t->state("normal");
+    is($t->state, "normal",
+       q{state change after map, normal});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $mw->update;
+    $t->withdraw;
+    $t->deiconify;
+    is($t->state, "normal",
+       q{state change after map, normal});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    $t->iconify;
+    $t->state("normal");
+    is($t->state, "normal",
+       q{state change before map, iconify+normal});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    $t->iconify;
+    $t->deiconify;
+    is($t->state, "normal",
+       q{state change before map, iconify+normal});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $mw->update;
+    $t->iconify;
+    $t->state("normal");
+    is($t->state, "normal",
+       q{state change after map, iconify+normal});
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $mw->update;
+    $t->iconify;
+    $t->deiconify;
+    is($t->state, "normal",
+       q{state change after map, iconify+normal});
+}
+
+SKIP: {
+    skip("zoomed only implemented on win", 1)
+	if $Tk::platform ne 'MSWin32';
+    deleteWindows;
+    my $t = $mw->Toplevel;
+    poswin $t;
+    $mw->update;
+    $t->state("zoomed");
+    is($t->state, "zoomed",
+       q{state change after map, zoomed});
+}
+
+{
+    ### wm withdraw ###
+    eval { $mw->withdraw("_") };
+    like($@, qr{\Qwrong # args: should be "wm withdraw window"},
+	 "wm withdraw usage");
+}
+
+{
+    deleteWindows;
+    my $t = $mw->Toplevel(Name => "t");
+    my $t2 = $mw->Toplevel(Name => "t2");
+    poswin $t;
+    $t->iconwindow($t2);
+    eval { $t2->withdraw };
+    like($@, qr{\Qcan't withdraw .t2: it is an icon for .t});
+    
+    $mw->update;
+    $t->withdraw;
+    is($t->state, "withdrawn");
+    is($t->ismapped, 0);
+    $t->deiconify;
+    is($t->state, "normal");
+    is($t->ismapped, 1);
+}
+
+### Misc. wm tests ###
+
+if (0) {
+    ## This test probably cannot be translated to Perl/Tk;
+    ## also needs TK_ALT_DISPLAY defined
+
+    # See Tk Bug #671330 "segfault when e.g. deiconifying destroyed window"
+    my $w = $mw->Toplevel(Name => "t", -screen => $ENV{TK_ALT_DISPLAY});
+    my $w2 = $w;
+    $w->deiconify  ;# this caches the WindowRep
+    $w->destroy;
+    eval { $w2->deiconify };
+    like($@, qr{\Qbad window path name ".t"},
+	 q{Deletion epoch on multiple displays});
+}
+
+# FIXME:
+
+# Test delivery of virtual events to the WM. We could check to see
+# if the window was raised after a button click for example.
+# This sort of testing may not be possible.
+
+__END__
diff -up '/usr/local/src/Tk-804.027/t/wm.t' '/home/e/eserte/work/svk-checkouts/Tk/t/wm.t'
Index: ./t/wm.t
--- ./t/wm.t	Tue Dec 23 19:19:51 2003
+++ ./t/wm.t	Tue Nov  7 22:47:01 2006
@@ -20,20 +20,69 @@ BEGIN {
     }
 }
 
-BEGIN { plan tests => 1 }
+BEGIN { plan tests => 7 }
 
 my $mw = MainWindow->new;
+
 $mw->withdraw;
 $mw->geometry("+10+10");
+$mw->Message(-text => "Set the icon with iconimage and iconphoto")->pack;
 my $icon = $mw->Photo(-format => 'gif',
 		      -file => Tk->findINC('Xcamel.gif'));
 $mw->iconimage($icon);
-$mw->iconify;
+$mw->deiconify;
 $mw->idletasks;
-ok(1);
+pass("Set iconimage");
+
+tk_sleep(0.5);
+
+{
+    my $icon2 = $mw->Photo(-file => Tk->findINC("icon.gif"));
+    $mw->withdraw;
+    $mw->iconphoto('-default', $icon2);
+    $mw->deiconify;
+
+    my $t = $mw->Toplevel;
+    $t->geometry("+100+20");
+    $t->Message(-text => "This toplevel should also get the same icon")->pack;
+
+    $mw->idletasks;
+    pass("Set iconphoto");
+}
+
+{
+    my($wrapper_id, $menu_height) = $mw->wrapper;
+    ok(defined $wrapper_id, "Wrapper Id <$wrapper_id>");
+    ok(defined $menu_height, "Menu height <$menu_height>");
+}
+
+if (0) { # capture/release not anymore available in Tk???
+    my $t2 = $mw->Toplevel;
+    $t2->capture;
+    $mw->update;
+    $mw->after(100);
+    $t2->release;
+    pass("wm capture/release ok");
+}
+
+{
+    is($mw->wmTracing, "", "wmTracing");
+    $mw->wmTracing(1);
+    is($mw->wmTracing, 1);
+    $mw->wmTracing(0);
+    is($mw->wmTracing, "");
+}
+
 $mw->after(1000,[destroy => $mw]);
 MainLoop;
 
-__END__
-
+sub tk_sleep {
+    my($s) = @_;
+    my $sleep_dummy = 0;
+    $mw->after($s*1000,
+	       sub { $sleep_dummy++ });
+    $mw->waitVariable(\$sleep_dummy)
+	unless $sleep_dummy;
+}
 
+__END__
diff -up '/usr/local/src/Tk-804.027/t/zzScrolled.t' '/home/e/eserte/work/svk-checkouts/Tk/t/zzScrolled.t'
Index: ./t/zzScrolled.t
--- ./t/zzScrolled.t	Wed Mar 24 15:14:49 2004
+++ ./t/zzScrolled.t	Tue Nov  7 23:56:45 2006
@@ -1,9 +1,20 @@
 # -*- perl -*-
 BEGIN { $|=1; $^W=1; }
 use strict;
-use Test;
 use Tk;
 
+BEGIN {
+    if (!eval q{
+	use Test::More;
+	1;
+    }) {
+	print "# tests only work with installed Test::More module\n";
+	print "1..1\n";
+	print "ok 1\n";
+	exit;
+    }
+}
+
 BEGIN { plan tests => 94};
 
 my $mw = Tk::MainWindow->new;
@@ -13,16 +24,16 @@ my $scrl;
 my $text;
 {
    eval { require Tk::Text; };
-   ok($@, "", "Problem loading Tk::Text");
+   is($@, "", "loading Tk::Text");
    eval { $scrl = $mw->Scrolled('Text', -scrollbars=>'sw', -setgrid=>1); };
-   ok($@, "", "Problem creating Scrolled('Text')");
+   is($@, "", "creating Scrolled('Text')");
    ok( Tk::Exists($scrl) );
    eval { $scrl->grid(-sticky => 'nw'); };
-   ok($@, "", 'Problem managing Scrolled Text with grid');
+   is($@, "", 'managing Scrolled Text with grid');
    eval { $scrl->update; };
-   ok($@, "", 'Problem with update');
+   is($@, "", 'update');
    eval { $text = $scrl->Subwidget('text'); };
-   ok($@, "", 'Problem get subwidget text');
+   is($@, "", 'get subwidget text');
 }
 ##
 ## -fg/-foreground was not propagated to Text widget until
@@ -35,24 +46,24 @@ my $text;
     for my $opt ( qw(-fg -foreground -bg -background) )
       {
         eval { $oldcol = $scrl->cget($opt); };
-        ok($@, "", "cget $opt");
+        is($@, "", "cget $opt");
 
-        ok( $oldcol ne $newcol, 1, "Ooops, colors are already the same $oldcol=$newcol");
+        isnt($oldcol, $newcol, "colors aren't already the same $oldcol=$newcol");
 
 	## Set
         eval { $scrl->configure($opt=>$newcol); };
-        ok($@, "", "configure $opt => $newcol");
+        is($@, "", "configure $opt => $newcol");
         eval { $txtcol = $text->cget($opt); };
-        ok($@, "", "text cget $opt");
-        ok($txtcol, $newcol, "$opt not propagated to Text subwidget");
+        is($@, "", "text cget $opt");
+        is($txtcol, $newcol, "$opt propagated to Text subwidget");
         $mw->update;
 
 	## ReSet
         eval { $scrl->configure($opt=>$oldcol); };
-        ok($@, "", "Reset: configure $opt => $oldcol");
+        is($@, "", "Reset: configure $opt => $oldcol");
         eval { $txtcol = $scrl->cget($opt); };
-        ok($@, "", "Reset: text cget $opt");
-        ok($txtcol, $oldcol, "Reset scrolled $opt color");
+        is($@, "", "Reset: text cget $opt");
+        is($txtcol, $oldcol, "Reset scrolled $opt color");
         $mw->update;
       }
 }
@@ -68,40 +79,42 @@ my $text;
         for my $chg (qw(-5 5))
           {
             eval { $oldsize = $scrl->cget($opt); };
-            ok($@, "", "Sizechk: cget $opt");
+            is($@, "", "Sizechk: cget $opt");
             eval { $oldgeo  = $scrl->geometry; };
-            ok($@, "", "Sizechk: geometry $opt");
+            is($@, "", "Sizechk: geometry $opt");
 
 	    ## Set
             eval { $scrl->configure($opt=>($oldsize+$chg)); };
-            ok($@, "", "configure $opt => $oldsize + $chg");
+            is($@, "", "configure $opt => $oldsize + $chg");
             eval { $mw->update; };
-            ok($@, "", "Sizechg: Error update configure $opt");
+            is($@, "", "Sizechg: Error update configure $opt");
             eval { $newsize = $text->cget($opt); };
-            ok($@, "", "Sizechg: cget $opt");
-            ok($newsize, $oldsize+$chg, "No size change.");
+            is($@, "", "Sizechg: cget $opt");
+            is($newsize, $oldsize+$chg, "No size change.");
 
 	    # check if geometry has changed
             eval { $newgeo  = $scrl->geometry; };
-            ok($@, "", "Sizechk: new geometry $opt");
-            ok($newgeo, $oldgeo, "Sizechk: Ooops, geometry has changed " .
+            is($@, "", "Sizechk: new geometry $opt");
+            is($newgeo, $oldgeo, "Sizechk: geometry is the same " .
 		"($newgeo) for $opt => $oldsize+($chg)"
 		);
 
 	    ## ReSet
             eval { $scrl->configure($opt=>$oldsize); };
-            ok($@, "", "Reset size: configure $opt => $oldsize");
+            is($@, "", "Reset size: configure $opt => $oldsize");
             eval { $mw->update; };
             eval { $newsize = $text->cget($opt); };
-            ok($@, "", "Reset size: text cget $opt");
-            ok($newsize, $oldsize, "Reset size: scrolled $opt ");
-            ok($@, "", "Sizechg: Error reset update configure $opt");
+            is($@, "", "Reset size: text cget $opt");
+            is($newsize, $oldsize, "Reset size: scrolled $opt ");
+            is($@, "", "Sizechg: no error reset update configure $opt");
             eval { $newgeo  = $scrl->geometry; };
-            ok($@, "", "Sizechk: reset geometry $opt");
-            # Next one often fails - window stays same size but moves
+            is($@, "", "Sizechk: reset geometry $opt");
+
+	    local $TODO = "Next one often fails - window stays same size but moves";
             # e.g. expect 589x341+0+32 get 589x341+17+32
             # tried changing -sticky above as a fix?
-            ok($newgeo, $oldgeo, "Sizechk: geometry has not changed not reset" .
+	    # Only seen on metacity, but not fvwm2 or twm
+            is($newgeo, $oldgeo, "Sizechk: geometry has changed not reset" .
 		" for $opt => $oldsize+($chg)"
 		);
           }
#### End of Patch data ####

#### ApplyPatch data follows ####
# Data version        : 1.0
# Date generated      : Sat Nov 11 16:00:39 2006
# Generated by        : makepatch 2.03
# Recurse directories : Yes
# Excluded files      : (\A|/).*\~\Z
#                       (\A|/).*\.a\Z
#                       (\A|/).*\.bak\Z
#                       (\A|/).*\.BAK\Z
#                       (\A|/).*\.elc\Z
#                       (\A|/).*\.exe\Z
#                       (\A|/).*\.gz\Z
#                       (\A|/).*\.ln\Z
#                       (\A|/).*\.o\Z
#                       (\A|/).*\.obj\Z
#                       (\A|/).*\.olb\Z
#                       (\A|/).*\.old\Z
#                       (\A|/).*\.orig\Z
#                       (\A|/).*\.rej\Z
#                       (\A|/).*\.so\Z
#                       (\A|/).*\.Z\Z
#                       (\A|/)\.del\-.*\Z
#                       (\A|/)\.make\.state\Z
#                       (\A|/)\.nse_depinfo\Z
#                       (\A|/)core\Z
#                       (\A|/)tags\Z
#                       (\A|/)TAGS\Z
# p 'Event/Event.pm' 410 1163256901 0100664
# p 'MANIFEST' 48280 1163027625 0100660
# p 'MANIFEST.SKIP' 5557 1163211371 0100666
# p 'Makefile.PL' 4752 1163256736 0100660
# p 'Menubutton/Menubutton.pm' 10882 1163210460 0100664
# p 'Text/Text.pm' 43613 1162648375 0100664
# p 'TextList/TextList.pm' 26480 1163028750 0100664
# p 'Tixish/NoteBook.pm' 9923 1162648546 0100664
# p 'Tk.pm' 17720 1163256402 0100664
# p 'Tk/FBox.pm' 30078 1162654088 0100664
# p 'Tk/MMtry.pm' 1403 1162648487 0100664
# p 'Tk/Menu.pm' 29308 1163210296 0100664
# p 'Tk/Wm.pm' 3807 1162849135 0100664
# p 'ToDo' 1300 1162757639 0100660
# p 'config/xft.c' 316 1162582568 0100660
# p 'demos/widget' 18915 1162254761 0100771
# p 'myConfig' 10333 1163256937 0100660
# p 'pTk/mTk/generic/tkCanvWind.c' 34145 1162255239 0100660
# p 'pTk/mTk/generic/tkEvent.c' 44822 1162246694 0100660
# p 'pTk/mTk/generic/tkInt.h' 42138 1162754278 0100660
# p 'pTk/mTk/tclUnix/tclUnixTime.c' 10915 1162246692 0100660
# p 'pTk/mTk/unix/tkUnixWm.c' 209810 1162935987 0100660
# p 'pTk/mTk/unix/tkUnixXft.c' 18178 1162582568 0100660
# p 'pTk/mTk/xlib/X11/Xlib.h' 41024 1162246693 0100660
# p 'pod/Font.pod' 15562 1162653502 0100660
# p 'pod/Widget.pod' 25131 1162246688 0100660
# p 'pod/Wm.pod' 29243 1162757238 0100660
# p 'ptksh' 17421 1162646207 0100775
# c 't/00wmcheck.t' 0 1163026721 0100775
# p 't/JP.t' 814 1162723291 0100775
# p 't/KR.t' 781 1162723227 0100775
# p 't/TkTest.pm' 932 1163018706 0100664
# c 't/canvas.t' 0 1162587645 0100775
# p 't/entry.t' 35494 1162418132 0100775
# p 't/fork.t' 297 1162939147 0100775
# p 't/listbox.t' 61131 1163029020 0100775
# c 't/wm-tcl.t' 0 1163027119 0100775
# p 't/wm.t' 505 1162936021 0100775
# p 't/zzScrolled.t' 3696 1162940205 0100660
#### End of ApplyPatch data ####

#### End of Patch kit [created: Sat Nov 11 16:00:39 2006] ####
#### Patch checksum: 14653 488943 30123 ####
#### Checksum: 14687 490042 56388 ####
