changeset 384:bbff43aa5eb7 r21-2-7

Import from CVS: tag r21-2-7
author cvs
date Mon, 13 Aug 2007 11:08:24 +0200
parents 6a50c6a581a5
children bc48d89bf15c
files CHANGES-beta ChangeLog configure configure.in etc/NEWS etc/sample.emacs lib-src/ChangeLog lib-src/movemail.c lib-src/pop.c lisp/ChangeLog lisp/glyphs.el lisp/hyper-apropos.el lisp/isearch-mode.el lisp/ldap.el lisp/package-admin.el lisp/package-get.el lisp/package-ui.el lisp/sound.el man/ChangeLog man/xemacs/packages.texi nt/ChangeLog nt/PROBLEMS nt/README nt/config.h nt/xemacs.mak src/ChangeLog src/Makefile.in.in src/callproc.c src/console-msw.h src/console-stream.c src/console-tty.c src/console.h src/device-x.c src/device.c src/device.h src/dired.c src/eldap.c src/emacs.c src/event-msw.c src/events.c src/faces.c src/faces.h src/fns.c src/frame-msw.c src/frame-x.c src/frame.c src/frame.h src/free-hook.c src/general.c src/glyphs-msw.c src/glyphs-msw.h src/glyphs-widget.c src/glyphs-x.c src/glyphs-x.h src/glyphs.c src/glyphs.h src/gui-msw.c src/gui.c src/gui.h src/lisp.h src/menubar-msw.c src/menubar-x.c src/redisplay-msw.c src/redisplay-output.c src/redisplay-tty.c src/redisplay-x.c src/redisplay.c src/redisplay.h src/sound.c src/specifier.c src/strftime.c src/symsinit.h src/toolbar-x.c src/window.c src/window.h tests/automated/byte-compiler-tests.el tests/automated/database-tests.el tests/automated/hash-table-tests.el tests/automated/lisp-tests.el tests/automated/md5-tests.el tests/automated/test-harness.el tests/glyph-test.el version.sh
diffstat 83 files changed, 6519 insertions(+), 1833 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES-beta	Mon Aug 13 11:07:40 2007 +0200
+++ b/CHANGES-beta	Mon Aug 13 11:08:24 2007 +0200
@@ -1,4 +1,20 @@
 							-*- indented-text -*-
+to 21.2 beta7 "Ares"
+-- mswindows modeline crash fix from Jonathan Harris
+-- picon glyph fix from Gunnar Evermann
+-- widgets-in-buffers and subwindow support from Andy Piper
+-- movemail pop support under mswindows from Fabrice Popineau
+-- ldap fixes from Oscar Figueiredo
+-- fns cleanup from Hrvoje Niksic
+-- menubar fixes from Didier Verna
+-- mswindows accelerator fix from Jonathan Harris
+-- dired mule fix from Didier Verna
+-- sound doc cleanup from Charles Waldman
+-- new display table functionality from Hrvoje Niksic
+-- minor cleanups
+-- package fixes from Jan Vroonhof
+-- subwindow support fixes from Martin Buchholz
+
 to 21.2 beta6 "Apollo"
 -- mswindows compile fixes from Martin Buchholz, Andy Piper, Greg
    Klanderman and Adrian Aichner
--- a/ChangeLog	Mon Aug 13 11:07:40 2007 +0200
+++ b/ChangeLog	Mon Aug 13 11:08:24 2007 +0200
@@ -1,3 +1,38 @@
+1998-12-24  Martin Buchholz <martin@xemacs.org>
+
+	* XEmacs 21.2.7 is released.
+
+1998-12-20  Martin Buchholz  <martin@xemacs.org>
+
+	* configure.in: Redo DBM support
+	- die if dbm support requested, but not provided.
+	- properly check for libgdbm, then libc, then libdbm
+	- properly check for ndbm.h
+	- comments improved
+	- XE_DIE should always prefix messages with Error: for clarity
+
+1998-12-07  Martin Buchholz  <martin@xemacs.org>
+
+	* xemacs.mak (TEMACS_OBJS):
+	(DOC_SRC4):
+	- Remove pure.c, pure.obj
+
+1998-12-06  Martin Buchholz  <martin@xemacs.org>
+
+	* Makefile.in.in (distclean):
+	* dynodump/Makefile.in.in (distclean):
+	* src/Makefile.in.in (distclean):
+	* lib-src/Makefile.in.in (distclean):
+	* lwlib/Makefile.in.in (distclean):
+	- Make sure GNUmakefile is deleted.
+
+1998-12-17  Andy Piper  <andy@xemacs.org>
+
+	* configure.in (all_widgets): remove gui.o addition - its always
+ 	in the makefile now.
+
+	* configure.in: add gui-msw.o to msw objects.
+
 1998-12-16  Andy Piper  <andy@xemacs.org>
 
 	* XEmacs 21.2.6 is released
@@ -146,7 +181,7 @@
 
 1998-07-12  Björn Torkelsson  <torkel@hpc2n.umu.se>
 
-	* Makefile.in: added LDFLAGS. 
+	* Makefile.in: added LDFLAGS.
 
 1998-07-12  SL Baur  <steve@altair.xemacs.org>
 
@@ -215,7 +250,7 @@
 
 1998-06-20  Michael Sperber [Mr. Preprocessor]  <sperber@informatik.uni-tuebingen.de>
 
-	* etc/PACKAGES: 
+	* etc/PACKAGES:
 	* etc/BETA: Moved some package stuff into Texinfo docs.  Other nitpicks
 
 1998-06-20  Kazuyuki IENAGA <ienaga@jsys.co.jp>
@@ -346,7 +381,7 @@
 	* PROBLEMS:
 	Document problems with Solaris 2.6 + XSUNTRANSPORT
 
-	* Makefile.in: 
+	* Makefile.in:
 	* lwlib/Makefile.in.in:
 	* modules/Makefile.in:
 	- Adjust for luser's CDPATH being set to something weird.
@@ -409,7 +444,7 @@
 
 1998-04-27  SL Baur  <steve@altair.xemacs.org>
 
-	* configure.in (progname): Parameterize program name on `progname' 
+	* configure.in (progname): Parameterize program name on `progname'
 	and add --with-infodock.
 
 1998-04-26  SL Baur  <steve@altair.xemacs.org>
@@ -474,7 +509,7 @@
 	* info/dir: Fixed the explanatory notes for
 	`Info-default-directory-list' removal and the new automatic dir
 	rebuilding facility.  Reindented the menu.  Added an entry for
-	term.info 
+	term.info
 
 1998-04-20  SL Baur  <steve@altair.xemacs.org>
 
@@ -494,14 +529,14 @@
 	* configure.in: enable install pre-processing for mswindows
 
 Fri Apr 17 12:59:35 1998  Andy Piper  <andyp@parallax.co.uk>
-	
+
 	* Makefile.in.in: add install_pp to install incantation.
 
 	* installexe.sh: new file. Add .exe to install targets if the
 	result is executable.
 
 Fri Apr 17 12:59:35 1998  Andy Piper  <andyp@parallax.co.uk>
-	
+
 	* Makefile.in: add install_pp to install incantation.
 
 1998-04-14  Itay Ben-Yaacov <pezz@www-mail.huji.ac.il>
@@ -515,7 +550,7 @@
 
 1998-04-06  Martin Buchholz  <martin@xemacs.org>
 
-	* config.h.in: Add _SVID_SOURCE to list of xmkmf #defines.  
+	* config.h.in: Add _SVID_SOURCE to list of xmkmf #defines.
 	Used (at least) by RedHat 4.2.
 
 1998-04-11  Michael Sperber [Mr. Preprocessor]  <sperber@informatik.uni-tuebingen.de>
@@ -598,7 +633,7 @@
 	* configure.in: Check for -lz, -lgz unconditionally.  Too many
 	system linkers don't properly die when there are cascaded link
 	dependencies, so we can't rely on the linker for that.  The only
-	downside is that we might link with an extra unneeded library.  If 
+	downside is that we might link with an extra unneeded library.  If
 	you really really care about this, you can go fix it.
 
 	* configure.in: Enhance PANIC msg to make it clear that
@@ -607,13 +642,13 @@
 1998-03-27  Martin Buchholz  <martin@xemacs.org>
 
 	* configure.in: $debug was not properly dependent on $beta
-	
-	* configure.in: Move offix configuration out of src/Makefile.in.in 
+
+	* configure.in: Move offix configuration out of src/Makefile.in.in
 	into configure.in.
 
 	* configure.in: Reorganize xpm detection code.
 
-	* configure.in: XIM default to ON if Motif which is not Lesstif is 
+	* configure.in: XIM default to ON if Motif which is not Lesstif is
 	found.
 
 	* configure.in: Keep auto-generated makefile dependencies out of
@@ -702,7 +737,7 @@
 	* configure.in (quoted_arguments): Fix unquoted variable in
 	error-checking test.
 	- fix bogus substitution.
-	
+
 1998-03-17  SL Baur  <steve@altair.xemacs.org>
 
 	* configure.in: In -lpng test, look for png_set_strip_alpha.
@@ -841,7 +876,7 @@
 
 1998-02-21  SL Baur  <steve@altair.xemacs.org>
 
-	* configure.in (after_morecore_hook_exists): Modify dlmalloc tests 
+	* configure.in (after_morecore_hook_exists): Modify dlmalloc tests
 	to also test for Linux libc5.
 
 1998-02-19  SL Baur  <steve@altair.xemacs.org>
@@ -855,7 +890,7 @@
 	* configure.usage (--with-gung): Document.  Turns on
 	USE_MINIMAL_TAGBITS and USE_INDEXED_LRECORD_IMPLEMENTATION.
 	(--with-term): Remove.
-	
+
 	* XEmacs-20.5-beta26 is released.
 
 1998-02-18  SL Baur  <steve@altair.xemacs.org>
@@ -943,8 +978,8 @@
 
 1998-01-13  Martin Buchholz  <martin@xemacs.org>
 
-	* configure.usage:  
-	* etc/NEWS:  
+	* configure.usage:
+	* etc/NEWS:
 	Remove doc for configure-time INFOPATH, no longer used.
 
 	* etc/BETA: Update ftp addresses.
@@ -955,13 +990,13 @@
 	* src/config.h.in:
 	Define HAVE_INVERSE_HYPERBOLIC using 1 configure test, not 3.
 
-	* lwlib/lwlib.h: 
-	* lwlib/lwlib.c: 
-	* lwlib/lwlib-config.c: 
-	* lwlib/lwlib-Xm.c: 
-	* lwlib/lwlib-Xaw.c: 
-	* lwlib/lwlib-Xlw.c: 
-	* lwlib/config.h.in: 
+	* lwlib/lwlib.h:
+	* lwlib/lwlib.c:
+	* lwlib/lwlib-config.c:
+	* lwlib/lwlib-Xm.c:
+	* lwlib/lwlib-Xaw.c:
+	* lwlib/lwlib-Xlw.c:
+	* lwlib/config.h.in:
 	* src/menubar-x.c:
 	Prepend LWLIB_ to (SCROLLBARS|MENUBARS|DIALOGS)_(MOTIF|LUCID|ATHENA).
 	Maintain only one set of variables.
@@ -969,13 +1004,13 @@
 	* etc/xemacs.1: Update author list.
 
 	* Makefile.in (install-arch-dep): Simplify.
-	Replace construct  `test -d $dir && foo'  with  
+	Replace construct  `test -d $dir && foo'  with
 	`if test -d $dir; then foo; fi'
 
-	* lwlib/xlwmenu.c: 
-	* lwlib/xlwscrollbar.c: 
-	* lwlib/lwlib-Xlw.c: 
-	* lwlib/lwlib-Xm.c: 
+	* lwlib/xlwmenu.c:
+	* lwlib/xlwscrollbar.c:
+	* lwlib/lwlib-Xlw.c:
+	* lwlib/lwlib-Xm.c:
 	Always assume presence of limits.h (ANSI).
 
 1998-01-12  SL Baur  <steve@altair.xemacs.org>
@@ -1058,7 +1093,7 @@
 
 1997-12-21  SL Baur  <steve@altair.xemacs.org>
 
-	* etc/BETA (Prerequisite): Add cookbook procedures for maintaining 
+	* etc/BETA (Prerequisite): Add cookbook procedures for maintaining
 	package lisp directories.
 
 1997-12-20  SL Baur  <steve@altair.xemacs.org>
@@ -1067,7 +1102,7 @@
 
 1997-12-19  SL Baur  <steve@altair.xemacs.org>
 
-	* configure.in (bitmapdir): Reenable --with-session by default for 
+	* configure.in (bitmapdir): Reenable --with-session by default for
 	testing.
 
 1997-12-18  Kyle Jones  <kyle_jones@wonderworks.com>
@@ -1078,7 +1113,7 @@
 1997-12-18  Kyle Jones  <kyle_jones@wonderworks.com>
 
 	* etc/toolbar: Added support for foregroundToolBarColor
-	  symbol to most icons. 
+	  symbol to most icons.
 
 1997-12-17  SL Baur  <steve@altair.xemacs.org>
 
@@ -1278,7 +1313,7 @@
 	  device-msw.c, emacs.c, event-msw.c, event-msw.h, event-stream.c,
 	  events.c, events.h, faces.c, frame-msw.c, frame.c, general.c,
 	  msw-proc.c, objects-msw.c, objects-msw.h, redisplay-msw.c,
-	  redisplay.c, symsinit.h, 
+	  redisplay.c, symsinit.h,
 
 	* Didn't change 'win32' in nt.c, nt.h, ntproc.c
 
@@ -1314,7 +1349,7 @@
 1997-11-05  Didier Verna  <verna@inf.enst.fr>
 
 	* configure.in: Added the --site-prefixes options for the configure
-	script. You give a colon or space separated list of prefixes, and 
+	script. You give a colon or space separated list of prefixes, and
 	subdirectories include/ and lib/ will be added with -I and -L.
 
 1997-11-05  Martin Buchholz  <Martin Buchholz <martin@xemacs.org>>
@@ -1406,7 +1441,7 @@
 	TIFF(broken) and replace with test for ImageMagick.
 
 1997-10-30  Kyle Jones  <kyle_jones@wonderworks.com>
-	
+
 	* etc/Emacs.ad: Added *XlwMenu*highlightForeground entry.
 	  Added *XlwMenu*titleForeground entry.
 
@@ -1445,7 +1480,7 @@
 	* lib-src/gnuslib.c: Always include config.h before system headers
 	* configure.in: Improve AIX configure support
 	  - NON_GNU_CC defaults to `xlc'
-	  - CFLAGS defaults to "-O3 -qstrict  -qlibansi -qinfo -qro 
+	  - CFLAGS defaults to "-O3 -qstrict  -qlibansi -qinfo -qro
 	    -qmaxmem=20000"
 	  - check for sin instead of sqrt in -lm to avoid xlc internal error
 	  - Detect -li18n for use with Motif
@@ -1482,7 +1517,7 @@
 
 1997-10-18  SL Baur  <steve@altair.xemacs.org>
 
-        * XEmacs 20.3-beta91 is released. 
+        * XEmacs 20.3-beta91 is released.
 
 1997-10-16  Hrvoje Niksic <hniksic@srce.hr>
 
@@ -1571,7 +1606,7 @@
 
 	* Makefile.in: Add `make configure' target
 
-	* etc/BETA: 
+	* etc/BETA:
 	  - remove Chuck as contact name
 	  - random small improvements
 	  - remove I/me references - the message should be that XEmacs
@@ -1622,8 +1657,8 @@
 1997-10-03  Martin Buchholz  <mrb@eng.sun.com>
 
 	* lib-src/etags.c:  etags 12.28 + prototypization
-	* INSTALL:  Better document --site-runtime-libraries 
-	* src/scrollbar-x.c (x_update_scrollbar_instance_status): 
+	* INSTALL:  Better document --site-runtime-libraries
+	* src/scrollbar-x.c (x_update_scrollbar_instance_status):
 	  FIX: M-x scroll-left; horizontal scrollbar appears; drag it
 	  left; scrollbar disappears; keyboard inoperative.
 	* configure.in:  Remove left-over references to *_switch_x_*
@@ -1643,7 +1678,7 @@
 	* etc/BETA: Document existence of `Installation' file.
 	- Document requirement of rebuilding finder-inf.el when building
 	from the full tarball.
-	
+
 	* Makefile.in (top_distclean): Remove finder-inf.el*.
 
 	* configure.in (use_union_type): Default to "yes".
@@ -1696,11 +1731,11 @@
 
 	* src/redisplay-tty.c: Fix crashes with non-7bit tty escape
 	sequences (needs more testing).
-	* */Makefile*: 
+	* */Makefile*:
 	- Cleanup man/*/Makefile for consistency.
 	- use $(MAKEFINFO), $(TEXI2DVI), etc...
 	- Make combination --with-srcdir + Sun make work properly.
-	- Change construct: test -d $${dir} || mkdir $${dir} 
+	- Change construct: test -d $${dir} || mkdir $${dir}
 	   --> if test ! -d $${dir}; then mkdir $${dir}; fi
 	* lisp/x11/x-win-sun.el: Fix remaining glitches with
 	re-mappings of Sun function keys.
@@ -1743,9 +1778,9 @@
 	- x-keysym-on-keyboard-sans-modifiers-p introduced.
 	- x-keysym-hashtable introduced.
 	- allow X11R4 libs to guess keysyms on X11R5 servers.
-	- A better workaround for the bug that some Xlibs generate 
+	- A better workaround for the bug that some Xlibs generate
 	  Multi_key a adiaeresis when pressing Multi_key a "
-	
+
 	* src/dgif_lib.c: Make sure size_t is defined before using it.
 
 1997-09-12  SL Baur  <steve@altair.xemacs.org>
@@ -1810,7 +1845,7 @@
 	- new variable `blddir' introduced for informational purposes.
 	* lib-src/config.values.in: new config.el implementation
 	* lib-src/config.values.sh: new config.el implementation
-	* lisp/modes/pascal.el: Sync with GNU Emacs, fix infloop problem 
+	* lisp/modes/pascal.el: Sync with GNU Emacs, fix infloop problem
 	(thanks to Espen Skoglund, pascal.el maintainer)
 	* src/chartab.c: maintainability improvements.
 	* src/mule-coding.c: FIX for: editing DOS files with ISO2022*
@@ -1869,10 +1904,10 @@
 
 	* src/fns.c (require): Print messages when loading a file as a
 	result of require.
-	
+
 	* configure.in:
 	* lisp/utils/config.el:
-	* lib-src/config.values: 
+	* lib-src/config.values:
 	- new file created and installed by building.
 	- Allow configuration time values to be queried by the lisp code.
 
@@ -1902,7 +1937,7 @@
 1997-07-10  Hrvoje Niksic  <hniksic@srce.hr>
 
  	* extents.c (print_extent): Print correctly.
-	
+
 1997-07-13  Steven L Baur  <steve@altair.xemacs.org>
 
 	* configure.in (CPP): Add -Wall to default gcc CFLAGS.
@@ -1927,12 +1962,12 @@
 
 	* lisp/x11/x-select.el:
 	* src/xselect.c: Try STRING if selection owner couldn't convert
-	COMPOUND_TEXT. 
+	COMPOUND_TEXT.
 
 	* src/*.c: Change defalt to default_, and in general allow
 	doc-snarfing functions to recognize and ignore trailing `_'
 
-	* src/*.[ch]: Introduce XVECTOR_DATA and XVECTOR_LENGTH macros and 
+	* src/*.[ch]: Introduce XVECTOR_DATA and XVECTOR_LENGTH macros and
 	convert source code to use them consistently.
 
 1997-07-08  Steven L Baur  <steve@altair.xemacs.org>
@@ -1941,7 +1976,7 @@
 
 1997-07-08  Martin Buchholz  <mrb@eng.sun.com>
 
-	* configure.in: Set options differently, depending on beta-ness of 
+	* configure.in: Set options differently, depending on beta-ness of
 	build tree.
 	* *Makefile*: Clean up *clean: targets, esp. Steven's beloved
 	distclean.
@@ -1980,7 +2015,7 @@
 	- Autodetect usleep
 
 	* src/s/sol2.h: Support gcc on various Solaris releases.
-	
+
 	* lib-src/*.c: Ansify prototypes.
 
 	* lisp/prim/files.el: Optimize auto-mode-alist.
@@ -2012,7 +2047,7 @@
 	* configure.in (CPP): Correct typo `print-lib-gcc-file-name'
 	should be `print-libgcc-file-name'
 	From Katsumi Yamaoka <yamaoka@ga.sony.co.jp>
-	
+
 	* XEmacs 20.3-beta10 is released.
 
 1997-06-29  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
@@ -2178,7 +2213,7 @@
 
 	* lwlib/lwlib-Xaw.c, lwlib/lwlib-Xlw.c, lwlib/lwlib-Xm.c,
 	lwlib/lwlib.c:  Make 64 bit clean.
-	
+
 1997-06-20  Steven L Baur  <steve@altair.xemacs.org>
 
 	* etc/gnuserv.1: Updates and cleanup.
@@ -2196,7 +2231,7 @@
 
 	* */Makefile.in.in: Another rewrite
 	Make makefiles immune from being mangled by various cpp
-	implementations by quoting non-preprocessor directive lines. 
+	implementations by quoting non-preprocessor directive lines.
 	- random cleanup
 	- Use $(RM) and $(pwd) macros consistently
 	- Add dependencies for balloon-help source files
@@ -2236,11 +2271,11 @@
 	  previously commented out and normalized everything vis a vis
 	  'backspace and 'delete keysyms.
 	* lisp/packages/*.el: Normalized all the "\177" bindings
-	* lisp/modes/cperl-mode.el: Created cperl-electric-delete function 
+	* lisp/modes/cperl-mode.el: Created cperl-electric-delete function
 	  which is a "smart" version of the cperl-electric-backspace
 	  function (it honors the desired delete direction).  Bound it to
 	  'delete and the electric-backspace to 'backspace.
-	* lisp/packages/pending-del.el: Added cperl-electric-backspace and 
+	* lisp/packages/pending-del.el: Added cperl-electric-backspace and
 	  cperl-electric-delete to the 'supersede list.
 
 1997-06-11  Steven L Baur  <steve@altair.xemacs.org>
@@ -2252,16 +2287,16 @@
 
 1997-06-11  Martin Buchholz  <mrb@eng.sun.com>
 
-	* src/Makefile.in: 
-	* lwlib/Makefile.in: 
-	* lib-src/Makefile.in: 
+	* src/Makefile.in:
+	* lwlib/Makefile.in:
+	* lib-src/Makefile.in:
 	* Makefile.in: More Makefile cleanup
 	- add .PHONY targets where necessary
 	- remove most builtin rules using .SUFFIXES
 	- -lXau only gets used for linking gnuserv binaries
 	- No VPATH for root Makefile
 	- remove gcc v1 support
-	* configure.in: 
+	* configure.in:
 	- A new test to autodetect need to define NARROWPROTO,
 	  needed by XFree86
 	- Consistently use idiom foo=`echo '' $foo | sed -s 's:^ ::' -e ...`
@@ -2269,7 +2304,7 @@
 	- Check for libPW
 	- Use more sophisticated Xpm test that confirms xpm.h and libXpm
 	  are in sync.
-	* src/s/linux.h: 
+	* src/s/linux.h:
 	* src/m/intel386.h: Yet another attempt to clean up linux defines.
 
 1997-06-10  Steven L Baur  <steve@altair.xemacs.org>
@@ -2335,7 +2370,7 @@
 	smiley faces.
 
 1997-06-10  Gary D. Foster  <Gary.Foster@corp.sun.com>
-	
+
 	* lisp/modes/view-less.el: Changed \177 bindings to 'delete
 	* lisp/modes/help.el: Changed \177 bindings to 'delete
 
@@ -2355,7 +2390,7 @@
 	* lisp/modes/cc-mode.el:
 	* lisp/modes/cperl-mode.el: Fixed references to delete functions
 	  to use the new names.
-	
+
 1997-06-09  Steven L Baur  <steve@altair.xemacs.org>
 
 	* XEmacs 20.3-b5 is released.
@@ -2380,24 +2415,24 @@
 	* src/s/netbsd.h: complete rewrite, use ORDINARY_LINK, #ifdef out
 	old cruft that can be obtained from system header files.
 	* lib-src/getopt*: Synch with FSF, remove compiler warnings.
-	
-	* lib-src/b2m.c: 
-	* src/gifalloc.c: 
-	* lib-src/gnuslib.c: 
-	* lib-src/profile.c: 
+
+	* lib-src/b2m.c:
+	* src/gifalloc.c:
+	* lib-src/gnuslib.c:
+	* lib-src/profile.c:
 	* lib-src/movemail.c: Fix compiler warnings
-	
+
 	* lib-src/Makefile.in.in: Remove unused -DCONFIG_BROKETS flag
 	- Fix up compile flags for new etags version
 
-	* etc/NEWS: 
-	* etc/etags.1: 
-	* man/xemacs/programs.texi: 
+	* etc/NEWS:
+	* etc/etags.1:
+	* man/xemacs/programs.texi:
 	* lib-src/etags.c:  Upgraded to etags 12.11
 
 	* src/config.h.in: Fix inline keyword support
-	
-	* configure.in: Use a different mechanism for removing extra white 
+
+	* configure.in: Use a different mechanism for removing extra white
 	space.  Avoid using foo=`echo $bar`, which loses with various echos.
 	- new M4 macro XE_SPACE(var, words...)
 	- Use autoconf 2's AC_HEADER_SYS_WAIT
@@ -2413,11 +2448,11 @@
 
 1997-06-04  Gary D. Foster  <Gary.Foster@corp.sun.com>
 
-	* lisp/modes/cc-mode.el: Modified `c-electric-delete' to honor the 
+	* lisp/modes/cc-mode.el: Modified `c-electric-delete' to honor the
 	  desired delete direction in both normal and "hungry" modes.
-	* lisp/modes/cperl-mode.el: Modified `cperl-electric-backspace' to 
+	* lisp/modes/cperl-mode.el: Modified `cperl-electric-backspace' to
 	  honor the desired delete direction.
-	
+
 1997-05-30  Martin Buchholz  <mrb@eng.sun.com>
 
 	* configure.in: Automagically compute -R path for gcc
@@ -2426,7 +2461,7 @@
 
 	* lisp/vm/vm-vars.el: Fixed delete key binding to call
 	  `vm-scroll-down'
-	
+
 Thu May 29 15:35:07 1997  Martin Buchholz  <mrb@eng.sun.com>
 
 	* configure.in: Add support for Solaris2.6 -z ignore linker flags
@@ -2445,9 +2480,9 @@
 	* lisp/modes/*.el: Removed conflicting \177 bindings.
 	* lisp/modes/cc-mode.el: Modified `c-electric-delete' to use new
 	  delete bindings.
-	* lisp/modes/cperl-mode.el: Modified `cperl-electric-backspace' to 
+	* lisp/modes/cperl-mode.el: Modified `cperl-electric-backspace' to
 	  use new delete bindings.
-	
+
 1997-06-03  MORIOKA Tomohiko  <morioka@jaist.ac.jp>
 
 	* lisp/x11/x-menubar.el (default-menubar): Add menu for Mule.
@@ -2629,14 +2664,14 @@
 	depend on it.
 	with-xim=motif only default on Solaris.
 	realpath moved from s&m to configure.in.
-	xemacs-version.h removed.  main_1 now contains $canonical as well, 
+	xemacs-version.h removed.  main_1 now contains $canonical as well,
 	for even more useful backtraces.
 	termcap handling rewritten.
 	Create .sbinit for Sun's source browser.
 	Warn user if no XPM support present.
 	Warn user if compiling in error checking.
 
-	* Makefile.in: use MAKE_SUBDIR consistently.  Remove references to 
+	* Makefile.in: use MAKE_SUBDIR consistently.  Remove references to
 	dynodump.  Remove core when cleaning.  Remove config.log.
 	make distclean now functional.
 
@@ -2730,7 +2765,7 @@
 
 	3) Rearranging the entries by relevance.  I have tried to put the most
 	   relevant entries in front.
-	
+
 Thu Apr 10 19:07:26 1997  Steven L Baur  <steve@altair.xemacs.org>
 
 	* XEmacs 20.1-b14 is released.  (Beta 13 was skipped).
@@ -2750,7 +2785,7 @@
 
 Wed Apr  2 15:27:35 1997  Steven L Baur  <steve@altair.xemacs.org>
 
-	* Makefile.in (install-only): New target.  Functionality suggested 
+	* Makefile.in (install-only): New target.  Functionality suggested
 	by Larry Schwimmer, correct way of doing it suggested by Chuck
 	Thompson.
 
@@ -2774,7 +2809,7 @@
 Wed Mar 26 22:31:10 1997  Steven L Baur  <steve@altair.xemacs.org>
 
 	* Remove vms top-level directory.
-	
+
 	* XEmacs 19.15 final released to beta testers.
 
 Tue Mar 25 19:13:27 1997  Steven L Baur  <steve@altair.xemacs.org>
@@ -3020,7 +3055,7 @@
 
 	* XEmacs 20.0 beta90 (prerelease 1) is released.
 	* XEmacs 19.15 beta90 (prerelease 1) is released.
-	
+
 Tue Jan  7 08:45:16 1997  Steven L Baur  <steve@altair.xemacs.org>
 
 	* configure.in (LIBS): Revise test for XFree86 (look for XF86Config).
@@ -3035,8 +3070,8 @@
 
 Wed Jan  1 08:30:48 1997  Martin Buchholz  <mrb@eng.sun.com>
 
-	* src/emacs.c: Make sure 
-	`./temacs -batch -l loadup.el run-temacs <emacs-args>' 
+	* src/emacs.c: Make sure
+	`./temacs -batch -l loadup.el run-temacs <emacs-args>'
 	works properly
 
 	* src/Makefile.in.in (rtcmacs): Add support for RTC, Sun's
@@ -3055,20 +3090,20 @@
 	* lib-src/update-autoloads.sh: Rewritten to use auto-autoloads.el.
 	* lisp/utils/autoload.el: Reorganization of autoload mechanism:
 	Errors during autoload generation are just that - errors.
-	
+
 	Generated autoloads are now in a separate file of their own.
-	
+
 	Reliability of autoload generation greatly increased.
-	
+
 	Distribution smaller by about 100k.
-	
+
 	`make autoloads' is still the preferred mechanism for update.
-	
+
 	Autoloads are always regenerated completely from scratch.  This
  	avoids errors with obsolete or corrupted autoload entries.
 
 	Caching of autoload entries using timestamps has been eliminated.
-	
+
 	Files that have no autoloads no longer have a comment placed into
  	the generated autoloads file.
 
@@ -3126,7 +3161,7 @@
 	  that various tools can recognize the filename as such.
 
 	* src/event-Xt.c (x_to_emacs_keysym): Fix crash when
-	  --with-xim=xlib and key event on window frame.  
+	  --with-xim=xlib and key event on window frame.
 	  Change return foo to return (foo) when return is a macro.
 
 	* src/editfns.c (Ffollowing_char): docstring fixes.
--- a/configure	Mon Aug 13 11:07:40 2007 +0200
+++ b/configure	Mon Aug 13 11:08:24 2007 +0200
@@ -2450,7 +2450,7 @@
     case "$arg" in
      -* ) ;;
      * ) test -d "$arg" || \
-           { echo "Invalid site library \`$arg': no such directory" >&2; exit 1; }
+           { echo "Error:" "Invalid site library \`$arg': no such directory" >&2; exit 1; }
        arg="-L${arg}" ;;
     esac
     ld_switch_site="$ld_switch_site $arg" &&  if test "$extra_verbose" = "yes"; then echo "    Appending \"$arg\" to \$ld_switch_site"; fi
@@ -2463,7 +2463,7 @@
     case "$arg" in
       -* ) ;;
       * ) test -d "$arg" || \
-           { echo "Invalid site include \`$arg': no such directory" >&2; exit 1; }
+           { echo "Error:" "Invalid site include \`$arg': no such directory" >&2; exit 1; }
       arg="-I${arg}" ;;
     esac
     c_switch_site="$c_switch_site $arg" &&  if test "$extra_verbose" = "yes"; then echo "    Appending \"$arg\" to \$c_switch_site"; fi
@@ -2476,11 +2476,11 @@
     inc_dir="${dir}/include"
     lib_dir="${dir}/lib"
     if test ! -d "$dir"; then
-      { echo "Invalid site prefix \`$dir': no such directory" >&2; exit 1; }
+      { echo "Error:" "Invalid site prefix \`$dir': no such directory" >&2; exit 1; }
     elif test ! -d "$inc_dir"; then
-      { echo "Invalid site prefix \`$dir': no such directory \`$inc_dir'" >&2; exit 1; }
+      { echo "Error:" "Invalid site prefix \`$dir': no such directory \`$inc_dir'" >&2; exit 1; }
     elif test ! -d "$lib_dir"; then
-      { echo "Invalid site prefix \`$dir': no such directory \`$lib_dir'" >&2; exit 1; }
+      { echo "Error:" "Invalid site prefix \`$dir': no such directory \`$lib_dir'" >&2; exit 1; }
     else
       c_switch_site="$c_switch_site "-I$inc_dir"" &&  if test "$extra_verbose" = "yes"; then echo "    Appending \""-I$inc_dir"\" to \$c_switch_site"; fi
       ld_switch_site="$ld_switch_site "-L$lib_dir"" &&  if test "$extra_verbose" = "yes"; then echo "    Appending \""-L$lib_dir"\" to \$ld_switch_site"; fi
@@ -5900,8 +5900,8 @@
     with_file_coding=yes
     use_minimal_tagbits=yes
     use_indexed_lrecord_implementation=yes
-    extra_objs="$extra_objs console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o glyphs-msw.o" &&  if test "$extra_verbose" = "yes"; then
-   echo "    xemacs will be linked with \"console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o glyphs-msw.o\""
+    extra_objs="$extra_objs console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o glyphs-msw.o gui-msw.o" &&  if test "$extra_verbose" = "yes"; then
+   echo "    xemacs will be linked with \"console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o glyphs-msw.o gui-msw.o\""
  fi
   fi
 fi
@@ -7489,9 +7489,6 @@
 test "$with_toolbars"   != "no"      && extra_objs="$extra_objs toolbar.o" &&  if test "$extra_verbose" = "yes"; then
    echo "    xemacs will be linked with \"toolbar.o\""
  fi
-test "$all_widgets" != "no no no no" && extra_objs="$extra_objs gui.o" &&  if test "$extra_verbose" = "yes"; then
-   echo "    xemacs will be linked with \"gui.o\""
- fi
 
 if test "$with_x11" = "yes"; then
   test "$with_menubars"   != "no"      && extra_objs="$extra_objs menubar-x.o" &&  if test "$extra_verbose" = "yes"; then
@@ -7556,7 +7553,7 @@
 
 if test "$with_mule" = "yes" ; then
   echo "checking for Mule-related features" 1>&6
-echo "configure:7560: checking for Mule-related features" >&5
+echo "configure:7557: checking for Mule-related features" >&5
   { test "$extra_verbose" = "yes" && cat << \EOF
     Defining MULE
 EOF
@@ -7581,15 +7578,15 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7585: checking for $ac_hdr" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 7588 "configure"
+echo "configure:7582: checking for $ac_hdr" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 7585 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7593: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7590: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -7620,12 +7617,12 @@
 
   
 echo $ac_n "checking for strerror in -lintl""... $ac_c" 1>&6
-echo "configure:7624: checking for strerror in -lintl" >&5
+echo "configure:7621: checking for strerror in -lintl" >&5
 ac_lib_var=`echo intl'_'strerror | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lintl "
 cat > conftest.$ac_ext <<EOF
-#line 7629 "configure"
+#line 7626 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7636,7 +7633,7 @@
 strerror()
 ; return 0; }
 EOF
-if { (eval echo configure:7640: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7637: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7669,19 +7666,19 @@
 
 
   echo "checking for Mule input methods" 1>&6
-echo "configure:7673: checking for Mule input methods" >&5
+echo "configure:7670: checking for Mule input methods" >&5
         case "$with_xim" in "" | "yes" )
     echo "checking for XIM" 1>&6
-echo "configure:7676: checking for XIM" >&5
+echo "configure:7673: checking for XIM" >&5
         if test "$have_lesstif" = "yes"; then with_xim=xlib
     else 
 echo $ac_n "checking for XmImMbLookupString in -lXm""... $ac_c" 1>&6
-echo "configure:7680: checking for XmImMbLookupString in -lXm" >&5
+echo "configure:7677: checking for XmImMbLookupString in -lXm" >&5
 ac_lib_var=`echo Xm'_'XmImMbLookupString | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lXm "
 cat > conftest.$ac_ext <<EOF
-#line 7685 "configure"
+#line 7682 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7692,7 +7689,7 @@
 XmImMbLookupString()
 ; return 0; }
 EOF
-if { (eval echo configure:7696: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7693: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7758,15 +7755,15 @@
 
     if test "$with_xfs" = "yes" ; then
     echo "checking for XFontSet" 1>&6
-echo "configure:7762: checking for XFontSet" >&5
+echo "configure:7759: checking for XFontSet" >&5
     
 echo $ac_n "checking for XmbDrawString in -lX11""... $ac_c" 1>&6
-echo "configure:7765: checking for XmbDrawString in -lX11" >&5
+echo "configure:7762: checking for XmbDrawString in -lX11" >&5
 ac_lib_var=`echo X11'_'XmbDrawString | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lX11 "
 cat > conftest.$ac_ext <<EOF
-#line 7770 "configure"
+#line 7767 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7777,7 +7774,7 @@
 XmbDrawString()
 ; return 0; }
 EOF
-if { (eval echo configure:7781: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7778: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7817,15 +7814,15 @@
     test "$with_wnn6" = "yes" && with_wnn=yes # wnn6 implies wnn support
   test -z "$with_wnn" && { ac_safe=`echo "wnn/jllib.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for wnn/jllib.h""... $ac_c" 1>&6
-echo "configure:7821: checking for wnn/jllib.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 7824 "configure"
+echo "configure:7818: checking for wnn/jllib.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 7821 "configure"
 #include "confdefs.h"
 #include <wnn/jllib.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7829: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7826: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -7850,10 +7847,10 @@
     for ac_func in crypt
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:7854: checking for $ac_func" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 7857 "configure"
+echo "configure:7851: checking for $ac_func" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 7854 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -7876,7 +7873,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:7880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -7905,12 +7902,12 @@
 
     test "$ac_cv_func_crypt" != "yes" && { 
 echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6
-echo "configure:7909: checking for crypt in -lcrypt" >&5
+echo "configure:7906: checking for crypt in -lcrypt" >&5
 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lcrypt "
 cat > conftest.$ac_ext <<EOF
-#line 7914 "configure"
+#line 7911 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7921,7 +7918,7 @@
 crypt()
 ; return 0; }
 EOF
-if { (eval echo configure:7925: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7922: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7956,12 +7953,12 @@
     if test -z "$with_wnn" -o "$with_wnn" = "yes"; then
     
 echo $ac_n "checking for jl_dic_list_e in -lwnn""... $ac_c" 1>&6
-echo "configure:7960: checking for jl_dic_list_e in -lwnn" >&5
+echo "configure:7957: checking for jl_dic_list_e in -lwnn" >&5
 ac_lib_var=`echo wnn'_'jl_dic_list_e | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lwnn "
 cat > conftest.$ac_ext <<EOF
-#line 7965 "configure"
+#line 7962 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -7972,7 +7969,7 @@
 jl_dic_list_e()
 ; return 0; }
 EOF
-if { (eval echo configure:7976: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:7973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -7990,12 +7987,12 @@
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for jl_dic_list_e in -lwnn4""... $ac_c" 1>&6
-echo "configure:7994: checking for jl_dic_list_e in -lwnn4" >&5
+echo "configure:7991: checking for jl_dic_list_e in -lwnn4" >&5
 ac_lib_var=`echo wnn4'_'jl_dic_list_e | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lwnn4 "
 cat > conftest.$ac_ext <<EOF
-#line 7999 "configure"
+#line 7996 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8006,7 +8003,7 @@
 jl_dic_list_e()
 ; return 0; }
 EOF
-if { (eval echo configure:8010: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8007: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8024,12 +8021,12 @@
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for jl_dic_list_e in -lwnn6""... $ac_c" 1>&6
-echo "configure:8028: checking for jl_dic_list_e in -lwnn6" >&5
+echo "configure:8025: checking for jl_dic_list_e in -lwnn6" >&5
 ac_lib_var=`echo wnn6'_'jl_dic_list_e | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lwnn6 "
 cat > conftest.$ac_ext <<EOF
-#line 8033 "configure"
+#line 8030 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8040,7 +8037,7 @@
 jl_dic_list_e()
 ; return 0; }
 EOF
-if { (eval echo configure:8044: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8041: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8058,12 +8055,12 @@
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for dic_list_e in -lwnn6_fromsrc""... $ac_c" 1>&6
-echo "configure:8062: checking for dic_list_e in -lwnn6_fromsrc" >&5
+echo "configure:8059: checking for dic_list_e in -lwnn6_fromsrc" >&5
 ac_lib_var=`echo wnn6_fromsrc'_'dic_list_e | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lwnn6_fromsrc "
 cat > conftest.$ac_ext <<EOF
-#line 8067 "configure"
+#line 8064 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8074,7 +8071,7 @@
 dic_list_e()
 ; return 0; }
 EOF
-if { (eval echo configure:8078: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8075: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8122,12 +8119,12 @@
     if test "$with_wnn6" != "no"; then
       
 echo $ac_n "checking for jl_fi_dic_list in -l$libwnn""... $ac_c" 1>&6
-echo "configure:8126: checking for jl_fi_dic_list in -l$libwnn" >&5
+echo "configure:8123: checking for jl_fi_dic_list in -l$libwnn" >&5
 ac_lib_var=`echo $libwnn'_'jl_fi_dic_list | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -l$libwnn "
 cat > conftest.$ac_ext <<EOF
-#line 8131 "configure"
+#line 8128 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8138,7 +8135,7 @@
 jl_fi_dic_list()
 ; return 0; }
 EOF
-if { (eval echo configure:8142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8139: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8173,15 +8170,15 @@
   if test "$with_canna" != "no"; then
     ac_safe=`echo "canna/jrkanji.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for canna/jrkanji.h""... $ac_c" 1>&6
-echo "configure:8177: checking for canna/jrkanji.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 8180 "configure"
+echo "configure:8174: checking for canna/jrkanji.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 8177 "configure"
 #include "confdefs.h"
 #include <canna/jrkanji.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8185: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8182: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -8208,15 +8205,15 @@
     c_switch_site="$c_switch_site -I/usr/local/canna/include"
     ac_safe=`echo "canna/jrkanji.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for canna/jrkanji.h""... $ac_c" 1>&6
-echo "configure:8212: checking for canna/jrkanji.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 8215 "configure"
+echo "configure:8209: checking for canna/jrkanji.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 8212 "configure"
 #include "confdefs.h"
 #include <canna/jrkanji.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8220: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8217: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -8244,15 +8241,15 @@
 
   test -z "$with_canna" && { ac_safe=`echo "canna/RK.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for canna/RK.h""... $ac_c" 1>&6
-echo "configure:8248: checking for canna/RK.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 8251 "configure"
+echo "configure:8245: checking for canna/RK.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 8248 "configure"
 #include "confdefs.h"
 #include <canna/RK.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:8256: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:8253: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -8275,12 +8272,12 @@
  }
   test -z "$with_canna" && { 
 echo $ac_n "checking for RkBgnBun in -lRKC""... $ac_c" 1>&6
-echo "configure:8279: checking for RkBgnBun in -lRKC" >&5
+echo "configure:8276: checking for RkBgnBun in -lRKC" >&5
 ac_lib_var=`echo RKC'_'RkBgnBun | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lRKC "
 cat > conftest.$ac_ext <<EOF
-#line 8284 "configure"
+#line 8281 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8291,7 +8288,7 @@
 RkBgnBun()
 ; return 0; }
 EOF
-if { (eval echo configure:8295: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8292: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8314,12 +8311,12 @@
  }
   test -z "$with_canna" && { 
 echo $ac_n "checking for jrKanjiControl in -lcanna""... $ac_c" 1>&6
-echo "configure:8318: checking for jrKanjiControl in -lcanna" >&5
+echo "configure:8315: checking for jrKanjiControl in -lcanna" >&5
 ac_lib_var=`echo canna'_'jrKanjiControl | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lcanna "
 cat > conftest.$ac_ext <<EOF
-#line 8323 "configure"
+#line 8320 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8330,7 +8327,7 @@
 jrKanjiControl()
 ; return 0; }
 EOF
-if { (eval echo configure:8334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8331: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8379,12 +8376,12 @@
   libs_x="-lXm $libs_x" &&  if test "$extra_verbose" = "yes"; then echo "    Prepending \"-lXm\" to \$libs_x"; fi
     
 echo $ac_n "checking for layout_object_getvalue in -li18n""... $ac_c" 1>&6
-echo "configure:8383: checking for layout_object_getvalue in -li18n" >&5
+echo "configure:8380: checking for layout_object_getvalue in -li18n" >&5
 ac_lib_var=`echo i18n'_'layout_object_getvalue | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -li18n "
 cat > conftest.$ac_ext <<EOF
-#line 8388 "configure"
+#line 8385 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -8395,7 +8392,7 @@
 layout_object_getvalue()
 ; return 0; }
 EOF
-if { (eval echo configure:8399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8396: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -8481,10 +8478,10 @@
 for ac_func in cbrt closedir dup2 eaccess fmod fpathconf frexp ftime gethostname getpagesize gettimeofday getcwd getwd logb lrand48 matherr mkdir mktime perror poll random rename res_init rint rmdir select setitimer setpgid setlocale setsid sigblock sighold sigprocmask snprintf strcasecmp strerror tzset ulimit usleep utimes waitpid vsnprintf
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8485: checking for $ac_func" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 8488 "configure"
+echo "configure:8482: checking for $ac_func" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 8485 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8507,7 +8504,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:8511: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -8548,10 +8545,10 @@
       * ) for ac_func in realpath
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8552: checking for $ac_func" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 8555 "configure"
+echo "configure:8549: checking for $ac_func" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 8552 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8574,7 +8571,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:8578: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -8608,16 +8605,16 @@
 esac
 
 echo $ac_n "checking whether netdb declares h_errno""... $ac_c" 1>&6
-echo "configure:8612: checking whether netdb declares h_errno" >&5
-cat > conftest.$ac_ext <<EOF
-#line 8614 "configure"
+echo "configure:8609: checking whether netdb declares h_errno" >&5
+cat > conftest.$ac_ext <<EOF
+#line 8611 "configure"
 #include "confdefs.h"
 #include <netdb.h>
 int main() {
 return h_errno;
 ; return 0; }
 EOF
-if { (eval echo configure:8621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
    { test "$extra_verbose" = "yes" && cat << \EOF
@@ -8637,16 +8634,16 @@
 rm -f conftest*
 
 echo $ac_n "checking for sigsetjmp""... $ac_c" 1>&6
-echo "configure:8641: checking for sigsetjmp" >&5
-cat > conftest.$ac_ext <<EOF
-#line 8643 "configure"
+echo "configure:8638: checking for sigsetjmp" >&5
+cat > conftest.$ac_ext <<EOF
+#line 8640 "configure"
 #include "confdefs.h"
 #include <setjmp.h>
 int main() {
 sigjmp_buf bar; sigsetjmp (bar, 0);
 ; return 0; }
 EOF
-if { (eval echo configure:8650: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8647: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6
    { test "$extra_verbose" = "yes" && cat << \EOF
@@ -8666,11 +8663,11 @@
 rm -f conftest*
 
 echo $ac_n "checking whether localtime caches TZ""... $ac_c" 1>&6
-echo "configure:8670: checking whether localtime caches TZ" >&5
+echo "configure:8667: checking whether localtime caches TZ" >&5
 
 if test "$ac_cv_func_tzset" = "yes"; then
 cat > conftest.$ac_ext <<EOF
-#line 8674 "configure"
+#line 8671 "configure"
 #include "confdefs.h"
 #include <time.h>
 #if STDC_HEADERS
@@ -8705,7 +8702,7 @@
   exit (0);
 }
 EOF
-if { (eval echo configure:8709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
+if { (eval echo configure:8706: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
 then
   emacs_cv_localtime_cache=no
 else
@@ -8735,9 +8732,9 @@
 
 if test "$HAVE_TIMEVAL" = "yes"; then
 echo $ac_n "checking whether gettimeofday accepts one or two arguments""... $ac_c" 1>&6
-echo "configure:8739: checking whether gettimeofday accepts one or two arguments" >&5
-cat > conftest.$ac_ext <<EOF
-#line 8741 "configure"
+echo "configure:8736: checking whether gettimeofday accepts one or two arguments" >&5
+cat > conftest.$ac_ext <<EOF
+#line 8738 "configure"
 #include "confdefs.h"
 
 #ifdef TIME_WITH_SYS_TIME
@@ -8759,7 +8756,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:8763: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   echo "$ac_t""two" 1>&6
 else
@@ -8781,19 +8778,19 @@
 
 
 echo $ac_n "checking for inline""... $ac_c" 1>&6
-echo "configure:8785: checking for inline" >&5
+echo "configure:8782: checking for inline" >&5
 
 ac_cv_c_inline=no
 for ac_kw in inline __inline__ __inline; do
   cat > conftest.$ac_ext <<EOF
-#line 8790 "configure"
+#line 8787 "configure"
 #include "confdefs.h"
 
 int main() {
 } $ac_kw foo() {
 ; return 0; }
 EOF
-if { (eval echo configure:8797: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:8794: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_inline=$ac_kw; break
 else
@@ -8843,17 +8840,17 @@
 # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
 # for constant arguments.  Useless!
 echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6
-echo "configure:8847: checking for working alloca.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 8850 "configure"
+echo "configure:8844: checking for working alloca.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 8847 "configure"
 #include "confdefs.h"
 #include <alloca.h>
 int main() {
 char *p = alloca(2 * sizeof(int));
 ; return 0; }
 EOF
-if { (eval echo configure:8857: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_header_alloca_h=yes
 else
@@ -8877,10 +8874,10 @@
 fi
 
 echo $ac_n "checking for alloca""... $ac_c" 1>&6
-echo "configure:8881: checking for alloca" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 8884 "configure"
+echo "configure:8878: checking for alloca" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 8881 "configure"
 #include "confdefs.h"
 
 #ifdef __GNUC__
@@ -8903,7 +8900,7 @@
 char *p = (char *) alloca(1);
 ; return 0; }
 EOF
-if { (eval echo configure:8907: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8904: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_func_alloca_works=yes
 else
@@ -8942,10 +8939,10 @@
 
 
 echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6
-echo "configure:8946: checking whether alloca needs Cray hooks" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 8949 "configure"
+echo "configure:8943: checking whether alloca needs Cray hooks" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 8946 "configure"
 #include "confdefs.h"
 #if defined(CRAY) && ! defined(CRAY2)
 webecray
@@ -8969,10 +8966,10 @@
 if test $ac_cv_os_cray = yes; then
 for ac_func in _getb67 GETB67 getb67; do
   echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:8973: checking for $ac_func" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 8976 "configure"
+echo "configure:8970: checking for $ac_func" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 8973 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -8995,7 +8992,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:8999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:8996: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -9025,10 +9022,10 @@
 fi
 
 echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6
-echo "configure:9029: checking stack direction for C alloca" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9032 "configure"
+echo "configure:9026: checking stack direction for C alloca" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9029 "configure"
 #include "confdefs.h"
 find_stack_direction ()
 {
@@ -9047,7 +9044,7 @@
   exit (find_stack_direction() < 0);
 }
 EOF
-if { (eval echo configure:9051: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
+if { (eval echo configure:9048: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
 then
   ac_cv_c_stack_direction=1
 else
@@ -9076,15 +9073,15 @@
 
 ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
-echo "configure:9080: checking for vfork.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9083 "configure"
+echo "configure:9077: checking for vfork.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9080 "configure"
 #include "confdefs.h"
 #include <vfork.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9088: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:9085: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9112,10 +9109,10 @@
 fi
 
 echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-echo "configure:9116: checking for working vfork" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9119 "configure"
+echo "configure:9113: checking for working vfork" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9116 "configure"
 #include "confdefs.h"
 /* Thanks to Paul Eggert for this test.  */
 #include <stdio.h>
@@ -9210,7 +9207,7 @@
   }
 }
 EOF
-if { (eval echo configure:9214: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
+if { (eval echo configure:9211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
 then
   ac_cv_func_vfork_works=yes
 else
@@ -9236,10 +9233,10 @@
 
 
 echo $ac_n "checking for working strcoll""... $ac_c" 1>&6
-echo "configure:9240: checking for working strcoll" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9243 "configure"
+echo "configure:9237: checking for working strcoll" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9240 "configure"
 #include "confdefs.h"
 #include <string.h>
 main ()
@@ -9249,7 +9246,7 @@
 	strcoll ("123", "456") >= 0);
 }
 EOF
-if { (eval echo configure:9253: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
+if { (eval echo configure:9250: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
 then
   ac_cv_func_strcoll_works=yes
 else
@@ -9277,10 +9274,10 @@
 for ac_func in getpgrp
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:9281: checking for $ac_func" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9284 "configure"
+echo "configure:9278: checking for $ac_func" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9281 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -9303,7 +9300,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:9307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:9304: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -9331,10 +9328,10 @@
 done
 
 echo $ac_n "checking whether getpgrp takes no argument""... $ac_c" 1>&6
-echo "configure:9335: checking whether getpgrp takes no argument" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9338 "configure"
+echo "configure:9332: checking whether getpgrp takes no argument" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9335 "configure"
 #include "confdefs.h"
 
 /*
@@ -9389,7 +9386,7 @@
 }
 
 EOF
-if { (eval echo configure:9393: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
+if { (eval echo configure:9390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
 then
   ac_cv_func_getpgrp_void=yes
 else
@@ -9416,10 +9413,10 @@
 
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:9420: checking for working mmap" >&5
+echo "configure:9417: checking for working mmap" >&5
 case "$opsys" in ultrix* ) have_mmap=no ;; *)
 cat > conftest.$ac_ext <<EOF
-#line 9423 "configure"
+#line 9420 "configure"
 #include "confdefs.h"
 #include <stdio.h>
 #include <unistd.h>
@@ -9452,7 +9449,7 @@
   return 1;
 }
 EOF
-if { (eval echo configure:9456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
+if { (eval echo configure:9453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
 then
   have_mmap=yes
 else
@@ -9477,15 +9474,15 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:9481: checking for $ac_hdr" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9484 "configure"
+echo "configure:9478: checking for $ac_hdr" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9481 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9489: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:9486: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9517,10 +9514,10 @@
 for ac_func in getpagesize
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:9521: checking for $ac_func" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9524 "configure"
+echo "configure:9518: checking for $ac_func" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9521 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -9543,7 +9540,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:9547: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:9544: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -9571,10 +9568,10 @@
 done
 
 echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:9575: checking for working mmap" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9578 "configure"
+echo "configure:9572: checking for working mmap" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9575 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test.
@@ -9714,7 +9711,7 @@
 }
 
 EOF
-if { (eval echo configure:9718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
+if { (eval echo configure:9715: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
 then
   ac_cv_func_mmap_fixed_mapped=yes
 else
@@ -9752,15 +9749,15 @@
 
 ac_safe=`echo "termios.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for termios.h""... $ac_c" 1>&6
-echo "configure:9756: checking for termios.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9759 "configure"
+echo "configure:9753: checking for termios.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9756 "configure"
 #include "confdefs.h"
 #include <termios.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9764: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:9761: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9803,15 +9800,15 @@
   echo "$ac_t""no" 1>&6
 ac_safe=`echo "termio.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for termio.h""... $ac_c" 1>&6
-echo "configure:9807: checking for termio.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9810 "configure"
+echo "configure:9804: checking for termio.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9807 "configure"
 #include "confdefs.h"
 #include <termio.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9815: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:9812: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9843,10 +9840,10 @@
 
 
 echo $ac_n "checking for socket""... $ac_c" 1>&6
-echo "configure:9847: checking for socket" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9850 "configure"
+echo "configure:9844: checking for socket" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9847 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char socket(); below.  */
@@ -9869,7 +9866,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:9873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:9870: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_socket=yes"
 else
@@ -9884,15 +9881,15 @@
   echo "$ac_t""yes" 1>&6
   ac_safe=`echo "netinet/in.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for netinet/in.h""... $ac_c" 1>&6
-echo "configure:9888: checking for netinet/in.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9891 "configure"
+echo "configure:9885: checking for netinet/in.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9888 "configure"
 #include "confdefs.h"
 #include <netinet/in.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9896: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:9893: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9909,15 +9906,15 @@
   echo "$ac_t""yes" 1>&6
   ac_safe=`echo "arpa/inet.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for arpa/inet.h""... $ac_c" 1>&6
-echo "configure:9913: checking for arpa/inet.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 9916 "configure"
+echo "configure:9910: checking for arpa/inet.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 9913 "configure"
 #include "confdefs.h"
 #include <arpa/inet.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:9921: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:9918: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -9942,9 +9939,9 @@
 }
 
       echo $ac_n "checking "for sun_len member in struct sockaddr_un"""... $ac_c" 1>&6
-echo "configure:9946: checking "for sun_len member in struct sockaddr_un"" >&5
+echo "configure:9943: checking "for sun_len member in struct sockaddr_un"" >&5
       cat > conftest.$ac_ext <<EOF
-#line 9948 "configure"
+#line 9945 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -9955,7 +9952,7 @@
 static struct sockaddr_un x; x.sun_len = 1;
 ; return 0; }
 EOF
-if { (eval echo configure:9959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:9956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6; { test "$extra_verbose" = "yes" && cat << \EOF
     Defining HAVE_SOCKADDR_SUN_LEN
@@ -9973,9 +9970,9 @@
 fi
 rm -f conftest*
       echo $ac_n "checking "for ip_mreq struct in netinet/in.h"""... $ac_c" 1>&6
-echo "configure:9977: checking "for ip_mreq struct in netinet/in.h"" >&5
+echo "configure:9974: checking "for ip_mreq struct in netinet/in.h"" >&5
       cat > conftest.$ac_ext <<EOF
-#line 9979 "configure"
+#line 9976 "configure"
 #include "confdefs.h"
 
 #include <sys/types.h>
@@ -9985,7 +9982,7 @@
 static struct ip_mreq x;
 ; return 0; }
 EOF
-if { (eval echo configure:9989: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:9986: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   echo "$ac_t""yes" 1>&6; { test "$extra_verbose" = "yes" && cat << \EOF
     Defining HAVE_MULTICAST
@@ -10016,10 +10013,10 @@
 
 
 echo $ac_n "checking for msgget""... $ac_c" 1>&6
-echo "configure:10020: checking for msgget" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10023 "configure"
+echo "configure:10017: checking for msgget" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10020 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char msgget(); below.  */
@@ -10042,7 +10039,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:10046: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:10043: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_msgget=yes"
 else
@@ -10057,15 +10054,15 @@
   echo "$ac_t""yes" 1>&6
   ac_safe=`echo "sys/ipc.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for sys/ipc.h""... $ac_c" 1>&6
-echo "configure:10061: checking for sys/ipc.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10064 "configure"
+echo "configure:10058: checking for sys/ipc.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10061 "configure"
 #include "confdefs.h"
 #include <sys/ipc.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10069: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10066: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10082,15 +10079,15 @@
   echo "$ac_t""yes" 1>&6
   ac_safe=`echo "sys/msg.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for sys/msg.h""... $ac_c" 1>&6
-echo "configure:10086: checking for sys/msg.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10089 "configure"
+echo "configure:10083: checking for sys/msg.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10086 "configure"
 #include "confdefs.h"
 #include <sys/msg.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10094: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10091: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10128,15 +10125,15 @@
 
 ac_safe=`echo "dirent.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for dirent.h""... $ac_c" 1>&6
-echo "configure:10132: checking for dirent.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10135 "configure"
+echo "configure:10129: checking for dirent.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10132 "configure"
 #include "confdefs.h"
 #include <dirent.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10140: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10137: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10163,15 +10160,15 @@
   echo "$ac_t""no" 1>&6
 ac_safe=`echo "sys/dir.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for sys/dir.h""... $ac_c" 1>&6
-echo "configure:10167: checking for sys/dir.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10170 "configure"
+echo "configure:10164: checking for sys/dir.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10167 "configure"
 #include "confdefs.h"
 #include <sys/dir.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10175: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10204,15 +10201,15 @@
 
 ac_safe=`echo "nlist.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for nlist.h""... $ac_c" 1>&6
-echo "configure:10208: checking for nlist.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10211 "configure"
+echo "configure:10205: checking for nlist.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10208 "configure"
 #include "confdefs.h"
 #include <nlist.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10216: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10213: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10242,7 +10239,7 @@
 
 
 echo "checking "for sound support"" 1>&6
-echo "configure:10246: checking "for sound support"" >&5
+echo "configure:10243: checking "for sound support"" >&5
 case "$with_sound" in
   native | both ) with_native_sound=yes;;
   nas    | no   ) with_native_sound=no;;
@@ -10253,15 +10250,15 @@
     if test -n "$native_sound_lib"; then
     ac_safe=`echo "multimedia/audio_device.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for multimedia/audio_device.h""... $ac_c" 1>&6
-echo "configure:10257: checking for multimedia/audio_device.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10260 "configure"
+echo "configure:10254: checking for multimedia/audio_device.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10257 "configure"
 #include "confdefs.h"
 #include <multimedia/audio_device.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10265: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10262: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10309,12 +10306,12 @@
       if test -z "$native_sound_lib"; then
         
 echo $ac_n "checking for ALopenport in -laudio""... $ac_c" 1>&6
-echo "configure:10313: checking for ALopenport in -laudio" >&5
+echo "configure:10310: checking for ALopenport in -laudio" >&5
 ac_lib_var=`echo audio'_'ALopenport | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -laudio "
 cat > conftest.$ac_ext <<EOF
-#line 10318 "configure"
+#line 10315 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10325,7 +10322,7 @@
 ALopenport()
 ; return 0; }
 EOF
-if { (eval echo configure:10329: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:10326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -10356,12 +10353,12 @@
       if test -z "$native_sound_lib"; then
 	
 echo $ac_n "checking for AOpenAudio in -lAlib""... $ac_c" 1>&6
-echo "configure:10360: checking for AOpenAudio in -lAlib" >&5
+echo "configure:10357: checking for AOpenAudio in -lAlib" >&5
 ac_lib_var=`echo Alib'_'AOpenAudio | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lAlib "
 cat > conftest.$ac_ext <<EOF
-#line 10365 "configure"
+#line 10362 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10372,7 +10369,7 @@
 AOpenAudio()
 ; return 0; }
 EOF
-if { (eval echo configure:10376: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:10373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -10410,15 +10407,15 @@
     for dir in "machine" "sys" "linux"; do
       ac_safe=`echo "${dir}/soundcard.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for ${dir}/soundcard.h""... $ac_c" 1>&6
-echo "configure:10414: checking for ${dir}/soundcard.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10417 "configure"
+echo "configure:10411: checking for ${dir}/soundcard.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10414 "configure"
 #include "confdefs.h"
 #include <${dir}/soundcard.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10422: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10419: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10488,7 +10485,7 @@
  fi
   libs_x="-laudio $libs_x" &&  if test "$extra_verbose" = "yes"; then echo "    Prepending \"-laudio\" to \$libs_x"; fi
       cat > conftest.$ac_ext <<EOF
-#line 10492 "configure"
+#line 10489 "configure"
 #include "confdefs.h"
 #include <audio/Xtutil.h>
 EOF
@@ -10515,7 +10512,7 @@
 
 if test "$with_tty" = "yes"  ; then
   echo "checking for TTY-related features" 1>&6
-echo "configure:10519: checking for TTY-related features" >&5
+echo "configure:10516: checking for TTY-related features" >&5
   { test "$extra_verbose" = "yes" && cat << \EOF
     Defining HAVE_TTY
 EOF
@@ -10531,12 +10528,12 @@
     if test -z "$with_ncurses"; then
     
 echo $ac_n "checking for tgetent in -lncurses""... $ac_c" 1>&6
-echo "configure:10535: checking for tgetent in -lncurses" >&5
+echo "configure:10532: checking for tgetent in -lncurses" >&5
 ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lncurses "
 cat > conftest.$ac_ext <<EOF
-#line 10540 "configure"
+#line 10537 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10547,7 +10544,7 @@
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:10551: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:10548: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -10580,15 +10577,15 @@
 
     ac_safe=`echo "ncurses/curses.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for ncurses/curses.h""... $ac_c" 1>&6
-echo "configure:10584: checking for ncurses/curses.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10587 "configure"
+echo "configure:10581: checking for ncurses/curses.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10584 "configure"
 #include "confdefs.h"
 #include <ncurses/curses.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10592: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10589: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10610,15 +10607,15 @@
 
     ac_safe=`echo "ncurses/term.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for ncurses/term.h""... $ac_c" 1>&6
-echo "configure:10614: checking for ncurses/term.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10617 "configure"
+echo "configure:10611: checking for ncurses/term.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10614 "configure"
 #include "confdefs.h"
 #include <ncurses/term.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10622: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10619: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10648,15 +10645,15 @@
       c_switch_site="$c_switch_site -I/usr/include/ncurses"
       ac_safe=`echo "ncurses/curses.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for ncurses/curses.h""... $ac_c" 1>&6
-echo "configure:10652: checking for ncurses/curses.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10655 "configure"
+echo "configure:10649: checking for ncurses/curses.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10652 "configure"
 #include "confdefs.h"
 #include <ncurses/curses.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10660: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10657: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10691,12 +10688,12 @@
 	for lib in curses termlib termcap; do
 	  
 echo $ac_n "checking for tgetent in -l$lib""... $ac_c" 1>&6
-echo "configure:10695: checking for tgetent in -l$lib" >&5
+echo "configure:10692: checking for tgetent in -l$lib" >&5
 ac_lib_var=`echo $lib'_'tgetent | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -l$lib "
 cat > conftest.$ac_ext <<EOF
-#line 10700 "configure"
+#line 10697 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10707,7 +10704,7 @@
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:10711: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:10708: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -10738,12 +10735,12 @@
       else
 	
 echo $ac_n "checking for tgetent in -lcurses""... $ac_c" 1>&6
-echo "configure:10742: checking for tgetent in -lcurses" >&5
+echo "configure:10739: checking for tgetent in -lcurses" >&5
 ac_lib_var=`echo curses'_'tgetent | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lcurses "
 cat > conftest.$ac_ext <<EOF
-#line 10747 "configure"
+#line 10744 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10754,7 +10751,7 @@
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:10758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:10755: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -10772,12 +10769,12 @@
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6
-echo "configure:10776: checking for tgetent in -ltermcap" >&5
+echo "configure:10773: checking for tgetent in -ltermcap" >&5
 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -ltermcap "
 cat > conftest.$ac_ext <<EOF
-#line 10781 "configure"
+#line 10778 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10788,7 +10785,7 @@
 tgetent()
 ; return 0; }
 EOF
-if { (eval echo configure:10792: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:10789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -10836,15 +10833,15 @@
 
     test -z "$with_gpm" && { ac_safe=`echo "gpm.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for gpm.h""... $ac_c" 1>&6
-echo "configure:10840: checking for gpm.h" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10843 "configure"
+echo "configure:10837: checking for gpm.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10840 "configure"
 #include "confdefs.h"
 #include <gpm.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10848: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10845: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10867,12 +10864,12 @@
  }
   test -z "$with_gpm" && { 
 echo $ac_n "checking for Gpm_Open in -lgpm""... $ac_c" 1>&6
-echo "configure:10871: checking for Gpm_Open in -lgpm" >&5
+echo "configure:10868: checking for Gpm_Open in -lgpm" >&5
 ac_lib_var=`echo gpm'_'Gpm_Open | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lgpm "
 cat > conftest.$ac_ext <<EOF
-#line 10876 "configure"
+#line 10873 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10883,7 +10880,7 @@
 Gpm_Open()
 ; return 0; }
 EOF
-if { (eval echo configure:10887: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:10884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -10931,23 +10928,22 @@
  fi
 
 
-echo "checking for database support" 1>&6
-echo "configure:10936: checking for database support" >&5
-
-if test "$with_database_gnudbm" != "no"; then
-  for ac_hdr in ndbm.h
-do
-ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
-echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:10943: checking for $ac_hdr" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 10946 "configure"
-#include "confdefs.h"
-#include <$ac_hdr>
+test "$with_database_gnudbm $with_database_dbm $with_database_berkdb" \
+  != "no no no" && echo "checking for database support" 1>&6
+echo "configure:10934: checking for database support" >&5
+
+if test "$with_database_gnudbm $with_database_dbm" != "no no"; then
+  ac_safe=`echo "ndbm.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for ndbm.h""... $ac_c" 1>&6
+echo "configure:10939: checking for ndbm.h" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 10942 "configure"
+#include "confdefs.h"
+#include <ndbm.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:10951: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:10947: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -10962,29 +10958,27 @@
 rm -f conftest*
 if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
-  { test "$extra_verbose" = "yes" && cat << EOF
-    Defining $ac_tr_hdr
-EOF
-cat >> confdefs.h <<EOF
-#define $ac_tr_hdr 1
-EOF
-}
- have_ndbm_h=yes
-else
-  echo "$ac_t""no" 1>&6
-fi
-done
-
-  if test "$have_ndbm_h" = "yes"; then
-    
+  :
+else
+  echo "$ac_t""no" 1>&6
+
+    test "$with_database_gnudbm" = "yes" -o \
+         "$with_database_dbm"    = "yes" && \
+      { echo "Error:" "Required DBM support cannot be provided." >&2; exit 1; }
+    with_database_gnudbm=no with_database_dbm=no
+fi
+
+fi
+
+if test "$with_database_gnudbm" != "no"; then
+  
 echo $ac_n "checking for dbm_open in -lgdbm""... $ac_c" 1>&6
-echo "configure:10983: checking for dbm_open in -lgdbm" >&5
+echo "configure:10977: checking for dbm_open in -lgdbm" >&5
 ac_lib_var=`echo gdbm'_'dbm_open | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lgdbm "
 cat > conftest.$ac_ext <<EOF
-#line 10988 "configure"
+#line 10982 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -10995,7 +10989,7 @@
 dbm_open()
 ; return 0; }
 EOF
-if { (eval echo configure:10999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:10993: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11009,81 +11003,24 @@
 
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes" ; then
   echo "$ac_t""yes" 1>&6
-  with_database_gnudbm=yes have_libgdbm=yes
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-
-  fi
-  if test "$with_database_gnudbm" != "yes"; then
-    echo $ac_n "checking for dbm_open""... $ac_c" 1>&6
-echo "configure:11022: checking for dbm_open" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 11025 "configure"
-#include "confdefs.h"
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char dbm_open(); below.  */
-#include <assert.h>
-/* Override any gcc2 internal prototype to avoid an error.  */
-/* We use char because int might match the return type of a gcc2
-    builtin and then its argument prototype would still apply.  */
-char dbm_open();
-
-int main() {
-
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined (__stub_dbm_open) || defined (__stub___dbm_open)
-choke me
-#else
-dbm_open();
-#endif
-
-; return 0; }
-EOF
-if { (eval echo configure:11048: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
-  rm -rf conftest*
-  eval "ac_cv_func_dbm_open=yes"
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -rf conftest*
-  eval "ac_cv_func_dbm_open=no"
-fi
-rm -f conftest*
-
-if eval "test \"`echo '$ac_cv_func_'dbm_open`\" = yes"; then
-  echo "$ac_t""yes" 1>&6
-  with_database_gnudbm=yes
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-      fi
-  if test "$with_database_gnudbm" = "yes"; then
-    { test "$extra_verbose" = "yes" && cat << \EOF
-    Defining HAVE_DBM
-EOF
-cat >> confdefs.h <<\EOF
-#define HAVE_DBM 1
-EOF
-}
-
-    test "$have_libgdbm" = "yes" && LIBS="-lgdbm $LIBS" &&  if test "$extra_verbose" = "yes"; then echo "    Prepending \"-lgdbm\" to \$LIBS"; fi
-    with_database_dbm=no
-  else with_database_gnudbm=no
-  fi
+  with_database_gnudbm=yes with_database_dbm=no libdbm=-lgdbm
+else
+  echo "$ac_t""no" 1>&6
+if test "$with_database_gnudbm" = "yes"; then
+     { echo "Error:" "Required GNU DBM support cannot be provided." >&2; exit 1; }
+   fi
+   with_database_gnudbm=no
+fi
+
+
 fi
 
 if test "$with_database_dbm" != "no"; then
   echo $ac_n "checking for dbm_open""... $ac_c" 1>&6
-echo "configure:11084: checking for dbm_open" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 11087 "configure"
+echo "configure:11021: checking for dbm_open" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 11024 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char dbm_open(); below.  */
@@ -11106,7 +11043,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:11110: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11047: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_dbm_open=yes"
 else
@@ -11119,20 +11056,18 @@
 
 if eval "test \"`echo '$ac_cv_func_'dbm_open`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-  with_database_dbm=yes need_libdbm=no
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-  if test "$need_libdbm" != "no"; then
+  with_database_dbm=yes libdbm=
+else
+  echo "$ac_t""no" 1>&6
+
     
 echo $ac_n "checking for dbm_open in -ldbm""... $ac_c" 1>&6
-echo "configure:11131: checking for dbm_open in -ldbm" >&5
+echo "configure:11066: checking for dbm_open in -ldbm" >&5
 ac_lib_var=`echo dbm'_'dbm_open | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -ldbm "
 cat > conftest.$ac_ext <<EOF
-#line 11136 "configure"
+#line 11071 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11143,7 +11078,7 @@
 dbm_open()
 ; return 0; }
 EOF
-if { (eval echo configure:11147: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11157,15 +11092,23 @@
 
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes" ; then
   echo "$ac_t""yes" 1>&6
-  with_database_dbm=yes need_libdbm=yes
-else
-  echo "$ac_t""no" 1>&6
-fi
-
-
-  fi
-  if test "$with_database_dbm" = "yes"; then
-    { test "$extra_verbose" = "yes" && cat << \EOF
+  with_database_dbm=yes libdbm=-ldbm
+else
+  echo "$ac_t""no" 1>&6
+test "$with_database_dbm" = "yes" && \
+        { echo "Error:" "Required DBM support cannot be provided." >&2; exit 1; }
+      with_database_dbm=no
+fi
+
+
+fi
+
+fi
+
+test -n "$libdbm" && LIBS=""$libdbm" $LIBS" &&  if test "$extra_verbose" = "yes"; then echo "    Prepending \""$libdbm"\" to \$LIBS"; fi
+test "$with_database_gnudbm" = "yes" -o \
+     "$with_database_dbm"    = "yes" && \
+  { test "$extra_verbose" = "yes" && cat << \EOF
     Defining HAVE_DBM
 EOF
 cat >> confdefs.h <<\EOF
@@ -11173,17 +11116,13 @@
 EOF
 }
 
-    test "$need_libdbm" = "yes" && LIBS="-ldbm $LIBS" &&  if test "$extra_verbose" = "yes"; then echo "    Prepending \"-ldbm\" to \$LIBS"; fi
-  else with_database_dbm=no
-  fi
-fi
 
 if test "$with_database_berkdb" != "no"; then
   echo $ac_n "checking for Berkeley db.h""... $ac_c" 1>&6
-echo "configure:11184: checking for Berkeley db.h" >&5
+echo "configure:11123: checking for Berkeley db.h" >&5
   for path in "db/db.h" "db.h"; do
     cat > conftest.$ac_ext <<EOF
-#line 11187 "configure"
+#line 11126 "configure"
 #include "confdefs.h"
 #ifdef HAVE_INTTYPES_H
 #define __BIT_TYPES_DEFINED__
@@ -11201,7 +11140,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:11205: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:11144: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   db_h_path="$path"; break
 else
@@ -11217,9 +11156,9 @@
 
   if test "$with_database_berkdb" != "no"; then
     echo $ac_n "checking for Berkeley DB version""... $ac_c" 1>&6
-echo "configure:11221: checking for Berkeley DB version" >&5
+echo "configure:11160: checking for Berkeley DB version" >&5
     cat > conftest.$ac_ext <<EOF
-#line 11223 "configure"
+#line 11162 "configure"
 #include "confdefs.h"
 #include <$db_h_path>
 #if DB_VERSION_MAJOR > 1
@@ -11238,10 +11177,10 @@
 rm -f conftest*
 
     echo $ac_n "checking for $dbfunc""... $ac_c" 1>&6
-echo "configure:11242: checking for $dbfunc" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 11245 "configure"
+echo "configure:11181: checking for $dbfunc" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 11184 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $dbfunc(); below.  */
@@ -11264,7 +11203,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:11268: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11207: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$dbfunc=yes"
 else
@@ -11283,12 +11222,12 @@
 
     
 echo $ac_n "checking for $dbfunc in -ldb""... $ac_c" 1>&6
-echo "configure:11287: checking for $dbfunc in -ldb" >&5
+echo "configure:11226: checking for $dbfunc in -ldb" >&5
 ac_lib_var=`echo db'_'$dbfunc | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -ldb "
 cat > conftest.$ac_ext <<EOF
-#line 11292 "configure"
+#line 11231 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11299,7 +11238,7 @@
 $dbfunc()
 ; return 0; }
 EOF
-if { (eval echo configure:11303: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11242: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11363,12 +11302,12 @@
 if test "$with_socks" = "yes"; then
   
 echo $ac_n "checking for SOCKSinit in -lsocks""... $ac_c" 1>&6
-echo "configure:11367: checking for SOCKSinit in -lsocks" >&5
+echo "configure:11306: checking for SOCKSinit in -lsocks" >&5
 ac_lib_var=`echo socks'_'SOCKSinit | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lsocks "
 cat > conftest.$ac_ext <<EOF
-#line 11372 "configure"
+#line 11311 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11379,7 +11318,7 @@
 SOCKSinit()
 ; return 0; }
 EOF
-if { (eval echo configure:11383: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11322: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11438,15 +11377,15 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:11442: checking for $ac_hdr" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 11445 "configure"
+echo "configure:11381: checking for $ac_hdr" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 11384 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:11450: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:11389: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -11477,12 +11416,12 @@
 
 test -z "$with_shlib" && test ! -z "$have_dlfcn" && { 
 echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:11481: checking for dlopen in -ldl" >&5
+echo "configure:11420: checking for dlopen in -ldl" >&5
 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -ldl "
 cat > conftest.$ac_ext <<EOF
-#line 11486 "configure"
+#line 11425 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11493,7 +11432,7 @@
 dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:11497: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11436: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11522,12 +11461,12 @@
  }
 test -z "$with_shlib" && test ! -z "$have_dlfcn" && { 
 echo $ac_n "checking for _dlopen in -lc""... $ac_c" 1>&6
-echo "configure:11526: checking for _dlopen in -lc" >&5
+echo "configure:11465: checking for _dlopen in -lc" >&5
 ac_lib_var=`echo c'_'_dlopen | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lc "
 cat > conftest.$ac_ext <<EOF
-#line 11531 "configure"
+#line 11470 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11538,7 +11477,7 @@
 _dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:11542: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11567,12 +11506,12 @@
  }
 test -z "$with_shlib" && test ! -z "$have_dlfcn" && { 
 echo $ac_n "checking for dlopen in -lc""... $ac_c" 1>&6
-echo "configure:11571: checking for dlopen in -lc" >&5
+echo "configure:11510: checking for dlopen in -lc" >&5
 ac_lib_var=`echo c'_'dlopen | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -lc "
 cat > conftest.$ac_ext <<EOF
-#line 11576 "configure"
+#line 11515 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11583,7 +11522,7 @@
 dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:11587: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11526: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11612,12 +11551,12 @@
  }
 test -z "$with_shlib" && { 
 echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
-echo "configure:11616: checking for shl_load in -ldld" >&5
+echo "configure:11555: checking for shl_load in -ldld" >&5
 ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -ldld "
 cat > conftest.$ac_ext <<EOF
-#line 11621 "configure"
+#line 11560 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11628,7 +11567,7 @@
 shl_load()
 ; return 0; }
 EOF
-if { (eval echo configure:11632: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11571: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11657,12 +11596,12 @@
  }
 test -z "$with_shlib" && { 
 echo $ac_n "checking for dld_init in -ldld""... $ac_c" 1>&6
-echo "configure:11661: checking for dld_init in -ldld" >&5
+echo "configure:11600: checking for dld_init in -ldld" >&5
 ac_lib_var=`echo dld'_'dld_init | sed 'y%./+-%__p_%'`
 
 xe_check_libs=" -ldld "
 cat > conftest.$ac_ext <<EOF
-#line 11666 "configure"
+#line 11605 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -11673,7 +11612,7 @@
 dld_init()
 ; return 0; }
 EOF
-if { (eval echo configure:11677: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11616: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -11723,7 +11662,7 @@
 dll_oflags="-o "
 
 echo $ac_n "checking how to build a shared library""... $ac_c" 1>&6
-echo "configure:11727: checking how to build a shared library" >&5
+echo "configure:11666: checking how to build a shared library" >&5
 case `uname -rs` in
 	UNIX_SV*|UNIX_System_V*)
 		dll_lflags="-G"
@@ -11814,10 +11753,10 @@
   for ac_func in dlerror
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:11818: checking for $ac_func" >&5
-
-cat > conftest.$ac_ext <<EOF
-#line 11821 "configure"
+echo "configure:11757: checking for $ac_func" >&5
+
+cat > conftest.$ac_ext <<EOF
+#line 11760 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -11840,7 +11779,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:11844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:11783: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -11876,11 +11815,11 @@
 fi
 
 cat > conftest.$ac_ext <<EOF
-#line 11880 "configure"
+#line 11819 "configure"
 #include "confdefs.h"
 int main(int c,char *v[]){return 0;}
 EOF
-if { (eval echo configure:11884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
+if { (eval echo configure:11823: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit $?) 2>&5
 then
   :
 else
@@ -11990,7 +11929,7 @@
   esac
   
 T=""
-for W in $SUBDIR_MAKEFILES $dir/Makefile; do if test -z "$T"; then T="$W"; else T="$T $W"; fi; done
+for W in $SUBDIR_MAKEFILES $dir/Makefile $dir/GNUmakefile; do if test -z "$T"; then T="$W"; else T="$T $W"; fi; done
 SUBDIR_MAKEFILES="$T"
 
   
--- a/configure.in	Mon Aug 13 11:07:40 2007 +0200
+++ b/configure.in	Mon Aug 13 11:08:24 2007 +0200
@@ -230,7 +230,7 @@
  if test "$extra_verbose" = "yes"; then echo "    Prepending \"[$1]\" to \$[$2]"; fi])
 
 dnl XE_DIE(message)
-define([XE_DIE], [{ echo $1 >&2; exit 1; }])
+define([XE_DIE], [{ echo "Error:" $1 >&2; exit 1; }])
 
 dnl XE_STRIP_4TH_COMPONENT(var)
 dnl Changes i986-pc-linux-gnu to i986-pc-linux, as God (not RMS) intended.
@@ -2483,7 +2483,7 @@
     with_file_coding=yes
     use_minimal_tagbits=yes
     use_indexed_lrecord_implementation=yes
-    XE_ADD_OBJS(console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o glyphs-msw.o)
+    XE_ADD_OBJS(console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o glyphs-msw.o gui-msw.o)
   fi
 fi
 
@@ -2922,7 +2922,6 @@
 test "$with_scrollbars" != "no"      && XE_ADD_OBJS(scrollbar.o)
 test "$with_dialogs"    != "no"      && XE_ADD_OBJS(dialog.o)
 test "$with_toolbars"   != "no"      && XE_ADD_OBJS(toolbar.o)
-test "$all_widgets" != "no no no no" && XE_ADD_OBJS(gui.o)
 
 if test "$with_x11" = "yes"; then
   test "$with_menubars"   != "no"      && XE_ADD_OBJS(menubar-x.o)
@@ -3485,45 +3484,48 @@
 test "$with_x11" = "yes" -o "$with_tty" = "yes" && XE_ADD_OBJS(event-unixoid.o)
 
 dnl Database support
-dnl <mdiers@logware.de>
 dnl We do not necessarily have to have libdb/lib(g)dbm for DB/(G)DBM support.
 dnl On FreeBSD, both DB and DBM are part of libc.
-dnl Note that unless support for DB/(G)DBM is explicitly disabled, we always
-dnl want to check for libdb/lib(g)dbm. Also note that libc will not be
-dnl checked if we have the libraries.
-dnl If support for DB/(G)DBM is requested, but we neither have libdb/lib(g)dbm,
-dnl nor does libc implement it, we are a bit lost :)
-
-AC_CHECKING(for database support)
-
+dnl By default, we check for DBM support in libgdbm, then libc, then libdbm.
+
+test "$with_database_gnudbm $with_database_dbm $with_database_berkdb" \
+  != "no no no" && AC_CHECKING(for database support)
+
+dnl Check for ndbm.h, required for either kind of DBM support.
+if test "$with_database_gnudbm $with_database_dbm" != "no no"; then
+  AC_CHECK_HEADER(ndbm.h, [:], [
+    test "$with_database_gnudbm" = "yes" -o \
+         "$with_database_dbm"    = "yes" && \
+      XE_DIE("Required DBM support cannot be provided.")
+    with_database_gnudbm=no with_database_dbm=no])
+fi
+
+dnl Check for DBM support in libgdbm.
 if test "$with_database_gnudbm" != "no"; then
-  AC_CHECK_HEADERS(ndbm.h, have_ndbm_h=yes)
-  if test "$have_ndbm_h" = "yes"; then
-    AC_CHECK_LIB(gdbm, dbm_open, with_database_gnudbm=yes have_libgdbm=yes)
-  fi
-  if test "$with_database_gnudbm" != "yes"; then
-    AC_CHECK_FUNC(dbm_open, with_database_gnudbm=yes)
-      fi
-  if test "$with_database_gnudbm" = "yes"; then
-    AC_DEFINE(HAVE_DBM)
-    test "$have_libgdbm" = "yes" && XE_PREPEND(-lgdbm, LIBS)
-    with_database_dbm=no
-  else with_database_gnudbm=no
-  fi
+  AC_CHECK_LIB(gdbm, dbm_open, [
+   with_database_gnudbm=yes with_database_dbm=no libdbm=-lgdbm], [
+   if test "$with_database_gnudbm" = "yes"; then
+     XE_DIE("Required GNU DBM support cannot be provided.")
+   fi
+   with_database_gnudbm=no])
 fi
 
+dnl Check for DBM support in libc and libdbm.
 if test "$with_database_dbm" != "no"; then
-  AC_CHECK_FUNC(dbm_open, with_database_dbm=yes need_libdbm=no)
-  if test "$need_libdbm" != "no"; then
-    AC_CHECK_LIB(dbm, dbm_open, with_database_dbm=yes need_libdbm=yes)
-  fi
-  if test "$with_database_dbm" = "yes"; then
-    AC_DEFINE(HAVE_DBM)
-    test "$need_libdbm" = "yes" && XE_PREPEND(-ldbm, LIBS)
-  else with_database_dbm=no
-  fi
+  AC_CHECK_FUNC(dbm_open, [with_database_dbm=yes libdbm=], [
+    AC_CHECK_LIB(dbm, dbm_open, [with_database_dbm=yes libdbm=-ldbm], [
+      test "$with_database_dbm" = "yes" && \
+        XE_DIE("Required DBM support cannot be provided.")
+      with_database_dbm=no])])
 fi
 
+dnl Tell make about the DBM support we detected.
+test -n "$libdbm" && XE_PREPEND("$libdbm", LIBS)
+test "$with_database_gnudbm" = "yes" -o \
+     "$with_database_dbm"    = "yes" && \
+  AC_DEFINE(HAVE_DBM)
+
+dnl Check for Berkeley DB.
 if test "$with_database_berkdb" != "no"; then
   AC_MSG_CHECKING(for Berkeley db.h)
   for path in "db/db.h" "db.h"; do
--- a/etc/NEWS	Mon Aug 13 11:07:40 2007 +0200
+++ b/etc/NEWS	Mon Aug 13 11:08:24 2007 +0200
@@ -502,6 +502,8 @@
 been tested:
   - LDAP 3.3 from the University of Michigan
     (get it from <URL:http://www.umich.edu/~dirsvcs/ldap/>)
+  - OpenLDAP 1.0.3 from the OpenLDAP Foundation
+    (get it from <URL:http://www.openldap.org/>)
   - LDAP SDK 1.0 from Netscape Corp.
     (get it from <URL:http://developer.netscape.com/>)
 
--- a/etc/sample.emacs	Mon Aug 13 11:07:40 2007 +0200
+++ b/etc/sample.emacs	Mon Aug 13 11:08:24 2007 +0200
@@ -173,9 +173,9 @@
 	      (set-glyph-image modeline-pointer-glyph "leftbutton")
 
 	      ;; Change the continuation glyph face so it stands out more
-	      (and (fboundp 'set-glyph-property)
+	      (and (fboundp 'make-face-bold)
 		   (boundp 'continuation-glyph)
-		   (set-glyph-property continuation-glyph 'face 'bold))
+		   (make-face-bold (glyph-face continuation-glyph)))
 
 	      ;; Change the pointer used during garbage collection.
 	      ;;
--- a/lib-src/ChangeLog	Mon Aug 13 11:07:40 2007 +0200
+++ b/lib-src/ChangeLog	Mon Aug 13 11:08:24 2007 +0200
@@ -1,3 +1,16 @@
+1998-12-24  Martin Buchholz <martin@xemacs.org>
+
+	* XEmacs 21.2.7 is released.
+
+1998-12-17  Andy Piper  <andy@xemacs.org>
+
+	* pop.c (pop_open): disable use of getpass() which doesn't exist under NT.
+
+	* movemail.c: mess with includes so that it builds under native NT.
+
+	* pop.c: mess with includes so that it builds under native NT.
+	From Fabrice Popineau <popineau@ese-metz.fr>
+	
 1998-12-16  Andy Piper  <andy@xemacs.org>
 
 	* XEmacs 21.2.6 is released
--- a/lib-src/movemail.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/lib-src/movemail.c	Mon Aug 13 11:08:24 2007 +0200
@@ -55,14 +55,18 @@
  */
 
 #define NO_SHORTNAMES   /* Tell config not to load remap.h */
+#define DONT_ENCAPSULATE
 #include <../src/config.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/file.h>
 #include <stdio.h>
 #include <errno.h>
+#include "../src/sysfile.h"
 #include "../src/syswait.h"
+#ifndef WINDOWSNT
 #include "../src/systime.h"
+#endif
 #include <stdlib.h>
 #include <string.h>
 #include "getopt.h"
@@ -305,7 +309,9 @@
       exit (retcode);
     }
 
+#ifndef WINDOWSNT
   setuid (getuid ());
+#endif
 #endif /* MAIL_USE_POP */
 
 #ifndef DISABLE_DIRECT_ACCESS
@@ -632,7 +638,7 @@
       error ("Error in open: %s, %s", strerror (errno), outfile);
       return (1);
     }
-#ifndef __CYGWIN32__
+#if !defined(__CYGWIN32__) && !defined(WINDOWSNT)
   fchown (mbfi, getuid (), -1);
 #endif
 
--- a/lib-src/pop.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/lib-src/pop.c	Mon Aug 13 11:08:24 2007 +0200
@@ -38,7 +38,6 @@
 
 #include <sys/types.h>
 #ifdef WINDOWSNT
-#include "ntlib.h"
 #include <winsock.h>
 #undef SOCKET_ERROR
 #define RECV(s,buf,len,flags) recv(s,buf,len,flags)
@@ -77,7 +76,9 @@
 #include <sys/stat.h>
 #include <sys/file.h>
 #include "../src/syswait.h"
+#ifndef WINDOWSNT
 #include "../src/systime.h"
+#endif
 #include <stdlib.h>
 #include <string.h>
 
@@ -183,6 +184,7 @@
       username = getenv ("USER");
       if (! (username && *username))
 	{
+#ifndef WINDOWSNT
 	  username = getlogin ();
 	  if (! (username && *username))
 	    {
@@ -198,6 +200,10 @@
 		  return (0);
 		}
 	    }
+#else
+	  strcpy (pop_error, "Could not determine username");
+	  return (0);
+#endif
 	}
     }
 
@@ -247,10 +253,12 @@
  
   if ((! password) && (! DONT_NEED_PASSWORD))
     {
+#ifndef WINDOWSNT
       if (! (flags & POP_NO_GETPASS))
 	{
 	  password = getpass ("Enter POP password:");
 	}
+#endif
       if (! password)
 	{
 	  strcpy (pop_error, "Could not determine POP password");
--- a/lisp/ChangeLog	Mon Aug 13 11:07:40 2007 +0200
+++ b/lisp/ChangeLog	Mon Aug 13 11:08:24 2007 +0200
@@ -1,3 +1,46 @@
+1998-12-24  Martin Buchholz <martin@xemacs.org>
+
+	* XEmacs 21.2.7 is released.
+
+1998-12-07  Jan Vroonhof  <vroonhof@math.ethz.ch>
+
+	* package-ui.el (pui-list-packages): Set truncate-lines.
+
+	* package-get.el (package-get-download-menu): Use
+	`package-ui-add-site'. Add a a toggle to indicate it is in the list.
+
+	* package-ui.el (pui-help): Ditch in favor of `describe-mode'
+	(pui-help-string): idem.
+	(list-packages-mode): New major mode.
+	(pui-list-packages): Use 'list-packages-mode' in the package buffer.
+	(pui-install-selected-packages): Add suport for removing packages.
+	(pui-toggle-package-delete-key): New function.
+	(pui-popup-context-sensitive): New kludge.
+	(pui-list-packages): Add warning when `package-get-remote' is nil.
+	(package-ui-add-site): New function.
+
+1998-12-01  Didier Verna  <verna@inf.enst.fr>
+
+	* hyper-apropos.el (hyper-where-is): added the missing autoload.
+
+1998-11-29  Oscar Figueiredo  <Oscar.Figueiredo@di.epfl.ch>
+
+	* ldap.el: Custom-ized
+	(toplevel): Do not provide `ldap' which is provided by C level
+	LDAP code
+	(ldap-search): Docstring and stylistic fixes as suggested by Hrvoje
+
+1998-12-05  Hrvoje Niksic  <hniksic@srce.hr>
+
+	* isearch-mode.el (isearch-mode): Really fix keymap lossage.
+
+1998-12-17  Andy Piper  <andy@xemacs.org>
+
+	* sound.el (sound-load-list): name changed from sound-load-alist.
+	(sound-extension-list): name changed from sound-ext-list.
+	(load-default-sounds): use new names.
+	(load-sound-file): use new names.
+
 1998-12-16  Andy Piper  <andy@xemacs.org>
 
 	* XEmacs 21.2.6 is released
--- a/lisp/glyphs.el	Mon Aug 13 11:07:40 2007 +0200
+++ b/lisp/glyphs.el	Mon Aug 13 11:08:24 2007 +0200
@@ -603,6 +603,10 @@
 ;;; (defvar x-toolbar-pointer-shape nil)
 (define-obsolete-pointer-glyph 'x-toolbar-pointer-shape 'toolbar-pointer-glyph)
 
+;; for subwindows
+(defalias 'subwindow-xid 'image-instance-subwindow-id)
+(defalias 'subwindow-width 'image-instance-width)
+(defalias 'subwindow-height 'image-instance-height)
 ;;;;;;;;;; initialization
 
 (defun init-glyphs ()
--- a/lisp/hyper-apropos.el	Mon Aug 13 11:07:40 2007 +0200
+++ b/lisp/hyper-apropos.el	Mon Aug 13 11:08:24 2007 +0200
@@ -481,6 +481,7 @@
 	(setq hyper-apropos-prev-wconfig (current-window-configuration)))
     (hyper-apropos-get-doc symbol t nil this-ref-buffer)))
 
+;;;###autoload
 (defun hyper-where-is (symbol)
   "Print message listing key sequences that invoke specified command."
   (interactive (list (hyper-apropos-read-function-symbol "Where is function")))
--- a/lisp/isearch-mode.el	Mon Aug 13 11:07:40 2007 +0200
+++ b/lisp/isearch-mode.el	Mon Aug 13 11:08:24 2007 +0200
@@ -455,15 +455,16 @@
 
 	  ;; #### Should we remember the old value of
 	  ;; overriding-local-map?
-	  overriding-local-map isearch-mode-map
+ 	  overriding-local-map (progn
+ 				 (set-keymap-parents isearch-mode-map
+ 				  (nconc (current-minor-mode-maps)
+					 (and (current-local-map)
+					      (list (current-local-map)))))
+ 				 isearch-mode-map)
 	  isearch-selected-frame (selected-frame)
 
 	  isearch-mode (gettext " Isearch")
 	  )
-    (let ((map (append (current-minor-mode-maps)
-		       (list (current-local-map)))))
-      (if (keymapp map)
-	  (set-keymap-parents isearch-mode-map map)))
 
     ;; XEmacs change: without clearing the match data, sometimes old values
     ;; of isearch-other-end get used.  Don't ask me why...
--- a/lisp/ldap.el	Mon Aug 13 11:07:40 2007 +0200
+++ b/lisp/ldap.el	Mon Aug 13 11:08:24 2007 +0200
@@ -5,7 +5,7 @@
 ;; Author: Oscar Figueiredo <Oscar.Figueiredo@di.epfl.ch>
 ;; Maintainer: Oscar Figueiredo <Oscar.Figueiredo@di.epfl.ch>
 ;; Created: Jan 1998
-;; Version: $Revision: 1.7.2.1 $
+;; Version: $Revision: 1.7.2.2 $
 ;; Keywords: help comm
 
 ;; This file is part of XEmacs
@@ -35,17 +35,42 @@
 
 ;;; Code:
 
-(eval-when '(load eval)
-  (require 'ldap))
+(require 'ldap)
+(require 'custom)
 
-(defvar ldap-default-host nil
-  "*Default LDAP server.")
+(defgroup ldap nil
+  "Lightweight Directory Access Protocol"
+  :group 'comm)
+
+(defcustom ldap-default-host nil
+  "*Default LDAP server."
+  :type '(choice (string :tag "Host name")
+		 (const :tag "Use library default" nil))
+  :group 'ldap)
 
-(defvar ldap-host-parameters-alist nil
-  "*An alist of per host options for LDAP transactions
-The list elements look like (HOST PROP1 VAL1 PROP2 VAL2 ...)
-HOST is the name of an LDAP server. PROPn and VALn are property/value pairs
-describing parameters for the server.  Valid properties: 
+(defcustom ldap-default-port nil
+  "*Default TCP port for LDAP connections.
+Initialized from the LDAP library at build time. Default value is 389."
+  :type '(choice (const :tag "Use library default" nil)
+		 (integer :tag "Port number"))
+  :group 'ldap)
+
+(defcustom ldap-default-base nil
+  "*Default base for LDAP searches.
+This is a string using the syntax of RFC 1779.
+For instance, \"o=ACME, c=US\" limits the search to the
+Acme organization in the United States."
+  :type '(choice (const :tag "Use library default" nil)
+		 (string :tag "Search base"))
+  :group 'ldap)
+
+
+(defcustom ldap-host-parameters-alist nil
+  "*Alist of host-specific options for LDAP transactions.
+The format of each list element is:
+\(HOST PROP1 VAL1 PROP2 VAL2 ...)
+HOST is the name of an LDAP server. PROPn and VALn are property/value 
+pairs describing parameters for the server.  Valid properties include: 
   `binddn' is the distinguished name of the user to bind as 
     (in RFC 1779 syntax).
   `passwd' is the password to use for simple authentication.
@@ -55,39 +80,95 @@
   `scope' is one of the three symbols `subtree', `base' or `onelevel'.
   `deref' is one of the symbols `never', `always', `search' or `find'.
   `timelimit' is the timeout limit for the connection in seconds.
-  `sizelimit' is the maximum number of matches to return." )
+  `sizelimit' is the maximum number of matches to return."
+  :type '(repeat :menu-tag "Host parameters"
+		 :tag "Host parameters"
+		 (list :menu-tag "Host parameters"
+		       :tag "Host parameters"
+		       :value nil
+		       (string :tag "Host name")
+		       (checklist :inline t
+				  :greedy t
+				  (list
+				   :tag "Binding DN"
+				   :inline t
+				   (const :tag "Binding DN" binddn)
+				   string)
+				  (list
+				   :tag "Password"
+				   :inline t
+				   (const :tag "Password" passwd)
+				   string)
+				  (list
+				   :tag "Authentication Method"
+				   :inline t
+				   (const :tag "Authentication Method" auth)
+				   (choice
+				    (const :menu-tag "None" :tag "None" nil)
+				    (const :menu-tag "Simple" :tag "Simple" simple)
+				    (const :menu-tag "Kerberos 4.1" :tag "Kerberos 4.1" krbv41)
+				    (const :menu-tag "Kerberos 4.2" :tag "Kerberos 4.2" krbv42)))
+				  (list
+				   :tag "Search Base" 
+				   :inline t
+				   (const :tag "Search Base" base)
+				   string)
+				  (list
+				   :tag "Search Scope" 
+				   :inline t
+				   (const :tag "Search Scope" scope)
+				   (choice
+				    (const :menu-tag "Default" :tag "Default" nil)
+				    (const :menu-tag "Subtree" :tag "Subtree" subtree)
+				    (const :menu-tag "Base" :tag "Base" base)
+				    (const :menu-tag "One Level" :tag "One Level" onelevel)))
+				  (list
+				   :tag "Dereferencing"
+				   :inline t
+				   (const :tag "Dereferencing" deref)
+				   (choice
+				    (const :menu-tag "Default" :tag "Default" nil)
+				    (const :menu-tag "Never" :tag "Never" never)
+				    (const :menu-tag "Always" :tag "Always" always)
+				    (const :menu-tag "When searching" :tag "When searching" search)
+				    (const :menu-tag "When locating base" :tag "When locating base" find)))
+				  (list
+				   :tag "Time Limit"
+				   :inline t
+				   (const :tag "Time Limit" timelimit)
+				   (integer :tag "(in seconds)"))
+				  (list
+				   :tag "Size Limit"
+				   :inline t
+				   (const :tag "Size Limit" sizelimit)
+				   (integer :tag "(number of records)")))))
+:group 'ldap)
 
 
 (defun ldap-search (filter &optional host attributes attrsonly)
   "Perform an LDAP search.
-FILTER is the search filter in RFC1558 syntax
-HOST is the LDAP host on which to perform the search
-ATTRIBUTES is a list of the specific attributes to retrieve, 
-nil means retrieve all
-ATTRSONLY if non nil retrieves the attributes only without 
+FILTER is the search filter in RFC1558 syntax, i.e. something that
+looks like \"(cn=John Smith)\".
+HOST is the LDAP host on which to perform the search.
+ATTRIBUTES is a list of attributes to retrieve; nil means retrieve all.
+If ATTRSONLY is non nil, the attributes will be retrieved without
 the associated values.
 Additional search parameters can be specified through 
 `ldap-host-parameters-alist' which see."
   (interactive "sFilter:")
-  (let (host-plist res ldap)
-    (if (null host)
-	(setq host ldap-default-host))
-    (if (null host)
-	(error "No LDAP host specified"))
-    (setq host-plist
-	  (cdr (assoc host ldap-host-parameters-alist)))
+  (or host
+      (setq host ldap-default-host))
+  (or host
+      (error "No LDAP host specified"))
+  (let ((host-plist (cdr (assoc host ldap-host-parameters-alist)))
+	ldap)
     (message "Opening LDAP connection to %s..." host)
     (setq ldap (ldap-open host host-plist))
     (message "Searching with LDAP on %s..." host)
-    (setq res (ldap-search-internal ldap filter 
-				    (plist-get host-plist 'base)
-				    (plist-get host-plist 'scope)
-				    attributes attrsonly))
-    (ldap-close ldap)
-    res))
-
+    (prog1 (ldap-search-internal ldap filter 
+				 (plist-get host-plist 'base)
+				 (plist-get host-plist 'scope)
+				 attributes attrsonly)
+      (ldap-close ldap))))
 		
-
-(provide 'ldap)
-
 ;;; ldap.el ends here
--- a/lisp/package-admin.el	Mon Aug 13 11:07:40 2007 +0200
+++ b/lisp/package-admin.el	Mon Aug 13 11:08:24 2007 +0200
@@ -324,7 +324,7 @@
 	start err-list
 	)
     (setq pkg-dir (package-admin-get-install-dir 'unknown pkg-dir))
-    ;; Insure that the current directory doesn't change
+    ;; Ensure that the current directory doesn't change
     (save-excursion
       (set-buffer buf)
       ;; This is not really needed
@@ -437,8 +437,7 @@
 	    ;; Delete empty directories.
 	    (if dirs
 		(let ( (orig-default-directory default-directory)
-;		       directory files file
-		       )
+		       directory files file )
 		  ;; Make sure we preserve the existing `default-directory'.
 		  ;; JV, why does this change the default directory? Does it indeed?
 		  (unwind-protect
--- a/lisp/package-get.el	Mon Aug 13 11:07:40 2007 +0200
+++ b/lisp/package-get.el	Mon Aug 13 11:08:24 2007 +0200
@@ -254,16 +254,16 @@
 (defvar package-get-was-current nil
   "Non-nil we did our best to fetch a current database.")
 
+
+;Shouldn't this be in package-ui?
 ;;;###autoload
 (defun package-get-download-menu ()
   "Build the `Add Download Site' menu."
   (mapcar (lambda (site)
             (vector (car site)
-                    `(push (quote ,(cdr site))
-                           package-get-remote)
-                    :style 'toggle
-                    :selected `(member (quote ,(cdr site))
-                                       package-get-remote)))
+               `(package-ui-add-site (quote ,(cdr site)))
+		    :style 'toggle :selected
+		    `(member (quote ,(cdr site)) package-get-remote)))
           package-get-download-sites))
 
 ;;;###autoload
@@ -612,6 +612,7 @@
                              (mapcar
                               #'(lambda (reqd)
                                   (let* ((reqd-package (package-get-package-provider reqd))
+                                         (reqd-version (cadr reqd-package))
                                          (reqd-name    (car reqd-package)))
                                     (if (null reqd-name)
                                         (error "Unable to find a provider for %s" reqd))
--- a/lisp/package-ui.el	Mon Aug 13 11:07:40 2007 +0200
+++ b/lisp/package-ui.el	Mon Aug 13 11:08:24 2007 +0200
@@ -62,6 +62,12 @@
   :group 'pui
   :type 'face)
 
+(defcustom pui-deleted-package-face 'blue
+  "*The face to use for packages marked for removal.
+Set this to `nil' to use the `default' face."
+  :group 'pui
+  :type 'face)
+
 (defcustom pui-outdated-package-face 'red
   "*The face to use for outdated packages.
 Set this to `nil' to use the `default' face."
@@ -87,24 +93,31 @@
 (defvar pui-selected-packages nil
   "The list of user-selected packages to install.")
 
+(defvar pui-deleted-packages nil
+  "The list of user-selected packages to remove.")
+
+(defvar pui-actual-package "")
+
 (defvar pui-display-keymap
   (let ((m (make-keymap)))
     (suppress-keymap m)
     (set-keymap-name m 'pui-display-keymap)
     (define-key m "q" 'pui-quit)
     (define-key m "g" 'pui-list-packages)
-    (define-key m " " 'pui-display-info)
-    (define-key m "?" 'pui-help)
+    (define-key m "i" 'pui-display-info)
+    (define-key m "?" 'describe-mode)
     (define-key m "v" 'pui-toggle-verbosity-redisplay)
-    (define-key m "d" 'pui-toggle-verbosity-redisplay)
+    (define-key m "d" 'pui-toggle-package-delete-key)
+    (define-key m "D" 'pui-toggle-package-delete-key)
     (define-key m [return] 'pui-toggle-package-key)
     (define-key m "x" 'pui-install-selected-packages)
     (define-key m "I" 'pui-install-selected-packages)
     (define-key m "r" 'pui-add-required-packages)
     (define-key m "n" 'next-line)
-    (define-key m "+" 'next-line)
+    (define-key m "+" 'pui-toggle-package-key)
     (define-key m "p" 'previous-line)
-    (define-key m "-" 'previous-line)
+    (define-key m " " 'scroll-up-command)
+    (define-key m [delete] 'scroll-down-command)
     m)
   "Keymap to use in the `pui-info-buffer' buffer")
 
@@ -113,7 +126,7 @@
     (set-keymap-name m 'pui-package-keymap)
     (define-key m 'button2 'pui-toggle-package-event)
 ;; We use a popup menu    
-;;    (define-key m 'button3 'pui-toggle-package-event)
+    (define-key m 'button3 'pui-popup-context-sensitive)
     m)
   "Keymap to use over package names/descriptions.")
 
@@ -160,6 +173,21 @@
     ))
 
 ;;;###autoload
+(defun package-ui-add-site (site)
+  "Add site to package-get-remote and possibly offer to update package list."
+  (let ((had-none (null package-get-remote)))
+    (push site package-get-remote)    
+    (when (and had-none package-get-was-current
+	       (y-or-n-p "Update Package list?"))
+      (setq package-get-was-current nil)
+      (package-get-require-base t)
+      (if (get-buffer pui-info-buffer)
+	  (save-window-excursion
+	    (pui-list-packages))))
+    (set-menubar-dirty-flag)))
+    
+
+;;;###autoload
 (defun pui-add-install-directory (dir)
   "Add a new package binary directory to the head of `package-get-remote'.
 Note that no provision is made for saving any changes made by this function.
@@ -198,18 +226,6 @@
   (interactive)
   (kill-buffer nil))
 
-(defun pui-help ()
-  (interactive)
-  (let ( (help-buffer (get-buffer-create "*Help*")) )
-    (display-buffer help-buffer t)
-    (save-window-excursion
-      (set-buffer help-buffer)
-      (buffer-disable-undo help-buffer)
-      (erase-buffer help-buffer)
-      (insert (pui-help-string))
-      )
-    ))
-
 (defun pui-package-symbol-char (pkg-sym version)
   (progn
     (if (package-get-info-find-package packages-package-list pkg-sym)
@@ -236,20 +252,22 @@
     (if (not version)
 	(setq version (package-get-info-prop (extent-property extent 'pui-info)
 					     'version)))
-    (if (member pkg-sym pui-selected-packages)
-	(progn
-	  (if pui-selected-package-face
-	      (set-extent-face extent (get-face pui-selected-package-face))
-	    (set-extent-face extent (get-face 'default)))
-	  (setq sym-char "+")
-	  )
-      (progn
-	(setq disp (pui-package-symbol-char pkg-sym version))
-	(setq sym-char (car disp))
-	(if (car (cdr disp))
-	    (set-extent-face extent (get-face (car (cdr disp))))
-	  (set-extent-face extent (get-face 'default)))
-	))
+    (cond ((member pkg-sym pui-selected-packages)
+	     (if pui-selected-package-face
+		 (set-extent-face extent (get-face pui-selected-package-face))
+	       (set-extent-face extent (get-face 'default)))
+	     (setq sym-char "+"))
+	  ((member pkg-sym pui-deleted-packages)
+	   (if pui-deleted-package-face
+		 (set-extent-face extent (get-face pui-deleted-package-face))
+	       (set-extent-face extent (get-face 'default)))
+	     (setq sym-char "D"))
+	  (t
+	   (setq disp (pui-package-symbol-char pkg-sym version))
+	   (setq sym-char (car disp))
+	   (if (car (cdr disp))
+	       (set-extent-face extent (get-face (car (cdr disp))))
+	     (set-extent-face extent (get-face 'default)))))
     (save-excursion
       (goto-char (extent-start-position extent))
       (delete-char 1)
@@ -265,7 +283,9 @@
 	(setq pui-selected-packages
 	      (delete pkg-sym pui-selected-packages))
       (setq pui-selected-packages
-	    (cons pkg-sym pui-selected-packages)))
+	    (cons pkg-sym pui-selected-packages))
+      (setq pui-deleted-packages
+	    (delete pkg-sym pui-deleted-packages)))
     (pui-update-package-display extent pkg-sym)
     ))
 
@@ -281,6 +301,37 @@
       (error "No package under cursor!"))
     ))
 
+(defun pui-toggle-package-delete (extent)
+  (let (pkg-sym)
+    (setq pkg-sym (extent-property extent 'pui-package))
+    (if (member pkg-sym pui-deleted-packages)
+	(setq pui-deleted-packages
+	      (delete pkg-sym pui-deleted-packages))
+      (setq pui-deleted-packages
+	    (cons pkg-sym pui-deleted-packages))
+      (setq pui-seleted-packages
+	    (delete pkg-sym pui-selected-packages)))
+    (pui-update-package-display extent pkg-sym)
+    ))
+  
+
+(defun pui-toggle-package-delete-key ()
+  "Select/unselect package for removal, using the keyboard."
+  (interactive)
+  (let (extent)
+    (if (setq extent (extent-at (point) (current-buffer) 'pui))
+	(progn
+	  (pui-toggle-package-delete extent)
+	  (forward-line 1)
+	  )
+      (error "No package under cursor!"))
+    ))
+
+(defun pui-current-package ()
+  (let ((extent (extent-at (point) (current-buffer) 'pui)))
+    (if extent
+	(extent-property extent 'pui-package))))
+
 (defun pui-toggle-package-event (event)
   "Select/unselect package for installation, using the mouse."
   (interactive "e")
@@ -302,6 +353,37 @@
 (defun pui-install-selected-packages ()
   "Install selected packages."
   (interactive)
+  (let ( (tmpbuf "*Packages-To-Remove*") do-delete)
+    (when pui-deleted-packages
+      (save-window-excursion
+	(with-output-to-temp-buffer tmpbuf
+	  (display-completion-list (sort
+				    (mapcar '(lambda (pkg)
+					       (symbol-name pkg)
+					       )
+					    pui-deleted-packages)
+					'string<)
+				       :activate-callback nil
+				       :help-string "Packages selected for removal:\n"
+				       :completion-string t
+				       ))
+	    (setq tmpbuf (get-buffer-create tmpbuf))
+	    (display-buffer tmpbuf)
+	    (setq do-delete (yes-or-no-p "Remove these packages? "))
+	    (kill-buffer tmpbuf))	    
+      (when do-delete
+	(message "Deleting selected packages ...") (sit-for 0)
+	(when (catch 'done
+		(mapcar (lambda (pkg)
+			  (if (not
+			       (package-admin-delete-binary-package
+				  pkg (package-admin-get-install-dir pkg nil)))
+				    (throw 'done nil)))
+			      pui-deleted-packages)
+		      t)
+	  (message "Packages deleted")
+	  ))))
+	 
   (let ( (tmpbuf "*Packages-To-Install*") do-install)
     (if pui-selected-packages
 	(progn
@@ -351,7 +433,9 @@
 	      (clear-message)
 	      )
 	  )
-      (error "No packages have been selected!"))
+      (if pui-deleted-packages
+	  (pui-list-packages)
+	(error "No packages have been selected!")))
     ))
 
 (defun pui-add-required-packages ()
@@ -434,52 +518,39 @@
 	  ))
     ))
 
-(defun pui-display-info (&optional no-error)
+(defun pui-display-info (&optional no-error event)
   "Display additional package info in the modeline.
 Designed to be called interactively (from a keypress)."
   (interactive)
   (let (extent)
     (save-excursion
       (beginning-of-line)
-      (if (setq extent (extent-at (point) (current-buffer) 'pui))
+      (if (setq extent 	(extent-at (point) (current-buffer) 'pui))
 	  (message (pui-help-echo extent t))
 	(if no-error
 	    (clear-message nil)
 	  (error "No package under cursor!")))
       )))
 
-(defun pui-help-string ()
-  "Return the help string for the package-info buffer.
-This is not a defconst because of the call to substitute-command-keys."
+;;; "Why is there no standard function to do this?"
+(defun pui-popup-context-sensitive (event)
+  (interactive "e")
   (save-excursion
-    (set-buffer (get-buffer pui-info-buffer))
-    (substitute-command-keys
-"Symbols in the leftmost column:
-
-  +	The package is marked for installation.
-  -     The package has not been installed.
-  *     The currently installed package is old, and a newer version is
-	available.
-
-Useful keys:
-
-  `\\[pui-toggle-package-key]' to select/unselect the current package for installation.
-  `\\[pui-add-required-packages]' to add any packages required by those selected.
-  `\\[pui-install-selected-packages]' to install selected packages.
-  `\\[pui-display-info]' to display additional information about the package in the modeline.
-  `\\[pui-list-packages]' to refresh the package list.
-  `\\[pui-toggle-verbosity-redisplay]' to toggle between a verbose and non-verbose display.
-  `\\[pui-quit]' to kill this buffer.
-")
-    ))
+    (set-buffer (event-buffer event))
+    (goto-char (event-point event))
+    (popup-menu pui-menu event)
+    ;; I agreee with dired.el this is seriously bogus.
+    (while (popup-menu-up-p)
+      (dispatch-event (next-event)))))
 
 (defvar pui-menu
   '("Packages"
-    ["Select" pui-toggle-package-key t]
-    ["Info" pui-display-info t]
+    ["Toggle install " pui-toggle-package-key :active (pui-current-package) :suffix (format "`%s'" (or (pui-current-package) "..."))]
+    ["Toggle delete " pui-toggle-package-delete-key :active (pui-current-package) :suffix (format "`%s'" (or (pui-current-package) "..."))]
+    ["Info on" pui-display-info  :active (pui-current-package) :suffix (format "`%s'" (or (pui-current-package) "..."))]
     "---"
     ["Add Required" pui-add-required-packages t]
-    ["Install Selected" pui-install-selected-packages t]
+    ["Install/Remove Selected" pui-install-selected-packages t]
     "---"
     ["Verbose" pui-toggle-verbosity-redisplay
      :active t :style toggle :selected pui-list-verbose]
@@ -488,6 +559,30 @@
     ["Quit" pui-quit t]))
 
 
+(defun list-packages-mode ()
+    "Symbols in the leftmost column:
+
+  +	The package is marked for installation.
+  -     The package has not been installed.
+  D     The package has been marked for deletion.
+  *     The currently installed package is old, and a newer version is
+	available.
+
+Useful keys:
+
+  `\\[pui-toggle-package-key]' to select/unselect the current package for installation.
+  `\\[pui-toggle-package-delete-key]' to select/unselect the current package for removal.
+  `\\[pui-add-required-packages]' to add any packages required by those selected.
+  `\\[pui-install-selected-packages]' to install/delete selected packages.
+  `\\[pui-display-info]' to display additional information about the package in the modeline.
+  `\\[pui-list-packages]' to refresh the package list.
+  `\\[pui-toggle-verbosity-redisplay]' to toggle between a verbose and non-verbose display.
+  `\\[pui-quit]' to kill this buffer.
+"
+  (error "You cannot enter this mode directly. Use `pui-list-packages'"))
+
+(put 'list-packages-mode 'mode-class 'special)
+
 ;;;###autoload
 (defun pui-list-packages ()
   "List all packages and package information.
@@ -505,7 +600,19 @@
     (setq buffer-read-only nil)
     (buffer-disable-undo outbuf)
     (erase-buffer outbuf)
+    (kill-all-local-variables)
     (use-local-map pui-display-keymap)
+    (setq major-mode 'list-packages-mode)
+    (setq mode-name "Packages")
+    (setq truncate-lines t)
+
+    (unless package-get-remote
+      (insert "
+Warning: No download sites specified.  Package index may be out of date.
+         If you intend to install packages, specify download sites first.
+
+"))
+    
     (if pui-list-verbose
 	(insert "                 Latest Installed
   Package name   Vers.  Vers.   Description
@@ -577,13 +684,14 @@
 				      (symbol-name (car b)))
 			       )))
     (insert sep-string)
-    (insert (pui-help-string))
+    (insert (documentation 'list-packages-mode))
     (set-buffer-modified-p nil)
     (setq buffer-read-only t)
     (pop-to-buffer outbuf)
     (delete-other-windows)
     (goto-char start)
     (setq pui-selected-packages nil)	; Reset list
+    (setq pui-deleted-packages nil)	; Reset list
     (when (featurep 'menubar)
       (set-buffer-menubar current-menubar)
       (add-submenu '() pui-menu)
@@ -592,6 +700,8 @@
 ;    (message (substitute-command-keys "Press `\\[pui-help]' for help."))
     ))
 
+;;;###autoload
+(defalias 'list-packages 'pui-list-packages)
 
 (provide 'package-ui)
 
--- a/lisp/sound.el	Mon Aug 13 11:07:40 2007 +0200
+++ b/lisp/sound.el	Mon Aug 13 11:08:24 2007 +0200
@@ -82,7 +82,7 @@
 				       (const :format "" :value :duration)
 				       (integer :tag "Duration"))))))
 
-(defcustom sound-load-alist
+(defcustom sound-load-list
   '((load-sound-file "drum-beep"	'drum)
     (load-sound-file "quiet-beep"	'quiet)
     (load-sound-file "bass-snap"	'bass 80)
@@ -105,9 +105,9 @@
   :type 'directory
   )
 
-(defcustom sound-ext (if (or (eq system-type 'cygwin32)
-			     (eq system-type 'windows-nt))
-			 ".wav:" ".au:")
+(defcustom sound-extension-list (if (or (eq system-type 'cygwin32)
+					(eq system-type 'windows-nt))
+				    ".wav:" ".au:")
   "Filename extensions to complete sound file name with. If more than one
    extension is used, they should be separated by \":\". "
   :group 'sound
@@ -144,7 +144,7 @@
     (error "volume not an integer or nil"))
   (let (buf
 	data
-	(file (locate-file filename  default-sound-directory-list  sound-ext)))
+	(file (locate-file filename  default-sound-directory-list  sound-extension-list)))
     (unless file
       (error "Couldn't load sound file %s" filename))
     (unwind-protect
@@ -180,7 +180,7 @@
   (message "Loading sounds...")
   (setq sound-alist nil)
   ;; this is where the calls to load-sound-file get done
-  (mapc 'eval sound-load-alist)
+  (mapc 'eval sound-load-list)
   (setq sound-alist
 	(append sound-default-alist
 		sound-alist))
--- a/man/ChangeLog	Mon Aug 13 11:07:40 2007 +0200
+++ b/man/ChangeLog	Mon Aug 13 11:08:24 2007 +0200
@@ -1,3 +1,7 @@
+1998-12-24  Martin Buchholz <martin@xemacs.org>
+
+	* XEmacs 21.2.7 is released.
+
 1998-12-16  Andy Piper  <andy@xemacs.org>
 
 	* XEmacs 21.2.6 is released
--- a/man/xemacs/packages.texi	Mon Aug 13 11:07:40 2007 +0200
+++ b/man/xemacs/packages.texi	Mon Aug 13 11:08:24 2007 +0200
@@ -35,13 +35,13 @@
 @cindex single-file packages
 A single-file package is an aggregate collection of thematically
 related but otherwise independent lisp files.  These files are bundled 
-together for download convenience and individual files may deleted at
+together for download convenience and individual files may be deleted at
 will without any loss of functionality.
 @end itemize
 
 @subsection Package Distributions
 
-XEmacs Lisp packages are distributed in two ways depending on the
+XEmacs Lisp packages are distributed in two ways, depending on the
 intended use.  Binary Packages are for installers and end-users and may
 be installed directly into an XEmacs package directory.  Source Packages
 are for developers and include all files necessary for rebuilding
@@ -56,7 +56,7 @@
 @cindex source packages
 Source packages contain all of the Package author's (where appropriate
 in regular packages) source code plus all of the files necessary to
-build distribution tarballs (Unix Tar format files and gzipped for space
+build distribution tarballs (Unix Tar format files, gzipped for space
 savings).
 
 @node Using Packages, Building Packages, Package Terminology, Packages
@@ -78,7 +78,7 @@
 @subsection Choosing the Packages You Need
 
 The available packages can currently be found in the same ftp directory
-where you grabbed the core distribition from, and are located in the
+where you grabbed the core distribution from, and are located in the
 subdirectory @file{packages/binary-packages}.  Package file names follow
 the naming convention @file{<package-name>-<version>-pkg.tar.gz}.
 
@@ -259,7 +259,7 @@
 
 Pre-compiled, binary packages can be installed in either a system
 package directory (this is determined when XEmacs is compiled), or in a
-subdirectory off your @file{$HOME} directory:
+subdirectory of your @file{$HOME} directory:
 
 @example
 ~/.xemacs/packages
--- a/nt/ChangeLog	Mon Aug 13 11:07:40 2007 +0200
+++ b/nt/ChangeLog	Mon Aug 13 11:08:24 2007 +0200
@@ -1,3 +1,26 @@
+1998-12-24  Martin Buchholz <martin@xemacs.org>
+
+	* XEmacs 21.2.7 is released.
+
+1998-12-13  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+	* xemacs.mak:
+	  Replaced PACKAGEPATH variable with PACKAGE_PREFIX. 
+	  configure-package-path is initialised to contain
+	  subdirectories of PACKAGE_PREFIX. The install target makes
+	  a skeleton package tree under PACKAGE_PREFIX.
+
+	* README, PROBLEMS:
+	  Documented the package path changes.
+	  Corrected the advice on a suitable minimal set of packages.
+
+1998-12-17  Andy Piper  <andy@xemacs.org>
+
+	* xemacs.mak ($(LIB_SRC)/movemail.exe): adapt make rule to build
+ 	with pop support.
+
+	* xemacs.mak: add gui-msw.c and glyphs-widget.c object lists.
+
 1998-12-16  Andy Piper  <andy@xemacs.org>
 
 	* XEmacs 21.2.6 is released
--- a/nt/PROBLEMS	Mon Aug 13 11:07:40 2007 +0200
+++ b/nt/PROBLEMS	Mon Aug 13 11:08:24 2007 +0200
@@ -47,9 +47,9 @@
 
 ** XEmacs can't find any packages
 
-The directory tree under which XEmacs looks for your packages is set
-at compile-time, and defaults to C:\Program Files\XEmacs\Packages. The
-variable configure-package-path holds the actual value that was
+XEmacs looks for your packages in subdirectories of a directory which
+is set at compile-time, and defaults to C:\Program Files\XEmacs. The
+variable configure-package-path holds the actual path that was
 compiled into your copy of XEmacs.
 
 The compile-time default location can be overridden by the
--- a/nt/README	Mon Aug 13 11:07:40 2007 +0200
+++ b/nt/README	Mon Aug 13 11:08:24 2007 +0200
@@ -23,8 +23,9 @@
 2.  Grab the latest XEmacs source from ftp.xemacs.org if necessary. All Win32
     support is in the nt\ subdirectory. You'll also need the xemacs-base
     package from the binary-packages subdirectory and you'll probably also
-    want at least the edit-utils, text-utils, cc-mode and prog-utils packages.
-    Unpack the packages into, say, "c:\Program Files\XEmacs\packages".
+    want at least the edit-utils, text-modes, fsf-compat, cc-mode,
+    prog-modes and xemacs-devel packages.
+    Unpack the packages into, say, "c:\Program Files\XEmacs\xemacs-packages".
 
 3.  At this point you can select X or Win32 native GUI support.
 
@@ -71,23 +72,24 @@
     If you want to build with GIF support, add this to the nmake command line:
 	HAVE_GIF=1
 
-7.  By default, XEmacs will look for packages in
-    "c:\Program Files\XEmacs\packages". If you want it to look elsewhere,
-    add this to the nmake command line:
-	PACKAGEPATH="x:\\location\\of\\your\\packages"
-    Note the doubled-up backslashes in that path. If you want to change the
-    package path after you've already built XEmacs, delete the file
-    .\obj\emacs.obj before rebuilding with the new value of PACKAGEPATH.
+7.  By default, XEmacs will expect to find its packages in the subdirectories
+    "site-packages", "mule-packages" and "xemacs-packages" under the package
+    prefix directory "c:\Program Files\XEmacs". If you want it to look for
+    these subdirectories elsewhere, add this to the nmake command line:
+	PACKAGE_PREFIX="x:\your\package\directory"
+    If you change your mind and want to alter the package prefix directory
+    after you've built XEmacs, delete the file .\obj\emacs.obj and rebuild with
+    the new PACKAGE_PREFIX.
 
 8.  By default, XEmacs will be installed in directories under the directory
-    "c:\Program Files\XEmacs\XEmacs-21.0". If you want to install it
-    elsewhere, add this to the nmake command line:
+    "c:\Program Files\XEmacs\XEmacs-21.0". If you want to install it elsewhere,
+    add this to the nmake command line:
 	INSTALL_DIR="x:\your\installation\directory"
 
 9.  Now you can press Enter. nmake will build temacs, the DOC file, update the
     elc's, dump xemacs and install the relevant files in the directories under
     the installation directory. Unless you set INSTALL_DIR above, the file that
-    you should run to start XEmacs will be installed as
+    you should run to start XEmacs will be installed as 
     "c:\Program Files\XEmacs\XEmacs-21.0\i386-pc-win32\runemacs.exe". You may
     want to create a shortcut to that file from your Desktop or Start Menu.
 
--- a/nt/config.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/nt/config.h	Mon Aug 13 11:08:24 2007 +0200
@@ -605,7 +605,7 @@
 
 /* movemail options */
 /* Should movemail use POP3 for mail access? */
-#undef MAIL_USE_POP
+/* #undef MAIL_USE_POP */
 /* Should movemail use kerberos for POP authentication? */
 #undef KERBEROS
 /* Should movemail use hesiod for getting POP server host? */
--- a/nt/xemacs.mak	Mon Aug 13 11:07:40 2007 +0200
+++ b/nt/xemacs.mak	Mon Aug 13 11:08:24 2007 +0200
@@ -65,11 +65,13 @@
 INSTALL_DIR=c:\Program Files\XEmacs\XEmacs-$(XEMACS_VERSION_STRING)
 ! endif
 !endif
-!if !defined(PACKAGEPATH)
-PATH_PACKAGEPATH="c:\\Program Files\\XEmacs\\packages"
-!else
-PATH_PACKAGEPATH="$(PACKAGEPATH)"
+!if !defined(PACKAGE_PATH)
+! if !defined(PACKAGE_PREFIX)
+PACKAGE_PREFIX=c:\Program Files\XEmacs
+! endif
+PACKAGE_PATH=~\.xemacs;;$(PACKAGE_PREFIX)\site-packages;$(PACKAGE_PREFIX)\mule-packages;$(PACKAGE_PREFIX)\xemacs-packages
 !endif
+PATH_PACKAGEPATH="$(PACKAGE_PATH:\=\\)"
 !if !defined(HAVE_MSW)
 HAVE_MSW=1
 !endif
@@ -222,7 +224,7 @@
 !message XEmacs $(XEMACS_VERSION_STRING) $(xemacs_codename) configured for "$(EMACS_CONFIGURATION)".
 !message 
 !message Installation directory is "$(INSTALL_DIR)".
-!message Package path is $(PATH_PACKAGEPATH).
+!message Package path is "$(PACKAGE_PATH)".
 !message 
 !if $(INFODOCK)
 !message Building InfoDock.
@@ -504,6 +506,9 @@
 ETAGS_DEPS = $(LIB_SRC)/getopt.c $(LIB_SRC)/getopt1.c $(LIB_SRC)/../src/regex.c
 $(LIB_SRC)/etags.exe : $(LIB_SRC)/etags.c $(ETAGS_DEPS)
 $(LIB_SRC)/movemail.exe: $(LIB_SRC)/movemail.c $(LIB_SRC)/pop.c $(ETAGS_DEPS)
+	@cd $(LIB_SRC)
+	$(CCV) -I. -I$(XEMACS)/src -I$(XEMACS)/nt/inc $(LIB_SRC_DEFINES) -O2 -W3 -Fe$@ $** wsock32.lib
+	@cd $(NT)
 
 LIB_SRC_TOOLS = \
 	$(LIB_SRC)/make-docfile.exe	\
@@ -1006,9 +1011,10 @@
 # use this rule to install the system
 install:	all
 	@echo Installing in $(INSTALL_DIR) ...
+	@echo PlaceHolder > PlaceHolder
 	@xcopy /q PROBLEMS "$(INSTALL_DIR)\"
-	@xcopy /q README "$(INSTALL_DIR)\lock\"
-	@del "$(INSTALL_DIR)\lock\README"
+	@xcopy /q PlaceHolder "$(INSTALL_DIR)\lock\"
+	@del "$(INSTALL_DIR)\lock\PlaceHolder"
 	@xcopy /q $(LIB_SRC)\*.exe "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)\"
 	@copy $(LIB_SRC)\DOC "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)"
 	@copy $(CONFIG_VALUES) "$(INSTALL_DIR)\$(EMACS_CONFIGURATION)"
@@ -1017,6 +1023,14 @@
 	@xcopy /e /q $(XEMACS)\etc  "$(INSTALL_DIR)\etc\"
 	@xcopy /e /q $(XEMACS)\info "$(INSTALL_DIR)\info\"
 	@xcopy /e /q $(XEMACS)\lisp "$(INSTALL_DIR)\lisp\"
+	@echo Making skeleton package tree in $(PACKAGE_PREFIX) ...
+	@xcopy /q PlaceHolder "$(PACKAGE_PREFIX)\site-packages\"
+	@del "$(PACKAGE_PREFIX)\site-packages\PlaceHolder"
+	@xcopy /q PlaceHolder "$(PACKAGE_PREFIX)\mule-packages\"
+	@del "$(PACKAGE_PREFIX)\mule-packages\PlaceHolder"
+	@xcopy /q PlaceHolder "$(PACKAGE_PREFIX)\xemacs-packages\"
+	@del "$(PACKAGE_PREFIX)\xemacs-packages\PlaceHolder"
+	@del PlaceHolder
 
 distclean:
 	del *.bak
--- a/src/ChangeLog	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/ChangeLog	Mon Aug 13 11:08:24 2007 +0200
@@ -1,3 +1,653 @@
+1998-12-24  Martin Buchholz <martin@xemacs.org>
+
+	* XEmacs 21.2.7 is released.
+
+1998-12-23  Martin Buchholz  <martin@xemacs.org>
+
+	* glyphs.c (decode_device_ii_format):
+	- Fix indentation.
+	- Use GET_C_STRING_FILENAME_DATA_ALLOCA with char *, not Extbyte *.
+
+	* glyphs-x.c (x_subwindow_instantiate): 
+	- A image instance mask was being assigned to a image instance type!
+	- X_SUBWINDOW_INSTANCE_DATA (ii) is not an lvalue in C++.
+	
+	* glyphs-msw.c (mswindows_initialize_dibitmap_image_instance): 
+	Fix indentation.
+	* glyphs-x.h: Make indentation consistent.
+
+	* emacs.c (Fdump_emacs): Remove Steve Martin merge artifacts.
+
+	* glyphs-widget.c (check_valid_glyph): Warning suppression.
+	- Make it static
+	- #ifdef it out, since it's not actually used yet (FIX THIS!)
+
+	* glyphs-widget.c:
+	* glyphs.h:
+	Move declarations of decode_device_ii_format and
+	decode_image_instantiator_format into glyphs.h where they belong.
+
+1998-12-22  Martin Buchholz  <martin@xemacs.org>
+
+	* frame-x.c (x_delete_frame): Revert part of my changes at the
+	suggestion of Gunnar Evermann - unfortunately no one really
+	understands this code.
+
+	* callproc.c (init_callproc): code cleanup.
+
+	* free-hook.c (malloc):
+	(check_malloc):
+	(__free_hook):
+	(__malloc_hook):
+	(__realloc_hook):
+	(block_input_malloc):
+	(block_input_realloc):
+	* device-x.c (x_delete_device):
+	* emacs.c (voodoo_free_hook):
+	* events.c (print_event):
+	(CHECK_EVENT_TYPE):
+	(CHECK_EVENT_TYPE2):
+	(CHECK_EVENT_TYPE3):
+	Use proper prototypes.
+	Make C_E_T macros a little faster.
+	Pedantic fiddly little changes.  You really don't care.
+
+1998-12-22  Andy Piper  <andy@xemacs.org>
+
+	* redisplay-output.c (redisplay_clear_region): make sure that
+ 	fg/bg colors get set even when we are in the border area.
+
+1998-12-13  Martin Buchholz  <martin@xemacs.org>
+
+	* console-msw.c: Function definitions follow coding standards
+	- This prevents e.g. find-tag on Lisp_Event finding DEVENT
+
+1998-12-11  Martin Buchholz  <martin@xemacs.org>
+
+	* events.h (struct timeout_data):
+	* event-tty.c (tty_timeout_to_emacs_event):
+	* event-msw.c (mswindows_wm_timer_callback):
+	* event-Xt.c (Xt_timeout_to_emacs_event):
+	* event-msw.c (mswindows_cancel_dispatch_event):
+	Make sure Lisp_Objects inside events are initialized to Qnil, not
+	Qnull_pointer, which is now illegal.
+
+1998-12-10  Martin Buchholz  <martin@xemacs.org>
+
+	* lisp.h: Fix up prototypes to match alloc.c
+
+1998-12-08  Martin Buchholz  <martin@xemacs.org>
+
+	* windowsnt.h: Remove `support' for using index and rindex
+
+	* filelock.c (current_lock_owner):
+	- Change uses of index -> strchr, rindex -> strrchr
+
+1998-12-07  Martin Buchholz  <martin@xemacs.org>
+
+	* sysdep.c (set_descriptor_non_blocking):
+	Since O_NONBLOCK is now always #defined, make use of fcntl
+	conditional on F_SETFL being defined.
+
+	* console-msw.c (DHEADgER):
+	(DOPAQUE_DATA):
+	(DEVENT):
+	(DCONS):
+	(DCONSCDR):
+	(DSTRING):
+	(DVECTOR):
+	(DSYMBOL):
+	(DSYMNAME):
+	- max_align_t should not be visible to the user of the
+	  XOPAQUE_DATA macro.
+	- use Bufbyte instead of char
+	- parens around (FOOP (obj)) are always redundant.
+	  If they were necessary, we should fix the macro instead.
+	- Always use string_data(foo) instead of foo->data.
+
+
+1998-12-06  Martin Buchholz  <martin@xemacs.org>
+
+	* frame-msw.c (mswindows_init_frame_1):
+	- use make_lisp_hash_table, not Fmake_hash_table
+	- include elhash.h
+
+	* lisp.h:
+	* alloc.c (make_vector): remove travesty
+	(Fmake_vector):
+	(make_pure_vector):
+	(pure_cons):
+	(make_bit_vector_internal):
+	(make_bit_vector):
+	(make_bit_vector_from_byte_vector):
+	(Fmake_bit_vector):
+	- make vector_equal a little faster.
+	- Don't use variable name `new'.
+	- Use size_t instead of EMACS_INT.
+	- usual Martin-style pointless bit-twiddling.
+
+	* fns.c (mapcar1):
+	(Fmapconcat):
+	(Fmapcar):
+	(Fmapvector):
+	Make mapcar faster.  In particular, make
+	  (mapc #'identity long-string)
+	MUCH faster under Mule.
+	* tests/automated/lisp-tests.el: Test 'em!
+
+	* bytecode.c (Ffetch_bytecode): Fix crash when loading lazy-loaded
+	bytecode.
+
+1998-12-01  Martin Buchholz  <martin@xemacs.org>
+
+	* menubar-x.c (menu_item_descriptor_to_widget_value_1): Always use
+	Qnil, not NULL, to initialize `null' Lisp_Objects.
+
+1998-11-29  Hrvoje Niksic  <hniksic@srce.hr>
+
+	* specifier.c (display_table_validate): Update.
+
+	* redisplay.c (create_text_block): Use them.
+
+	* glyphs.c (display_table_entry): New function.
+	(get_display_tables): Ditto.
+
+1998-12-15  Oscar Figueiredo  <Oscar.Figueiredo@di.epfl.ch>
+
+	* eldap.c (toplevel): Mention that eldap.c compiles with
+	OpenLDAP libs
+	(Fldap_open): Use `GET_C_STRING_OS_DATA_ALLOCA'
+	(Fldap_search_internal): Ditto
+
+1998-12-11  Martin Buchholz  <martin@xemacs.org>
+
+        * event-msw.c (mswindows_cancel_dispatch_event):
+        Gratuitous code prettification
+
+
+1998-12-07  Hrvoje Niksic  <hniksic@srce.hr>
+
+	* fns.c (Fnconc): Fix use of wrong_type_argument().
+
+	* floatfns.c (Ffloat): Fix docstring.
+	(Ffloat): Fix use of wrong_type_argument().
+	(Fabs): Ditto.
+	(extract_float): Ditto.
+	(Fceiling): Ditto.
+	(Fround): Ditto.
+	(Ftruncate): Ditto.
+
+1998-12-06  Martin Buchholz  <martin@xemacs.org>
+
+	* frame-msw.c (mswindows_init_frame_1):
+	- use make_lisp_hash_table, not Fmake_hash_table
+	- include elhash.h
+
+	* lisp.h:
+	* alloc.c (make_vector): remove travesty
+	(Fmake_vector):
+	(make_pure_vector):
+	(pure_cons):
+	(make_bit_vector_internal):
+	(make_bit_vector):
+	(make_bit_vector_from_byte_vector):
+	(Fmake_bit_vector):
+	- make vector_equal a little faster.
+	- Don't use variable name `new'.
+	- Use size_t instead of EMACS_INT.
+	- usual Martin-style pointless bit-twiddling.
+
+	* fns.c (mapcar1):
+	(Fmapconcat):
+	(Fmapcar):
+	(Fmapvector):
+	Make mapcar faster.  In particular, make
+	  (mapc #'identity long-string)
+	MUCH faster under Mule.
+	* tests/automated/lisp-tests.el: Test 'em!
+
+	* bytecode.c (Ffetch_bytecode): Fix crash when loading lazy-loaded
+	bytecode.
+
+1998-12-02  Didier Verna  <verna@inf.enst.fr>
+
+	* menubar-x.c (menu_item_descriptor_to_widget_value_1): set the
+	accelerator field to nil for labels.
+
+1998-12-16  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+	* menubar-msw.c (displayable_menu_item):
+	  Escape occurrences of '&' and support occurrences of the
+	 '%_' accelerator indicator in menus.
+
+1998-11-26  Didier Verna  <verna@inf.enst.fr>
+
+	* dired.c (Fdirectory_files): use make_string instead of
+	make_ext_string on the filename. The conversion external->internal
+	format is already done in sys_readdir.
+
+1998-12-15  Gunnar Evermann  <ge204@eng.cam.ac.uk>
+
+	* glyphs.c (normalize_image_instantiator): GCPRO instantiator
+
+1998-12-16  Jonathan Harris  <jhar@tardis.ed.ac.uk>
+
+	* event-msw.c
+	  (Belatedly) added Kirill to list of file's authors.
+	  emacs_mswindows_quit_p: Don't process WM_PAINT messages in
+	  quit checking. WM_PAINT messages cause redisplay, but
+	  windows' states are not necessarily stable when this function
+	  gets called.
+
+1998-12-17  Andy Piper  <andy@xemacs.org>
+
+	* strftime.c (zone_name): CONSTify.
+
+1998-12-15  Andy Piper  <andy@xemacs.org>
+
+	* glyphs-msw.c (mswindows_combo_instantiate): ditto.
+	(mswindows_widget_property): return Qunbound when no property available.
+	(mswindows_button_property): ditto.
+	(mswindows_combo_property): ditto.
+	(mswindows_widget_set_property): ditto.
+
+	* glyphs-widget.c (check_valid_item_list): use properties.
+
+	* glyphs.h (struct Lisp_Image_Instance): we have properties now.
+
+	* glyphs.c (Fset_image_instance_property): allow setting of arbitrary properties.
+	(Fimage_instance_property): ditto.
+	* glyphs-widget.c (widget_property): ditto.
+	(widget_set_property): ditto.
+
+	* frame-msw.c (mswindows_set_frame_pointer): SetCursor() as well
+ 	as setting the class cursor so that GC actually changes the
+ 	cursor.
+
+	* config.h: don't undef MAIL_USE_POP.
+
+1998-12-13  Andy Piper  <andy@xemacs.org>
+
+	* glyphs-msw.c
+ 	(image_instantiator_format_create_glyphs_mswindows): line ->
+ 	label.
+	(mswindows_label_instantiate): ditto. Play with window flags.
+	(image_instantiator_format_create_glyphs_mswindows): ditto.
+	(vars_of_glyphs_mswindows): provide Qlabel as we support it now.
+
+	* glyphs-widget.c (widget_instantiate_1): re-jig autosizing to
+ 	cope with lines and labels.
+	(static_instantiate): use widget_instantiate_1.
+	line -> label.
+	(image_instantiator_format_create_glyphs_widget): ditto.
+
+1998-12-10  Andy Piper  <andy@xemacs.org>
+
+	* Makefile.in.in (objs): add gui.o
+
+1998-12-10  Andy Piper  <andy@xemacs.org>
+
+	* gui.c: adjust defines of HAVE_POPUPS so that we can build with
+ 	no window system.
+
+1998-12-09  Andy Piper  <andy@xemacs.org>
+
+	* glyphs.c (finalize_image_instance): mark glyphs changed when an
+ 	image instance is removed so that the subwindow cache gets reset
+ 	and thus destroyed images get GC'd.
+
+1998-12-08  Andy Piper  <andy@xemacs.org>
+
+	* gui-msw.c (mswindows_handle_gui_wm_command): call
+ 	MARK_SUBWINDOWS_CHANGED.
+
+	* glyphs-msw.c (mswindows_finalize_image_instance): make sure
+ 	subwindows really get deleted.
+
+	* redisplay.c: new variable subwindows_changed[_set].
+	(redisplay_window): use it.
+	(redisplay_frame): ditto.
+	(redisplay_device): ditto.
+	(redisplay_without_hooks): ditto.
+
+	* device.h (MARK_DEVICE_SUBWINDOWS_CHANGED): new macro for
+ 	subwindows redisplay as per glyphs equivalent.
+	* redisplay.h: ditto.
+	(MARK_SUBWINDOWS_CHANGED): ditto.
+	(RESET_CHANGED_SET_FLAGS): ditto.
+	* frame.h (MARK_FRAME_SUBWINDOWS_CHANGED): ditto.
+
+1998-12-07  Andy Piper  <andy@xemacs.org>
+
+	* frame.c (Fmake_frame): reset subwindow cachels on non-stream
+ 	frames.
+
+	* redisplay.c (redisplay_frame): invalidate subwindow cachels.
+
+	* event-msw.c (mswindows_wnd_proc): catch the various WM_CTLCOLOR*
+ 	messages and paint widget glyphs as appropriate with their face fg
+ 	& bg.
+
+1998-12-06  Andy Piper  <andy@xemacs.org>
+
+	* glyphs-msw.c (vars_of_glyphs_mswindows): provide widget types
+ 	here rather than in glyphs-widget - do this because we only want
+ 	to provide what is really available.
+
+	* glyphs.c (Fimage_instance_property): new function to get the
+ 	properties of image instances. wires through to console specific
+ 	methods and then to widget specific methods.
+	(Fset_image_instance_property): ditto but for setting widget properties.
+	(check_valid_face): make extern so that it can be used elsewhere.
+
+	* glyphs-widget.c (widget_property): new function. gets the
+ 	properties of widgets in general and wires the function through to
+ 	widget specific ones.
+	(widget_set_property): ditto but for setting widget properties.
+
+	* glyphs-msw.c (mswindows_combo_instantiate): Add functionality to
+ 	add items to the list. Play with window styles a bit to get the
+ 	desired effect.
+	(mswindows_widget_property): break out specific widget properties.
+	(mswindows_button_property): new function. gets the checked state
+ 	of a button.
+	(mswindows_combo_property): new function. gets the current
+ 	selection in the combo box.
+	(mswindows_widget_set_property): new function. sets specific
+ 	properties of specific widgets.
+
+	* glyphs-widget.c (check_valid_item_list): new function. check
+ 	that items for a combo-box are just a list of strings.
+	(combo_validate): new function. check there is an item list.
+	(widget_instantiate_1): new function. renamed from
+ 	widget_instantiate so that we can do slightly different things for
+ 	other widgets.
+	(widget_instantiate): call widget_instantiate_1.
+	(combo_instantiate): new function to instantiate combo boxes,
+ 	defaults height to the pixel height of the number of items in the
+ 	box.
+	(syms_of_glyphs_widget): move widget keywords here.
+	(image_instantiator_format_create_glyphs_widget): use new combo
+ 	functions.
+
+1998-12-04  Andy Piper  <andy@xemacs.org>
+
+	* event-msw.c (mswindows_wnd_proc): mule-ize.
+
+	* glyphs.c (pixmap_to_lisp_data): mule-ize.
+
+	* glyphs-msw.c (extract_xpm_color_names): mule-ize.
+	(resource_name_to_resource): ditto.
+	(mswindows_resource_instantiate): ditto.
+	(mswindows_widget_instantiate): ditto.
+	(mswindows_widget_set_property): ditto.
+
+	* redisplay-output.c (redisplay_output_subwindow): don't show
+ 	subwindows if they are obscured at the edge of the frame, emacs
+ 	gets into some sort of redisplay loop otherwise.
+
+	* gui.h: prototype gui_item_selected_p.
+
+	* gui.c (gui_item_selected_p): new function to determine the
+ 	selected state of a gui_item.
+
+	* frame.h (struct frame): add subwindows_changed flag.
+
+	* redisplay.c (redisplay_frame): call update_frame_subwindows ().
+
+	* glyphs.c (update_subwindow): new function to update a
+ 	subwindow's state.
+	(update_frame_subwindows): new function to update all the
+ 	subwindows on a frame.
+
+	* console.h (struct console_methods): add update_subwindow.
+
+	* glyphs-msw.c (mswindows_widget_property): return selected state
+ 	for selected property.
+	(mswindows_update_subwindow): new function. updates widget glyphs
+ 	in redisplay as per menubars or toolbars e.g. selected state.
+	(console_type_create_glyphs_mswindows): add update_subwindow.
+
+1998-12-03  Andy Piper  <andy@xemacs.org>
+
+	* console-tty.c (syms_of_console_tty): MULE -> FILE_CODING since
+ 	tty coding system things are such.
+
+	* glyphs-widget.c (widget_face_font_info): new function for
+ 	pulling out height and width metrics for a widget's face.
+	(widget_text_to_pixel_conversion): calculate pixel sizes of text
+ 	for widgets.
+
+	* event-msw.c (mswindows_drain_windows_queue): translate messages
+ 	that are destined for subwindows. This makes edit fields interact
+ 	with the keyboard correctly.
+	nuke warnings by #ifndef'ing out stuff not required by msg select().
+
+	* glyphs.h (INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM): new
+ 	macro defining the iiforma without the symbol required by widget.
+	(INITIALIZE_IMAGE_INSTANTIATOR_FORMAT): use it.
+
+	* general.c (syms_of_general): add Qwidget, Qselected.
+
+	* faces.c (complex_vars_of_faces): add widget face inheriting from
+ 	gui-element face.
+
+1998-11-09  Andy Piper  <andy@xemacs.org>
+
+	* window.h (struct window): add a cache of subwindows on a
+ 	per-window basis.
+
+	* window.c (mark_window): mark the subwindow_instance_cache.
+	(allocate_window): initialise the subwindow instance_cache.
+
+	* toolbar-x.c (x_output_toolbar): call redisplay_clear_region
+ 	instead of the devmeth.
+	(x_clear_toolbar): ditto.
+
+	* redisplay-x.c (x_output_display_block): call
+ 	redisplay_output_subwindow for subwindows and widgets.
+
+	* redisplay-tty.c (tty_output_display_block): add IMAGE_WIDGET to
+ 	types to do nothing for.
+
+	* lisp.h: declare new widget/subwindow symbols.
+
+	* glyphs.c (image_instantiate): cache subwindows on a per-window
+ 	basis.
+	(subwindow_possible_dest_types): new function for subwindow dest
+ 	types.
+	(subwindow_instantiate): generic instantiation of a
+ 	subwindow. specialised by device multi-methods.
+	(Fsubwindowp): moved from glyphs-x.c. adapted for glyph-based
+ 	subwindows.
+	(Fimage_instance_subwindow_id): ditto.
+	(Fresize_subwindow): ditto.
+	(Fforce_subwindow_map): ditto.
+
+	* glyphs-x.c (x_print_image_instance): remove subwindow
+ 	stuff. Handled genrically in glyphs.c.
+	(x_image_instance_equal): ditto.
+	(x_image_instance_hash): ditto.
+	(x_finalize_image_instance): delete subwindows when required.
+	(mark_subwindow) (print_subwindow) (finalize_subwindow)
+ 	(subwindow_hash) (Fmake_subwindow): deleted because of new,
+ 	glyph-based, subwindow implementation.
+	(Fsubwindow_height) (Fsubwindow_width) (Fsubwindow_xid): aliased
+ 	in glyphs.el
+	(Fsubwindowp) (Fresize_subwindow) (Fforce_subwindow_map): moved to
+ 	glyphs.c.
+	(x_unmap_subwindow): new function to unmap X subwindows.
+	(x_map_subwindow): new function to map X subwindows.
+	(x_subwindow_instantiate): new function to instantiate X
+ 	subwindows.
+	(x_resize_subwindow): new function to resize X subwindows.
+	(console_type_create_glyphs_x): add subwindow functions.
+	(image_instantiator_format_create_glyphs_x): add device
+ 	multi-methods for xpm, xbm and subwindow.
+
+	* glyphs.el (subwindow-xid): old alias for new subwindow functions.
+	(subwindow-width): ditto.
+	(subwindow-height): ditto.
+
+	* glyphs-msw.c (mswindows_widget_instantiate): new function for
+ 	generally instantiating ms subwindows. Used by
+ 	mswindows_*_instantiate.
+	(mswindows_edit_instantiate): instantiate an edit field on a
+ 	mswindows frame.
+
+1998-11-04  Andy Piper  <andy@xemacs.org>
+
+	* symsinit.h: declare new functions.
+
+	* redisplay.h: declare new functions.
+
+	* redisplay-x.c (x_output_display_block): call
+ 	redisplay_clear_region rather than x_clear_region.
+	(x_output_string): ditto.
+	(x_output_pixmap): ditto.
+	(x_clear_to_window_end): ditto.
+	(x_output_eol_cursor): ditto.
+	(x_clear_region): only do X specific things. other duties handled
+ 	in redisplay_clear_region.
+
+	* redisplay-tty.c (tty_clear_region): do tty specific things - some
+ 	duties moved to redisplay_clear_region.
+
+	* redisplay-output.c (clear_left_border): use
+ 	redisplay_clear_region instead of device method.
+	(clear_right_border): ditto.
+	(output_display_line): ditto.
+	(redisplay_output_subwindow): ditto.
+	(redisplay_clear_top_of_window): ditto.
+	(redisplay_clear_region): perform duties previously handled by
+ 	device methods. call the appropriate device method at the
+ 	end. unmap subwindows if necessary.
+
+	* redisplay-msw.c (mswindows_output_string): use
+ 	redisplay_clear_region instead of mswindows_clear_region.
+	(mswindows_clear_to_window_end): ditto.
+	(mswindows_output_display_block): output subwindows when required.
+	(mswindows_clear_region): only do mswindows specific things,
+ 	everything else is now handled in redisplay_clear_region.
+
+	* gui.h: add item id hash defines and declare function prototypes.
+
+	* gui.c (mark_gui_item): new function for marking gui_items.
+	(gui_item_hash): generic hash function for generating command ids
+ 	for gui_items.
+
+	* gui-msw.c: new file.
+	(mswindows_handle_gui_wm_command): new function to handle widget
+ 	callbacks.
+
+	* glyphs.h (MAYBE_IIFORMAT_DEVMETH): new function for device
+ 	multi-methods.
+	(IIFORMAT_HAS_SHARED_METHOD): ditto.
+	(DEFINE_DEVICE_IIFORMAT): ditto.
+	(INITIALIZE_DEVICE_IIFORMAT): ditto.
+	(struct Lisp_Image_Instance): add widget and subwindow data plus
+ 	appropriate access functions.
+
+	* glyphs.c (decode_device_ii_format): new function for decoding
+ 	image instantiator functions based on a device type as well as an
+ 	image format.
+	(decode_image_instantiator_format): just call
+ 	decode_device_ii_format with nil device.
+	(add_entry_to_device_ii_format_list): new function for per device
+ 	method instances.
+	(add_entry_to_image_instantiator_format_list): just call
+ 	add_entry_to_device_ii_format_list with nil device.
+	(check_valid_vector): new function.
+	(instantiate_image_instantiator): instantiate using per-format
+ 	method and then per-format-per-device method (device
+ 	multi-methods). signal an error if neither is possible.
+	(mark_image_instance): cope with subwindows and widgets.
+	(print_image_instance): ditto.
+	(image_instance_equal): ditto.
+	(image_instance_hash): ditto.
+	(allocate_glyph): ditto.
+	(glyph_width): ditto.
+	(glyph_height_internal): ditto.
+	(xpm_instantiate): removed because of device multi-methods.
+	(mark_subwindow_cachels): new cachel functions for caching
+ 	instantiated subwindows on a per-frame basis. mostly copied from
+ 	glyph cachel functions.
+	(update_subwindow_cachel_data): ditto.
+	(add_subwindow_cachel): ditto.
+	(get_subwindow_cachel_index): ditto.
+	(reset_subwindow_cachels): ditto.
+	(mark_subwindow_cachels_as_not_updated): ditto.
+	(unmap_subwindow): generic unmapping of subwindows based on cachel
+ 	data.
+	(map_subwindow): ditto.
+	(initialize_subwindow_image_instance): generic initialisation of
+ 	subwindow data.
+	(syms_of_glyphs): add widget keywords.
+
+	* glyphs-x.h (struct x_subwindow_data): convert Lisp_Subwindow to
+ 	x_subwindow_data.
+
+1998-11-04  Andy Piper  <andy@xemacs.org>
+
+	* glyphs-widget.c: new file for instantiating widget type glyphs.
+	(widget_possible_dest_types): new general dest type function for
+ 	widgets.
+	(widget_validate): ditto.
+	(initialize_widget_image_instance): ditto
+	(widget_instantiate): ditto. Sets up fg/bg, gui_item parsing
+ 	before handing on control to device multi-methods.
+	(syms_of_glyphs_widget): new function.
+	(image_instantiator_format_create_glyphs_widget): new function,
+ 	added placeholders for button, edit, combo, scrollbar
+	(vars_of_glyphs_widget): new function.
+
+	* glyphs-msw.h (WIDGET_INSTANCE_MSWINDOWS_HANDLE): new define for
+ 	storing window ids of widgets.
+
+	* glyphs-msw.c (mswindows_finalize_image_instance): cope with
+ 	deletion of widget and subwindow glyphs.
+	(mswindows_unmap_subwindow): new device function for unmapping
+ 	subwindows on a msw frame.
+	(mswindows_map_subwindow): ditto.
+	(mswindows_register_image_instance): register instantiated widgets
+ 	with the widget hastable.
+	(mswindows_button_instantiate): instantiate a button type widget
+ 	on an msw frame.
+	(mswindows_subwindow_instantiate): instanttiate a subwindow on a
+ 	mswindows frame.
+	(image_instantiator_format_create_glyphs_mswindows): add device
+ 	multi-methods for xbm, xpm, subwindow, edit and button.
+
+	* frame.h (struct frame): add subwindow_cachels dynarr for caching
+ 	information about subwindows visible on the current frame. used by
+ 	redisplay_clear_region to unmap subwindows as required.
+
+	* frame.c (mark_frame): mark subwindow_cachels.
+	(allocate_frame_core): instantiate subwindow_cachels.
+
+	* frame-msw.c (mswindows_init_frame_1): instntiate and mark the
+ 	widget hashtable.
+
+	* event-msw.c (mswindows_wnd_proc): add call to
+ 	mswindows_handle_gui_wm_command to handle widget callbacks.
+
+	* emacs.c (main_1): add calls to glyphs-widget initialisation
+ 	routines.
+
+	* console.h (struct console_methods): add
+ 	unmap/map_subwindow_method for use be redisplay_clear_region to
+ 	map and unmap subwindows. Remove xpm and xbm stuff - now dealt
+ 	with by image instantiator multi-methods. Add
+ 	resize_subwindow_method.
+
+	* console-stream.c (stream_clear_region): change signature to
+ 	match new generic clear region function.
+
+	* Makefile.in.in: add glyphs-widget.o to list of objects.
+
+	* console-msw.h (struct mswindows_frame): add widget hashtable for
+ 	wiring command ids to callbacks.
+
 1998-12-16  Andy Piper  <andy@xemacs.org>
 
 	* XEmacs 21.2.6 is released
@@ -23,11 +673,11 @@
 	- Don't use variable name `new'.
 	- Use size_t instead of EMACS_INT.
 	- usual Martin-style pointless bit-twiddling.
-	
-	* fns.c (mapcar1): 
-	(Fmapconcat): 
-	(Fmapcar): 
-	(Fmapvector): 
+
+	* fns.c (mapcar1):
+	(Fmapconcat):
+	(Fmapcar):
+	(Fmapvector):
 	Make mapcar faster.  In particular, make
 	  (mapc #'identity long-string)
 	MUCH faster under Mule.
@@ -35,7 +685,7 @@
 
 1998-12-06  Martin Buchholz  <martin@xemacs.org>
 
-	* bytecode.c (Ffetch_bytecode): Fix crash when loading lazy-loaded 
+	* bytecode.c (Ffetch_bytecode): Fix crash when loading lazy-loaded
 	bytecode.
 
 1998-12-13  Martin Buchholz  <martin@xemacs.org>
@@ -45,10 +695,10 @@
 
 1998-12-11  Martin Buchholz  <martin@xemacs.org>
 
-	* events.h (struct timeout_data): 
-	* event-tty.c (tty_timeout_to_emacs_event): 
-	* event-msw.c (mswindows_wm_timer_callback): 
-	* event-Xt.c (Xt_timeout_to_emacs_event): 
+	* events.h (struct timeout_data):
+	* event-tty.c (tty_timeout_to_emacs_event):
+	* event-msw.c (mswindows_wm_timer_callback):
+	* event-Xt.c (Xt_timeout_to_emacs_event):
 	* event-msw.c (mswindows_cancel_dispatch_event):
 	Make sure Lisp_Objects inside events are initialized to Qnil, not
 	Qnull_pointer, which is now illegal.
@@ -65,15 +715,15 @@
 1998-12-07  Martin Buchholz  <martin@xemacs.org>
 
 	* opaque.h:
-	* console-msw.c (DHEADER): 
-	(DOPAQUE_DATA): 
-	(DEVENT): 
-	(DCONS): 
-	(DCONSCDR): 
-	(DSTRING): 
-	(DVECTOR): 
-	(DSYMBOL): 
-	(DSYMNAME): 
+	* console-msw.c (DHEADER):
+	(DOPAQUE_DATA):
+	(DEVENT):
+	(DCONS):
+	(DCONSCDR):
+	(DSTRING):
+	(DVECTOR):
+	(DSYMBOL):
+	(DSYMNAME):
 	- max_align_t should not be visible to the user of the
 	  XOPAQUE_DATA macro.
 	- use Bufbyte instead of char
@@ -83,7 +733,7 @@
 
 1998-12-07  Martin Buchholz  <martin@xemacs.org>
 
-	* sysdep.c (set_descriptor_non_blocking): 
+	* sysdep.c (set_descriptor_non_blocking):
 	Since O_NONBLOCK is now always #defined, make use of fcntl
 	conditional on F_SETFL being defined.
 
@@ -101,7 +751,7 @@
 
 	* windowsnt.h: Remove `support' for using index and rindex
 
-	* filelock.c (current_lock_owner): 
+	* filelock.c (current_lock_owner):
 	- Change uses of index -> strchr, rindex -> strrchr
 
 1998-12-06  Martin Buchholz  <martin@xemacs.org>
@@ -771,7 +1421,7 @@
 	- rewrite basic lisp functions for speed
 	- rewrite bytecode interpreter for speed
 	- rewrite list looping constructs for speed and safety using
-	  tortoise/hare. 
+	  tortoise/hare.
 	- use size_t where appropriate.
 	- new hashtable implementation
 	- cleanup implementation of opaques
@@ -792,7 +1442,7 @@
 	- use O_RDONLY and O_RDWR instead of magic `0' and `2'.
 	- define (and maybe use!) STDERR_FILENO and friends.
 	- add support for macros defined in C
-	- `when', `unless', `not' and `defalias' now defined in C, 
+	- `when', `unless', `not' and `defalias' now defined in C,
 	  so that they are universally available.
 	- rename defvar_mumble to defvar_magic
 	- rename RETURN__ to RETURN_SANS_WARNINGS
@@ -837,7 +1487,7 @@
 
 1998-11-27  Hrvoje Niksic  <hniksic@srce.hr>
 
-	* dired.c (make_directory_hash_table): make_string() is OK because 
+	* dired.c (make_directory_hash_table): make_string() is OK because
 	readdir() Mule-encapsulates.
 
 1998-11-26  Hrvoje Niksic  <hniksic@srce.hr>
@@ -852,7 +1502,7 @@
 
 1998-11-25  Hrvoje Niksic  <hniksic@srce.hr>
 
-	* editfns.c (Ftranslate_region): Accept vectors and char-tables as 
+	* editfns.c (Ftranslate_region): Accept vectors and char-tables as
 	well as strings.
 	(Ftranslate_region): Turn table into an array of Emchars for
 	larger regions.
@@ -880,7 +1530,7 @@
 
 	* process-unix.c (unix_create_process): handle properly
 	Vfile_name_coding_system for converting the program and directory
-	names. 
+	names.
 
 1998-11-27  SL Baur  <steve@altair.xemacs.org>
 
@@ -902,7 +1552,7 @@
 	* fns.c (free_malloced_ptr): New function.
 	(XMALLOC_OR_ALLOCA): New macro.
 	(XMALLOC_UNBIND): Ditto.
-	(Fbase64_encode_region): Use malloc() for large blocks; arrange it 
+	(Fbase64_encode_region): Use malloc() for large blocks; arrange it
 	to be freed in case of non-local exit.
 	(Fbase64_encode_string): Ditto.
 	(Fbase64_decode_region): Ditto.
@@ -1015,7 +1665,7 @@
 
 1998-10-07  Jonathan Harris  <jhar@tardis.ed.ac.uk>
 
-	* scrollbar-msw.c: Use the same vertical scrollbar drag hack as 
+	* scrollbar-msw.c: Use the same vertical scrollbar drag hack as
 	  is used for Motif or Lucid scrollbars under X.
 
 1998-10-08  Pierre Wendling  <pw@ebc.vbe.dec.com>
@@ -1070,9 +1720,9 @@
 	  mswindows_enumerate_fonts() function in objects-msw.c instead
 	  of font_enum_callback_1() to enumerate fonts.
 
-	  font_enum_callback_1() and _2() moved to objects-msw.c. 
-
-	* faces.c (complex_vars_of_faces): Make the mswindows default 
+	  font_enum_callback_1() and _2() moved to objects-msw.c.
+
+	* faces.c (complex_vars_of_faces): Make the mswindows default
 	  face font fully specified and provide some fallbacks.
 
 	* objects-msw.c: font_enum_callback_1() and _2() moved here
@@ -1100,7 +1750,7 @@
 	  sig_enable_code_end() since they are now redundant.
 
 	  send_signal() and enable_child_signals(): Don't try to work
-	  out the end of the code fragments passed to 
+	  out the end of the code fragments passed to
 	  run_in_other_process()
 
 1998-09-10  Kazuyuki IENAGA  <ienaga@jsys.co.jp>
@@ -1182,14 +1832,14 @@
 
 	* filelock.c: Replaced by version from FSF 20.2. Now implements
 	locking by using symlinks which is NFS safe. However keep the
-	GCPRO's in lock_file and the calls to callx_in_buffer like our old 
+	GCPRO's in lock_file and the calls to callx_in_buffer like our old
 	version (and of course use ansi C, acessor macros, etc).
 
 1998-09-06  Jan Vroonhof  <vroonhof@math.ethz.ch>
 
 	* process-unix.c (unix_create_process): Reset SIGHUP handler to
 	SIG_DFL. We now try to conserve any inherted SIG_IGN settings
-	in init_signals_very_early. However these should not be passed 
+	in init_signals_very_early. However these should not be passed
 	on to children attached to the new pty.
 
 1998-08-28  Andy Piper  <andyp@parallax.co.uk>
@@ -1199,7 +1849,7 @@
 1998-09-07  Jonathan Harris  <jhar@tardis.ed.ac.uk>
 
 	* fileio.c (file-name-directory, file_name_as_directory):
-	  Don't call CORRECT_DIR_SEPS, even when #defined WINDOWSNT. 
+	  Don't call CORRECT_DIR_SEPS, even when #defined WINDOWSNT.
 
 1998-09-02  Andy Piper  <andyp@parallax.co.uk>
 
@@ -1235,7 +1885,7 @@
 
 	* frame-x.c (x_delete_frame): Flush the X output buffer after
 	calling XtDestroyWidget to ensure that the windows are really
-	killed right now. 
+	killed right now.
 
 1998-08-26  Hrvoje Niksic  <hniksic@srce.hr>
 
@@ -1263,7 +1913,7 @@
 	all the buffers.
 	(buffer_delete_range): Ditto.
 
-	* marker.c (init_buffer_markers): Set point-marker to the value of 
+	* marker.c (init_buffer_markers): Set point-marker to the value of
 	point in an indirect buffer.
 
 1998-08-30  Hrvoje Niksic  <hniksic@srce.hr>
@@ -1343,7 +1993,7 @@
 
 1998-08-07 Matt Stupple <matts@tibco.com>
 
-        * ntproc.c: don't wait on char_consumed at thread entry. 
+        * ntproc.c: don't wait on char_consumed at thread entry.
 	Additionally, to get the 'process' marked as finished, ensure
 	that the CHILD_ACTIVE macro returns false, so before exiting
 	close char_avail and set it to NULL, and close other handles
@@ -1370,7 +2020,7 @@
 
 1998-07-20  Martin Buchholz  <martin@xemacs.org>
 
-	* casefiddle.c (casify_object): 
+	* casefiddle.c (casify_object):
 	Change algorithm from O(N**2) to O(N).
 	Code cleanup.
 	Doc string cleanup.
@@ -1473,7 +2123,7 @@
 1998-07-16  Jan Vroonhof  <vroonhof@math.ethz.ch>
 
 	* event-Xt.c (x_to_emacs_keysym): Return nil for modifier keysyms.
-	(x_event_to_emacs_event): Let x_to_emacs_keysym check for modifier 
+	(x_event_to_emacs_event): Let x_to_emacs_keysym check for modifier
 	keys thus no longer considering all keysyms on a key.
 
 1998-07-19  SL Baur  <steve@altair.xemacs.org>
@@ -1604,7 +2254,7 @@
 
 	* eval.c (run_hook_with_args_in_buffer): Check
 	  default (non-buffer-local) value of hook for
-	  nil before treating it as a function.  Don't initialize 
+	  nil before treating it as a function.  Don't initialize
 	  the `globals' variable twice.
 
 1998-06-24  Jonathan Harris  <jhar@tardis.ed.ac.uk>
@@ -1635,7 +2285,7 @@
 
 	* eval.c (run_hook_with_args_in_buffer): Don't treat
 	  the default value of a buffer local hook as a list of
-	  hooks unless it is both a cons and the car of that cons 
+	  hooks unless it is both a cons and the car of that cons
 	  is not Qlambda.
 
 1998-06-29  SL Baur  <steve@altair.xemacs.org>
@@ -1665,7 +2315,7 @@
 	* winslots.h: Rename.
 
 	* window.c (specifier_vars_of_window): Renamed
-	vertical-divider-draggable-p to vertical-divider-always-visible-p, 
+	vertical-divider-draggable-p to vertical-divider-always-visible-p,
 	as suggested by Ben Wing.
 	(specifier_vars_of_window): Fix docstrings.
 
@@ -1701,7 +2351,7 @@
 	Set last_known_column_point to the buffer position for
 	which the column was requested, not buffer's point.
 
-	* redisplay.c (decode_mode_spec): for current-column, show 
+	* redisplay.c (decode_mode_spec): for current-column, show
 	window's point's column, not buffer's point's column.
 
 1998-06-23  Andy Piper  <andyp@parallax.co.uk>
@@ -1800,7 +2450,7 @@
 	mswindows_size_frame_internal function and size frame if frame
 	parameters not just if init is finished - WM_SIZE happens too
 	early for some specs. (mswindows_size_frame_internal): new
-	function abstracted from mswindows_set_frame_properties. 
+	function abstracted from mswindows_set_frame_properties.
 	(Vmswindows_use_system_frame_size_defaults):
 	new variable controls whether to allow the system to pick frame
 	size defaults, defaults to nil.
@@ -1824,7 +2474,7 @@
 
 1998-06-05  Hrvoje Niksic  <hniksic@srce.hr>
 
-	* eldap.c (Fldap_search_internal): Use build_ext_string instead of 
+	* eldap.c (Fldap_search_internal): Use build_ext_string instead of
 	build_string to avoid crashes under Mule.
 
 1998-06-13  Andy Piper  <andyp@parallax.co.uk>
@@ -2017,7 +2667,7 @@
 
 	* glyphs-msw.c (read_bitmap_data) (NextInt)
 	(read_bitmap_data_from_file): new functions copied from Xmu
-	sources. 
+	sources.
 	(xbm_create_bitmap_from_data) from Ben <ben@666.com> convert
 	inline data to an mswindows bitmap.
 	(init_image_instance_from_xbm_inline) (xbm_instantiate_1)
@@ -2063,7 +2713,7 @@
 	Added prototype for mswindows_enqueue_misc_user_event().
 
 	* menubar-msw.c (mswindows_handle_wm_command): Use
-	mswindows_enqueue_misc_user_event(). 
+	mswindows_enqueue_misc_user_event().
 
 	* toolbar-msw.c (mswindows_handle_toolbar_wm_command): Ditto.
 
@@ -2076,11 +2726,11 @@
 1998-05-29  Greg Klanderman  <greg@alphatech.com>
 
 	* window.c (Fwindow_displayed_text_pixel_height): was relying on
-	incorrect semantics of vmotion_pixels which has been fixed.  don't 
+	incorrect semantics of vmotion_pixels which has been fixed.  don't
 	use it anymore as it can't easily be used.
 
 	* indent.c (vmotion_pixels): fix off by one bug moving up.  also
-	the motion was reported incorrectly if you tried to go past end of 
+	the motion was reported incorrectly if you tried to go past end of
 	buffer.
 
 1998-05-30  Kirill M. Katsnelson  <kkm@kis.ru>
@@ -2106,11 +2756,11 @@
 
 1998-05-28  Martin Buchholz  <martin@xemacs.org>
 
-	* alloc.c (dbg_constants): 
+	* alloc.c (dbg_constants):
 	* dbxrc:
 	* gdbinit:
 	Remove toolbar_data debugging code, since that lrecord has
-	also been removed. 
+	also been removed.
 
 Wed May 27, 1998  Darryl Okahata  <darrylo@sr.hp.com>
 
@@ -2141,7 +2791,7 @@
 	* fileio.c: replaced egetenv("HOME") with calls to the new
 	  get_home_directory().
 
-	* lisp.h: Added function prototypes for uncache_home_directory() 
+	* lisp.h: Added function prototypes for uncache_home_directory()
 	  and get_home_directory(), along with lisp prototypes for
 	  Fuser_home_directory() and friends.
 
@@ -2158,7 +2808,7 @@
 
 	* event-msw.c (mswindows_wnd_proc, WM_KEYDOWN): Unconditionally
 	remove MOD_SHIFT from ASCII characters.
-	(mswindows_wnd_proc, WM_KEYDOWN): Do not activate the menubar when 
+	(mswindows_wnd_proc, WM_KEYDOWN): Do not activate the menubar when
 	F10 is pressed.
 
 1998-05-24  Oliver Graf <ograf@fga.de>
@@ -2195,10 +2845,10 @@
 	(syms_of_indent): DEFSUBR.
 	* lisp.h: declaration for vmotion_pixels().
 
-	* indent.c (Fvertical_motion): Add optional third argument PIXELS, 
+	* indent.c (Fvertical_motion): Add optional third argument PIXELS,
 	to request returning motion in pixels.
 	(Fvertical_motion_pixels): Remove, functionality merged into
-	Fvertical_motion. 
+	Fvertical_motion.
  	* window.c (window_scroll): call Fvertical_motion with 3 arguments.
 	(Fmove_to_window_line): ditto.
 	* lisp.h: Change declaration for Fvertical_motion.
@@ -2212,7 +2862,7 @@
 	Tooltalk_Message_plist_str and Tooltalk_Pattern_plist_str
 
 1998-05-27  Andy Piper  <andyp@parallax.co.uk>
-		
+
 	* faces.c: create a new 3d_object_face, make modeline and
 	vertical_divider faces fallback to this rather than the default.
 
@@ -2260,9 +2910,9 @@
 	* This patch is to fix compilation warnings under Windows.
 
 	* s/windowsnt.h: Encapsulate getpid with sys_getpid.
-	Added prototypes for FSF inherited functions, with which XEmacs is 
+	Added prototypes for FSF inherited functions, with which XEmacs is
 	sprinkled thoroughly.
-	Removed some #if 0 code. Bracketed some more definitions, probably 
+	Removed some #if 0 code. Bracketed some more definitions, probably
 	related to Visual C versions prior to 4 (we do not support them).
 
 	* sysfloat.h (logb): Finally, get logb() prototyped.
@@ -2278,10 +2928,10 @@
 	vars_of_dired_mswindows and init_ntproc (Grrr).
 
 	* realpath.c: Added Windows specific include files.
-	(xrealpath): Conditionalized declaration of some auto variables on 
+	(xrealpath): Conditionalized declaration of some auto variables on
 	S_IFLNK, to avoid warnings.
 
-	* ntproc.c: Disabled some compiler warnings. This file is going to 
+	* ntproc.c: Disabled some compiler warnings. This file is going to
 	die, so I have not cleaned it up much.
 	(set_process_dir): Const parameter.
 	(Fwin32_short_file_name): Down CHECK_* macros to one argument.
@@ -2357,7 +3007,7 @@
 
 	* symsinit.h: Prototyped the above functions.
 
-	* dialog-x.c (x_popup_dialog_box): Moved dialog descriptor consistency 
+	* dialog-x.c (x_popup_dialog_box): Moved dialog descriptor consistency
 	checks to dialog.c...
 
 	* dialog.c (Fpopup_dialog_box): ...right here. Added more checks: a
@@ -2410,7 +3060,7 @@
 
 	* EmacsFrame.c (Xt_StringToScrollBarPlacement):  Added support for
 	{top,bottom}-{left,right} values in addition to
-	{top,bottom}_{left,right}. 
+	{top,bottom}_{left,right}.
 
 1998-05-18  Hrvoje Niksic  <hniksic@srce.hr>
 
@@ -2421,10 +3071,10 @@
 
 1998-05-19  Martin Buchholz  <martin@xemacs.org>
 
-	* unexhp9k800.c: 
-	* sound.c (vars_of_sound): 
-	* sysdep.c (reset_sigio_on_device): 
-	* window.c (window_bottom_gutter_height): 
+	* unexhp9k800.c:
+	* sound.c (vars_of_sound):
+	* sysdep.c (reset_sigio_on_device):
+	* window.c (window_bottom_gutter_height):
 	unexhp9k800.c:258: warning: implicit declaration of function
 	`calculate_checksum'
 	sound.c:604: warning: implicit declaration of function `vars_of_hpplay'
@@ -2454,7 +3104,7 @@
 	* frame-x.c (x_update_frame_external_traits): Start preprocessor
 	directives in column 1.
 
-	* search.c (skip_chars): Avoid using xzero with arrays, since some 
+	* search.c (skip_chars): Avoid using xzero with arrays, since some
 	compilers get confused by the construct &array.
 
 1998-05-18  Kirill M. Katsnelson  <kkm@kis.ru>
@@ -2478,7 +3128,7 @@
 1998-05-18  Kirill M. Katsnelson  <kkm@kis.ru>
 
 	* objects-msw.c (mswindows_initialize_font_instance): Use ANSI
-	charset when creating font. 
+	charset when creating font.
 	(mswindows_initialize_color_instance): Do not create brush along
 	with a color.
 	(mswindows_finalize_color_instance): Do not delete it then.
@@ -2502,7 +3152,7 @@
 	(compute_frame_toolbars_data): Removed unused second parameter;
 	Adjusted callers of this static function throughout the file.
 	(init_frame_toolbars): Initialize current_toolbar_size.
-	(update_frame_toolbars): Use DEVICE_SUPPORTS_TOOLBARS_P instead of 
+	(update_frame_toolbars): Use DEVICE_SUPPORTS_TOOLBARS_P instead of
 	what is its current expansion, for clarity.
 	(init_frame_toolbars): Ditto.
 	(init_device_toolbars): Ditto.
@@ -2547,7 +3197,7 @@
 
 	* emacs.c (main_1): Call syms_of_process_nt()
 
-	* process-nt.c: Quote process arguments by a call to Lisp function 
+	* process-nt.c: Quote process arguments by a call to Lisp function
 	`nt-quote-process-args'.
 	(syms_of_process_nt): New function.
 	(nt_send_process): Flush data stream after each write, to avoid
@@ -2572,7 +3222,7 @@
 
 1998-05-17  Michael Sperber [Mr. Preprocessor]  <sperber@informatik.uni-tuebingen.de>
 
-	* s/aix4-2.h (ALIGN_DATA_RELOC): Undefined to support new unexaix.c. 
+	* s/aix4-2.h (ALIGN_DATA_RELOC): Undefined to support new unexaix.c.
 
 	* s/aix3-1.h (ALIGN_DATA_RELOC): Defined to support new unexaix.c.
 
@@ -2644,7 +3294,7 @@
 
 	* bufslots.h: Removed buffer_file_type slot.
 
-	* buffer.c (complex_vars_of_buffer): Removed buffer_file_type from 
+	* buffer.c (complex_vars_of_buffer): Removed buffer_file_type from
 	buffer local flags.
 	(complex_vars_of_buffer): Removed buffer-file-type variable and
 	its default reference.
@@ -2673,9 +3323,9 @@
 	(x_divider_width): ditto.
 
 	* window.c (specifier_vars_of_window): new specifiers:
-	vertical-divier -line-width and -spacing. 
+	vertical-divier -line-width and -spacing.
 	(vertical_divider_global_width_changed): formerly known as
-	vertical_divider_shadow_thickness_changed. 
+	vertical_divider_shadow_thickness_changed.
 
 	* winslots.h: new slots: vertical_specifier _line_width and
 	_spacing. Plus corrected a comment typo.
@@ -2688,7 +3338,7 @@
 	(console_type_create_stream): And declaration for it.
 
 	* redisplay.c (pixel_to_glyph_translation): Use
-	window_divider_width() instead of divider_width redisplay method. 
+	window_divider_width() instead of divider_width redisplay method.
 	(pixel_to_glyph_translation): Fix top divider edge calculation
 	when scrollbar is on top.
 
@@ -2698,7 +3348,7 @@
 	(specifier_vars_of_window): For	vertical-divider-{spacing,line-width}
 	specifiers, set fallback values differently on TTYs, and document
 	the behavior of these on TTYs in the docstrings.
-	
+
 	* scrollbar.c (update_scrollbar_instance): Use
 	window_divider_width() instead of divider_width redisplay method.
 
@@ -2753,7 +3403,7 @@
 
 	* emacs.c (main_1): Call console_type_create_dialog_x().
 
-	* dialog-x.c (x_popup_dialog_box): Old Fpopup_dialog_box converted 
+	* dialog-x.c (x_popup_dialog_box): Old Fpopup_dialog_box converted
 	into this device method.
 	(console_type_create_dialog_x): New function.
 
@@ -2761,7 +3411,7 @@
 	(syms_of_dialog): Defsubr it.
 
 	* console.h (struct console_methods): Declared
-	popup_dialog_box_method(). 
+	popup_dialog_box_method().
 
 	* symsinit.h: Defined console_type_create_dialog_{x,mswindows}
 
@@ -2799,10 +3449,10 @@
 	** Renamed window-divider-map => vertical-divider-map
 	and event-over-divider-p => event-over-vertical-divider-p,
 	in the following files/functions:
-	* events.h: 
-	* events.c (Fevent_over_divider_p): 
-	* keymap.c (get_relevant_keymaps): 
-	(vars_of_keymap): 
+	* events.h:
+	* events.c (Fevent_over_divider_p):
+	* keymap.c (get_relevant_keymaps):
+	(vars_of_keymap):
 
 	* redisplay.h (OVER_V_DIVIDER): Renamed so from OVER_DIVIDER.
 
@@ -2825,7 +3475,7 @@
 
 	* window.h: Prototype invalidate_vertical_divider_cache_in_window.
 	(struct window): Added need_vertical_divider_p and
-	need_vertical_divider_valid_p. 
+	need_vertical_divider_valid_p.
 
 	* winslots.h: Added vertical_divider_draggable_p slot.
 
@@ -2881,7 +3531,7 @@
 	thickness is negative.
 
 	* console-stream.c (stream_divider_width): pass a struct window *
-	argument. 
+	argument.
 
 	* redisplay-tty.c (tty_divider_width): ditto.
 
@@ -2890,12 +3540,12 @@
 	* redisplay.c (generate_modeline): ittod.
 
 	* scrollbar.c (update_scrollbar_instance): ttido.
-	
-	* redisplay-msw.c (mswindows_divider_width): ottid. 
+
+	* redisplay-msw.c (mswindows_divider_width): ottid.
 	WARNING: this enables to compile, but the feature is not functional.
 
 	* window.h (struct window): new field
-	vertical_divider_shadow_thickness. 
+	vertical_divider_shadow_thickness.
 
 	* window.c (specifier_vars_of_window): new specifier
 	vertical-divider-shadow-thickness.
@@ -2946,7 +3596,7 @@
 1998-05-10  Andy Piper  <andyp@parallax.co.uk>
 
 	* redisplay-msw.c (mswindows_output_dibitmap_region): make sure
-	multiple bitmaps are output vertically as well as horizontally.  
+	multiple bitmaps are output vertically as well as horizontally.
 	* (mswindows_output_dibitmap): don't cope with bitmap boundaries
 	crossing lines this is handled by
 	mswindows_output_dibitmap_region.
@@ -2955,7 +3605,7 @@
 
 	* inline.c: Include eldap.h
 
-	* menubar-x.c (x_update_frame_menubar_internal): 
+	* menubar-x.c (x_update_frame_menubar_internal):
 	Remove: unused variable `container'
 
 1998-05-11  Martin Buchholz  <martin@xemacs.org>
@@ -2963,8 +3613,8 @@
 	* s/aix4.h: Allow AIX 4.3 XEmacs to compile cleanly.
 	Unfortunately, the resulting temacs still cannot dump.
 
-	* symbols.c (symbol_is_constant): 
-	(verify_ok_for_buffer_local): 
+	* symbols.c (symbol_is_constant):
+	(verify_ok_for_buffer_local):
 	-Wswitch Warning suppression - add default case to switches.
 
 	* redisplay.c (decode_mode_spec): Remove unused variables,
@@ -3011,7 +3661,7 @@
 1998-05-12  Didier Verna  <verna@inf.enst.fr>
 
 	* redisplay.c: removed the scrolling modeline code that didn't
-	make it for 21.0. To be continued ... 
+	make it for 21.0. To be continued ...
 
 1998-05-13  Michael Sperber [Mr. Preprocessor]  <sperber@informatik.uni-tuebingen.de>
 
@@ -3068,7 +3718,7 @@
 	(mswindows_output_vertical_divider): Always output the divider on
 	the right side of a window, down to bottom.
 
-	* keymap.c (get_relevant_keymaps): Route mouse button events which 
+	* keymap.c (get_relevant_keymaps): Route mouse button events which
 	happened over a window divider through window-divider-map.
 	(Fkey_binding): Documented that in the docstring.
 	Defined the variable Vwindow_divider_map.
@@ -3117,7 +3767,7 @@
 	(metrics); Changed parameters order and added DEFAULT parameter;
 	Unabbreviated some metric constants; Fixed and untabified doc string.
 	(Fdevice_system_metrics): Added. Returns a plist of all provided
-	metrics. 
+	metrics.
 
 	* device-msw.c (mswindows_device_system_metrics): Renamed
 	device_metrics enum constants.
--- a/src/Makefile.in.in	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/Makefile.in.in	Mon Aug 13 11:08:24 2007 +0200
@@ -174,8 +174,8 @@
  eval.o events.o $(extra_objs)\
  event-stream.o extents.o faces.o\
  fileio.o $(LOCK_OBJ) filemode.o floatfns.o fns.o font-lock.o\
- frame.o general.o getloadavg.o glyphs.o glyphs-eimage.o\
- $(gui_objs) hash.o imgproc.o indent.o insdel.o intl.o\
+ frame.o general.o getloadavg.o glyphs.o glyphs-eimage.o glyphs-widget.o\
+ gui.o $(gui_objs) hash.o imgproc.o indent.o insdel.o intl.o\
  keymap.o $(RTC_patch_objs) line-number.o lread.o lstream.o\
  macros.o marker.o md5.o minibuf.o objects.o opaque.o\
  print.o process.o profile.o\
--- a/src/callproc.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/callproc.c	Mon Aug 13 11:08:24 2007 +0200
@@ -823,13 +823,12 @@
 init_callproc (void)
 {
   /* This function can GC */
-  REGISTER char *sh;
 
-  Vprocess_environment = Qnil;
-  /* jwz: always initialize Vprocess_environment, so that egetenv() works
-     in temacs. */
   {
+    /* jwz: always initialize Vprocess_environment, so that egetenv()
+       works in temacs. */
     char **envp;
+    Vprocess_environment = Qnil;
     for (envp = environ; envp && *envp; envp++)
       {
 	Vprocess_environment = Fcons (build_ext_string (*envp, FORMAT_OS),
@@ -837,32 +836,18 @@
       }
   }
 
+  {
+    /* Initialize shell-file-name from environment variables or best guess. */
 #ifdef WINDOWSNT
-  /* Sync with FSF Emacs 19.34.6 note: this is not in 19.34.6. --marcpa */
-  /*
-  ** If NT then we look at COMSPEC for the shell program.
-  */
-  sh = egetenv ("COMSPEC");
-  /*
-  ** If COMSPEC has been set, then convert the
-  ** DOS formatted name into a UNIX format. Then
-  ** create a LISP object.
-  */
-  if (sh)
-    Vshell_file_name = build_string (sh);
-  /*
-  ** Odd, no COMSPEC, so let's default to our
-  ** best guess for NT.
-  */
-  else
-    Vshell_file_name = build_string ("\\WINNT\\system32\\cmd.exe");
+    CONST char *shell = egetenv ("COMSPEC");
+    if (!shell) shell = "\\WINNT\\system32\\cmd.exe";
+#else /* not WINDOWSNT */
+    CONST char *shell = egetenv ("SHELL");
+    if (!shell) shell = "/bin/sh";
+#endif
 
-#else /* not WINDOWSNT */
-
-  sh = (char *) egetenv ("SHELL");
-  Vshell_file_name = build_string (sh ? sh : "/bin/sh");
-
-#endif
+    Vshell_file_name = build_string (shell);
+  }
 }
 
 #if 0
--- a/src/console-msw.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/console-msw.h	Mon Aug 13 11:08:24 2007 +0200
@@ -153,6 +153,9 @@
   /* Menu checksum. See menubar-msw.c */
   unsigned int menu_checksum;
 
+  /* Widget glyphs attached to this frame. See glyphs-msw.c */
+  Lisp_Object widget_hash_table;
+
   /* Frame title hash value. See frame-msw.c */
   unsigned int title_checksum;
 
@@ -181,6 +184,8 @@
 #define FRAME_MSWINDOWS_MENU_HASH_TABLE(f) (FRAME_MSWINDOWS_DATA (f)->menu_hash_table)
 #define FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE(f) \
  (FRAME_MSWINDOWS_DATA (f)->toolbar_hash_table)
+#define FRAME_MSWINDOWS_WIDGET_HASH_TABLE(f) \
+ (FRAME_MSWINDOWS_DATA (f)->widget_hash_table)
 #define FRAME_MSWINDOWS_TOOLBAR_CHECKSUM(f,pos) \
  (FRAME_MSWINDOWS_DATA (f)->toolbar_checksum[pos])
 #define FRAME_MSWINDOWS_MENU_CHECKSUM(f)  (FRAME_MSWINDOWS_DATA (f)->menu_checksum)
--- a/src/console-stream.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/console-stream.c	Mon Aug 13 11:08:24 2007 +0200
@@ -241,8 +241,10 @@
 }
 
 static void
-stream_clear_region (Lisp_Object locale, face_index findex, int x, int y,
-		       int width, int height)
+stream_clear_region (Lisp_Object window, struct device* d, struct frame * f,
+		  face_index findex, int x, int y,
+		  int width, int height, Lisp_Object fcolor, Lisp_Object bcolor, 
+		  Lisp_Object background_pixmap)
 {
 }
 
--- a/src/console-tty.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/console-tty.c	Mon Aug 13 11:08:24 2007 +0200
@@ -233,7 +233,7 @@
   return CONSOLE_TTY_DATA (decode_tty_console (console))->controlling_process;
 }
 
-#ifdef MULE
+#ifdef FILE_CODING
 
 DEFUN ("console-tty-input-coding-system", Fconsole_tty_input_coding_system,
        0, 1, 0, /*
@@ -298,7 +298,7 @@
   Fset_console_tty_output_coding_system (console, codesys);
   return Qnil;
 }
-#endif /* MULE */
+#endif /* FILE_CODING */
 
 
 Lisp_Object
@@ -341,13 +341,13 @@
   DEFSUBR (Fconsole_tty_controlling_process);
   defsymbol (&Qterminal_type, "terminal-type");
   defsymbol (&Qcontrolling_process, "controlling-process");
-#ifdef MULE
+#ifdef FILE_CODING
   DEFSUBR (Fconsole_tty_output_coding_system);
   DEFSUBR (Fset_console_tty_output_coding_system);
   DEFSUBR (Fconsole_tty_input_coding_system);
   DEFSUBR (Fset_console_tty_input_coding_system);
   DEFSUBR (Fset_console_tty_coding_system);
-#endif /* MULE */
+#endif /* FILE_CODING */
 }
 
 void
--- a/src/console.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/console.h	Mon Aug 13 11:08:24 2007 +0200
@@ -139,7 +139,9 @@
   int (*eol_cursor_width_method) (void);
   void (*output_vertical_divider_method) (struct window *, int);
   void (*clear_to_window_end_method) (struct window *, int, int);
-  void (*clear_region_method) (Lisp_Object, face_index, int, int, int, int);
+  void (*clear_region_method) (Lisp_Object, struct device*, struct frame*, face_index,
+			       int, int, int, int,
+			       Lisp_Object, Lisp_Object, Lisp_Object);
   void (*clear_frame_method) (struct frame *);
   void (*output_begin_method) (struct device *);
   void (*output_end_method) (struct device *);
@@ -202,6 +204,10 @@
 				       Lisp_Object printcharfun,
 				       int escapeflag);
   void (*finalize_image_instance_method) (struct Lisp_Image_Instance *);
+  void (*unmap_subwindow_method) (struct Lisp_Image_Instance *);
+  void (*map_subwindow_method) (struct Lisp_Image_Instance *, int x, int y);
+  void (*resize_subwindow_method) (struct Lisp_Image_Instance *, int w, int h);
+  void (*update_subwindow_method) (struct Lisp_Image_Instance *);
   int (*image_instance_equal_method) (struct Lisp_Image_Instance *,
 				      struct Lisp_Image_Instance *,
 				      int depth);
@@ -216,22 +222,6 @@
   Lisp_Object (*locate_pixmap_file_method) (Lisp_Object file_method);
   int (*colorize_image_instance_method) (Lisp_Object image_instance,
 					 Lisp_Object fg, Lisp_Object bg);
-#ifdef HAVE_XPM
-    /* which is more tacky - this or #defines in glyphs.c? */
-  void (*xpm_instantiate_method)(Lisp_Object image_instance,
-				 Lisp_Object instantiator,
-				 Lisp_Object pointer_fg,
-				 Lisp_Object pointer_bg,
-				 int dest_mask, Lisp_Object domain);
-#endif
-#ifdef HAVE_WINDOW_SYSTEM
-    /* which is more tacky - this or #defines in glyphs.c? */
-  void (*xbm_instantiate_method)(Lisp_Object image_instance,
-				 Lisp_Object instantiator,
-				 Lisp_Object pointer_fg,
-				 Lisp_Object pointer_bg,
-				 int dest_mask, Lisp_Object domain);
-#endif
   Lisp_Object image_conversion_list;
 
 #ifdef HAVE_TOOLBARS
--- a/src/device-x.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/device-x.c	Mon Aug 13 11:08:24 2007 +0200
@@ -622,7 +622,7 @@
   Lisp_Object device;
   Display *display;
 #ifdef FREE_CHECKING
-  extern void (*__free_hook)();
+  extern void (*__free_hook) (void *);
   int checking_free;
 #endif
 
--- a/src/device.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/device.c	Mon Aug 13 11:08:24 2007 +0200
@@ -76,7 +76,6 @@
 Lisp_Object Qdelete_device;
 Lisp_Object Qcreate_device_hook;
 Lisp_Object Qdelete_device_hook;
-
 Lisp_Object Vdevice_class_list;
 
 
@@ -883,6 +882,7 @@
 	  recompute_all_cached_specifiers_in_frame (f);
 	  MARK_FRAME_FACES_CHANGED (f);
 	  MARK_FRAME_GLYPHS_CHANGED (f);
+	  MARK_FRAME_SUBWINDOWS_CHANGED (f);
 	  MARK_FRAME_TOOLBARS_CHANGED (f);
 	  f->menubar_changed = 1;
 	}
--- a/src/device.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/device.h	Mon Aug 13 11:08:24 2007 +0200
@@ -167,6 +167,7 @@
   unsigned int faces_changed :1;
   unsigned int frame_changed :1;
   unsigned int glyphs_changed :1;
+  unsigned int subwindows_changed :1;
   unsigned int icon_changed :1;
   unsigned int menubar_changed :1;
   unsigned int modeline_changed :1;
@@ -343,6 +344,9 @@
 #define MARK_DEVICE_GLYPHS_CHANGED(d)			\
   ((void) (glyphs_changed = (d)->glyphs_changed = 1))
 
+#define MARK_DEVICE_SUBWINDOWS_CHANGED(d)			\
+  ((void) (subwindows_changed = (d)->subwindows_changed = 1))
+
 #define MARK_DEVICE_TOOLBARS_CHANGED(d)			\
   ((void) (toolbar_changed = (d)->toolbar_changed = 1))
 
--- a/src/dired.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/dired.c	Mon Aug 13 11:08:24 2007 +0200
@@ -180,7 +180,7 @@
 
 	  {
 	    Lisp_Object name =
-	      make_ext_string ((Bufbyte *)dp->d_name, len, FORMAT_FILENAME);
+	      make_string ((Bufbyte *)dp->d_name, len);
 	    if (!NILP (full))
 	      name = concat2 (dirname, name);
 
--- a/src/eldap.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/eldap.c	Mon Aug 13 11:08:24 2007 +0200
@@ -26,6 +26,7 @@
    conforming to the API defined in RFC 1823.
    It has been tested with:
    - UMich LDAP 3.3 (http://www.umich.edu/~dirsvcs/ldap/)
+   - OpenLDAP 1.0.3 (http://www.openldap.org/)
    - Netscape's LDAP SDK 1.0 (http://developer.netscape.com) */
 
 
@@ -33,6 +34,7 @@
 #include "lisp.h"
 #include "opaque.h"
 #include "sysdep.h"
+#include "buffer.h"
 
 #include <errno.h>
 
@@ -244,15 +246,13 @@
       else if (EQ (keyword, Qbinddn))
         {
           CHECK_STRING (value);
-          ldap_binddn = alloca (XSTRING_LENGTH (value) + 1);
-          strcpy (ldap_binddn, (char *)XSTRING_DATA (value));
+          GET_C_STRING_OS_DATA_ALLOCA (value, ldap_binddn);
         }
       /* Password */
       else if (EQ (keyword, Qpasswd))
         {
           CHECK_STRING (value);
-          ldap_passwd = alloca (XSTRING_LENGTH (value) + 1);
-          strcpy (ldap_passwd, (char *)XSTRING_DATA (value));
+          GET_C_STRING_OS_DATA_ALLOCA (value, ldap_passwd);
         }
       /* Deref */
       else if (EQ (keyword, Qderef))
@@ -454,11 +454,7 @@
 	{
 	  Lisp_Object current = XCAR (attrs);
 	  CHECK_STRING (current);
-	  ldap_attributes[i] =
-	    alloca_array (char, 1 + XSTRING_LENGTH (current));
-          /* XSTRING_LENGTH is increased by one in order to copy the final 0 */
-	  memcpy (ldap_attributes[i],
-		  XSTRING_DATA (current), 1 + XSTRING_LENGTH (current));
+          GET_C_STRING_OS_DATA_ALLOCA (current, ldap_attributes[i]);
 	  ++i;
 	}
       ldap_attributes[i] = NULL;
--- a/src/emacs.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/emacs.c	Mon Aug 13 11:08:24 2007 +0200
@@ -920,6 +920,7 @@
       syms_of_general ();
       syms_of_glyphs ();
       syms_of_glyphs_eimage ();
+      syms_of_glyphs_widget ();
 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
       syms_of_gui ();
 #endif
@@ -1170,6 +1171,7 @@
 
       image_instantiator_format_create ();
       image_instantiator_format_create_glyphs_eimage ();
+      image_instantiator_format_create_glyphs_widget ();
 #ifdef HAVE_X_WINDOWS
       image_instantiator_format_create_glyphs_x ();
 #endif /* HAVE_X_WINDOWS */
@@ -1300,6 +1302,7 @@
       vars_of_frame ();
       vars_of_glyphs ();
       vars_of_glyphs_eimage ();
+      vars_of_glyphs_widget ();
 #if defined (HAVE_MENUBARS) || defined (HAVE_SCROLLBARS) || defined (HAVE_DIALOGS) || defined (HAVE_TOOLBARS)
       vars_of_gui ();
 #endif
@@ -2152,7 +2155,7 @@
 /* GCC >= 2.8.  -slb */
 #if defined(GNU_MALLOC)
 static void
-voodoo_free_hook(void *mem)
+voodoo_free_hook (void *mem)
 {
   /* Disable all calls to free() when XEmacs is exiting and it doesn't */
   /* matter. */
@@ -2410,8 +2413,6 @@
   /* When we're dumping, we can't use the debugging free() */
   disable_free_hook ();
 #endif
-#if 1 /* martin */
-#endif
 
   CHECK_STRING (intoname);
   intoname = Fexpand_file_name (intoname, Qnil);
--- a/src/event-msw.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/event-msw.c	Mon Aug 13 11:08:24 2007 +0200
@@ -28,6 +28,7 @@
    Ultimately based on FSF.
    Rewritten by Ben Wing.
    Rewritten for mswindows by Jonathan Harris, November 1997 for 21.0.
+   Subprocess and modal loop support by Kirill M. Katsnelson.
  */
 
 #include <config.h>
@@ -50,6 +51,8 @@
 #include "device.h"
 #include "events.h"
 #include "frame.h"
+#include "buffer.h"
+#include "faces.h"
 #include "lstream.h"
 #include "process.h"
 #include "redisplay.h"
@@ -57,6 +60,7 @@
 #include "syswait.h"
 #include "systime.h"
 #include "sysdep.h"
+#include "objects-msw.h"
 
 #include "events-mod.h"
 #ifdef HAVE_MSG_SELECT
@@ -84,6 +88,8 @@
 mswindows_get_toolbar_button_text (struct frame* f, int command_id);
 extern Lisp_Object
 mswindows_handle_toolbar_wm_command (struct frame* f, HWND ctrl, WORD id);
+extern Lisp_Object
+mswindows_handle_gui_wm_command (struct frame* f, HWND ctrl, WORD id);
 
 static Lisp_Object mswindows_find_frame (HWND hwnd);
 static Lisp_Object mswindows_find_console (HWND hwnd);
@@ -118,8 +124,13 @@
 /* List of mswindows waitable handles. */
 static HANDLE mswindows_waitable_handles[MAX_WAITABLE];
 
+#ifndef HAVE_MSG_SELECT
 /* Number of wait handles */
 static int mswindows_waitable_count=0;
+#endif /* HAVE_MSG_SELECT */
+/* Brush for painting widgets */
+static HBRUSH widget_brush = 0;
+static LONG	last_widget_brushed = 0;
 
 /* Count of quit chars currently in the queue */
 /* Incremented in WM_[SYS]KEYDOWN handler in the mswindows_wnd_proc()
@@ -470,6 +481,7 @@
 DEFINE_LSTREAM_IMPLEMENTATION ("ntpipe-output", lstream_ntpipe_shove,
 			       sizeof (struct ntpipe_shove_stream));
 
+#ifndef HAVE_MSG_SELECT
 static DWORD WINAPI
 shove_thread (LPVOID vparam)
 {
@@ -541,6 +553,7 @@
   struct ntpipe_shove_stream* s = NTPIPE_SHOVE_STREAM_DATA(stream);
   return s->user_data;
 }
+#endif
 
 static int
 ntpipe_shove_writer (Lstream *stream, const unsigned char *data, size_t size)
@@ -939,6 +952,13 @@
     {
       event->event_type = button_press_event;
       SetCapture (hwnd);
+      /* we need this to make sure the main window regains the focus
+         from control subwindows */
+      if (GetFocus() != hwnd)
+	{
+	  SetFocus (hwnd);
+	  mswindows_enqueue_magic_event (hwnd, WM_SETFOCUS);
+	}
     }
   else
     {
@@ -997,18 +1017,18 @@
 
 /*
  * Remove and return the first emacs event on the dispatch queue that matches
- * the supplied event
- * Timeout event matches if interval_id equals to that of the given event.
+ * the supplied event.
+ * Timeout event matches if interval_id is equal to that of the given event.
  * Keypress event matches if logical AND between modifiers bitmask of the
- * event in the queue and that of the given event is non-zero
- * For all other event types, this function asserts.
+ * event in the queue and that of the given event is non-zero.
+ * For all other event types, this function aborts.
  */
 
 Lisp_Object
-mswindows_cancel_dispatch_event (struct Lisp_Event* match)
+mswindows_cancel_dispatch_event (struct Lisp_Event *match)
 {
   Lisp_Object event;
-  Lisp_Object previous_event=Qnil;
+  Lisp_Object previous_event = Qnil;
   int user_p = mswindows_user_event_p (match);
   Lisp_Object* head = user_p ? &mswindows_u_dispatch_event_queue : 
     			       &mswindows_s_dispatch_event_queue;
@@ -1020,19 +1040,12 @@
 
   EVENT_CHAIN_LOOP (event, *head)
     {
-      int found = 1;
-      if (XEVENT_TYPE (event) != match->event_type)
-	found = 0;
-      if (found && match->event_type == timeout_event
-	  && (XEVENT(event)->event.timeout.interval_id !=
-	      match->event.timeout.interval_id))
-	found = 0;
-      if (found && match->event_type == key_press_event
-	  && ((XEVENT(event)->event.key.modifiers &
-	      match->event.key.modifiers) == 0))
-	found = 0;
-
-      if (found)
+      struct Lisp_Event *e = XEVENT (event);
+      if ((e->event_type == match->event_type) &&
+	  ((e->event_type == timeout_event) ?
+	   (e->event.timeout.interval_id == match->event.timeout.interval_id) :
+	   /* Must be key_press_event */
+	   ((e->event.key.modifiers & match->event.key.modifiers) != 0)))
 	{
 	  if (NILP (previous_event))
 	    dequeue_event (head, tail);
@@ -1050,6 +1063,7 @@
   return Qnil;
 }
 
+#ifndef HAVE_MSG_SELECT
 /************************************************************************/
 /*                     Waitable handles manipulation                    */
 /************************************************************************/
@@ -1085,6 +1099,7 @@
   mswindows_waitable_handles [ix] = 
     mswindows_waitable_handles [--mswindows_waitable_count];
 }
+#endif /* HAVE_MSG_SELECT */
 
 
 /************************************************************************/
@@ -1214,6 +1229,14 @@
   MSG msg;
   while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
     {
+      /* we have to translate messages that are not sent to the main
+         window. this is so that key presses work ok in things like
+         edit fields. however, we *musn't* translate message for the
+         main window as this is handled in the wnd proc. */
+      if ( GetWindowLong (msg.hwnd, GWL_STYLE) & WS_CHILD )
+	{
+	  TranslateMessage (&msg);
+	}
       DispatchMessage (&msg);
       mswindows_unmodalize_signal_maybe ();
     }
@@ -1648,7 +1671,8 @@
 	{
 	  int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
 	  BYTE keymap_orig[256];
-	  MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) };
+	  POINT pnt = { LOWORD (GetMessagePos()), HIWORD (GetMessagePos()) };
+	  MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), pnt };
 
 	  /* GetKeyboardState() does not work as documented on Win95. We have
 	   * to loosely track Left and Right modifiers on behalf of the OS,
@@ -1918,7 +1942,8 @@
 	    {
 	      /* I think this is safe since the text will only go away
                  when the toolbar does...*/
-	      tttext->lpszText=XSTRING_DATA (btext);
+	      GET_C_STRING_EXT_DATA_ALLOCA (btext, FORMAT_OS, 
+					    tttext->lpszText);
 	    }
 #if 0
 	  tttext->uFlags |= TTF_DI_SETITEM;
@@ -2115,6 +2140,7 @@
   case WM_COMMAND:
     {
       WORD id = LOWORD (wParam);
+      WORD nid = HIWORD (wParam);
       HWND cid = (HWND)lParam;
       frame = XFRAME (mswindows_find_frame (hwnd));
 
@@ -2122,17 +2148,86 @@
       if (!NILP (mswindows_handle_toolbar_wm_command (frame, cid, id)))
 	break;
 #endif
-
+      /* widgets in a buffer only eval a callback for suitable events.*/
+      switch (nid)
+	{
+	case BN_CLICKED:
+	case EN_CHANGE:
+	case CBN_EDITCHANGE:
+	case CBN_SELCHANGE:
+	  if (!NILP (mswindows_handle_gui_wm_command (frame, cid, id)))
+	    return 0;
+	default:		/* do nothing */
+	}
+      /* menubars always must come last since the hashtables do not
+         always exist*/
 #ifdef HAVE_MENUBARS
       if (!NILP (mswindows_handle_wm_command (frame, id)))
 	break;
 #endif
 
-      /* Bite me - a spurious command. This cannot happen. */
-      error ("XEMACS BUG: Cannot decode command message");
+      return DefWindowProc (hwnd, message, wParam, lParam);
+      /* Bite me - a spurious command. This used to not be able to
+         happen but with the introduction of widgets its now
+         possible. */
     }
   break;
 
+  case WM_CTLCOLORBTN:
+  case WM_CTLCOLORLISTBOX:
+  case WM_CTLCOLOREDIT:
+  case WM_CTLCOLORSTATIC:
+  case WM_CTLCOLORSCROLLBAR:
+    {
+      /* if we get an opportunity to paint a widget then do so if
+         there is an appropriate face */
+      HWND crtlwnd = (HWND)lParam;
+      LONG ii = GetWindowLong (crtlwnd, GWL_USERDATA);
+      if (ii)
+	{
+	  Lisp_Object image_instance;
+	  VOID_TO_LISP (image_instance, ii);
+	  if (IMAGE_INSTANCEP (image_instance)
+	      && 
+	      IMAGE_INSTANCE_TYPE_P (image_instance, IMAGE_WIDGET)
+	      &&
+	      !NILP (XIMAGE_INSTANCE_WIDGET_FACE (image_instance)))
+	    {
+	      /* set colors for the buttons */
+	      HDC hdc = (HDC)wParam;
+	      if (last_widget_brushed != ii)
+		{
+		  if (widget_brush)
+		    DeleteObject (widget_brush);
+		  widget_brush = CreateSolidBrush 
+		    (COLOR_INSTANCE_MSWINDOWS_COLOR 
+		     (XCOLOR_INSTANCE 
+		      (FACE_BACKGROUND 
+		       (XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
+			XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance)))));
+		}
+	      last_widget_brushed = ii;
+	      SetTextColor
+		(hdc,
+		 COLOR_INSTANCE_MSWINDOWS_COLOR 
+		 (XCOLOR_INSTANCE 
+		  (FACE_FOREGROUND 
+		   (XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
+		    XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance)))));
+	      SetBkMode (hdc, OPAQUE);
+	      SetBkColor
+		(hdc,
+		 COLOR_INSTANCE_MSWINDOWS_COLOR 
+		 (XCOLOR_INSTANCE 
+		  (FACE_BACKGROUND 
+		   (XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
+		    XIMAGE_INSTANCE_SUBWINDOW_FRAME (image_instance)))));
+	      return (LRESULT)widget_brush;
+	    }
+	}
+    }
+    goto defproc;
+
 #ifdef HAVE_DRAGNDROP
   case WM_DROPFILES:	/* implementation ripped-off from event-Xt.c */
     {
@@ -2518,6 +2613,7 @@
     }
 }
 
+#ifndef HAVE_MSG_SELECT
 static HANDLE
 get_process_input_waitable (struct Lisp_Process *process)
 {
@@ -2567,6 +2663,7 @@
   HANDLE hev = get_process_input_waitable (process);
   remove_waitable_handle (hev);
 }
+#endif /* HAVE_MSG_SELECT */
 
 static void
 emacs_mswindows_select_console (struct console *con)
@@ -2581,14 +2678,20 @@
 static void
 emacs_mswindows_quit_p (void)
 {
+  MSG msg;
+
   /* Quit cannot happen in modal loop: all program
      input is dedicated to Windows. */
   if (mswindows_in_modal_loop)
     return;
 
-  /* Drain windows queue. This sets up number of quit
-     characters in in the queue */
-  mswindows_drain_windows_queue ();
+  /* Drain windows queue. This sets up number of quit characters in the queue
+   * (and also processes wm focus change, move, resize, etc messages).
+   * We don't want to process WM_PAINT messages because this function can be
+   * called from almost anywhere and the windows' states may be changing. */
+  while (PeekMessage (&msg, NULL, 0, WM_PAINT-1, PM_REMOVE) ||
+	 PeekMessage (&msg, NULL, WM_PAINT+1, WM_USER-1, PM_REMOVE))
+      DispatchMessage (&msg);
 
   if (mswindows_quit_chars_count > 0)
     {
--- a/src/events.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/events.c	Mon Aug 13 11:08:24 2007 +0200
@@ -179,7 +179,7 @@
 	assert (INTP (Vx));
 	Vy = Fevent_y_pixel (obj);
 	assert (INTP (Vy));
-	sprintf (buf, "#<motion-event %ld, %ld", (long)(XINT (Vx)), (long)(XINT (Vy)));
+	sprintf (buf, "#<motion-event %ld, %ld", (long) XINT (Vx), (long) XINT (Vy));
 	write_c_string (buf, printcharfun);
 	break;
       }
@@ -1455,22 +1455,28 @@
 #define CHECK_EVENT_TYPE(e,t1,sym) do {		\
   CHECK_LIVE_EVENT (e);				\
   if (XEVENT(e)->event_type != (t1))		\
-    e = wrong_type_argument ((sym),(e));	\
+    e = wrong_type_argument (sym,e);		\
 } while (0)
 
-#define CHECK_EVENT_TYPE2(e,t1,t2,sym) do {	\
-  CHECK_LIVE_EVENT (e);				\
-  if (XEVENT(e)->event_type != (t1) &&		\
-      XEVENT(e)->event_type != (t2))		\
-    e = wrong_type_argument ((sym),(e));	\
+#define CHECK_EVENT_TYPE2(e,t1,t2,sym) do {		\
+  CHECK_LIVE_EVENT (e);					\
+  {							\
+    emacs_event_type CET_type = XEVENT (e)->event_type;	\
+    if (CET_type != (t1) &&				\
+	CET_type != (t2))				\
+      e = wrong_type_argument (sym,e);			\
+  }							\
 } while (0)
 
-#define CHECK_EVENT_TYPE3(e,t1,t2,t3,sym) do {	\
-  CHECK_LIVE_EVENT (e);				\
-  if (XEVENT(e)->event_type != (t1) &&		\
-      XEVENT(e)->event_type != (t2) &&		\
-      XEVENT(e)->event_type != (t3))		\
-    e = wrong_type_argument ((sym),(e));	\
+#define CHECK_EVENT_TYPE3(e,t1,t2,t3,sym) do {		\
+  CHECK_LIVE_EVENT (e);					\
+  {							\
+    emacs_event_type CET_type = XEVENT (e)->event_type;	\
+    if (CET_type != (t1) &&				\
+	CET_type != (t2) &&				\
+	CET_type != (t3))				\
+      e = wrong_type_argument (sym,e);			\
+  }							\
 } while (0)
 
 DEFUN ("event-key", Fevent_key, 1, 1, 0, /*
--- a/src/faces.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/faces.c	Mon Aug 13 11:08:24 2007 +0200
@@ -55,7 +55,7 @@
    calling Ffind_face. */
 Lisp_Object Vdefault_face, Vmodeline_face, Vgui_element_face;
 Lisp_Object Vleft_margin_face, Vright_margin_face, Vtext_cursor_face;
-Lisp_Object Vpointer_face, Vvertical_divider_face, Vtoolbar_face;
+Lisp_Object Vpointer_face, Vvertical_divider_face, Vtoolbar_face, Vwidget_face;
 
 /* Qdefault, Qhighlight defined in general.c */
 Lisp_Object Qmodeline, Qgui_element, Qleft_margin, Qright_margin, Qtext_cursor;
@@ -1736,7 +1736,7 @@
 void
 syms_of_faces (void)
 {
-  /* Qdefault defined in general.c */
+  /* Qdefault & Qwidget defined in general.c */
   defsymbol (&Qmodeline, "modeline");
   defsymbol (&Qgui_element, "gui-element");
   defsymbol (&Qleft_margin, "left-margin");
@@ -1793,6 +1793,8 @@
   Vdefault_face = Qnil;
   staticpro (&Vgui_element_face);
   Vgui_element_face = Qnil;
+  staticpro (&Vwidget_face);
+  Vwidget_face = Qnil;
   staticpro (&Vmodeline_face);
   Vmodeline_face = Qnil;
   staticpro (&Vtoolbar_face);
@@ -1998,6 +2000,18 @@
 			  Fget (Vgui_element_face, Qbackground_pixmap,
 				Qunbound));
 
+  /* widget is another gui element */
+  Vwidget_face = Fmake_face (Qwidget,
+			     build_string ("widget face"),
+			     Qnil);
+  set_specifier_fallback (Fget (Vwidget_face, Qforeground, Qunbound),
+			  Fget (Vgui_element_face, Qforeground, Qunbound));
+  set_specifier_fallback (Fget (Vwidget_face, Qbackground, Qunbound),
+			  Fget (Vgui_element_face, Qbackground, Qunbound));
+  set_specifier_fallback (Fget (Vwidget_face, Qbackground_pixmap, Qnil),
+			  Fget (Vgui_element_face, Qbackground_pixmap,
+				Qunbound));
+
   Vleft_margin_face = Fmake_face (Qleft_margin,
 				  build_string ("left margin face"),
 				  Qnil);
--- a/src/faces.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/faces.h	Mon Aug 13 11:08:24 2007 +0200
@@ -260,8 +260,8 @@
 
 extern Lisp_Object Qstrikethru, Vbuilt_in_face_specifiers, Vdefault_face;
 extern Lisp_Object Vleft_margin_face, Vpointer_face, Vright_margin_face;
-extern Lisp_Object Vtext_cursor_face, Vvertical_divider_face;
-extern Lisp_Object Vtoolbar_face, Vgui_element_face;
+extern Lisp_Object Vtext_cursor_face, Vvertical_divider_face; 
+extern Lisp_Object Vtoolbar_face, Vgui_element_face, Vwidget_face;
 
 void mark_all_faces_as_clean (void);
 void init_frame_faces (struct frame *f);
--- a/src/fns.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/fns.c	Mon Aug 13 11:08:24 2007 +0200
@@ -3037,7 +3037,9 @@
 
   while (argnum < nargs)
     {
-      Lisp_Object val = args[argnum];
+      Lisp_Object val;
+    retry:
+      val = args[argnum];
       if (CONSP (val))
 	{
 	  /* `val' is the first cons, which will be our return value.  */
@@ -3048,7 +3050,7 @@
 	  for (argnum++; argnum < nargs; argnum++)
 	    {
 	      Lisp_Object next = args[argnum];
-	    retry:
+	    retry_next:
 	      if (CONSP (next) || argnum == nargs -1)
 		{
 		  /* (setcdr (last val) next) */
@@ -3073,8 +3075,8 @@
 		}
 	      else
 		{
-		  next = wrong_type_argument (next, Qlistp);
-		  goto retry;
+		  next = wrong_type_argument (Qlistp, next);
+		  goto retry_next;
 		}
 	    }
 	  RETURN_UNGCPRO (val);
@@ -3084,51 +3086,67 @@
       else if (argnum == nargs - 1) /* last arg? */
 	RETURN_UNGCPRO (val);
       else
-	args[argnum] = wrong_type_argument (val, Qlistp);
+	{
+	  args[argnum] = wrong_type_argument (Qlistp, val);
+	  goto retry;
+	}
     }
   RETURN_UNGCPRO (Qnil);  /* No non-nil args provided. */
 }
 
 
 /* This is the guts of all mapping functions.
- Apply fn to each element of seq, one by one,
- storing the results into elements of vals, a C vector of Lisp_Objects.
- leni is the length of vals, which should also be the length of seq.
-
- If VALS is a null pointer, do not accumulate the results. */
+   Apply fn to each element of seq, one by one,
+   storing the results into elements of vals, a C vector of Lisp_Objects.
+   leni is the length of vals, which should also be the length of seq.
+
+   If VALS is a null pointer, do not accumulate the results. */
 
 static void
-mapcar1 (int leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
+mapcar1 (size_t leni, Lisp_Object *vals, Lisp_Object fn, Lisp_Object seq)
 {
-  Lisp_Object tail;
-  Lisp_Object dummy = Qnil;
+  Lisp_Object result;
+  Lisp_Object args[2];
   int i;
-  struct gcpro gcpro1, gcpro2, gcpro3;
-  Lisp_Object result;
-
-  GCPRO3 (dummy, fn, seq);
+  struct gcpro gcpro1;
 
   if (vals)
     {
-      /* Don't let vals contain any garbage when GC happens.  */
-      for (i = 0; i < leni; i++)
-	vals[i] = Qnil;
-      gcpro1.var = vals;
-      gcpro1.nvars = leni;
+      GCPRO1 (vals[0]);
+      gcpro1.nvars = 0;
     }
 
-  /* We need not explicitly protect `tail' because it is used only on
-    lists, and 1) lists are not relocated and 2) the list is marked
-    via `seq' so will not be freed */
-
-  if (VECTORP (seq))
+  args[0] = fn;
+
+  if (LISTP (seq))
     {
       for (i = 0; i < leni; i++)
 	{
-	  dummy = XVECTOR_DATA (seq)[i];
-	  result = call1 (fn, dummy);
-	  if (vals)
-	    vals[i] = result;
+	  args[1] = XCAR (seq);
+	  seq = XCDR (seq);
+	  result = Ffuncall (2, args);
+	  if (vals) vals[gcpro1.nvars++] = result;
+	}
+    }
+  else if (VECTORP (seq))
+    {
+      Lisp_Object *objs = XVECTOR_DATA (seq);
+      for (i = 0; i < leni; i++)
+	{
+	  args[1] = *objs++;
+	  result = Ffuncall (2, args);
+	  if (vals) vals[gcpro1.nvars++] = result;
+	}
+    }
+  else if (STRINGP (seq))
+    {
+      Bufbyte *p = XSTRING_DATA (seq);
+      for (i = 0; i < leni; i++)
+	{
+	  args[1] = make_char (charptr_emchar (p));
+	  INC_CHARPTR (p);
+	  result = Ffuncall (2, args);
+	  if (vals) vals[gcpro1.nvars++] = result;
 	}
     }
   else if (BIT_VECTORP (seq))
@@ -3136,34 +3154,16 @@
       struct Lisp_Bit_Vector *v = XBIT_VECTOR (seq);
       for (i = 0; i < leni; i++)
 	{
-	  XSETINT (dummy, bit_vector_bit (v, i));
-	  result = call1 (fn, dummy);
-	  if (vals)
-	    vals[i] = result;
+	  args[1] = make_int (bit_vector_bit (v, i));
+	  result = Ffuncall (2, args);
+	  if (vals) vals[gcpro1.nvars++] = result;
 	}
     }
-  else if (STRINGP (seq))
-    {
-      for (i = 0; i < leni; i++)
-	{
-	  result = call1 (fn, make_char (string_char (XSTRING (seq), i)));
-	  if (vals)
-	    vals[i] = result;
-	}
-    }
-  else   /* Must be a list, since Flength did not get an error */
-    {
-      tail = seq;
-      for (i = 0; i < leni; i++)
-	{
-	  result = call1 (fn, Fcar (tail));
-	  if (vals)
-	    vals[i] = result;
-	  tail = Fcdr (tail);
-	}
-    }
-
-  UNGCPRO;
+  else
+    abort(); /* cannot get here since Flength(seq) did not get an error */
+
+  if (vals)
+    UNGCPRO;
 }
 
 DEFUN ("mapconcat", Fmapconcat, 3, 3, 0, /*
@@ -3173,7 +3173,7 @@
 */
        (fn, seq, sep))
 {
-  int len = XINT (Flength (seq));
+  size_t len = XINT (Flength (seq));
   Lisp_Object *args;
   int i;
   struct gcpro gcpro1;
@@ -3203,7 +3203,7 @@
 */
        (fn, seq))
 {
-  int len = XINT (Flength (seq));
+  size_t len = XINT (Flength (seq));
   Lisp_Object *args = alloca_array (Lisp_Object, len);
 
   mapcar1 (len, args, fn, seq);
@@ -3218,9 +3218,7 @@
 */
        (fn, seq))
 {
-  int len = XINT (Flength (seq));
-  /* Ideally, this should call make_vector_internal, because we don't
-     need initialization.  */
+  size_t len = XINT (Flength (seq));
   Lisp_Object result = make_vector (len, Qnil);
   struct gcpro gcpro1;
 
--- a/src/frame-msw.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/frame-msw.c	Mon Aug 13 11:08:24 2007 +0200
@@ -33,6 +33,7 @@
 #include "lisp.h"
 
 #include "buffer.h"
+#include "elhash.h"
 #include "console-msw.h"
 #include "glyphs-msw.h"
 #include "elhash.h"
@@ -129,10 +130,12 @@
   FRAME_MSWINDOWS_DATA(f)->sizing = 0;
   FRAME_MSWINDOWS_MENU_HASH_TABLE(f) = Qnil;
 #ifdef HAVE_TOOLBARS
-  FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE(f) =
+  FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE(f) = 
     make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQUAL);
 #endif
-
+  /* hashtable of instantiated glyphs on the frame. */
+  FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f) = 
+    make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQUAL);
   /* Will initialize these in WM_SIZE handler. We cannot do it now,
      because we do not know what is CW_USEDEFAULT height and width */
   FRAME_WIDTH (f) = 0;
@@ -249,6 +252,7 @@
 #ifdef HAVE_TOOLBARS
   markobj (FRAME_MSWINDOWS_TOOLBAR_HASH_TABLE (f));
 #endif
+  markobj (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
 }
 
 static void
@@ -394,6 +398,10 @@
     {
       SetClassLong (FRAME_MSWINDOWS_HANDLE (f), GCL_HCURSOR,
 		    (LONG) XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
+      /* we only have to do this because GC doesn't cause a mouse
+         event and doesn't give time to event processing even if it
+         did. */
+      SetCursor (XIMAGE_INSTANCE_MSWINDOWS_ICON (f->pointer));
     }
 }
 
--- a/src/frame-x.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/frame-x.c	Mon Aug 13 11:08:24 2007 +0200
@@ -2632,25 +2632,25 @@
   DtDndDropUnregister (FRAME_X_TEXT_WIDGET (f));
 #endif /* HAVE_CDE */
 
-  assert (FRAME_X_SHELL_WIDGET (f));
-  if (FRAME_X_SHELL_WIDGET (f))
-    {
-      Display *dpy = XtDisplay (FRAME_X_SHELL_WIDGET (f));
-      expect_x_error (dpy);
-      /* for obscure reasons having (I think) to do with the internal
-	 window-to-widget hierarchy maintained by Xt, we have to call
-	 XtUnrealizeWidget() here.  Xt can really suck. */
-      if (f->being_deleted)
-	XtUnrealizeWidget (FRAME_X_SHELL_WIDGET (f));
-      XtDestroyWidget (FRAME_X_SHELL_WIDGET (f));
-      x_error_occurred_p (dpy);
-
-      /* make sure the windows are really gone! */
-      /* ### Is this REALLY necessary? */
-      XFlush (dpy);
-
-      FRAME_X_SHELL_WIDGET (f) = 0;
-    }
+  assert (FRAME_X_SHELL_WIDGET (f) != 0);
+
+#ifdef EXTERNAL_WIDGET
+  expect_x_error (XtDisplay (FRAME_X_SHELL_WIDGET (f)));
+  /* for obscure reasons having (I think) to do with the internal
+     window-to-widget hierarchy maintained by Xt, we have to call
+     XtUnrealizeWidget() here.  Xt can really suck. */
+  if (f->being_deleted)
+    XtUnrealizeWidget (FRAME_X_SHELL_WIDGET (f));
+  XtDestroyWidget (FRAME_X_SHELL_WIDGET (f));
+  x_error_occurred_p (XtDisplay (FRAME_X_SHELL_WIDGET (f)));
+#else
+  XtDestroyWidget (FRAME_X_SHELL_WIDGET (f));
+  /* make sure the windows are really gone! */
+  /* ### Is this REALLY necessary? */
+  XFlush (XtDisplay (FRAME_X_SHELL_WIDGET (f)));
+#endif /* EXTERNAL_WIDGET */
+
+  FRAME_X_SHELL_WIDGET (f) = 0;
 
   if (FRAME_X_GEOM_FREE_ME_PLEASE (f))
     {
--- a/src/frame.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/frame.c	Mon Aug 13 11:08:24 2007 +0200
@@ -128,6 +128,8 @@
 #define MARKED_SLOT(x) ((void) (markobj (f->x)));
 #include "frameslots.h"
 
+  mark_subwindow_cachels (f->subwindow_cachels, markobj);
+
   if (FRAME_LIVE_P (f)) /* device is nil for a dead frame */
     MAYBE_FRAMEMETH (f, mark_frame, (f, markobj));
 
@@ -203,6 +205,9 @@
   f->selected_window = root_window;
   f->last_nonminibuf_window = root_window;
 
+  /* cache of subwindows visible on frame */
+  f->subwindow_cachels    = Dynarr_new (subwindow_cachel);
+
   /* Choose a buffer for the frame's root window.  */
   XWINDOW (root_window)->buffer = Qt;
   {
@@ -451,9 +456,9 @@
 	 things. */
       init_frame_toolbars (f);
 #endif
-
       reset_face_cachels (XWINDOW (FRAME_SELECTED_WINDOW (f)));
       reset_glyph_cachels (XWINDOW (FRAME_SELECTED_WINDOW (f)));
+      reset_subwindow_cachels (f);
       change_frame_size (f, f->height, f->width, 0);
     }
 
@@ -1531,6 +1536,13 @@
   delete_all_subwindows (XWINDOW (f->root_window));
   f->root_window = Qnil;
 
+  /* clear out the cached glyph information */
+  if (f->subwindow_cachels)
+    {
+      Dynarr_free (f->subwindow_cachels);
+      f->subwindow_cachels = 0;
+    }
+
   /* Remove the frame now from the list.  This way, any events generated
      on this frame by the maneuvers below will disperse themselves. */
 
--- a/src/frame.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/frame.h	Mon Aug 13 11:08:24 2007 +0200
@@ -32,6 +32,7 @@
 #endif
 
 #include "device.h"
+#include "glyphs.h"
 
 #define FRAME_TYPE_NAME(f) ((f)->framemeths->name)
 #define FRAME_TYPE(f) ((f)->framemeths->symbol)
@@ -89,6 +90,9 @@
 
   int modiff;
 
+  /* subwindow cache elements for this frame */
+  subwindow_cachel_dynarr *subwindow_cachels;
+
 #ifdef HAVE_SCROLLBARS
   /* frame-local scrollbar information.  See scrollbar.c. */
   int scrollbar_y_offset;
@@ -163,6 +167,7 @@
   unsigned int extents_changed :1;
   unsigned int faces_changed :1;
   unsigned int frame_changed :1;
+  unsigned int subwindows_changed :1;
   unsigned int glyphs_changed :1;
   unsigned int icon_changed :1;
   unsigned int menubar_changed :1;
@@ -311,6 +316,19 @@
     glyphs_changed = 1;					\
 } while (0)
 
+#define MARK_FRAME_SUBWINDOWS_CHANGED(f) do {		\
+  struct frame *mfgc_f = (f);				\
+  mfgc_f->subwindows_changed = 1;				\
+  mfgc_f->modiff++;					\
+  if (!NILP (mfgc_f->device))				\
+    {							\
+      struct device *mfgc_d = XDEVICE (mfgc_f->device);	\
+      MARK_DEVICE_SUBWINDOWS_CHANGED (mfgc_d);		\
+    }							\
+  else							\
+    subwindows_changed = 1;					\
+} while (0)
+
 #define MARK_FRAME_TOOLBARS_CHANGED(f) do {		\
   struct frame *mftc_f = (f);				\
   mftc_f->toolbar_changed = 1;				\
@@ -422,6 +440,11 @@
 #define FRAME_SCROLLBAR_HEIGHT(f) 0
 #endif
 
+#define FW_FRAME(obj)					\
+   (WINDOWP (obj) ? WINDOW_FRAME (XWINDOW (obj))	\
+ : (FRAMEP  (obj) ? obj						\
+ : Qnil))
+
 #define FRAME_NEW_HEIGHT(f) ((f)->new_height)
 #define FRAME_NEW_WIDTH(f) ((f)->new_width)
 #define FRAME_CURSOR_X(f) ((f)->cursor_x)
@@ -439,6 +462,7 @@
   NON_LVALUE ((f)->last_nonminibuf_window)
 #define FRAME_SB_VCACHE(f) ((f)->sb_vcache)
 #define FRAME_SB_HCACHE(f) ((f)->sb_hcache)
+#define FRAME_SUBWINDOW_CACHE(f) ((f)->subwindow_cachels)
 
 #if 0 /* FSFmacs */
 
--- a/src/free-hook.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/free-hook.c	Mon Aug 13 11:08:24 2007 +0200
@@ -66,7 +66,7 @@
 #include <config.h>
 #include "lisp.h"
 #else
-void *malloc (unsigned long);
+void *malloc (size_t);
 #endif
 
 #if !defined(HAVE_LIBMCHECK)
@@ -88,9 +88,9 @@
 struct hash_table *pointer_table;
 
 extern void (*__free_hook) (void *);
-extern void *(*__malloc_hook) (unsigned long);
+extern void *(*__malloc_hook) (size_t);
 
-static void *check_malloc (unsigned long);
+static void *check_malloc (size_t);
 
 typedef void (*fun_ptr) ();
 
@@ -212,9 +212,9 @@
 }
 
 static void *
-check_malloc (unsigned long size)
+check_malloc (size_t size)
 {
-  unsigned long rounded_up_size;
+  size_t rounded_up_size;
   void *result;
 
   __free_hook = 0;
@@ -240,7 +240,7 @@
   return result;
 }
 
-extern void *(*__realloc_hook) (void *, unsigned long);
+extern void *(*__realloc_hook) (void *, size_t);
 
 #ifdef MIN
 #undef MIN
@@ -250,10 +250,10 @@
 /* Don't optimize realloc */
 
 static void *
-check_realloc (void * ptr, unsigned long size)
+check_realloc (void * ptr, size_t size)
 {
   EMACS_INT present;
-  unsigned long old_size;
+  size_t old_size;
   void *result = malloc (size);
 
   if (!ptr) return result;
@@ -295,7 +295,7 @@
    completely gone in XEmacs */
 
 static void *
-block_input_malloc (unsigned long size);
+block_input_malloc (size_t size);
 
 static void
 block_input_free (void* ptr)
@@ -308,7 +308,7 @@
 }
 
 static void *
-block_input_malloc (unsigned long size)
+block_input_malloc (size_t size)
 {
   void* result;
   __free_hook = 0;
@@ -321,7 +321,7 @@
 
 
 static void *
-block_input_realloc (void* ptr, unsigned long size)
+block_input_realloc (void* ptr, size_t size)
 {
   void* result;
   __free_hook = 0;
@@ -406,9 +406,9 @@
 }
 
 #else
-void (*__free_hook)() = check_free;
-void *(*__malloc_hook)() = check_malloc;
-void *(*__realloc_hook)() = check_realloc;
+void (*__free_hook)(void *) = check_free;
+void *(*__malloc_hook)(size_t) = check_malloc;
+void *(*__realloc_hook)(void *, size_t) = check_realloc;
 #endif
 
 #endif /* !defined(HAVE_LIBMCHECK) */
--- a/src/general.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/general.c	Mon Aug 13 11:08:24 2007 +0200
@@ -149,6 +149,7 @@
 Lisp_Object Qreverse;
 Lisp_Object Qright;
 Lisp_Object Qsearch;
+Lisp_Object Qselected;
 Lisp_Object Qsignal;
 Lisp_Object Qsimple;
 Lisp_Object Qsize;
@@ -177,6 +178,7 @@
 Lisp_Object Qwarning;
 Lisp_Object Qwhite;
 Lisp_Object Qwidth;
+Lisp_Object Qwidget;
 Lisp_Object Qwindow;
 Lisp_Object Qwindow_system;
 Lisp_Object Qx;
@@ -303,6 +305,7 @@
   defsymbol (&Qreverse, "reverse");
   defsymbol (&Qright, "right");
   defsymbol (&Qsearch, "search");
+  defsymbol (&Qselected, "selected");
   defsymbol (&Qsignal, "signal");
   defsymbol (&Qsimple, "simple");
   defsymbol (&Qsize, "size");
@@ -331,6 +334,7 @@
   defsymbol (&Qwarning, "warning");
   defsymbol (&Qwhite, "white");
   defsymbol (&Qwidth, "width");
+  defsymbol (&Qwidget, "widget");
   defsymbol (&Qwindow, "window");
   defsymbol (&Qwindow_system, "window-system");
   defsymbol (&Qx, "x");
--- a/src/glyphs-msw.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/glyphs-msw.c	Mon Aug 13 11:08:24 2007 +0200
@@ -1,4 +1,4 @@
-/* mswindows-specific Lisp objects.
+/* mswindows-specific glyph objects.
    Copyright (C) 1998 Andy Piper.
    
 This file is part of XEmacs.
@@ -20,7 +20,7 @@
 
 /* Synched up with: Not in FSF. */
 
-/* written by Andy Piper <andyp@parallax.co.uk> plagerising buts from
+/* written by Andy Piper <andy@xemacs.org> plagerising bits from
    glyphs-x.c */
 
 #include <config.h>
@@ -32,6 +32,8 @@
 #include "glyphs-msw.h"
 #include "objects-msw.h"
 
+#include "window.h"
+#include "elhash.h"
 #include "buffer.h"
 #include "frame.h"
 #include "insdel.h"
@@ -46,6 +48,22 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#define WIDGET_GLYPH_SLOT 0
+
+#ifdef HAVE_XPM
+DEFINE_DEVICE_IIFORMAT (mswindows, xpm);
+#endif
+DEFINE_DEVICE_IIFORMAT (mswindows, xbm);
+DEFINE_DEVICE_IIFORMAT (mswindows, button);
+DEFINE_DEVICE_IIFORMAT (mswindows, edit);
+#if 0
+DEFINE_DEVICE_IIFORMAT (mswindows, group);
+#endif
+DEFINE_DEVICE_IIFORMAT (mswindows, subwindow);
+DEFINE_DEVICE_IIFORMAT (mswindows, widget);
+DEFINE_DEVICE_IIFORMAT (mswindows, label);
+DEFINE_DEVICE_IIFORMAT (mswindows, scrollbar);
+DEFINE_DEVICE_IIFORMAT (mswindows, combo);
 
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (bmp);
 Lisp_Object Qbmp;
@@ -58,7 +76,7 @@
 
 static void
 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
-					    enum image_instance_type type);
+					      enum image_instance_type type);
 static void
 mswindows_initialize_image_instance_mask (struct Lisp_Image_Instance* image, 
 					  struct frame* f);
@@ -660,7 +678,7 @@
       colortbl[j].color = 
 	COLOR_INSTANCE_MSWINDOWS_COLOR (XCOLOR_INSTANCE (XCDR (cons)));
 
-      colortbl[j].name = (char *) XSTRING_DATA (XCAR (cons));
+      GET_C_STRING_OS_DATA_ALLOCA (XCAR (cons), colortbl[j].name);
       free_cons (XCONS (cons));
       cons = results;
       results = XCDR (results);
@@ -1093,7 +1111,9 @@
     }
   
   do {
-    if (!strcasecmp ((char*)res->name, XSTRING_DATA (name)))
+    Extbyte* nm=0;
+    GET_C_STRING_OS_DATA_ALLOCA (name, nm);
+      if (!strcasecmp ((char*)res->name, nm))
       return res->resource_id;
   } while ((++res)->name);
   return 0;
@@ -1151,11 +1171,13 @@
   /* mess with the keyword info we were provided with */
   if (!NILP (file))
     {
+      Extbyte* f=0;
+      GET_C_STRING_FILENAME_DATA_ALLOCA (file, f);
 #ifdef __CYGWIN32__
-      CYGWIN_WIN32_PATH (XSTRING_DATA (file), fname);
+      CYGWIN_WIN32_PATH (f, fname);
 #else
       /* #### FIXME someone who knows ... */
-      fname = XSTRING_DATA (file);
+      fname = f
 #endif
       
       if (NILP (resource_id))
@@ -1168,7 +1190,7 @@
 							   type));
 	  
 	  if (!resid)
-	    resid = XSTRING_DATA (resource_id);
+	    GET_C_STRING_OS_DATA_ALLOCA (resource_id, resid);
 	}
     }
   else if (!(resid = MAKEINTRESOURCE (resource_name_to_resource (resource_id,
@@ -1839,6 +1861,7 @@
 	}
       write_c_string (")", printcharfun);
       break;
+
     default:
       break;
     }
@@ -1847,24 +1870,140 @@
 static void
 mswindows_finalize_image_instance (struct Lisp_Image_Instance *p)
 {
-  if (!p->data)
-    return;
-
   if (DEVICE_LIVE_P (XDEVICE (p->device)))
     {
-      if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
-	DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
-      IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
-      if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
-	DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
-      IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
-      if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
-	DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
-      IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
+      if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET
+	  || 
+	  IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
+	{
+	  if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
+	    DestroyWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p));
+	  IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
+	}
+      else if (p->data)
+	{
+	  if (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p))
+	    DeleteObject (IMAGE_INSTANCE_MSWINDOWS_BITMAP (p));
+	  IMAGE_INSTANCE_MSWINDOWS_BITMAP (p) = 0;
+	  if (IMAGE_INSTANCE_MSWINDOWS_MASK (p))
+	    DeleteObject (IMAGE_INSTANCE_MSWINDOWS_MASK (p));
+	  IMAGE_INSTANCE_MSWINDOWS_MASK (p) = 0;
+	  if (IMAGE_INSTANCE_MSWINDOWS_ICON (p))
+	    DestroyIcon (IMAGE_INSTANCE_MSWINDOWS_ICON (p));
+	  IMAGE_INSTANCE_MSWINDOWS_ICON (p) = 0;
+	}
     }
 
-  xfree (p->data);
-  p->data = 0;
+  if (p->data)
+    {
+      xfree (p->data);
+      p->data = 0;
+    }
+}
+
+/************************************************************************/
+/*                      subwindow and widget support                      */
+/************************************************************************/
+
+/* unmap the image if it is a widget. This is used by redisplay via
+   redisplay_unmap_subwindows */
+static void
+mswindows_unmap_subwindow (struct Lisp_Image_Instance *p)
+{
+  if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
+    {
+      SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), 
+		    NULL, 
+		    0, 0, 0, 0,
+		    SWP_HIDEWINDOW | SWP_NOMOVE | SWP_NOSIZE 
+		    | SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
+    }
+}
+
+/* map the subwindow. This is used by redisplay via
+   redisplay_output_subwindow */
+static void
+mswindows_map_subwindow (struct Lisp_Image_Instance *p, int x, int y)
+{
+  /*  ShowWindow (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), SW_SHOW);*/
+  SetWindowPos (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), 
+		NULL, 
+		x, y, 0, 0,
+		SWP_NOZORDER | SWP_SHOWWINDOW | SWP_NOSIZE
+		| SWP_NOCOPYBITS | SWP_NOSENDCHANGING);
+}
+
+/* when you click on a widget you may activate another widget this
+   needs to be checked and all appropriate widgets updated */
+static void
+mswindows_update_subwindow (struct Lisp_Image_Instance *p)
+{
+  if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET)
+    {
+      /* buttons checked or otherwise */
+      if ( EQ (IMAGE_INSTANCE_WIDGET_TYPE (p), Qbutton))
+	{
+	  if (gui_item_selected_p (&IMAGE_INSTANCE_WIDGET_ITEM (p)))
+	    SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p), 
+			 BM_SETCHECK, (WPARAM)BST_CHECKED, 0); 
+	  else
+	    SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (p),
+			 BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+	}
+    }
+}
+
+/* register widgets into our hastable so that we can cope with the
+   callbacks. The hashtable is weak so deregistration is handled
+   automatically */
+static int
+mswindows_register_widget_instance (Lisp_Object instance, Lisp_Object domain)
+{
+  Lisp_Object frame = FW_FRAME (domain);
+  struct frame* f = XFRAME (frame);
+  int id = gui_item_hash (FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f),
+			  &XIMAGE_INSTANCE_WIDGET_ITEM (instance),
+			  WIDGET_GLYPH_SLOT);
+  Fputhash (make_int (id),
+	    XIMAGE_INSTANCE_WIDGET_CALLBACK (instance),
+	    FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f));
+  return id;
+}
+
+static void
+mswindows_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+				 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+				 int dest_mask, Lisp_Object domain)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+  struct device* d = XDEVICE (device);
+  Lisp_Object frame = FW_FRAME (domain);
+  HWND wnd;
+
+  if (!DEVICE_MSWINDOWS_P (d))
+    signal_simple_error ("Not an mswindows device", device);
+
+  /* have to set the type this late in case there is no device
+     instantiation for a widget */
+  IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
+
+  wnd = CreateWindow( "STATIC",  
+		      "",
+		      WS_CHILD,  
+		      0,         /* starting x position */
+		      0,         /* starting y position */
+		      IMAGE_INSTANCE_WIDGET_WIDTH (ii),
+		      IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
+		      FRAME_MSWINDOWS_HANDLE (XFRAME (frame)), /* parent window */
+		      0,
+		      (HINSTANCE) 
+		      GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
+				     GWL_HINSTANCE), 
+		      NULL);
+
+  SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
+  IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
 }
 
 static int
@@ -1880,6 +2019,7 @@
 	  != IMAGE_INSTANCE_MSWINDOWS_BITMAP (p2))
 	return 0;
       break;
+    
     default:
       break;
     }
@@ -1896,6 +2036,7 @@
     case IMAGE_COLOR_PIXMAP:
     case IMAGE_POINTER:
       return (unsigned long) IMAGE_INSTANCE_MSWINDOWS_BITMAP (p);
+    
     default:
       return 0;
     }
@@ -1909,7 +2050,7 @@
 
 static void
 mswindows_initialize_dibitmap_image_instance (struct Lisp_Image_Instance *ii,
-					    enum image_instance_type type)
+					      enum image_instance_type type)
 {
   ii->data = xnew_and_zero (struct mswindows_image_instance_data);
   IMAGE_INSTANCE_TYPE (ii) = type;
@@ -1923,6 +2064,292 @@
 
 
 /************************************************************************/
+/*                            widgets                            */
+/************************************************************************/
+
+static void
+mswindows_widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+			      Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+			      int dest_mask, Lisp_Object domain,
+			      CONST char* class, int flags, int exflags)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+#if 0
+  struct Lisp_Image_Instance *groupii = 0;
+  Lisp_Object group = find_keyword_in_vector (instantiator, Q_group);
+#endif
+  Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii), style;
+  struct device* d = XDEVICE (device);
+  Lisp_Object frame = FW_FRAME (domain);
+  Extbyte* nm=0;
+  HWND wnd;
+  int id = 0xffff;
+  struct gui_item* pgui = &IMAGE_INSTANCE_WIDGET_ITEM (ii);
+
+  if (!DEVICE_MSWINDOWS_P (d))
+    signal_simple_error ("Not an mswindows device", device);
+#if 0
+  /* if the user specified another glyph as a group pick up the
+     instance in our domain. */
+  if (!NILP (group))
+    {
+      if (SYMBOLP (group))
+	group = XSYMBOL (group)->value;
+      group = glyph_image_instance (group, domain, ERROR_ME, 1);
+      groupii = XIMAGE_INSTANCE (group);
+    }
+#endif
+  if (!gui_item_active_p (pgui))
+    flags |= WS_DISABLED;
+
+  style = pgui->style;
+
+  if (!NILP (pgui->callback))
+    {
+      id = mswindows_register_widget_instance (image_instance, domain);
+    }
+  /* have to set the type this late in case there is no device
+     instantiation for a widget */
+  IMAGE_INSTANCE_TYPE (ii) = IMAGE_WIDGET;
+  if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
+    GET_C_STRING_OS_DATA_ALLOCA (IMAGE_INSTANCE_WIDGET_TEXT (ii), nm);
+
+  wnd = CreateWindowEx( 
+		       exflags /* | WS_EX_NOPARENTNOTIFY*/,
+		       class,  
+		       nm,
+		       flags | WS_CHILD,
+		       0,         /* starting x position */
+		       0,         /* starting y position */
+		       IMAGE_INSTANCE_WIDGET_WIDTH (ii),
+		       IMAGE_INSTANCE_WIDGET_HEIGHT (ii),
+		       /* parent window */
+		       FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
+		       (HMENU)id,       /* No menu */
+		       (HINSTANCE) 
+		       GetWindowLong (FRAME_MSWINDOWS_HANDLE (XFRAME (frame)),
+				      GWL_HINSTANCE), 
+		       NULL);
+
+  IMAGE_INSTANCE_SUBWINDOW_ID (ii) = wnd;
+  SetWindowLong (wnd, GWL_USERDATA, (LONG)LISP_TO_VOID(image_instance));
+  /* set the widget font from the widget face */
+  SendMessage (wnd, WM_SETFONT, 
+	       (WPARAM)FONT_INSTANCE_MSWINDOWS_HFONT 
+	       (XFONT_INSTANCE (widget_face_font_info 
+				(domain, 
+				 IMAGE_INSTANCE_WIDGET_FACE (ii),
+				 0, 0))), 
+	       MAKELPARAM (TRUE, 0));
+}
+
+/* Instantiate a button widget. Unfortunately instantiated widgets are
+   particular to a frame since they need to have a parent. It's not
+   like images where you just select the image into the context you
+   want to display it in and BitBlt it. So images instances can have a
+   many-to-one relationship with things you see, whereas widgets can
+   only be one-to-one (i.e. per frame) */
+static void
+mswindows_button_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+			      Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+			      int dest_mask, Lisp_Object domain)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  HWND wnd;
+  int flags = BS_NOTIFY;
+  Lisp_Object style;
+  struct gui_item* pgui = &IMAGE_INSTANCE_WIDGET_ITEM (ii);
+  
+  if (!gui_item_active_p (pgui))
+    flags |= WS_DISABLED;
+
+  style = pgui->style;
+
+  if (EQ (style, Qradio))
+    {
+      flags |= BS_RADIOBUTTON;
+    }
+  else if (EQ (style, Qtoggle))
+    {
+      flags |= BS_AUTOCHECKBOX;
+    }
+  else
+    flags |= BS_DEFPUSHBUTTON;
+
+  mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+				pointer_bg, dest_mask, domain, "BUTTON", flags, 
+				WS_EX_CONTROLPARENT);
+
+  wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+  /* set the checked state */
+  if (gui_item_selected_p (pgui))
+    SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); 
+  else
+    SendMessage (wnd, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+}
+
+/* instantiate an edit control */
+static void
+mswindows_edit_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+			    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+			    int dest_mask, Lisp_Object domain)
+{
+  mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+				pointer_bg, dest_mask, domain, "EDIT", 
+				ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP
+				| WS_BORDER,
+				WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
+}
+
+/* instantiate a static control possible for putting other things in */
+static void
+mswindows_label_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+			     Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+			     int dest_mask, Lisp_Object domain)
+{
+  mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+				pointer_bg, dest_mask, domain, "STATIC", 
+				0, WS_EX_STATICEDGE);
+}
+
+#if 0
+/* instantiate a static control possible for putting other things in */
+static void
+mswindows_group_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+			    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+			    int dest_mask, Lisp_Object domain)
+{
+  mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+				pointer_bg, dest_mask, domain, "BUTTON", 
+				WS_GROUP | BS_GROUPBOX | WS_BORDER,
+				WS_EX_CLIENTEDGE );
+}
+#endif
+
+/* instantiate a scrollbar control */
+static void
+mswindows_scrollbar_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+				 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+				 int dest_mask, Lisp_Object domain)
+{
+  mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+				pointer_bg, dest_mask, domain, "SCROLLBAR", 
+				0,
+				WS_EX_CLIENTEDGE );
+}
+
+/* instantiate a combo control */
+static void
+mswindows_combo_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+			     Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+			     int dest_mask, Lisp_Object domain)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  HANDLE wnd;
+  Lisp_Object rest;
+
+  /* Maybe ought to generalise this more but it may be very windows
+     specific. In windows the window height of a combo box is the
+     height when the combo box is open. Thus we need to set the height
+     before creating the window and then reset it to a single line
+     after the window is created so that redisplay does the right
+     thing. */
+  mswindows_widget_instantiate (image_instance, instantiator, pointer_fg,
+				pointer_bg, dest_mask, domain, "COMBOBOX", 
+				WS_BORDER | WS_TABSTOP | CBS_DROPDOWN
+				| CBS_AUTOHSCROLL  
+				| CBS_HASSTRINGS | WS_VSCROLL,
+				WS_EX_CLIENTEDGE | WS_EX_CONTROLPARENT);
+  /* reset the height */
+  widget_text_to_pixel_conversion (domain, 
+				   IMAGE_INSTANCE_WIDGET_FACE (ii), 1, 0, 
+				   &IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii), 0);
+  wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+  /* add items to the combo box */
+  SendMessage (wnd, CB_RESETCONTENT, 0, 0);
+  LIST_LOOP (rest, Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), Q_items, Qnil))
+    {
+      Extbyte* lparam;
+      GET_C_STRING_OS_DATA_ALLOCA (XCAR (rest), lparam);
+      if (SendMessage (wnd, CB_ADDSTRING, 0, (LPARAM)lparam) == CB_ERR)
+	signal_simple_error ("error adding combo entries", instantiator);
+    }
+}
+
+/* get properties of a control */
+static Lisp_Object
+mswindows_widget_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+  /* get the text from a control */
+  if (EQ (prop, Qtext))
+    {
+      Extcount len = SendMessage (wnd, WM_GETTEXTLENGTH, 0, 0);
+      Extbyte* buf =alloca (len+1);
+      
+      SendMessage (wnd, WM_GETTEXT, (WPARAM)len+1, (LPARAM) buf);
+      return build_ext_string (buf, FORMAT_OS);
+    }
+  return Qunbound;
+}
+
+/* get properties of a button */
+static Lisp_Object
+mswindows_button_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+  /* check the state of a button */
+  if (EQ (prop, Qselected))
+    {
+      if (SendMessage (wnd, BM_GETSTATE, 0, 0) & BST_CHECKED)
+	return Qt;
+      else
+	return Qnil;
+    }
+  return Qunbound;
+}
+
+/* get properties of a combo box */
+static Lisp_Object
+mswindows_combo_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  HANDLE wnd = WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii);
+  /* get the text from a control */
+  if (EQ (prop, Qtext))
+    {
+      long item = SendMessage (wnd, CB_GETCURSEL, 0, 0);
+      Extcount len = SendMessage (wnd, CB_GETLBTEXTLEN, (WPARAM)item, 0);
+      Extbyte* buf = alloca (len+1);
+      SendMessage (wnd, CB_GETLBTEXT, (WPARAM)item, (LPARAM)buf);
+      return build_ext_string (buf, FORMAT_OS);
+    }
+  return Qunbound;
+}
+
+/* set the properties of a control */
+static Lisp_Object
+mswindows_widget_set_property (Lisp_Object image_instance, Lisp_Object prop,
+			       Lisp_Object val)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+
+  if (EQ (prop, Qtext))
+    {
+      Extbyte* lparam=0;
+      CHECK_STRING (val);
+      GET_C_STRING_OS_DATA_ALLOCA (val, lparam);
+      SendMessage (WIDGET_INSTANCE_MSWINDOWS_HANDLE (ii),
+		   WM_SETTEXT, 0, (LPARAM)lparam);
+      return Qt;
+    }
+  return Qunbound;
+}
+
+
+/************************************************************************/
 /*                            initialization                            */
 /************************************************************************/
 
@@ -1940,20 +2367,52 @@
 
   CONSOLE_HAS_METHOD (mswindows, print_image_instance);
   CONSOLE_HAS_METHOD (mswindows, finalize_image_instance);
+  CONSOLE_HAS_METHOD (mswindows, unmap_subwindow);
+  CONSOLE_HAS_METHOD (mswindows, map_subwindow);
+  CONSOLE_HAS_METHOD (mswindows, update_subwindow);
   CONSOLE_HAS_METHOD (mswindows, image_instance_equal);
   CONSOLE_HAS_METHOD (mswindows, image_instance_hash);
   CONSOLE_HAS_METHOD (mswindows, init_image_instance_from_eimage);
   CONSOLE_HAS_METHOD (mswindows, locate_pixmap_file);
-#ifdef HAVE_XPM
-  CONSOLE_HAS_METHOD (mswindows, xpm_instantiate);
-#endif
-  CONSOLE_HAS_METHOD (mswindows, xbm_instantiate);
 }
 
 void
 image_instantiator_format_create_glyphs_mswindows (void)
 {
   /* image-instantiator types */
+#ifdef HAVE_XPM
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, xpm);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, xpm, instantiate);
+#endif
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, xbm);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, xbm, instantiate);
+
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, button);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, button, property);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, button, instantiate);
+
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, edit);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, edit, instantiate);
+  
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, subwindow);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, subwindow, instantiate);
+
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, widget);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, widget, property);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, widget, set_property);
+#if 0
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, group);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, group, instantiate);
+#endif
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, label);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, label, instantiate);
+
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, combo);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, combo, property);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, combo, instantiate);
+
+  INITIALIZE_DEVICE_IIFORMAT (mswindows, scrollbar);
+  IIFORMAT_HAS_DEVMETHOD (mswindows, scrollbar, instantiate);
 
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (bmp, "bmp");
 
@@ -1989,6 +2448,12 @@
 This is used by the `make-image-instance' function.
 */ );
   Vmswindows_bitmap_file_path = Qnil;
+
+  Fprovide (Qbutton);
+  Fprovide (Qedit);
+  Fprovide (Qcombo);
+  Fprovide (Qscrollbar);
+  Fprovide (Qlabel);
 }
 
 void
--- a/src/glyphs-msw.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/glyphs-msw.h	Mon Aug 13 11:08:24 2007 +0200
@@ -1,8 +1,5 @@
 /* mswindows-specific glyphs and related.
-   Copyright (C) 1993, 1994 Free Software Foundation, Inc.
-   Copyright (C) 1995 Board of Trustees, University of Illinois.
-   Copyright (C) 1995, 1996 Ben Wing
-   Copyright (C) 1995 Sun Microsystems, Inc.
+   Copyright (C) 1998 Andy Piper
 
 This file is part of XEmacs.
 
@@ -75,5 +72,11 @@
 mswindows_initialize_image_instance_icon (struct Lisp_Image_Instance* image,
 					  int cursor);
 
+#define WIDGET_INSTANCE_MSWINDOWS_HANDLE(i) \
+     (HWND) (IMAGE_INSTANCE_SUBWINDOW_ID (i))
+
+#define XWIDGET_INSTANCE_MSWINDOWS_HANDLE(i) \
+  WIDGET_INSTANCE_MSWINDOWS_HANDLE (XIMAGE_INSTANCE (i))
+
 #endif /* HAVE_MS_WINDOWS */
 #endif /* _XEMACS_GLYPHS_MSW_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/glyphs-widget.c	Mon Aug 13 11:08:24 2007 +0200
@@ -0,0 +1,444 @@
+/* Widget-specific glyph objects.
+   Copyright (C) 1998 Andy Piper
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Synched up with: Not in FSF. */
+
+#include <config.h>
+#include "lisp.h"
+#include "lstream.h"
+#include "console.h"
+#include "device.h"
+#include "faces.h"
+#include "glyphs.h"
+#include "objects.h"
+
+#include "window.h"
+#include "buffer.h"
+#include "frame.h"
+#include "insdel.h"
+#include "opaque.h"
+
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (button);
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (combo);
+Lisp_Object Qcombo;
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (edit);
+Lisp_Object Qedit;
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (scrollbar);
+Lisp_Object Qscrollbar;
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (widget);
+#if 0
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (group);
+Lisp_Object Qgroup;
+#endif
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (label);
+Lisp_Object Qlabel;
+
+Lisp_Object Q_descriptor, Q_height, Q_width, Q_properties, Q_items;
+
+#define WIDGET_BORDER_HEIGHT 2
+#define WIDGET_BORDER_WIDTH 4
+
+/* TODO:
+   - more complex controls.
+   - tooltips for controls.
+   - images in controls.
+ */
+
+/* In windows normal windows work in pixels, dialog boxes work in
+   dialog box units. Why? sigh. We could reuse the metrics for dialogs
+   if this were not the case. As it is we have to position things
+   pixel wise. I'm not even sure that X has this problem at least for
+   buttons in groups. */
+Lisp_Object
+widget_face_font_info (Lisp_Object domain, Lisp_Object face,
+		       int *height, int *width)
+{
+  Lisp_Object font_instance = FACE_FONT (face, domain, Vcharset_ascii);
+
+  if (height)
+    *height = XFONT_INSTANCE (font_instance)->height;
+  if (width)
+    *width = XFONT_INSTANCE (font_instance)->width;
+  
+  return font_instance;
+}
+
+void
+widget_text_to_pixel_conversion (Lisp_Object domain, Lisp_Object face,
+				 int th, int tw,
+				 int* height, int* width)
+{
+  int ch=0, cw=0;
+  widget_face_font_info (domain, face, &ch, &cw);
+  if (height)
+    *height = th * (ch + 2 * WIDGET_BORDER_HEIGHT);
+  if (width)
+    *width = tw * cw + 2 * WIDGET_BORDER_WIDTH;
+}
+
+static int
+widget_possible_dest_types (void)
+{
+  return IMAGE_WIDGET_MASK;
+}
+
+#if 0 /* currently unused */
+static void
+check_valid_glyph (Lisp_Object data)
+{
+  if (SYMBOLP (data))
+    CHECK_BUFFER_GLYPH (XSYMBOL (data)->value);
+  else
+    CHECK_BUFFER_GLYPH (data);
+}
+#endif /* currently unused */
+
+static void
+check_valid_item_list (Lisp_Object data)
+{
+  Lisp_Object rest;
+  Lisp_Object items;
+  Fcheck_valid_plist (data);
+  
+  items = Fplist_get (data, Q_items, Qnil);
+
+  CHECK_LIST (items);
+  EXTERNAL_LIST_LOOP (rest, items)
+    {
+      CHECK_STRING (XCAR (rest));
+    }
+}
+
+/* wire widget property invocations to specific widgets ...  The
+ problem we are solving here is that when instantiators get converted
+ to instances they lose some type information (they just become
+ subwindows or widgets for example). For widgets we need to preserve
+ this type information so that we can do widget specific operations on
+ the instances. This is encoded in the widget type
+ field. widget_property gets invoked by decoding the primary type
+ (Qwidget), widget property then invokes based on the secondary type
+ (Qedit for example). It is debatable that we should wire things in this
+ generalised way rather than treating widgets specially in
+ image_instance_property. */
+static Lisp_Object 
+widget_property (Lisp_Object image_instance, Lisp_Object prop)
+{
+  struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
+  struct image_instantiator_methods* meths;
+
+  /* first see if its a general property ... */
+  if (!NILP (Fplist_member (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop)))
+    return Fplist_get (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, Qnil);
+
+  /* .. then try device specific methods ... */
+  meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), 
+				   IMAGE_INSTANCE_WIDGET_TYPE (ii), 
+				   ERROR_ME_NOT);
+  if (meths && HAS_IIFORMAT_METH_P (meths, property))
+    return IIFORMAT_METH (meths, property, (image_instance, prop));
+  /* ... then format specific methods ... */
+  meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), 
+				   ERROR_ME_NOT);
+  if (meths && HAS_IIFORMAT_METH_P (meths, property))
+    return IIFORMAT_METH (meths, property, (image_instance, prop));
+  /* ... then fail */
+  return Qunbound;
+}
+
+static Lisp_Object 
+widget_set_property (Lisp_Object image_instance, Lisp_Object prop, Lisp_Object val)
+{
+  struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (image_instance);
+  struct image_instantiator_methods* meths;
+  Lisp_Object ret;
+
+  /* try device specific methods first ... */
+  meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), 
+				   IMAGE_INSTANCE_WIDGET_TYPE (ii), 
+				   ERROR_ME_NOT);
+  if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
+      &&
+      !UNBOUNDP (ret = 
+		 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
+    {
+      return ret;
+    }
+  /* ... then format specific methods ... */
+  meths = decode_device_ii_format (Qnil, IMAGE_INSTANCE_WIDGET_TYPE (ii), 
+				   ERROR_ME_NOT);
+  if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
+      &&
+      !UNBOUNDP (ret = 
+		 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
+    {
+      return ret;
+    }
+  /* we didn't do any device specific properties, so shove the property in our plist */
+  IMAGE_INSTANCE_WIDGET_PROPS (ii)
+    = Fplist_put (IMAGE_INSTANCE_WIDGET_PROPS (ii), prop, val);
+  return val;
+}
+
+static void
+widget_validate (Lisp_Object instantiator)
+{
+  Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
+  struct gui_item gui;
+  if (NILP (desc))
+    signal_simple_error ("Must supply :descriptor", instantiator);
+
+  gui_parse_item_keywords (desc, &gui);
+
+  if (!NILP (find_keyword_in_vector (instantiator, Q_width))
+	     && !NILP (find_keyword_in_vector (instantiator, Q_pixel_width)))
+    signal_simple_error ("Must supply only one of :width and :pixel-width", instantiator);
+
+  if (!NILP (find_keyword_in_vector (instantiator, Q_height))
+	     && !NILP (find_keyword_in_vector (instantiator, Q_pixel_height)))
+    signal_simple_error ("Must supply only one of :height and :pixel-height", instantiator);
+}
+
+static void
+combo_validate (Lisp_Object instantiator)
+{
+  widget_validate (instantiator);
+  if (NILP (find_keyword_in_vector (instantiator, Q_properties)))
+    signal_simple_error ("Must supply item list", instantiator);
+}
+
+static void
+initialize_widget_image_instance (struct Lisp_Image_Instance *ii, Lisp_Object type)
+{
+  /*  initialize_subwindow_image_instance (ii);*/
+  IMAGE_INSTANCE_WIDGET_TYPE (ii) = type;
+  IMAGE_INSTANCE_WIDGET_PROPS (ii) = Qnil;
+  IMAGE_INSTANCE_WIDGET_FACE (ii) = Vwidget_face;
+  gui_item_init (&IMAGE_INSTANCE_WIDGET_ITEM (ii));
+}
+
+/* Instantiate a button widget. Unfortunately instantiated widgets are
+   particular to a frame since they need to have a parent. It's not
+   like images where you just select the image into the context you
+   want to display it in and BitBlt it. So images instances can have a
+   many-to-one relationship with things you see, whereas widgets can
+   only be one-to-one (i.e. per frame) */
+static void
+widget_instantiate_1 (Lisp_Object image_instance, Lisp_Object instantiator,
+		      Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+		      int dest_mask, Lisp_Object domain, int default_textheight,
+		      int default_pixheight)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  struct gui_item* pgui = &IMAGE_INSTANCE_WIDGET_ITEM (ii);
+  Lisp_Object face = find_keyword_in_vector (instantiator, Q_face);
+  Lisp_Object height = find_keyword_in_vector (instantiator, Q_height);
+  Lisp_Object width = find_keyword_in_vector (instantiator, Q_width);
+  Lisp_Object pixwidth = find_keyword_in_vector (instantiator, Q_pixel_width);
+  Lisp_Object pixheight = find_keyword_in_vector (instantiator, Q_pixel_height);
+  Lisp_Object desc = find_keyword_in_vector (instantiator, Q_descriptor);
+  int pw=0, ph=0, tw=0, th=0;
+  
+  /* this just does pixel type sizing */
+  subwindow_instantiate (image_instance, instantiator, pointer_fg, pointer_bg,
+			 dest_mask, domain);
+
+  if (!(dest_mask & IMAGE_WIDGET_MASK))
+    incompatible_image_types (instantiator, dest_mask, IMAGE_WIDGET_MASK);
+
+  initialize_widget_image_instance (ii, XVECTOR_DATA (instantiator)[0]);
+
+  /* retrieve the fg and bg colors */
+  if (!NILP (face))
+    IMAGE_INSTANCE_WIDGET_FACE (ii) = Fget_face (face);
+  
+  /* data items for some widgets */
+  IMAGE_INSTANCE_WIDGET_PROPS (ii) = 
+    find_keyword_in_vector (instantiator, Q_properties);
+
+  /* retrieve the gui item information */
+  if (STRINGP (desc) || NILP (desc))
+    IMAGE_INSTANCE_WIDGET_TEXT (ii) = desc;
+  else
+    gui_parse_item_keywords (find_keyword_in_vector (instantiator, Q_descriptor),
+			     pgui);
+
+  /* normalize size information */
+  if (!NILP (width))
+    tw = XINT (width);
+  if (!NILP (height))
+    th = XINT (height);
+  if (!NILP (pixwidth))
+    pw = XINT (pixwidth);
+  if (!NILP (pixheight))
+    ph = XINT (pixheight);
+
+  if (!tw && !pw && !NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
+    tw = XSTRING_LENGTH (IMAGE_INSTANCE_WIDGET_TEXT (ii));
+  if (!th && !ph)
+    {
+      if (default_textheight)
+	th = default_textheight;
+      else if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
+	th = 1;
+      else
+	ph = default_pixheight;
+    }
+
+  if (tw !=0 || th !=0)
+    widget_text_to_pixel_conversion (domain,
+				     IMAGE_INSTANCE_WIDGET_FACE (ii),
+				     th, tw, th ? &ph : 0, tw ? &pw : 0);
+
+  IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = pw;
+  IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = ph;
+}
+
+static void
+widget_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+		    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+		    int dest_mask, Lisp_Object domain)
+{
+  widget_instantiate_1 (image_instance, instantiator, pointer_fg,
+			       pointer_bg, dest_mask, domain, 1, 0);
+}
+
+static void
+combo_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+		   Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+		   int dest_mask, Lisp_Object domain)
+{
+  Lisp_Object data = Fplist_get (find_keyword_in_vector (instantiator, Q_properties),
+				 Q_items, Qnil);
+  int len;
+  GET_LIST_LENGTH (data, len);
+  widget_instantiate_1 (image_instance, instantiator, pointer_fg,
+			pointer_bg, dest_mask, domain, len + 1, 0);
+}
+
+/* Instantiate a static control */
+static void
+static_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+		    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+		    int dest_mask, Lisp_Object domain)
+{
+  widget_instantiate_1 (image_instance, instantiator, pointer_fg,
+			pointer_bg, dest_mask, domain, 0, 4);
+}
+
+
+/************************************************************************/
+/*                            initialization                            */
+/************************************************************************/
+
+void
+syms_of_glyphs_widget (void)
+{
+  defkeyword (&Q_descriptor, ":descriptor");
+  defkeyword (&Q_height, ":height");
+  defkeyword (&Q_width, ":width");
+  defkeyword (&Q_properties, ":properties");
+  defkeyword (&Q_items, ":items");
+}
+
+void
+image_instantiator_format_create_glyphs_widget (void)
+{
+  /* we only do this for properties */
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM (widget, "widget");
+  IIFORMAT_HAS_METHOD (widget, property);
+  IIFORMAT_HAS_METHOD (widget, set_property);
+
+  /* widget image-instantiator types - buttons */
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (button, "button");
+  IIFORMAT_HAS_SHARED_METHOD (button, validate, widget);
+  IIFORMAT_HAS_SHARED_METHOD (button, possible_dest_types, widget);
+  IIFORMAT_HAS_SHARED_METHOD (button, instantiate, widget);
+
+  IIFORMAT_VALID_KEYWORD (button, Q_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (button, Q_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (button, Q_pixel_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (button, Q_pixel_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (button, Q_face, check_valid_face);
+  IIFORMAT_VALID_KEYWORD (button, Q_descriptor, check_valid_vector);
+  /* edit fields */
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (edit, "edit");
+  IIFORMAT_HAS_SHARED_METHOD (edit, validate, widget);
+  IIFORMAT_HAS_SHARED_METHOD (edit, possible_dest_types, widget);
+  IIFORMAT_HAS_SHARED_METHOD (edit, instantiate, widget);
+
+  IIFORMAT_VALID_KEYWORD (edit, Q_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (edit, Q_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (edit, Q_pixel_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (edit, Q_pixel_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (edit, Q_face, check_valid_face);
+  IIFORMAT_VALID_KEYWORD (edit, Q_descriptor, check_valid_vector);
+  /* combo box */
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (combo, "combo");
+  IIFORMAT_HAS_METHOD (combo, validate);
+  IIFORMAT_HAS_SHARED_METHOD (combo, possible_dest_types, widget);
+  IIFORMAT_HAS_METHOD (combo, instantiate);
+
+  IIFORMAT_VALID_KEYWORD (combo, Q_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (combo, Q_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (combo, Q_pixel_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (combo, Q_face, check_valid_face);
+  IIFORMAT_VALID_KEYWORD (combo, Q_descriptor, check_valid_vector);
+  IIFORMAT_VALID_KEYWORD (combo, Q_properties, check_valid_item_list);
+  /* scrollbar */
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (scrollbar, "scrollbar");
+  IIFORMAT_HAS_SHARED_METHOD (scrollbar, validate, widget);
+  IIFORMAT_HAS_SHARED_METHOD (scrollbar, possible_dest_types, widget);
+  IIFORMAT_HAS_SHARED_METHOD (scrollbar, instantiate, widget);
+
+  IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (scrollbar, Q_pixel_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (scrollbar, Q_face, check_valid_face);
+  IIFORMAT_VALID_KEYWORD (scrollbar, Q_descriptor, check_valid_vector);
+  /* labels */
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (label, "label");
+  IIFORMAT_HAS_SHARED_METHOD (label, possible_dest_types, widget);
+  IIFORMAT_HAS_SHARED_METHOD (label, instantiate, static);
+
+  IIFORMAT_VALID_KEYWORD (label, Q_pixel_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (label, Q_pixel_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (label, Q_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (label, Q_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (label, Q_face, check_valid_face);
+  IIFORMAT_VALID_KEYWORD (label, Q_descriptor, check_valid_string);
+#if 0
+  /* group */
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (group, "group");
+  IIFORMAT_HAS_SHARED_METHOD (group, possible_dest_types, widget);
+  IIFORMAT_HAS_METHOD (group, instantiate);
+
+  IIFORMAT_VALID_KEYWORD (group, Q_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (group, Q_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (group, Q_pixel_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (group, Q_pixel_height, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (group, Q_face, check_valid_face);
+  IIFORMAT_VALID_KEYWORD (group, Q_background, check_valid_string);
+  IIFORMAT_VALID_KEYWORD (group, Q_descriptor, check_valid_string);
+#endif
+}
+
+void
+vars_of_glyphs_widget (void)
+{
+}
--- a/src/glyphs-x.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/glyphs-x.c	Mon Aug 13 11:08:24 2007 +0200
@@ -54,6 +54,7 @@
 #include "xmu.h"
 
 #include "buffer.h"
+#include "window.h"
 #include "frame.h"
 #include "insdel.h"
 #include "opaque.h"
@@ -80,6 +81,11 @@
 
 #define LISP_DEVICE_TO_X_SCREEN(dev) XDefaultScreenOfDisplay (DEVICE_X_DISPLAY (XDEVICE (dev)))
 
+#ifdef HAVE_XPM
+DEFINE_DEVICE_IIFORMAT (x, xpm);
+#endif
+DEFINE_DEVICE_IIFORMAT (x, xbm);
+DEFINE_DEVICE_IIFORMAT (x, subwindow);
 #ifdef HAVE_XFACE
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xface);
 Lisp_Object Qxface;
@@ -314,10 +320,6 @@
 	}
       write_c_string (")", printcharfun);
       break;
-#if HAVE_SUBWINDOWS
-    case IMAGE_SUBWINDOW:
-      /* #### implement me */
-#endif
     default:
       break;
     }
@@ -333,27 +335,38 @@
     {
       Display *dpy = DEVICE_X_DISPLAY (XDEVICE (p->device));
 
-      if (IMAGE_INSTANCE_X_PIXMAP (p))
-	XFreePixmap (dpy, IMAGE_INSTANCE_X_PIXMAP (p));
-      if (IMAGE_INSTANCE_X_MASK (p) &&
-	  IMAGE_INSTANCE_X_MASK (p) != IMAGE_INSTANCE_X_PIXMAP (p))
-	XFreePixmap (dpy, IMAGE_INSTANCE_X_MASK (p));
-      IMAGE_INSTANCE_X_PIXMAP (p) = 0;
-      IMAGE_INSTANCE_X_MASK (p) = 0;
-
-      if (IMAGE_INSTANCE_X_CURSOR (p))
+      if (IMAGE_INSTANCE_TYPE (p) == IMAGE_WIDGET
+	  || 
+	  IMAGE_INSTANCE_TYPE (p) == IMAGE_SUBWINDOW)
+	{
+	  if (IMAGE_INSTANCE_SUBWINDOW_ID (p))
+	    XDestroyWindow (dpy, IMAGE_INSTANCE_X_SUBWINDOW_ID (p));
+	  IMAGE_INSTANCE_SUBWINDOW_ID (p) = 0;
+	}
+      else
 	{
-	  XFreeCursor (dpy, IMAGE_INSTANCE_X_CURSOR (p));
-	  IMAGE_INSTANCE_X_CURSOR (p) = 0;
-	}
-
-      if (IMAGE_INSTANCE_X_NPIXELS (p) != 0)
-	{
-	  XFreeColors (dpy,
-		       IMAGE_INSTANCE_X_COLORMAP (p),
-		       IMAGE_INSTANCE_X_PIXELS (p),
-		       IMAGE_INSTANCE_X_NPIXELS (p), 0);
-	  IMAGE_INSTANCE_X_NPIXELS (p) = 0;
+	  if (IMAGE_INSTANCE_X_PIXMAP (p))
+	    XFreePixmap (dpy, IMAGE_INSTANCE_X_PIXMAP (p));
+	  if (IMAGE_INSTANCE_X_MASK (p) &&
+	      IMAGE_INSTANCE_X_MASK (p) != IMAGE_INSTANCE_X_PIXMAP (p))
+	    XFreePixmap (dpy, IMAGE_INSTANCE_X_MASK (p));
+	  IMAGE_INSTANCE_X_PIXMAP (p) = 0;
+	  IMAGE_INSTANCE_X_MASK (p) = 0;
+	  
+	  if (IMAGE_INSTANCE_X_CURSOR (p))
+	    {
+	      XFreeCursor (dpy, IMAGE_INSTANCE_X_CURSOR (p));
+	      IMAGE_INSTANCE_X_CURSOR (p) = 0;
+	    }
+	  
+	  if (IMAGE_INSTANCE_X_NPIXELS (p) != 0)
+	    {
+	      XFreeColors (dpy,
+			   IMAGE_INSTANCE_X_COLORMAP (p),
+			   IMAGE_INSTANCE_X_PIXELS (p),
+			   IMAGE_INSTANCE_X_NPIXELS (p), 0);
+	      IMAGE_INSTANCE_X_NPIXELS (p) = 0;
+	    }
 	}
     }
   if (IMAGE_INSTANCE_X_PIXELS (p))
@@ -378,10 +391,6 @@
       if (IMAGE_INSTANCE_X_COLORMAP (p1) != IMAGE_INSTANCE_X_COLORMAP (p2) ||
 	  IMAGE_INSTANCE_X_NPIXELS (p1) != IMAGE_INSTANCE_X_NPIXELS (p2))
 	return 0;
-#if HAVE_SUBWINDOWS
-    case IMAGE_SUBWINDOW:
-      /* #### implement me */
-#endif
       break;
     default:
       break;
@@ -399,11 +408,6 @@
     case IMAGE_COLOR_PIXMAP:
     case IMAGE_POINTER:
       return IMAGE_INSTANCE_X_NPIXELS (p);
-#if HAVE_SUBWINDOWS
-    case IMAGE_SUBWINDOW:
-      /* #### implement me */
-      return 0;
-#endif
     default:
       return 0;
     }
@@ -2020,168 +2024,82 @@
 }
 
 
-#if HAVE_SUBWINDOWS
 /************************************************************************/
-/*                               subwindows                             */
+/*                      subwindow and widget support                      */
 /************************************************************************/
 
-Lisp_Object Qsubwindowp;
-
-static Lisp_Object
-mark_subwindow (Lisp_Object obj, void (*markobj) (Lisp_Object))
+/* unmap the image if it is a widget. This is used by redisplay via
+   redisplay_unmap_subwindows */
+static void
+x_unmap_subwindow (struct Lisp_Image_Instance *p)
 {
-  struct Lisp_Subwindow *sw = XSUBWINDOW (obj);
-  return sw->frame;
+  XUnmapWindow (DisplayOfScreen (IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (p)),
+		IMAGE_INSTANCE_X_SUBWINDOW_ID (p));
 }
 
+/* map the subwindow. This is used by redisplay via
+   redisplay_output_subwindow */
 static void
-print_subwindow (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
+x_map_subwindow (struct Lisp_Image_Instance *p, int x, int y)
 {
-  char buf[100];
-  struct Lisp_Subwindow *sw = XSUBWINDOW (obj);
-  struct frame *frm = XFRAME (sw->frame);
-
-  if (print_readably)
-    error ("printing unreadable object #<subwindow 0x%x>",
-	   sw->header.uid);
-
-  write_c_string ("#<subwindow", printcharfun);
-  sprintf (buf, " %dx%d", sw->width, sw->height);
-  write_c_string (buf, printcharfun);
-
-  /* This is stolen from frame.c.  Subwindows are strange in that they
-     are specific to a particular frame so we want to print in their
-     description what that frame is. */
-
-  write_c_string (" on #<", printcharfun);
-  if (!FRAME_LIVE_P (frm))
-    write_c_string ("dead", printcharfun);
-  else if (FRAME_TTY_P (frm))
-    write_c_string ("tty", printcharfun);
-  else if (FRAME_X_P (frm))
-    write_c_string ("x", printcharfun);
-  else
-    write_c_string ("UNKNOWN", printcharfun);
-  write_c_string ("-frame ", printcharfun);
-  print_internal (frm->name, printcharfun, 1);
-  sprintf (buf, " 0x%x>", frm->header.uid);
-  write_c_string (buf, printcharfun);
-
-  sprintf (buf, ") 0x%x>", sw->header.uid);
-  write_c_string (buf, printcharfun);
-}
-
-static void
-finalize_subwindow (void *header, int for_disksave)
-{
-  struct Lisp_Subwindow *sw = (struct Lisp_Subwindow *) header;
-  if (for_disksave) finalose (sw);
-  if (sw->subwindow)
-    {
-      XDestroyWindow (DisplayOfScreen (sw->xscreen), sw->subwindow);
-      sw->subwindow = 0;
-    }
-}
-
-/* subwindows are equal iff they have the same window XID */
-static int
-subwindow_equal (Lisp_Object obj1, Lisp_Object obj2, int depth)
-{
-  return (XSUBWINDOW (obj1)->subwindow == XSUBWINDOW (obj2)->subwindow);
-}
-
-static unsigned long
-subwindow_hash (Lisp_Object obj, int depth)
-{
-  return XSUBWINDOW (obj)->subwindow;
+  XMapWindow (DisplayOfScreen (IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (p)),
+	      IMAGE_INSTANCE_X_SUBWINDOW_ID (p));
+  XMoveWindow (DisplayOfScreen (IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (p)),
+	       IMAGE_INSTANCE_X_SUBWINDOW_ID (p), x, y);
 }
 
-DEFINE_LRECORD_IMPLEMENTATION ("subwindow", subwindow,
-			       mark_subwindow, print_subwindow,
-			       finalize_subwindow, subwindow_equal,
-			       subwindow_hash, struct Lisp_Subwindow);
-
-/* #### PROBLEM: The display routines assume that the glyph is only
- being displayed in one buffer.  If it is in two different buffers
- which are both being displayed simultaneously you will lose big time.
- This can be dealt with in the new redisplay. */
-
-/* #### These are completely un-re-implemented in 19.14.  Get it done
-   for 19.15. */
-
-DEFUN ("make-subwindow", Fmake_subwindow, 0, 3, 0, /*
-Creates a new `subwindow' object of size WIDTH x HEIGHT.
-The default is a window of size 1x1, which is also the minimum allowed
-window size.  Subwindows are per-frame.  A buffer being shown in two
-different frames will only display a subwindow glyph in the frame in
-which it was actually created.  If two windows on the same frame are
-displaying the buffer then the most recently used window will actually
-display the window.  If the frame is not specified, the selected frame
-is used.
-
-Subwindows are not currently implemented.
-*/
-       (width, height, frame))
+/* instantiate and x type subwindow */
+static void
+x_subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+			Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+			int dest_mask, Lisp_Object domain)
 {
+  /* This function can GC */
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+  Lisp_Object frame = FW_FRAME (domain);
+  struct frame* f = XFRAME (frame);
   Display *dpy;
   Screen *xs;
-  Window pw;
-  struct frame *f;
-  unsigned int iw, ih;
+  Window pw, win;
   XSetWindowAttributes xswa;
   Mask valueMask = 0;
+  unsigned int w = IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii), 
+    h = IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii);
 
-  error ("subwindows are not functional in 20.2; they may be again someday");
+  if (!DEVICE_X_P (XDEVICE (device)))
+    signal_simple_error ("Not an X device", device);
 
-  f = decode_x_frame (frame);
+  dpy = DEVICE_X_DISPLAY (XDEVICE (device));
+  xs = DefaultScreenOfDisplay (dpy);
 
-  xs = LISP_DEVICE_TO_X_SCREEN (FRAME_DEVICE (f));
-  dpy = DisplayOfScreen (xs);
+  if (dest_mask & IMAGE_SUBWINDOW_MASK)
+    IMAGE_INSTANCE_TYPE (ii) = IMAGE_SUBWINDOW;
+  else
+    incompatible_image_types (instantiator, dest_mask,
+			      IMAGE_SUBWINDOW_MASK);
+
   pw = XtWindow (FRAME_X_TEXT_WIDGET (f));
 
-  if (NILP (width))
-    iw = 1;
-  else
-    {
-      CHECK_INT (width);
-      iw = XINT (width);
-      if (iw < 1) iw = 1;
-    }
-  if (NILP (height))
-    ih = 1;
-  else
-    {
-      CHECK_INT (height);
-      ih = XINT (height);
-      if (ih < 1) ih = 1;
-    }
+  ii->data = xnew_and_zero (struct x_subwindow_data);
+
+  IMAGE_INSTANCE_X_SUBWINDOW_PARENT (ii) = pw;
+  IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (ii) = xs;
 
-  {
-    struct Lisp_Subwindow *sw =
-      alloc_lcrecord_type (struct Lisp_Subwindow, lrecord_subwindow);
-    Lisp_Object val;
-    sw->frame = frame;
-    sw->xscreen = xs;
-    sw->parent_window = pw;
-    sw->height = ih;
-    sw->width = iw;
-
-    xswa.backing_store = Always;
-    valueMask |= CWBackingStore;
-
-    xswa.colormap = DefaultColormapOfScreen (xs);
-    valueMask |= CWColormap;
-
-    sw->subwindow = XCreateWindow (dpy, pw, 0, 0, iw, ih, 0, CopyFromParent,
-				   InputOutput, CopyFromParent, valueMask,
-				   &xswa);
-
-    XSETSUBWINDOW (val, sw);
-    return val;
-  }
+  xswa.backing_store = Always;
+  valueMask |= CWBackingStore;
+  xswa.colormap = DefaultColormapOfScreen (xs);
+  valueMask |= CWColormap;
+  
+  win = XCreateWindow (dpy, pw, 0, 0, w, h, 0, CopyFromParent,
+		       InputOutput, CopyFromParent, valueMask,
+		       &xswa);
+  
+  IMAGE_INSTANCE_SUBWINDOW_ID (ii) = (void*)win;
 }
 
-/* #### Should this function exist? */
+#if 0
+/* #### Should this function exist? If there's any doubt I'm not implementing it --andyp */
 DEFUN ("change-subwindow-property", Fchange_subwindow_property, 3, 3, 0, /*
 For the given SUBWINDOW, set PROPERTY to DATA, which is a string.
 Subwindows are not currently implemented.
@@ -2208,91 +2126,16 @@
 
   return property;
 }
+#endif
 
-DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /*
-Return non-nil if OBJECT is a subwindow.
-Subwindows are not currently implemented.
-*/
-       (object))
-{
-  return SUBWINDOWP (object) ? Qt : Qnil;
-}
-
-DEFUN ("subwindow-width", Fsubwindow_width, 1, 1, 0, /*
-Width of SUBWINDOW.
-Subwindows are not currently implemented.
-*/
-       (subwindow))
+static void 
+x_resize_subwindow (struct Lisp_Image_Instance* ii, int w, int h)
 {
-  CHECK_SUBWINDOW (subwindow);
-  return make_int (XSUBWINDOW (subwindow)->width);
-}
-
-DEFUN ("subwindow-height", Fsubwindow_height, 1, 1, 0, /*
-Height of SUBWINDOW.
-Subwindows are not currently implemented.
-*/
-       (subwindow))
-{
-  CHECK_SUBWINDOW (subwindow);
-  return make_int (XSUBWINDOW (subwindow)->height);
-}
-
-DEFUN ("subwindow-xid", Fsubwindow_xid, 1, 1, 0, /*
-Return the xid of SUBWINDOW as a number.
-Subwindows are not currently implemented.
-*/
-       (subwindow))
-{
-  CHECK_SUBWINDOW (subwindow);
-  return make_int (XSUBWINDOW (subwindow)->subwindow);
+  XResizeWindow (DisplayOfScreen (IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (ii)),
+		 IMAGE_INSTANCE_X_SUBWINDOW_ID (ii),
+		 w, h);
 }
 
-DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /*
-Resize SUBWINDOW to WIDTH x HEIGHT.
-If a value is nil that parameter is not changed.
-Subwindows are not currently implemented.
-*/
-       (subwindow, width, height))
-{
-  int neww, newh;
-  struct Lisp_Subwindow *sw;
-
-  CHECK_SUBWINDOW (subwindow);
-  sw = XSUBWINDOW (subwindow);
-
-  if (NILP (width))
-    neww = sw->width;
-  else
-    neww = XINT (width);
-
-  if (NILP (height))
-    newh = sw->height;
-  else
-    newh = XINT (height);
-
-  XResizeWindow (DisplayOfScreen (sw->xscreen), sw->subwindow, neww, newh);
-
-  sw->height = newh;
-  sw->width = neww;
-
-  return subwindow;
-}
-
-DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /*
-Generate a Map event for SUBWINDOW.
-Subwindows are not currently implemented.
-*/
-       (subwindow))
-{
-  CHECK_SUBWINDOW (subwindow);
-
-  XMapWindow (DisplayOfScreen (XSUBWINDOW (subwindow)->xscreen),
-	      XSUBWINDOW (subwindow)->subwindow);
-
-  return subwindow;
-}
-#endif
 
 /************************************************************************/
 /*                            initialization                            */
@@ -2301,17 +2144,8 @@
 void
 syms_of_glyphs_x (void)
 {
-#if HAVE_SUBWINDOWS
-  defsymbol (&Qsubwindowp, "subwindowp");
-
-  DEFSUBR (Fmake_subwindow);
+#if 0
   DEFSUBR (Fchange_subwindow_property);
-  DEFSUBR (Fsubwindowp);
-  DEFSUBR (Fsubwindow_width);
-  DEFSUBR (Fsubwindow_height);
-  DEFSUBR (Fsubwindow_xid);
-  DEFSUBR (Fresize_subwindow);
-  DEFSUBR (Fforce_subwindow_map);
 #endif
 }
 
@@ -2327,15 +2161,23 @@
   CONSOLE_HAS_METHOD (x, colorize_image_instance);
   CONSOLE_HAS_METHOD (x, init_image_instance_from_eimage);
   CONSOLE_HAS_METHOD (x, locate_pixmap_file);
-#ifdef HAVE_XPM
-  CONSOLE_HAS_METHOD (x, xpm_instantiate);
-#endif
-  CONSOLE_HAS_METHOD (x, xbm_instantiate);
+  CONSOLE_HAS_METHOD (x, unmap_subwindow);
+  CONSOLE_HAS_METHOD (x, map_subwindow);
+  CONSOLE_HAS_METHOD (x, resize_subwindow);
 }
 
 void
 image_instantiator_format_create_glyphs_x (void)
 {
+#ifdef HAVE_XPM
+  INITIALIZE_DEVICE_IIFORMAT (x, xpm);
+  IIFORMAT_HAS_DEVMETHOD (x, xpm, instantiate);
+#endif
+  INITIALIZE_DEVICE_IIFORMAT (x, xbm);
+  IIFORMAT_HAS_DEVMETHOD (x, xbm, instantiate);
+
+  INITIALIZE_DEVICE_IIFORMAT (x, subwindow);
+  IIFORMAT_HAS_DEVMETHOD (x, subwindow, instantiate);
 
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (cursor_font, "cursor-font");
 
--- a/src/glyphs-x.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/glyphs-x.h	Mon Aug 13 11:08:24 2007 +0200
@@ -74,33 +74,28 @@
 #define XIMAGE_INSTANCE_X_NPIXELS(i) \
   IMAGE_INSTANCE_X_NPIXELS (XIMAGE_INSTANCE (i))
 
-/* Set to 1 if you wish to implement this feature */
-# define HAVE_SUBWINDOWS 0
-# if HAVE_SUBWINDOWS
 /****************************************************************************
  *                            Subwindow Object                              *
  ****************************************************************************/
 
-DECLARE_LRECORD (subwindow, struct Lisp_Subwindow);
-#define XSUBWINDOW(x) XRECORD (x, subwindow, struct Lisp_Subwindow)
-#define XSETSUBWINDOW(x, p) XSETRECORD (x, p, subwindow)
-#define SUBWINDOWP(x) RECORDP (x, subwindow)
-#define GC_SUBWINDOWP(x) GC_RECORDP (x, subwindow)
-#define CHECK_SUBWINDOW(x) CHECK_RECORD (x, subwindow)
-
-struct Lisp_Subwindow
+struct x_subwindow_data
 {
-  struct lcrecord_header header;
-  Lisp_Object frame;
   Screen *xscreen;
   Window parent_window;
+};
 
-  unsigned int width, height;
-  Window subwindow;
+#define X_SUBWINDOW_INSTANCE_DATA(i) ((struct x_subwindow_data *) (i)->data)
 
-  int being_displayed;		/* used to detect when needs to be unmapped */
-};
-# endif
+#define IMAGE_INSTANCE_X_SUBWINDOW_SCREEN(i) \
+  (X_SUBWINDOW_INSTANCE_DATA (i)->xscreen)
+#define IMAGE_INSTANCE_X_SUBWINDOW_PARENT(i) \
+  (X_SUBWINDOW_INSTANCE_DATA (i)->parent_window)
+#define XIMAGE_INSTANCE_X_SUBWINDOW_PARENT(i) \
+  IMAGE_INSTANCE_X_SUBWINDOW_PARENT (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_X_SUBWINDOW_SCREEN(i) \
+  IMAGE_INSTANCE_X_SUBWINDOW_SCREEN (XIMAGE_INSTANCE (i))
+#define IMAGE_INSTANCE_X_SUBWINDOW_ID(i) \
+  ((Window) IMAGE_INSTANCE_SUBWINDOW_ID (i))
 
 #endif /* HAVE_X_WINDOWS */
 #endif /* _XEMACS_GLYPHS_X_H_ */
--- a/src/glyphs.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/glyphs.c	Mon Aug 13 11:08:24 2007 +0200
@@ -3,6 +3,7 @@
    Copyright (C) 1995 Tinker Systems
    Copyright (C) 1995, 1996 Ben Wing
    Copyright (C) 1995 Sun Microsystems
+   Copyright (C) 1998 Andy Piper
 
 This file is part of XEmacs.
 
@@ -34,10 +35,13 @@
 #include "faces.h"
 #include "frame.h"
 #include "insdel.h"
-#include "glyphs.h"
+#include "opaque.h"
 #include "objects.h"
 #include "redisplay.h"
 #include "window.h"
+#include "frame.h"
+#include "chartab.h"
+#include "rangetab.h"
 
 #ifdef HAVE_XPM
 #include <X11/xpm.h>
@@ -52,11 +56,11 @@
 Lisp_Object Qcolor_pixmap_image_instance_p;
 Lisp_Object Qpointer_image_instance_p;
 Lisp_Object Qsubwindow_image_instance_p;
+Lisp_Object Qwidget_image_instance_p;
 Lisp_Object Qconst_glyph_variable;
 Lisp_Object Qmono_pixmap, Qcolor_pixmap, Qsubwindow;
-Lisp_Object Q_file, Q_data, Q_face;
+Lisp_Object Q_file, Q_data, Q_face, Q_pixel_width, Q_pixel_height;
 Lisp_Object Qformatted_string;
-
 Lisp_Object Vcurrent_display_table;
 Lisp_Object Vtruncation_glyph, Vcontinuation_glyph, Voctal_escape_glyph;
 Lisp_Object Vcontrol_arrow_glyph, Vinvisible_text_glyph, Vhscroll_glyph;
@@ -70,6 +74,7 @@
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (inherit);
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (string);
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (formatted_string);
+DEFINE_IMAGE_INSTANTIATOR_FORMAT (subwindow);
 
 #ifdef HAVE_WINDOW_SYSTEM
 DEFINE_IMAGE_INSTANTIATOR_FORMAT (xbm);
@@ -95,6 +100,7 @@
 struct image_instantiator_format_entry
 {
   Lisp_Object symbol;
+  Lisp_Object device;
   struct image_instantiator_methods *meths;
 };
 
@@ -119,8 +125,9 @@
  *                          Image Instantiators                             *
  ****************************************************************************/
 
-static struct image_instantiator_methods *
-decode_image_instantiator_format (Lisp_Object format, Error_behavior errb)
+struct image_instantiator_methods *
+decode_device_ii_format (Lisp_Object device, Lisp_Object format,
+			 Error_behavior errb)
 {
   int i;
 
@@ -134,10 +141,19 @@
   for (i = 0; i < Dynarr_length (the_image_instantiator_format_entry_dynarr);
        i++)
     {
-      if (EQ (format,
-	      Dynarr_at (the_image_instantiator_format_entry_dynarr, i).
-	      symbol))
-	return Dynarr_at (the_image_instantiator_format_entry_dynarr, i).meths;
+      if ( EQ (format,
+	       Dynarr_at (the_image_instantiator_format_entry_dynarr, i).
+	       symbol) )
+	{
+	  Lisp_Object d = Dynarr_at (the_image_instantiator_format_entry_dynarr, i).
+	    device;
+	  if ((NILP (d) && NILP (device))
+	      ||
+	      (!NILP (device) &&
+	       EQ (CONSOLE_TYPE (XCONSOLE 
+				 (DEVICE_CONSOLE (XDEVICE (device)))), d)))
+	    return Dynarr_at (the_image_instantiator_format_entry_dynarr, i).meths;
+	}
     }
 
   maybe_signal_simple_error ("Invalid image-instantiator format", format,
@@ -146,6 +162,12 @@
   return 0;
 }
 
+struct image_instantiator_methods *
+decode_image_instantiator_format (Lisp_Object format, Error_behavior errb)
+{
+  return decode_device_ii_format (Qnil, format, errb);
+}
+
 static int
 valid_image_instantiator_format_p (Lisp_Object format)
 {
@@ -157,7 +179,7 @@
 Given an IMAGE-INSTANTIATOR-FORMAT, return non-nil if it is valid.
 Valid formats are some subset of 'nothing, 'string, 'formatted-string,
 'xpm, 'xbm, 'xface, 'gif, 'jpeg, 'png, 'tiff, 'cursor-font, 'font,
-'autodetect, and 'subwindow, depending on how XEmacs was compiled.
+'autodetect, 'widget and 'subwindow, depending on how XEmacs was compiled.
 */
        (image_instantiator_format))
 {
@@ -175,17 +197,25 @@
 }
 
 void
+add_entry_to_device_ii_format_list (Lisp_Object device, Lisp_Object symbol,
+				    struct image_instantiator_methods *meths)
+{
+  struct image_instantiator_format_entry entry;
+
+  entry.symbol = symbol;
+  entry.device = device;
+  entry.meths = meths;
+  Dynarr_add (the_image_instantiator_format_entry_dynarr, entry);
+  Vimage_instantiator_format_list =
+    Fcons (symbol, Vimage_instantiator_format_list);
+}
+
+void
 add_entry_to_image_instantiator_format_list (Lisp_Object symbol,
 					     struct
 					     image_instantiator_methods *meths)
 {
-  struct image_instantiator_format_entry entry;
-
-  entry.symbol = symbol;
-  entry.meths = meths;
-  Dynarr_add (the_image_instantiator_format_entry_dynarr, entry);
-  Vimage_instantiator_format_list =
-    Fcons (symbol, Vimage_instantiator_format_list);
+  add_entry_to_device_ii_format_list (Qnil, symbol, meths);
 }
 
 static Lisp_Object *
@@ -355,7 +385,13 @@
   CHECK_STRING (data);
 }
 
-static void
+void
+check_valid_vector (Lisp_Object data)
+{
+  CHECK_VECTOR (data);
+}
+
+void
 check_valid_face (Lisp_Object data)
 {
   Fget_face (data);
@@ -481,12 +517,16 @@
      longer exist (e.g. w3 pixmaps are almost always from temporary
      files). */
   {
-    struct image_instantiator_methods * meths =
-      decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
-					ERROR_ME);
-    return IIFORMAT_METH_OR_GIVEN (meths, normalize,
-				   (instantiator, contype),
-				   instantiator);
+    struct gcpro gcpro1;
+    struct image_instantiator_methods *meths;
+
+    GCPRO1 (instantiator);
+    
+    meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
+					      ERROR_ME);
+    RETURN_UNGCPRO (IIFORMAT_METH_OR_GIVEN (meths, normalize,
+					    (instantiator, contype),
+					    instantiator));
   }
 }
 
@@ -499,16 +539,25 @@
   Lisp_Object ii = allocate_image_instance (device);
   struct image_instantiator_methods *meths;
   struct gcpro gcpro1;
+  int  methp = 0;
 
   GCPRO1 (ii);
   meths = decode_image_instantiator_format (XVECTOR_DATA (instantiator)[0],
 					    ERROR_ME);
-  if (!HAS_IIFORMAT_METH_P (meths, instantiate))
+  methp = (int)HAS_IIFORMAT_METH_P (meths, instantiate);
+  MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
+					    pointer_bg, dest_mask, domain));
+  
+  /* now do device specific instantiation */
+  meths = decode_device_ii_format (device, XVECTOR_DATA (instantiator)[0],
+				   ERROR_ME_NOT);
+
+  if (!methp && (!meths || !HAS_IIFORMAT_METH_P (meths, instantiate)))
     signal_simple_error
       ("Don't know how to instantiate this image instantiator?",
        instantiator);
-  IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
-				      pointer_bg, dest_mask, domain));
+  MAYBE_IIFORMAT_METH (meths, instantiate, (ii, instantiator, pointer_fg,
+					    pointer_bg, dest_mask, domain));
   UNGCPRO;
 
   return ii;
@@ -541,9 +590,16 @@
       markobj (IMAGE_INSTANCE_PIXMAP_FG (i));
       markobj (IMAGE_INSTANCE_PIXMAP_BG (i));
       break;
+
+    case IMAGE_WIDGET:
+      markobj (IMAGE_INSTANCE_WIDGET_TYPE (i));
+      markobj (IMAGE_INSTANCE_WIDGET_PROPS (i));
+      markobj (IMAGE_INSTANCE_WIDGET_FACE (i));
+      mark_gui_item (&IMAGE_INSTANCE_WIDGET_ITEM (i), markobj);
     case IMAGE_SUBWINDOW:
-      /* #### implement me */
+      markobj (IMAGE_INSTANCE_SUBWINDOW_FRAME (i));
       break;
+
     default:
       break;
     }
@@ -645,8 +701,48 @@
 	}
       break;
 
+    case IMAGE_WIDGET:
+      if (!NILP (IMAGE_INSTANCE_WIDGET_CALLBACK (ii)))
+	{
+	  print_internal (IMAGE_INSTANCE_WIDGET_CALLBACK (ii), printcharfun, 0);
+	  write_c_string (", ", printcharfun);
+	}
+      if (!NILP (IMAGE_INSTANCE_WIDGET_FACE (ii)))
+	{
+	  write_c_string (" (", printcharfun);
+	  print_internal
+	    (IMAGE_INSTANCE_WIDGET_FACE (ii), printcharfun, 0);
+	  write_c_string (")", printcharfun);
+	}
+
+      if (!NILP (IMAGE_INSTANCE_WIDGET_TEXT (ii)))
+	print_internal (IMAGE_INSTANCE_WIDGET_TEXT (ii), printcharfun, 0);
+
     case IMAGE_SUBWINDOW:
-      /* #### implement me */
+      sprintf (buf, " %dx%d", IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii),
+	       IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii));
+      write_c_string (buf, printcharfun);
+
+      /* This is stolen from frame.c.  Subwindows are strange in that they
+	 are specific to a particular frame so we want to print in their
+	 description what that frame is. */
+
+      write_c_string (" on #<", printcharfun);
+      {
+	struct frame* f  = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+	
+	if (!FRAME_LIVE_P (f))
+	  write_c_string ("dead", printcharfun);
+	else 
+	  write_c_string (DEVICE_TYPE_NAME (XDEVICE (FRAME_DEVICE (f))),
+			  printcharfun);
+
+	write_c_string ("-frame ", printcharfun);
+      }
+      write_c_string (">", printcharfun);
+      sprintf (buf, " 0x%p", IMAGE_INSTANCE_SUBWINDOW_ID (ii));
+      write_c_string (buf, printcharfun);
+      
       break;
 
     default:
@@ -669,6 +765,15 @@
     return;
   if (for_disksave) finalose (i);
 
+  /* do this so that the cachels get reset */
+  if (IMAGE_INSTANCE_TYPE (i) == IMAGE_WIDGET
+      ||
+      IMAGE_INSTANCE_TYPE (i) == IMAGE_SUBWINDOW)
+    {
+      MARK_FRAME_GLYPHS_CHANGED 
+	(XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (i)));
+    }
+
   MAYBE_DEVMETH (XDEVICE (i->device), finalize_image_instance, (i));
 }
 
@@ -722,8 +827,26 @@
 	return 0;
       break;
 
+    case IMAGE_WIDGET:
+      if (!(EQ (IMAGE_INSTANCE_WIDGET_TYPE (i1),
+		IMAGE_INSTANCE_WIDGET_TYPE (i2)) &&
+	    EQ (IMAGE_INSTANCE_WIDGET_CALLBACK (i1),
+		IMAGE_INSTANCE_WIDGET_CALLBACK (i2))
+	    && internal_equal (IMAGE_INSTANCE_WIDGET_PROPS (i1),
+			       IMAGE_INSTANCE_WIDGET_PROPS (i2),
+			       depth + 1)
+	    && internal_equal (IMAGE_INSTANCE_WIDGET_TEXT (i1),
+			       IMAGE_INSTANCE_WIDGET_TEXT (i2),
+			       depth + 1)))
+	return 0;
     case IMAGE_SUBWINDOW:
-      /* #### implement me */
+      if (!(IMAGE_INSTANCE_SUBWINDOW_WIDTH (i1) ==
+	    IMAGE_INSTANCE_SUBWINDOW_WIDTH (i2) &&
+	    IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i1) ==
+	    IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i2) &&
+	    IMAGE_INSTANCE_SUBWINDOW_ID (i1) ==
+	    IMAGE_INSTANCE_SUBWINDOW_ID (i2)))
+	return 0;
       break;
 
     default:
@@ -760,8 +883,15 @@
 				   depth + 1));
       break;
 
+    case IMAGE_WIDGET:
+      hash = HASH4 (hash, 
+		    internal_hash (IMAGE_INSTANCE_WIDGET_TYPE (i), depth + 1),
+		    internal_hash (IMAGE_INSTANCE_WIDGET_PROPS (i), depth + 1),
+		    internal_hash (IMAGE_INSTANCE_WIDGET_CALLBACK (i), depth + 1));
     case IMAGE_SUBWINDOW:
-      /* #### implement me */
+      hash = HASH4 (hash, IMAGE_INSTANCE_SUBWINDOW_WIDTH (i),
+		    IMAGE_INSTANCE_SUBWINDOW_HEIGHT (i),
+		    (int) IMAGE_INSTANCE_SUBWINDOW_ID (i));
       break;
 
     default:
@@ -805,6 +935,7 @@
   if (EQ (type, Qcolor_pixmap)) return IMAGE_COLOR_PIXMAP;
   if (EQ (type, Qpointer))      return IMAGE_POINTER;
   if (EQ (type, Qsubwindow))    return IMAGE_SUBWINDOW;
+  if (EQ (type, Qwidget))    return IMAGE_WIDGET;
 
   maybe_signal_simple_error ("Invalid image-instance type", type,
 			     Qimage, errb);
@@ -823,6 +954,7 @@
     case IMAGE_COLOR_PIXMAP: return Qcolor_pixmap;
     case IMAGE_POINTER:      return Qpointer;
     case IMAGE_SUBWINDOW:    return Qsubwindow;
+    case IMAGE_WIDGET:    return Qwidget;
     default:
       abort ();
     }
@@ -1069,17 +1201,94 @@
 
 DEFUN ("image-instance-string", Fimage_instance_string, 1, 1, 0, /*
 Return the string of the given image instance.
-This will only be non-nil for text image instances.
+This will only be non-nil for text image instances and widgets.
 */
        (image_instance))
 {
   CHECK_IMAGE_INSTANCE (image_instance);
   if (XIMAGE_INSTANCE_TYPE (image_instance) == IMAGE_TEXT)
     return XIMAGE_INSTANCE_TEXT_STRING (image_instance);
+  else if (XIMAGE_INSTANCE_TYPE (image_instance) == IMAGE_WIDGET)
+    return XIMAGE_INSTANCE_WIDGET_TEXT (image_instance);
   else
     return Qnil;
 }
 
+DEFUN ("image-instance-property", Fimage_instance_property, 2, 2, 0, /*
+Return the given property of the given image instance.  
+Returns nil if the property or the property method do not exist for
+the image instance in the domain.  
+*/
+       (image_instance, prop))
+{
+  struct Lisp_Image_Instance* ii;
+  Lisp_Object type, ret;
+  struct image_instantiator_methods* meths;
+
+  CHECK_IMAGE_INSTANCE (image_instance);
+  CHECK_SYMBOL (prop);
+  ii = XIMAGE_INSTANCE (image_instance);
+
+  /* ... then try device specific methods ... */
+  type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
+  meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), 
+				   type, ERROR_ME_NOT);
+  if (meths && HAS_IIFORMAT_METH_P (meths, property)
+      && 
+      !UNBOUNDP (ret =  IIFORMAT_METH (meths, property, (image_instance, prop))))
+    {
+      return ret;
+    }
+  /* ... then format specific methods ... */
+  meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
+  if (meths && HAS_IIFORMAT_METH_P (meths, property)
+      &&
+      !UNBOUNDP (ret = IIFORMAT_METH (meths, property, (image_instance, prop))))
+    {
+      return ret;
+    }
+  /* ... then fail */
+  return Qnil;
+}
+
+DEFUN ("set-image-instance-property", Fset_image_instance_property, 3, 3, 0, /*
+Set the given property of the given image instance.  
+Does nothing if the property or the property method do not exist for
+the image instance in the domain.
+*/
+       (image_instance, prop, val))
+{
+  struct Lisp_Image_Instance* ii;
+  Lisp_Object type, ret;
+  struct image_instantiator_methods* meths;
+
+  CHECK_IMAGE_INSTANCE (image_instance);
+  CHECK_SYMBOL (prop);
+  ii = XIMAGE_INSTANCE (image_instance);
+  type = encode_image_instance_type (IMAGE_INSTANCE_TYPE (ii));
+  /* try device specific methods first ... */
+  meths = decode_device_ii_format (IMAGE_INSTANCE_DEVICE (ii), 
+				   type, ERROR_ME_NOT);
+  if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
+      &&
+      !UNBOUNDP (ret = 
+		 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
+    {
+      return ret;
+    }
+  /* ... then format specific methods ... */
+  meths = decode_device_ii_format (Qnil, type, ERROR_ME_NOT);
+  if (meths && HAS_IIFORMAT_METH_P (meths, set_property)
+      &&
+      !UNBOUNDP (ret = 
+		 IIFORMAT_METH (meths, set_property, (image_instance, prop, val))))
+    {
+      return ret;
+    }
+
+  return val;
+}
+
 DEFUN ("image-instance-file-name", Fimage_instance_file_name, 1, 1, 0, /*
 Return the file name from which IMAGE-INSTANCE was read, if known.
 */
@@ -1152,6 +1361,10 @@
     case IMAGE_POINTER:
       return make_int (XIMAGE_INSTANCE_PIXMAP_HEIGHT (image_instance));
 
+    case IMAGE_SUBWINDOW:
+    case IMAGE_WIDGET:
+      return make_int (XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (image_instance));
+
     default:
       return Qnil;
     }
@@ -1171,6 +1384,10 @@
     case IMAGE_POINTER:
       return make_int (XIMAGE_INSTANCE_PIXMAP_WIDTH (image_instance));
 
+    case IMAGE_SUBWINDOW:
+    case IMAGE_WIDGET:
+      return make_int (XIMAGE_INSTANCE_SUBWINDOW_WIDTH (image_instance));
+
     default:
       return Qnil;
     }
@@ -1240,6 +1457,12 @@
     case IMAGE_POINTER:
       return XIMAGE_INSTANCE_PIXMAP_FG (image_instance);
 
+    case IMAGE_WIDGET:
+      return FACE_FOREGROUND (
+			      XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
+			      XIMAGE_INSTANCE_SUBWINDOW_FRAME 
+			      (image_instance));
+
     default:
       return Qnil;
     }
@@ -1261,6 +1484,12 @@
     case IMAGE_POINTER:
       return XIMAGE_INSTANCE_PIXMAP_BG (image_instance);
 
+    case IMAGE_WIDGET:
+      return FACE_BACKGROUND (
+			      XIMAGE_INSTANCE_WIDGET_FACE (image_instance),
+			      XIMAGE_INSTANCE_SUBWINDOW_FRAME 
+			      (image_instance));
+
     default:
       return Qnil;
     }
@@ -1769,19 +1998,6 @@
     IMAGE_POINTER_MASK;
 }
 
-static void
-xbm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
-		 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
-		 int dest_mask, Lisp_Object domain)
-{
-  Lisp_Object device= IMAGE_INSTANCE_DEVICE (XIMAGE_INSTANCE (image_instance));
-
-  MAYBE_DEVMETH (XDEVICE (device),
-		 xbm_instantiate,
-		 (image_instance, instantiator, pointer_fg,
-		  pointer_bg, dest_mask, domain));
-}
-
 #endif
 
 
@@ -1796,8 +2012,10 @@
 {
   char **data;
   int result;
-
-  result = XpmReadFileToData ((char *) XSTRING_DATA (name), &data);
+  char *fname = 0;
+  
+  GET_C_STRING_FILENAME_DATA_ALLOCA (name, fname);
+  result = XpmReadFileToData (fname, &data);
 
   if (result == XpmSuccess)
     {
@@ -1994,19 +2212,6 @@
     IMAGE_POINTER_MASK;
 }
 
-static void
-xpm_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
-		 Lisp_Object pointer_fg, Lisp_Object pointer_bg,
-		 int dest_mask, Lisp_Object domain)
-{
-  Lisp_Object device= IMAGE_INSTANCE_DEVICE (XIMAGE_INSTANCE (image_instance));
-
-  MAYBE_DEVMETH (XDEVICE (device),
-		 xpm_instantiate,
-		 (image_instance, instantiator, pointer_fg,
-		  pointer_bg, dest_mask, domain));
-}
-
 #endif /* HAVE_XPM */
 
 
@@ -2109,7 +2314,7 @@
 	  /* For the image instance cache, we do comparisons with EQ rather
 	     than with EQUAL, as we do for color and font names.
 	     The reasons are:
-
+	     
 	     1) pixmap data can be very long, and thus the hashing and
 	     comparing will take awhile.
 	     2) It's not so likely that we'll run into things that are EQUAL
@@ -2133,8 +2338,28 @@
 	  instance = Qunbound;
 	}
       else
-	instance = Fgethash (pointerp ? ls3 : instantiator,
-			     subtable, Qunbound);
+	{
+	  instance = Fgethash (pointerp ? ls3 : instantiator,
+			       subtable, Qunbound);
+	  /* subwindows have a per-window cache and have to be treated
+	     differently.  dest_mask can be a bitwise OR of all image
+	     types so we will only catch someone possibly trying to
+	     instantiate a subwindow type thing. Unfortunately, this
+	     will occur most of the time so this probably slows things
+	     down. But with the current design I don't see anyway
+	     round it. */
+	  if (UNBOUNDP (instance)
+	      &&
+	      dest_mask & (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
+	    {
+	      if (!WINDOWP (domain))
+		signal_simple_error ("Can't instantiate subwindow outside a window",
+				     instantiator);
+	      instance = Fgethash (instantiator, 
+				   XWINDOW (domain)->subwindow_instance_cache, 
+				   Qunbound);
+	    }
+	}
 
       if (UNBOUNDP (instance))
 	{
@@ -2143,7 +2368,7 @@
 			  noseeum_cons (pointerp ? ls3 : instantiator,
 					subtable));
 	  int speccount = specpdl_depth ();
-
+	  
 	  /* make sure we cache the failures, too.
 	     Use an unwind-protect to catch such errors.
 	     If we fail, the unwind-protect records nil in
@@ -2157,7 +2382,21 @@
 						     instantiator,
 						     pointer_fg, pointer_bg,
 						     dest_mask);
+	  
 	  Fsetcar (locative, instance);
+	  /* only after the image has been instantiated do we know
+             whether we need to put it in the per-window image instance
+             cache. */
+	  if (image_instance_type_to_mask (XIMAGE_INSTANCE_TYPE (instance))
+	      &
+	      (IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK))
+	    {
+	      if (!WINDOWP (domain))
+		signal_simple_error ("Can't instantiate subwindow outside a window",
+				     instantiator);
+	      
+	      Fsetcdr (XCDR (locative), XWINDOW (domain)->subwindow_instance_cache );
+ 	    }
 	  unbind_to (speccount, Qnil);
 	}
       else
@@ -2357,7 +2596,7 @@
   (Display this image as a text string, with replaceable fields;
   not currently implemented.)
 'xbm
-  (An X bitmap; only if X support was compiled into this XEmacs.
+  (An X bitmap; only if X or Windows support was compiled into this XEmacs.
    Can be instanced as `mono-pixmap', `color-pixmap', or `pointer'.)
 'xpm
   (An XPM pixmap; only if XPM support was compiled into this XEmacs.
@@ -2393,6 +2632,8 @@
    probably be fixed.)
 'subwindow
   (An embedded X window; not currently implemented.)
+'widget
+  (A widget control, for instance text field or radio button.)
 'autodetect
   (XEmacs tries to guess what format the data is in.  If X support
   exists, the data string will be checked to see if it names a filename.
@@ -2423,7 +2664,7 @@
   `cursor-font', `font', `autodetect', and `inherit'.)
 :foreground
 :background
-  (For `xbm', `xface', `cursor-font', and `font'.  These keywords
+  (For `xbm', `xface', `cursor-font', `widget' and `font'.  These keywords
   allow you to explicitly specify foreground and background colors.
   The argument should be anything acceptable to `make-color-instance'.
   This will cause what would be a `mono-pixmap' to instead be colorized
@@ -2628,8 +2869,9 @@
     {
     case GLYPH_BUFFER:
       XIMAGE_SPECIFIER_ALLOWED (g->image) =
-	IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK | IMAGE_MONO_PIXMAP_MASK |
-	  IMAGE_COLOR_PIXMAP_MASK | IMAGE_SUBWINDOW_MASK;
+	IMAGE_NOTHING_MASK | IMAGE_TEXT_MASK 
+	| IMAGE_MONO_PIXMAP_MASK | IMAGE_COLOR_PIXMAP_MASK 
+	| IMAGE_SUBWINDOW_MASK | IMAGE_WIDGET_MASK;
       break;
     case GLYPH_POINTER:
       XIMAGE_SPECIFIER_ALLOWED (g->image) =
@@ -2825,8 +3067,8 @@
       return 0;
 
     case IMAGE_SUBWINDOW:
-      /* #### implement me */
-      return 0;
+    case IMAGE_WIDGET:
+      return XIMAGE_INSTANCE_SUBWINDOW_WIDTH (instance);
 
     default:
       abort ();
@@ -2929,8 +3171,12 @@
       return 0;
 
     case IMAGE_SUBWINDOW:
-      /* #### implement me */
-      return 0;
+    case IMAGE_WIDGET:
+      /* #### Ugh ugh ugh -- temporary crap */
+      if (function == RETURN_ASCENT || function == RETURN_HEIGHT)
+	return XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (instance);
+      else
+	return 0;
 
     default:
       abort ();
@@ -3200,36 +3446,399 @@
 
 #endif /* MEMORY_USAGE_STATS */
 
+
+
+/*****************************************************************************
+ *                     subwindow cachel functions                         	     *
+ *****************************************************************************/
+/* subwindows are curious in that you have to physically unmap them to
+   not display them. It is problematic deciding what to do in
+   redisplay. We have two caches - a per-window instance cache that
+   keeps track of subwindows on a window, these are linked to their
+   instantiator in the hashtable and when the instantiator goes away
+   we want the instance to go away also. However we also have a
+   per-frame instance cache that we use to determine if a subwindow is
+   obscuring an area that we want to clear. We need to be able to flip
+   through this quickly so a hashtable is not suitable hence the
+   subwindow_cachels. The question is should we just not mark
+   instances in the subwindow_cachelsnor should we try and invalidate
+   the cache at suitable points in redisplay? If we don't invalidate
+   the cache it will fill up with crud that will only get removed when
+   the frame is deleted. So invalidation is good, the question is when
+   and whether we mark as well. Go for the simple option - don't mark,
+   MARK_SUBWINDOWS_CHANGED when a subwindow gets deleted. */
+
+void
+mark_subwindow_cachels (subwindow_cachel_dynarr *elements,
+			void (*markobj) (Lisp_Object))
+{
+  int elt;
+
+  if (!elements)
+    return;
+
+  for (elt = 0; elt < Dynarr_length (elements); elt++)
+    {
+      struct subwindow_cachel *cachel = Dynarr_atp (elements, elt);
+      markobj (cachel->subwindow);
+    }
+}
+
+static void
+update_subwindow_cachel_data (struct frame *f, Lisp_Object subwindow,
+			  struct subwindow_cachel *cachel)
+{
+  if (NILP (cachel->subwindow) || !EQ (cachel->subwindow, subwindow))
+    {
+      cachel->subwindow   = subwindow;
+      cachel->width   = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow);
+      cachel->height   = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow);
+    }
+
+  cachel->updated = 1;
+}
+
+static void
+add_subwindow_cachel (struct frame *f, Lisp_Object subwindow)
+{
+  struct subwindow_cachel new_cachel;
+
+  xzero (new_cachel);
+  new_cachel.subwindow = Qnil;
+  new_cachel.x=0;
+  new_cachel.y=0;
+  new_cachel.being_displayed=0;
+
+  update_subwindow_cachel_data (f, subwindow, &new_cachel);
+  Dynarr_add (f->subwindow_cachels, new_cachel);
+}
+
+static int
+get_subwindow_cachel_index (struct frame *f, Lisp_Object subwindow)
+{
+  int elt;
+
+  if (noninteractive)
+    return 0;
+
+  for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
+    {
+      struct subwindow_cachel *cachel =
+	Dynarr_atp (f->subwindow_cachels, elt);
+
+      if (EQ (cachel->subwindow, subwindow) && !NILP (subwindow))
+	{
+	  if (!cachel->updated)
+	    update_subwindow_cachel_data (f, subwindow, cachel);
+	  return elt;
+	}
+    }
+
+  /* If we didn't find the glyph, add it and then return its index. */
+  add_subwindow_cachel (f, subwindow);
+  return elt;
+}
+
+void
+reset_subwindow_cachels (struct frame *f)
+{
+  Dynarr_reset (f->subwindow_cachels);
+}
+
+void
+mark_subwindow_cachels_as_not_updated (struct frame *f)
+{
+  int elt;
+
+  for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
+    Dynarr_atp (f->subwindow_cachels, elt)->updated = 0;
+}
+
+
+/*****************************************************************************
+ *                              subwindow functions                          *
+ *****************************************************************************/
+
+/* update the displayed characteristics of a subwindow */
+static void
+update_subwindow (Lisp_Object subwindow)
+{
+  struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
+
+  if (!IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
+      ||
+      NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
+    return;
+
+  MAYBE_DEVMETH (XDEVICE (ii->device), update_subwindow, (ii));
+}
+
+void
+update_frame_subwindows (struct frame *f)
+{
+  int elt;
+
+  if (f->subwindows_changed || f->glyphs_changed)
+    for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
+      {
+	struct subwindow_cachel *cachel =
+	  Dynarr_atp (f->subwindow_cachels, elt);
+	
+	if (cachel->being_displayed)
+	  {
+	    update_subwindow (cachel->subwindow);
+	  }
+      }
+}
+
+/* remove a subwindow from its frame */
+void unmap_subwindow (Lisp_Object subwindow)
+{
+  struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
+  int elt;
+  struct subwindow_cachel* cachel;
+  struct frame* f;
+
+  if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
+	||
+	IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW)
+      ||
+      NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
+    return;
+
+  f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+  elt = get_subwindow_cachel_index (f, subwindow);
+  cachel = Dynarr_atp (f->subwindow_cachels, elt);
+
+  cachel->x = -1;
+  cachel->y = -1;
+  cachel->being_displayed = 0;
+  IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
+
+  MAYBE_DEVMETH (XDEVICE (ii->device), unmap_subwindow, (ii));
+}
+
+/* show a subwindow in its frame */
+void map_subwindow (Lisp_Object subwindow, int x, int y)
+{
+  struct Lisp_Image_Instance* ii = XIMAGE_INSTANCE (subwindow);
+  int elt; 
+  struct subwindow_cachel* cachel;
+  struct frame* f;
+
+  if (!(IMAGE_INSTANCE_TYPE (ii) == IMAGE_WIDGET
+	||
+	IMAGE_INSTANCE_TYPE (ii) == IMAGE_SUBWINDOW)
+      ||
+      NILP (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii)))
+    return;
+
+  f = XFRAME (IMAGE_INSTANCE_SUBWINDOW_FRAME (ii));
+  IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 1;
+  elt = get_subwindow_cachel_index (f, subwindow);
+  cachel = Dynarr_atp (f->subwindow_cachels, elt);
+  cachel->x = x;
+  cachel->y = y;
+  cachel->being_displayed = 1;
+
+  MAYBE_DEVMETH (XDEVICE (ii->device), map_subwindow, (ii, x, y));
+}
+
+static int
+subwindow_possible_dest_types (void)
+{
+  return IMAGE_SUBWINDOW_MASK;
+}
+
+/* Partially instantiate a subwindow. */
+void
+subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+		       Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+		       int dest_mask, Lisp_Object domain)
+{
+  struct Lisp_Image_Instance *ii = XIMAGE_INSTANCE (image_instance);
+  Lisp_Object device = IMAGE_INSTANCE_DEVICE (ii);
+  Lisp_Object frame = FW_FRAME (domain);
+  Lisp_Object width = find_keyword_in_vector (instantiator, Q_pixel_width);
+  Lisp_Object height = find_keyword_in_vector (instantiator, Q_pixel_height);
+
+  if (NILP (frame))
+    signal_simple_error ("No selected frame", device);
+  
+  if (!(dest_mask & IMAGE_SUBWINDOW_MASK))
+    incompatible_image_types (instantiator, dest_mask, IMAGE_SUBWINDOW_MASK);
+
+  ii->data = 0;
+  IMAGE_INSTANCE_SUBWINDOW_ID (ii) = 0;
+  IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = Qnil;
+  IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (ii) = 0;
+  IMAGE_INSTANCE_SUBWINDOW_FRAME (ii) = frame;
+
+  /* this stuff may get overidden by the widget code */
+  if (NILP (width))
+    IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = 20;
+  else
+    {
+      int w = 1;
+      CHECK_INT (width);
+      if (XINT (width) > 1)
+	w = XINT (width);
+      IMAGE_INSTANCE_SUBWINDOW_WIDTH (ii) = w;
+    }
+  if (NILP (height))
+    IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = 20;
+  else
+    {
+      int h = 1;
+      CHECK_INT (height);
+      if (XINT (height) > 1)
+	h = XINT (height);
+      IMAGE_INSTANCE_SUBWINDOW_HEIGHT (ii) = h;
+    }
+}
+
+DEFUN ("subwindowp", Fsubwindowp, 1, 1, 0, /*
+Return non-nil if OBJECT is a subwindow.
+*/
+       (object))
+{
+  CHECK_IMAGE_INSTANCE (object);
+  return (XIMAGE_INSTANCE_TYPE (object) == IMAGE_SUBWINDOW) ? Qt : Qnil;
+}
+
+DEFUN ("image-instance-subwindow-id", Fimage_instance_subwindow_id, 1, 1, 0, /*
+Return the window id of SUBWINDOW as a number.
+*/
+       (subwindow))
+{
+  CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
+  return make_int ((int) (XIMAGE_INSTANCE_SUBWINDOW_ID (subwindow)));
+}
+
+DEFUN ("resize-subwindow", Fresize_subwindow, 1, 3, 0, /*
+Resize SUBWINDOW to WIDTH x HEIGHT.
+If a value is nil that parameter is not changed.
+*/
+       (subwindow, width, height))
+{
+  int neww, newh;
+
+  CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
+
+  if (NILP (width))
+    neww = XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow);
+  else
+    neww = XINT (width);
+
+  if (NILP (height))
+    newh = XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow);
+  else
+    newh = XINT (height);
+
+  
+  MAYBE_DEVMETH (XDEVICE (XIMAGE_INSTANCE_DEVICE (subwindow)), 
+		 resize_subwindow, (XIMAGE_INSTANCE (subwindow), neww, newh));
+
+  XIMAGE_INSTANCE_SUBWINDOW_HEIGHT (subwindow) = newh;
+  XIMAGE_INSTANCE_SUBWINDOW_WIDTH (subwindow) = neww;
+
+  return subwindow;
+}
+
+DEFUN ("force-subwindow-map", Fforce_subwindow_map, 1, 1, 0, /*
+Generate a Map event for SUBWINDOW.
+*/
+       (subwindow))
+{
+  CHECK_SUBWINDOW_IMAGE_INSTANCE (subwindow);
+
+  map_subwindow (subwindow, 0, 0);
+
+  return subwindow;
+}
+
 
 /*****************************************************************************
  *                              display tables                               *
  *****************************************************************************/
 
-/* Get the display table for use currently on window W with face FACE.
-   Precedence:
-
-   -- FACE's display table
-   -- W's display table (comes from specifier `current-display-table')
-
-   Ignore the specified tables if they are not valid;
-   if no valid table is specified, return 0.  */
-
-struct Lisp_Vector *
-get_display_table (struct window *w, face_index findex)
+/* Get the display tables for use currently on window W with face
+   FACE.  #### This will have to be redone.  */
+
+void
+get_display_tables (struct window *w, face_index findex,
+		    Lisp_Object *face_table, Lisp_Object *window_table)
 {
   Lisp_Object tem;
-
   tem = WINDOW_FACE_CACHEL_DISPLAY_TABLE (w, findex);
-  if (VECTORP (tem) && XVECTOR_LENGTH (tem) == DISP_TABLE_SIZE)
-    return XVECTOR (tem);
-
+  if (UNBOUNDP (tem))
+    tem = Qnil;
+  if (!LISTP (tem))
+    tem = noseeum_cons (tem, Qnil);
+  *face_table = tem;
   tem = w->display_table;
-  if (VECTORP (tem) && XVECTOR_LENGTH (tem) == DISP_TABLE_SIZE)
-    return XVECTOR (tem);
-
-  return 0;
+  if (UNBOUNDP (tem))
+    tem = Qnil;
+  if (!LISTP (tem))
+    tem = noseeum_cons (tem, Qnil);
+  *window_table = tem;
 }
 
+Lisp_Object
+display_table_entry (Emchar ch, Lisp_Object face_table,
+		     Lisp_Object window_table)
+{
+  Lisp_Object tail;
+
+  /* Loop over FACE_TABLE, and then over WINDOW_TABLE. */
+  for (tail = face_table; 1; tail = XCDR (tail))
+    {
+      Lisp_Object table;
+      if (NILP (tail))
+	{
+	  if (!NILP (window_table))
+	    {
+	      tail = window_table;
+	      window_table = Qnil;
+	    }
+	  else
+	    return Qnil;
+	}
+      table = XCAR (tail);
+
+      if (VECTORP (table))
+	{
+	  if (ch < XVECTOR_LENGTH (table) && !NILP (XVECTOR_DATA (table)[ch]))
+	    return XVECTOR_DATA (table)[ch];
+	  else
+	    continue;
+	}
+      else if (CHAR_TABLEP (table)
+	       && XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_CHAR)
+	{
+	  return get_char_table (ch, XCHAR_TABLE (table));
+	}
+      else if (CHAR_TABLEP (table)
+	       && XCHAR_TABLE_TYPE (table) == CHAR_TABLE_TYPE_GENERIC)
+	{
+	  Lisp_Object gotit = get_char_table (ch, XCHAR_TABLE (table));
+	  if (!NILP (gotit))
+	    return gotit;
+	  else
+	    continue;
+	}
+      else if (RANGE_TABLEP (table))
+	{
+	  Lisp_Object gotit = Fget_range_table (make_char (ch), table, Qnil);
+	  if (!NILP (gotit))
+	    return gotit;
+	  else
+	    continue;
+	}
+      else
+	abort ();
+    }
+}
 
 /*****************************************************************************
  *                              initialization                               *
@@ -3248,6 +3857,8 @@
   defkeyword (&Q_file, ":file");
   defkeyword (&Q_data, ":data");
   defkeyword (&Q_face, ":face");
+  defkeyword (&Q_pixel_height, ":pixel-height");
+  defkeyword (&Q_pixel_width, ":pixel-width");
 
 #ifdef HAVE_XPM
   defkeyword (&Q_color_symbols, ":color-symbols");
@@ -3274,6 +3885,7 @@
   defsymbol (&Qmono_pixmap_image_instance_p, "mono-pixmap-image-instance-p");
   defsymbol (&Qcolor_pixmap_image_instance_p, "color-pixmap-image-instance-p");
   defsymbol (&Qpointer_image_instance_p, "pointer-image-instance-p");
+  defsymbol (&Qwidget_image_instance_p, "widget-image-instance-p");
   defsymbol (&Qsubwindow_image_instance_p, "subwindow-image-instance-p");
 
   DEFSUBR (Fmake_image_instance);
@@ -3292,7 +3904,14 @@
   DEFSUBR (Fimage_instance_hotspot_y);
   DEFSUBR (Fimage_instance_foreground);
   DEFSUBR (Fimage_instance_background);
+  DEFSUBR (Fimage_instance_property);
+  DEFSUBR (Fset_image_instance_property);
   DEFSUBR (Fcolorize_image_instance);
+  /* subwindows */
+  DEFSUBR (Fsubwindowp);
+  DEFSUBR (Fimage_instance_subwindow_id);
+  DEFSUBR (Fresize_subwindow);
+  DEFSUBR (Fforce_subwindow_map);
 
   /* Qnothing defined as part of the "nothing" image-instantiator
      type. */
@@ -3300,7 +3919,6 @@
   defsymbol (&Qmono_pixmap, "mono-pixmap");
   defsymbol (&Qcolor_pixmap, "color-pixmap");
   /* Qpointer defined in general.c */
-  defsymbol (&Qsubwindow, "subwindow");
 
   /* glyphs */
 
@@ -3390,13 +4008,19 @@
 
   IIFORMAT_VALID_KEYWORD (formatted_string, Q_data, check_valid_string);
 
+  /* subwindows */
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (subwindow, "subwindow");
+  IIFORMAT_HAS_METHOD (subwindow, possible_dest_types);
+  IIFORMAT_HAS_METHOD (subwindow, instantiate);
+  IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_width, check_valid_int);
+  IIFORMAT_VALID_KEYWORD (subwindow, Q_pixel_height, check_valid_int);
+
 #ifdef HAVE_WINDOW_SYSTEM
   INITIALIZE_IMAGE_INSTANTIATOR_FORMAT (xbm, "xbm");
 
   IIFORMAT_HAS_METHOD (xbm, validate);
   IIFORMAT_HAS_METHOD (xbm, normalize);
   IIFORMAT_HAS_METHOD (xbm, possible_dest_types);
-  IIFORMAT_HAS_METHOD (xbm, instantiate);
 
   IIFORMAT_VALID_KEYWORD (xbm, Q_data, check_valid_xbm_inline);
   IIFORMAT_VALID_KEYWORD (xbm, Q_file, check_valid_string);
@@ -3414,7 +4038,6 @@
   IIFORMAT_HAS_METHOD (xpm, validate);
   IIFORMAT_HAS_METHOD (xpm, normalize);
   IIFORMAT_HAS_METHOD (xpm, possible_dest_types);
-  IIFORMAT_HAS_METHOD (xpm, instantiate);
 
   IIFORMAT_VALID_KEYWORD (xpm, Q_data, check_valid_string);
   IIFORMAT_VALID_KEYWORD (xpm, Q_file, check_valid_string);
@@ -3430,8 +4053,9 @@
 
   /* image instances */
 
-  Vimage_instance_type_list = list6 (Qnothing, Qtext, Qmono_pixmap,
-				     Qcolor_pixmap, Qpointer, Qsubwindow);
+  Vimage_instance_type_list = Fcons (Qnothing, 
+				     list6 (Qtext, Qmono_pixmap, Qcolor_pixmap, 
+					    Qpointer, Qsubwindow, Qwidget));
   staticpro (&Vimage_instance_type_list);
 
   /* glyphs */
@@ -3467,7 +4091,9 @@
 What to display at the beginning of horizontally scrolled lines.
 */);
   Vhscroll_glyph = allocate_glyph (GLYPH_BUFFER, redisplay_glyph_changed);
-
+#ifdef HAVE_WINDOW_SYSTEM
+  Fprovide (Qxbm);
+#endif
 #ifdef HAVE_XPM
   Fprovide (Qxpm);
 
--- a/src/glyphs.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/glyphs.h	Mon Aug 13 11:08:24 2007 +0200
@@ -25,6 +25,7 @@
 #define _XEMACS_GLYPHS_H_
 
 #include "specifier.h"
+#include "gui.h"
 
 /************************************************************************/
 /*			Image Instantiators				*/
@@ -47,11 +48,18 @@
   jpeg				color-pixmap
   png				color-pixmap
   tiff				color-pixmap
+  bmp				color-pixmap
   cursor-font			pointer
+  mswindows-resource		pointer
   font				pointer
   subwindow			subwindow
   inherit			mono-pixmap
   autodetect			mono-pixmap, color-pixmap, pointer, text
+  button				widget
+  edit				widget
+  combo				widget
+  scrollbar			widget
+  static				widget
 */
 
 /* These are methods specific to a particular format of image instantiator
@@ -74,6 +82,8 @@
 {
   Lisp_Object symbol;
 
+  Lisp_Object device;		/* sometimes used */
+
   ii_keyword_entry_dynarr *keywords;
   /* Implementation specific methods: */
 
@@ -104,6 +114,15 @@
 			      Lisp_Object pointer_bg,
 			      int dest_mask,
 			      Lisp_Object domain);
+  /* Property method: Given an image instance, return device specific
+     properties. */
+  Lisp_Object (*property_method) (Lisp_Object image_instance,
+				  Lisp_Object property);
+  /* Set-property method: Given an image instance, set device specific
+     properties. */
+  Lisp_Object (*set_property_method) (Lisp_Object image_instance,
+				      Lisp_Object property,
+				      Lisp_Object val);
 };
 
 /***** Calling an image-instantiator method *****/
@@ -112,12 +131,22 @@
 #define IIFORMAT_METH(mstruc, m, args) (((mstruc)->m##_method) args)
 
 /* Call a void-returning specifier method, if it exists */
-#define MAYBE_IIFORMAT_METH(mstruc, m, args) do {				\
-  struct image_instantiator_methods *maybe_iiformat_meth_mstruc = (mstruc);	\
-  if (HAS_IIFORMAT_METH_P (maybe_iiformat_meth_mstruc, m))			\
-    IIFORMAT_METH (maybe_iiformat_meth_mstruc, m, args);			\
+#define MAYBE_IIFORMAT_METH(mstruc, m, args)				     \
+if (mstruc)							\
+do {									     \
+  struct image_instantiator_methods *maybe_iiformat_meth_mstruc = (mstruc); \
+  if (HAS_IIFORMAT_METH_P (maybe_iiformat_meth_mstruc, m))		     \
+    IIFORMAT_METH (maybe_iiformat_meth_mstruc, m, args);		     \
 } while (0)
 
+#define MAYBE_IIFORMAT_DEVMETH(device, mstruc, m, args)				\
+do {											\
+  struct image_instantiator_methods *_mstruc = decode_ii_device (device, mstruc);	\
+  if (_mstruc)										\
+    MAYBE_IIFORMAT_METH(_mstruc, m, args);						\
+} while (0)
+
+
 /* Call a specifier method, if it exists; otherwise return
    the specified value */
 
@@ -133,23 +162,32 @@
 #define DEFINE_IMAGE_INSTANTIATOR_FORMAT(format)		\
 struct image_instantiator_methods *format##_image_instantiator_methods
 
-#define INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(format, obj_name)	\
+#define INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM(format, obj_name)	\
 do {								\
   format##_image_instantiator_methods =				\
     xnew_and_zero (struct image_instantiator_methods);		\
-  defsymbol (&Q##format, obj_name);				\
   format##_image_instantiator_methods->symbol = Q##format;	\
+  format##_image_instantiator_methods->device = Qnil;		\
   format##_image_instantiator_methods->keywords =		\
     Dynarr_new (ii_keyword_entry);				\
   add_entry_to_image_instantiator_format_list			\
     (Q##format, format##_image_instantiator_methods);		\
 } while (0)
 
+#define INITIALIZE_IMAGE_INSTANTIATOR_FORMAT(format, obj_name)	\
+do {								\
+  defsymbol (&Q##format, obj_name);				\
+  INITIALIZE_IMAGE_INSTANTIATOR_FORMAT_NO_SYM(format, obj_name);	\
+} while (0)
+
 /* Declare that image-instantiator format FORMAT has method M; used in
    initialization routines */
 #define IIFORMAT_HAS_METHOD(format, m) \
   (format##_image_instantiator_methods->m##_method = format##_##m)
 
+#define IIFORMAT_HAS_SHARED_METHOD(format, m, type) \
+  (format##_image_instantiator_methods->m##_method = type##_##m)
+
 /* Declare that KEYW is a valid keyword for image-instantiator format
    FORMAT.  VALIDATE_FUN if a function that returns whether the data
    is valid.  The keyword may not appear more than once. */
@@ -177,8 +215,36 @@
 		entry);							\
   } while (0)
 
+#define DEFINE_DEVICE_IIFORMAT(type, format)\
+struct image_instantiator_methods *type##_##format##_image_instantiator_methods
+
+#define INITIALIZE_DEVICE_IIFORMAT(type, format)	\
+do {								\
+  type##_##format##_image_instantiator_methods =				\
+    xnew_and_zero (struct image_instantiator_methods);		\
+  type##_##format##_image_instantiator_methods->symbol = Q##format;	\
+  type##_##format##_image_instantiator_methods->device = Q##type;	\
+  type##_##format##_image_instantiator_methods->keywords =		\
+    Dynarr_new (ii_keyword_entry);				\
+  add_entry_to_device_ii_format_list				\
+    (Q##type, Q##format, type##_##format##_image_instantiator_methods);	\
+} while (0)
+
+/* Declare that image-instantiator format FORMAT has method M; used in
+   initialization routines */
+#define IIFORMAT_HAS_DEVMETHOD(type, format, m) \
+  (type##_##format##_image_instantiator_methods->m##_method = type##_##format##_##m)
+
+struct image_instantiator_methods *
+decode_device_ii_format (Lisp_Object device, Lisp_Object format,
+			 Error_behavior errb);
+struct image_instantiator_methods *
+decode_image_instantiator_format (Lisp_Object format, Error_behavior errb);
+
 void add_entry_to_image_instantiator_format_list (Lisp_Object symbol,
 			struct image_instantiator_methods *meths);
+void add_entry_to_device_ii_format_list (Lisp_Object device, Lisp_Object symbol,
+			struct image_instantiator_methods *meths);
 Lisp_Object find_keyword_in_vector (Lisp_Object vector,
 				    Lisp_Object keyword);
 Lisp_Object find_keyword_in_vector_or_given (Lisp_Object vector,
@@ -193,6 +259,14 @@
 						Lisp_Object console_type);
 void check_valid_string (Lisp_Object data);
 void check_valid_int (Lisp_Object data);
+void check_valid_face (Lisp_Object data);
+void check_valid_vector (Lisp_Object data);
+
+void initialize_subwindow_image_instance (struct Lisp_Image_Instance*);
+void subwindow_instantiate (Lisp_Object image_instance, Lisp_Object instantiator,
+			    Lisp_Object pointer_fg, Lisp_Object pointer_bg,
+			    int dest_mask, Lisp_Object domain);
+
 DECLARE_DOESNT_RETURN (incompatible_image_types (Lisp_Object instantiator,
                                                  int given_dest_mask,
                                                  int desired_dest_mask));
@@ -250,7 +324,8 @@
   IMAGE_MONO_PIXMAP,
   IMAGE_COLOR_PIXMAP,
   IMAGE_POINTER,
-  IMAGE_SUBWINDOW
+  IMAGE_SUBWINDOW,
+  IMAGE_WIDGET
 };
 
 #define IMAGE_NOTHING_MASK (1 << 0)
@@ -259,6 +334,7 @@
 #define IMAGE_COLOR_PIXMAP_MASK (1 << 3)
 #define IMAGE_POINTER_MASK (1 << 4)
 #define IMAGE_SUBWINDOW_MASK (1 << 5)
+#define IMAGE_WIDGET_MASK (1 << 6)
 
 #define IMAGE_INSTANCE_TYPE_P(ii, type) \
 (IMAGE_INSTANCEP (ii) && XIMAGE_INSTANCE_TYPE (ii) == type)
@@ -275,6 +351,8 @@
      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_POINTER)
 #define SUBWINDOW_IMAGE_INSTANCEP(ii) \
      IMAGE_INSTANCE_TYPE_P (ii, IMAGE_SUBWINDOW)
+#define WIDGET_IMAGE_INSTANCEP(ii) \
+     IMAGE_INSTANCE_TYPE_P (ii, IMAGE_WIDGET)
 
 #define CHECK_NOTHING_IMAGE_INSTANCE(x) do {			\
   CHECK_IMAGE_INSTANCE (x);					\
@@ -308,10 +386,17 @@
 
 #define CHECK_SUBWINDOW_IMAGE_INSTANCE(x) do {			\
   CHECK_IMAGE_INSTANCE (x);					\
-  if (!SUBWINDOW_IMAGE_INSTANCEP (x))				\
+  if (!SUBWINDOW_IMAGE_INSTANCEP (x)				\
+      && !WIDGET_IMAGE_INSTANCEP (x))				\
     x = wrong_type_argument (Qsubwindow_image_instance_p, (x));	\
 } while (0)
 
+#define CHECK_WIDGET_IMAGE_INSTANCE(x) do {			\
+  CHECK_IMAGE_INSTANCE (x);					\
+  if (!WIDGET_IMAGE_INSTANCEP (x))				\
+    x = wrong_type_argument (Qwidget_image_instance_p, (x));	\
+} while (0)
+
 struct Lisp_Image_Instance
 {
   struct lcrecord_header header;
@@ -338,7 +423,17 @@
     } pixmap; /* used for pointers as well */
     struct
     {
-      int dummy; /* #### fill in this structure */
+      Lisp_Object frame;
+      unsigned int width, height;
+      void* subwindow;		/* specific devices can use this as necessary */
+      int being_displayed;		/* used to detect when needs to be unmapped */
+      struct
+      {
+	Lisp_Object face; /* foreground and background colors */
+	Lisp_Object type;
+	Lisp_Object props;	/* properties */
+	struct gui_item gui_item;
+      } widget;			/* widgets are subwindows */
     } subwindow;
   } u;
 
@@ -366,6 +461,25 @@
 #define IMAGE_INSTANCE_PIXMAP_BG(i) ((i)->u.pixmap.bg)
 #define IMAGE_INSTANCE_PIXMAP_AUXDATA(i) ((i)->u.pixmap.auxdata)
 
+#define IMAGE_INSTANCE_SUBWINDOW_WIDTH(i) ((i)->u.subwindow.width)
+#define IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) ((i)->u.subwindow.height)
+#define IMAGE_INSTANCE_SUBWINDOW_ID(i) ((i)->u.subwindow.subwindow)
+#define IMAGE_INSTANCE_SUBWINDOW_FRAME(i) ((i)->u.subwindow.frame)
+#define IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP(i) \
+((i)->u.subwindow.being_displayed)
+
+#define IMAGE_INSTANCE_WIDGET_WIDTH(i) \
+  IMAGE_INSTANCE_SUBWINDOW_WIDTH(i)
+#define IMAGE_INSTANCE_WIDGET_HEIGHT(i) \
+  IMAGE_INSTANCE_SUBWINDOW_HEIGHT(i)
+#define IMAGE_INSTANCE_WIDGET_CALLBACK(i) \
+  ((i)->u.subwindow.widget.gui_item.callback)
+#define IMAGE_INSTANCE_WIDGET_TYPE(i) ((i)->u.subwindow.widget.type)
+#define IMAGE_INSTANCE_WIDGET_PROPS(i) ((i)->u.subwindow.widget.props)
+#define IMAGE_INSTANCE_WIDGET_FACE(i) ((i)->u.subwindow.widget.face)
+#define IMAGE_INSTANCE_WIDGET_TEXT(i) ((i)->u.subwindow.widget.gui_item.name)
+#define IMAGE_INSTANCE_WIDGET_ITEM(i) ((i)->u.subwindow.widget.gui_item)
+
 #define XIMAGE_INSTANCE_DEVICE(i) \
   IMAGE_INSTANCE_DEVICE (XIMAGE_INSTANCE (i))
 #define XIMAGE_INSTANCE_NAME(i) \
@@ -395,6 +509,34 @@
 #define XIMAGE_INSTANCE_PIXMAP_BG(i) \
   IMAGE_INSTANCE_PIXMAP_BG (XIMAGE_INSTANCE (i))
 
+#define XIMAGE_INSTANCE_WIDGET_WIDTH(i) \
+  IMAGE_INSTANCE_WIDGET_WIDTH (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_WIDGET_HEIGHT(i) \
+  IMAGE_INSTANCE_WIDGET_HEIGHT (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_WIDGET_CALLBACK(i) \
+  IMAGE_INSTANCE_WIDGET_CALLBACK (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_WIDGET_TYPE(i) \
+  IMAGE_INSTANCE_WIDGET_TYPE (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_WIDGET_PROPS(i) \
+  IMAGE_INSTANCE_WIDGET_PROPS (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_WIDGET_FACE(i) \
+  IMAGE_INSTANCE_WIDGET_FACE (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_WIDGET_TEXT(i) \
+  IMAGE_INSTANCE_WIDGET_TEXT (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_WIDGET_ITEM(i) \
+  IMAGE_INSTANCE_WIDGET_ITEM (XIMAGE_INSTANCE (i))
+
+#define XIMAGE_INSTANCE_SUBWINDOW_WIDTH(i) \
+  IMAGE_INSTANCE_SUBWINDOW_WIDTH (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_SUBWINDOW_HEIGHT(i) \
+  IMAGE_INSTANCE_SUBWINDOW_HEIGHT (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_SUBWINDOW_ID(i) \
+  IMAGE_INSTANCE_SUBWINDOW_ID (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_SUBWINDOW_FRAME(i) \
+  IMAGE_INSTANCE_SUBWINDOW_FRAME (XIMAGE_INSTANCE (i))
+#define XIMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP(i) \
+  IMAGE_INSTANCE_SUBWINDOW_DISPLAYEDP (XIMAGE_INSTANCE (i))
+
 #ifdef HAVE_XPM
 Lisp_Object evaluate_xpm_color_symbols (void);
 Lisp_Object pixmap_to_lisp_data (Lisp_Object name, int ok_if_data_invalid);
@@ -480,10 +622,11 @@
 
 extern Lisp_Object Qxpm;
 extern Lisp_Object Q_data, Q_file, Q_color_symbols, Qconst_glyph_variable;
-extern Lisp_Object Qxbm;
+extern Lisp_Object Qxbm, Qedit, Qgroup, Qlabel, Qcombo, Qscrollbar;
 extern Lisp_Object Q_mask_file, Q_mask_data, Q_hotspot_x, Q_hotspot_y;
-extern Lisp_Object Q_foreground, Q_background;
-extern Lisp_Object Qimage_conversion_error;
+extern Lisp_Object Q_foreground, Q_background, Q_face, Q_descriptor, Q_group;
+extern Lisp_Object Q_width, Q_height, Q_pixel_width, Q_pixel_height;
+extern Lisp_Object Q_items, Q_properties, Qimage_conversion_error;
 extern Lisp_Object Vcontinuation_glyph, Vcontrol_arrow_glyph, Vhscroll_glyph;
 extern Lisp_Object Vinvisible_text_glyph, Voctal_escape_glyph, Vtruncation_glyph;
 extern Lisp_Object Vxemacs_logo;
@@ -519,6 +662,11 @@
 			    void (*after_change) (Lisp_Object glyph,
 						  Lisp_Object property,
 						  Lisp_Object locale));
+Lisp_Object widget_face_font_info (Lisp_Object domain, Lisp_Object face,
+				   int *height, int *width);
+void widget_text_to_pixel_conversion (Lisp_Object domain, Lisp_Object face,
+				      int th, int tw,
+				      int* height, int* width);
 
 /************************************************************************/
 /*				Glyph Cachels				*/
@@ -557,6 +705,7 @@
 			 void (*markobj) (Lisp_Object));
 void mark_glyph_cachels_as_not_updated (struct window *w);
 void reset_glyph_cachels (struct window *w);
+
 #ifdef MEMORY_USAGE_STATS
 int compute_glyph_cachel_usage (glyph_cachel_dynarr *glyph_cachels,
 				struct overhead_stats *ovstats);
@@ -566,9 +715,37 @@
 /*				Display Tables				*/
 /************************************************************************/
 
-#define DISP_TABLE_SIZE	256
-#define DISP_CHAR_ENTRY(dp, c) ((c < (dp)->size) ? (dp)->contents[c] : Qnil)
+Lisp_Object display_table_entry (Emchar, Lisp_Object, Lisp_Object);
+void get_display_tables (struct window *, face_index,
+			 Lisp_Object *, Lisp_Object *);
+
+/****************************************************************************
+ *                            Subwindow Object                              *
+ ****************************************************************************/
 
-struct Lisp_Vector *get_display_table (struct window *, face_index);
+/* redisplay needs a per-frame cache of subwindows being displayed so
+ * that we known when to unmap them */
+typedef struct subwindow_cachel subwindow_cachel;
+struct subwindow_cachel
+{
+  Lisp_Object subwindow;
+  int x, y;
+  int width, height;
+  int being_displayed;
+  int updated;
+};
+
+typedef struct
+{
+  Dynarr_declare (subwindow_cachel);
+} subwindow_cachel_dynarr;
+
+void mark_subwindow_cachels (subwindow_cachel_dynarr *elements,
+			 void (*markobj) (Lisp_Object));
+void mark_subwindow_cachels_as_not_updated (struct frame *f);
+void reset_subwindow_cachels (struct frame *f);
+void unmap_subwindow (Lisp_Object subwindow);
+void map_subwindow (Lisp_Object subwindow, int x, int y);
+void update_frame_subwindows (struct frame *f);
 
 #endif /* _XEMACS_GLYPHS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/gui-msw.c	Mon Aug 13 11:08:24 2007 +0200
@@ -0,0 +1,57 @@
+/* mswindows GUI code. (menubars, scrollbars, toolbars, dialogs)
+   Copyright (C) 1998 Andy Piper.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Synched up with: Not in FSF. */
+
+#include <config.h>
+#include "lisp.h"
+#include "gui.h"
+#include "redisplay.h"
+#include "frame.h"
+#include "elhash.h"
+#include "console-msw.h"
+
+/*
+ * Return value is Qt if we have dispatched the command,
+ * or Qnil if id has not been mapped to a callback.
+ * Window procedure may try other targets to route the
+ * command if we return nil
+ */
+Lisp_Object
+mswindows_handle_gui_wm_command (struct frame* f, HWND ctrl, WORD id)
+{
+  /* Try to map the command id through the proper hash table */
+  Lisp_Object data, fn, arg, frame;
+
+  data = Fgethash (make_int (id), 
+		   FRAME_MSWINDOWS_WIDGET_HASH_TABLE (f), Qnil);
+  
+  if (NILP (data) || UNBOUNDP (data))
+    return Qnil;
+
+  MARK_SUBWINDOWS_CHANGED;
+  /* Ok, this is our one. Enqueue it. */
+  get_gui_callback (data, &fn, &arg);
+  XSETFRAME (frame, f);
+  mswindows_enqueue_misc_user_event (frame, fn, arg);
+
+  return Qt;
+}
+
--- a/src/gui.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/gui.c	Mon Aug 13 11:08:24 2007 +0200
@@ -26,6 +26,7 @@
 #include <config.h>
 #include "lisp.h"
 #include "gui.h"
+#include "elhash.h"
 #include "bytecode.h"
 
 Lisp_Object Q_active, Q_suffix, Q_keys, Q_style, Q_selected;
@@ -46,6 +47,7 @@
 {
   return popup_up_p ? Qt : Qnil;
 }
+#endif /* HAVE_POPUPS */
 
 int
 separator_string_p (CONST char *s)
@@ -148,26 +150,36 @@
 void
 gui_parse_item_keywords (Lisp_Object item, struct gui_item *pgui_item)
 {
-  int length, plist_p;
+  int length, plist_p, start;
   Lisp_Object *contents;
 
   CHECK_VECTOR (item);
   length = XVECTOR_LENGTH (item);
   contents = XVECTOR_DATA (item);
 
-  if (length < 2)
-    signal_simple_error ("GUI item descriptors must be at least 2 elts long", item);
+  if (length < 1)
+    signal_simple_error ("GUI item descriptors must be at least 1 elts long", item);
 
-  /* length 2:		[ "name" callback ]
+  /* length 1:     		[ "name" ]
+     length 2:		[ "name" callback ]
      length 3:		[ "name" callback active-p ]
+     		   or	[ "name" keyword  value  ]
      length 4:		[ "name" callback active-p suffix ]
      		   or	[ "name" callback keyword  value  ]
      length 5+:		[ "name" callback [ keyword value ]+ ]
+     		   or	[ "name" [ keyword value ]+ ]
   */
-  plist_p = (length >= 5 || (length > 2 && KEYWORDP (contents [2])));
+  plist_p = (length > 2 && (KEYWORDP (contents [1])
+			    || KEYWORDP (contents [2])));
 
   pgui_item->name = contents [0];
-  pgui_item->callback = contents [1];
+  if (length > 1 && !KEYWORDP (contents [1]))
+    {
+      pgui_item->callback = contents [1];
+      start = 2;
+    }
+  else 
+    start =1;
 
   if (!plist_p && length > 2)
     /* the old way */
@@ -180,12 +192,12 @@
     /* the new way */
     {
       int i;
-      if (length & 1)
+      if ((length - start) & 1)
 	signal_simple_error (
 		"GUI item descriptor has an odd number of keywords and values",
 			     item);
 
-      for (i = 2; i < length;)
+      for (i = start; i < length;)
 	{
 	  Lisp_Object key = contents [i++];
 	  Lisp_Object val = contents [i++];
@@ -209,6 +221,20 @@
 }
 
 /*
+ * Decide whether a GUI item is selected by evaluating its :selected form
+ * if any
+ */
+int
+gui_item_selected_p (CONST struct gui_item *pgui_item)
+{
+  /* This function can call lisp */
+
+  /* Shortcut to avoid evaluating Qt each time */
+  return (EQ (pgui_item->selected, Qt)
+	  || !NILP (Feval (pgui_item->selected)));
+}
+
+/*
  * Decide whether a GUI item is included by evaluating its :included
  * form if given, and testing its :config form against supplied CONFLIST
  * configuration variable
@@ -237,6 +263,7 @@
   signal_simple_error ("GUI item produces too long displayable string", name);
 }
 
+#ifdef HAVE_WINDOW_SYSTEM
 /*
  * Format "left flush" display portion of an item into BUF, guarded by
  * maximum buffer size BUF_LEN. BUF_LEN does not count for terminating
@@ -330,8 +357,37 @@
   /* No keys - no right flush display */
   return 0;
 }
+#endif /* HAVE_WINDOW_SYSTEM */
 
-#endif /* HAVE_POPUPS */
+Lisp_Object
+mark_gui_item (struct gui_item* p, void (*markobj) (Lisp_Object))
+{
+  markobj (p->name);
+  markobj (p->callback);
+  markobj (p->suffix);
+  markobj (p->active);
+  markobj (p->included);
+  markobj (p->config);
+  markobj (p->filter);
+  markobj (p->style);
+  markobj (p->selected);
+  markobj (p->keys);
+
+  return Qnil;
+}
+
+int
+gui_item_hash (Lisp_Object hashtable, struct gui_item* g, int slot)
+{
+  int hashid = HASH2 (internal_hash (g->callback, 0), internal_hash (g->name, 0));
+  int id = GUI_ITEM_ID_BITS (hashid, slot);
+  while (!NILP (Fgethash (make_int (id),
+			  hashtable, Qnil)))
+    {
+      id = GUI_ITEM_ID_BITS (id + 1, slot);
+    }
+  return id;
+}
 
 void
 syms_of_gui (void)
--- a/src/gui.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/gui.h	Mon Aug 13 11:08:24 2007 +0200
@@ -27,7 +27,6 @@
 #ifndef _XEMACS_GUI_H_
 #define _XEMACS_GUI_H_
 
-#ifdef HAVE_POPUPS
 int separator_string_p (CONST char *s);
 void get_gui_callback (Lisp_Object, Lisp_Object *, Lisp_Object *);
 
@@ -76,12 +75,19 @@
 			       Lisp_Object key, Lisp_Object val);
 void gui_parse_item_keywords (Lisp_Object item, struct gui_item *pgui_item);
 int  gui_item_active_p (CONST struct gui_item *pgui_item);
+int  gui_item_selected_p (CONST struct gui_item *pgui_item);
 int  gui_item_included_p (CONST struct gui_item *pgui_item, Lisp_Object into);
+int  gui_item_hash (Lisp_Object, struct gui_item*, int);
+Lisp_Object mark_gui_item (struct gui_item* p, void (*markobj) (Lisp_Object));
 unsigned int gui_item_display_flush_left  (CONST struct gui_item *pgui_item,
 					   char* buf, Bytecount buf_len);
 unsigned int gui_item_display_flush_right (CONST struct gui_item *pgui_item,
 					   char* buf, Bytecount buf_len);
 
-#endif /* HAVE_POPUPS */
+/* this is mswindows biased but reasonably safe I think */
+#define GUI_ITEM_ID_SLOTS 8
+#define GUI_ITEM_ID_MIN(s) (s * 0x2000)
+#define GUI_ITEM_ID_MAX(s) (0x1FFF + GUI_ITEM_ID_MIN (s))
+#define GUI_ITEM_ID_BITS(x,s) (((x) & 0x1FFF) + GUI_ITEM_ID_MIN (s))
 
 #endif /* _XEMACS_GUI_H_ */
--- a/src/lisp.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/lisp.h	Mon Aug 13 11:08:24 2007 +0200
@@ -2868,6 +2868,7 @@
 EXFUN (Fold_member, 2);
 EXFUN (Fold_memq, 2);
 EXFUN (Fplist_get, 3);
+EXFUN (Fplist_member, 2);
 EXFUN (Fplist_put, 3);
 EXFUN (Fplus, MANY);
 EXFUN (Fpoint, 1);
@@ -3000,11 +3001,11 @@
 extern Lisp_Object Qread_from_minibuffer, Qreally_early_error_handler;
 extern Lisp_Object Qregion_beginning, Qregion_end, Qrequire, Qresource;
 extern Lisp_Object Qreturn, Qreverse, Qright, Qrun_hooks, Qsans_modifiers;
-extern Lisp_Object Qsave_buffers_kill_emacs, Qsearch, Qself_insert_command;
+extern Lisp_Object Qsave_buffers_kill_emacs, Qsearch, Qselected, Qself_insert_command;
 extern Lisp_Object Qsequencep, Qsetting_constant, Qseven, Qshift_jis, Qshort;
 extern Lisp_Object Qsignal, Qsimple, Qsingularity_error, Qsize, Qspace;
 extern Lisp_Object Qspecifier, Qstandard_input, Qstandard_output, Qstart_open;
-extern Lisp_Object Qstream, Qstring, Qstring_lessp;
+extern Lisp_Object Qstream, Qstring, Qstring_lessp, Qsubwindow;
 extern Lisp_Object Qsubwindow_image_instance_p, Qsymbol, Qsyntax, Qt, Qtest;
 extern Lisp_Object Qtext, Qtext_image_instance_p, Qtimeout, Qtimestamp;
 extern Lisp_Object Qtoolbar, Qtop, Qtop_level, Qtrue_list_p, Qtty, Qtype;
@@ -3012,7 +3013,7 @@
 extern Lisp_Object Qunderline, Qunimplemented, Quser_files_and_directories;
 extern Lisp_Object Qvalue_assoc, Qvalues;
 extern Lisp_Object Qvariable_documentation, Qvariable_domain, Qvector;
-extern Lisp_Object Qvoid_function, Qvoid_variable, Qwarning, Qwidth, Qwindow;
+extern Lisp_Object Qvoid_function, Qvoid_variable, Qwarning, Qwidth, Qwidget, Qwindow;
 extern Lisp_Object Qwindow_live_p, Qwindow_system, Qwrong_number_of_arguments;
 extern Lisp_Object Qwrong_type_argument, Qx, Qy, Qyes_or_no_p;
 extern Lisp_Object Vactivate_menubar_hook, Vascii_canon_table;
--- a/src/menubar-msw.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/menubar-msw.c	Mon Aug 13 11:08:24 2007 +0200
@@ -130,11 +130,37 @@
      and better be caught than displayed! */
   
   static char buf[MAX_MENUITEM_LENGTH+2];
+  char *ptr;
   unsigned int ll, lr;
 
   /* Left flush part of the string */
   ll = gui_item_display_flush_left (pgui_item, buf, MAX_MENUITEM_LENGTH);
 
+  /* Escape '&' as '&&' */
+  ptr = buf;
+  while ((ptr=memchr (ptr, '&', ll-(ptr-buf))) != NULL)
+    {
+      if (ll+2 >= MAX_MENUITEM_LENGTH)
+	signal_simple_error ("Menu item produces too long displayable string",
+			     pgui_item->name);
+      memmove (ptr+1, ptr, ll-(ptr-buf));
+      ll++;
+      ptr+=2;
+    }
+
+  /* Replace XEmacs accelerator '%_' with Windows accelerator '&' */
+  ptr = buf;
+  while ((ptr=memchr (ptr, '%', ll-(ptr-buf))) != NULL)
+    {
+      if (*(ptr+1) == '_')
+	{
+	  *ptr = '&';
+	  memmove (ptr+1, ptr+2, ll-(ptr-buf+2));
+	  ll--;
+	}
+      ptr++;
+    }
+
   /* Right flush part, unless we're at the top-level where it's not allowed */
   if (!bar_p)
     {
--- a/src/menubar-x.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/menubar-x.c	Mon Aug 13 11:08:24 2007 +0200
@@ -122,6 +122,11 @@
 	{
 	  wv->name = string_chars;
 	  wv->enabled = 1;
+	  /* dverna Dec. 98: command_builder_operate_menu_accelerator will
+	     manipulate the accel as a Lisp_Object if the widget has a name.
+	     Since simple labels have a name, but no accel, we *must* set it
+	     to nil */
+	  wv->accel = LISP_TO_VOID (Qnil);
 	}
     }
   else if (VECTORP (desc))
--- a/src/redisplay-msw.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/redisplay-msw.c	Mon Aug 13 11:08:24 2007 +0200
@@ -58,8 +58,6 @@
  */
 static void mswindows_update_dc (HDC hdc, Lisp_Object font, Lisp_Object fg,
 				 Lisp_Object bg, Lisp_Object bg_pmap);
-static void mswindows_clear_region (Lisp_Object locale, face_index findex,
-			      int x, int y, int width, int height);
 static void mswindows_output_vertical_divider (struct window *w, int clear);
 static void mswindows_redraw_exposed_windows (Lisp_Object window, int x,
 					int y, int width, int height);
@@ -351,7 +349,7 @@
 {
   struct frame *f = XFRAME (w->frame);
   struct device *d = XDEVICE (f->device);
-  struct face_cachel *cachel;
+  struct face_cachel *cachel=0;
   Lisp_Object font = Qnil;
   int focus = EQ (w->frame, DEVICE_FRAME_WITH_FOCUS_REAL (d));
   HDC hdc = FRAME_MSWINDOWS_DC (f);
@@ -555,7 +553,7 @@
 	  int clear_end = min (xpos + this_width, clip_end);
 	  
 	  {
-	    mswindows_clear_region (window, findex, clear_start,
+	    redisplay_clear_region (window, findex, clear_start,
 				    dl->ypos - dl->ascent, 
 				    clear_end - clear_start,
 				    height);
@@ -794,7 +792,7 @@
 	}
 
       if (!offset_bitmap)	/* i.e. not a bg pixmap */
-	mswindows_clear_region (window, findex, clear_x, clear_y,
+	redisplay_clear_region (window, findex, clear_x, clear_y,
 				clear_width, clear_height);
     }
 
@@ -1181,7 +1179,7 @@
 		  /* Clear in case a cursor was formerly here. */
 		  int height = dl->ascent + dl->descent - dl->clip;
 
-		  mswindows_clear_region (window, findex, xpos, dl->ypos - dl->ascent,
+		  redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent,
 				    rb->width, height);
 		  elt++;
 		}
@@ -1262,7 +1260,14 @@
 		    abort ();
 
 		  case IMAGE_SUBWINDOW:
-		    /* #### implement me */
+		  case IMAGE_WIDGET:
+		    redisplay_output_subwindow (w, dl, instance, xpos,
+						rb->object.dglyph.xoffset, start_pixpos,
+						rb->width, findex, cursor_start,
+						cursor_width, cursor_height);
+		    if (rb->cursor_type == CURSOR_ON)
+		      mswindows_output_cursor (w, dl, xpos, cursor_width,
+					       findex, 0, 1);
 		    break;
 
 		  case IMAGE_NOTHING:
@@ -1386,69 +1391,15 @@
  given face.
  ****************************************************************************/
 static void
-mswindows_clear_region (Lisp_Object locale, face_index findex, int x, int y,
-		  int width, int height)
+mswindows_clear_region (Lisp_Object locale, struct device* d, struct frame* f, 
+			face_index findex, int x, int y,
+			int width, int height, Lisp_Object fcolor, Lisp_Object bcolor,
+			Lisp_Object background_pixmap)
 {
-  struct window *w;
-  struct frame *f;
-  Lisp_Object background_pixmap = Qunbound;
-  Lisp_Object temp;
   RECT rect = { x, y, x+width, y+height };
 
-  if (!(width && height))   /* We often seem to get called with width==0 */
-    return;
-
-  if (WINDOWP (locale))
-    {
-      w = XWINDOW (locale);
-      f = XFRAME (w->frame);
-    }
-  else if (FRAMEP (locale))
-    {
-      w = NULL;
-      f = XFRAME (locale);
-    }
-  else
-    abort ();
-  
-  if (w)
+  if (!NILP (background_pixmap))
     {
-      temp = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, findex);
-
-      if (IMAGE_INSTANCEP (temp)
-	  && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp)))
-	{
-	  /* #### maybe we could implement such that a string
-	     can be a background pixmap? */
-	  background_pixmap = temp;
-	}
-    }
-  else
-    {
-      temp = FACE_BACKGROUND_PIXMAP (Vdefault_face, locale);
-
-      if (IMAGE_INSTANCEP (temp)
-	  && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp)))
-	{
-	  background_pixmap = temp;
-	}
-    }
-
-  if (!UNBOUNDP (background_pixmap))
-    {
-      Lisp_Object fcolor, bcolor;
-      
-      if (w)
-	{
-	  fcolor = WINDOW_FACE_CACHEL_FOREGROUND (w, findex);
-	  bcolor = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
-	}
-      else
-	{
-	  fcolor = FACE_FOREGROUND (Vdefault_face, locale);
-	  bcolor = FACE_BACKGROUND (Vdefault_face, locale);
-	}
-
       mswindows_update_dc (FRAME_MSWINDOWS_DC (f),
 			   Qnil, fcolor, bcolor, background_pixmap);
 
@@ -1458,15 +1409,14 @@
     }
   else
     {
-      Lisp_Object color = (w ? WINDOW_FACE_CACHEL_BACKGROUND (w, findex) :
-			   FACE_BACKGROUND (Vdefault_face, locale));
-      mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, color, Qnil);
-      ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
+      mswindows_update_dc (FRAME_MSWINDOWS_DC (f), Qnil, Qnil, fcolor, Qnil);
+      ExtTextOut (FRAME_MSWINDOWS_DC (f), 0, 0, ETO_OPAQUE, 
+		  &rect, NULL, 0, NULL);
     }
 
 #ifdef HAVE_SCROLLBARS
   if (WINDOWP (locale))
-    mswindows_redisplay_deadbox_maybe (w, &rect);
+    mswindows_redisplay_deadbox_maybe (XWINDOW (locale), &rect);
 #endif
 }
 
@@ -1493,27 +1443,27 @@
       XSETWINDOW (window, w);
 
       if (window_is_leftmost (w))
-	mswindows_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f),
+	redisplay_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f),
 			  ypos1, FRAME_BORDER_WIDTH (f), height);
 
       if (bounds.left_in - bounds.left_out > 0)
-	mswindows_clear_region (window,
+	redisplay_clear_region (window,
 			  get_builtin_face_cache_index (w, Vleft_margin_face),
 			  bounds.left_out, ypos1,
 			  bounds.left_in - bounds.left_out, height);
 
       if (bounds.right_in - bounds.left_in > 0)
-	mswindows_clear_region (window, DEFAULT_INDEX, bounds.left_in, ypos1,
+	redisplay_clear_region (window, DEFAULT_INDEX, bounds.left_in, ypos1,
 			  bounds.right_in - bounds.left_in, height);
 
       if (bounds.right_out - bounds.right_in > 0)
-	mswindows_clear_region (window,
+	redisplay_clear_region (window,
 			  get_builtin_face_cache_index (w, Vright_margin_face),
 			  bounds.right_in, ypos1,
 			  bounds.right_out - bounds.right_in, height);
 
       if (window_is_rightmost (w))
-	mswindows_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f),
+	redisplay_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f),
 			  ypos1, FRAME_BORDER_WIDTH (f), height);
     }
 
--- a/src/redisplay-output.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/redisplay-output.c	Mon Aug 13 11:08:24 2007 +0200
@@ -432,13 +432,12 @@
 clear_left_border (struct window *w, int y, int height)
 {
   struct frame *f = XFRAME (w->frame);
-  struct device *d = XDEVICE (f->device);
   Lisp_Object window;
 
   XSETWINDOW (window, w);
-  DEVMETH (d, clear_region, (window, DEFAULT_INDEX,
-			     FRAME_LEFT_BORDER_START (f), y,
-			     FRAME_BORDER_WIDTH (f), height));
+  redisplay_clear_region (window, DEFAULT_INDEX,
+		FRAME_LEFT_BORDER_START (f), y,
+		FRAME_BORDER_WIDTH (f), height);
 }
 
 /*****************************************************************************
@@ -450,13 +449,12 @@
 clear_right_border (struct window *w, int y, int height)
 {
   struct frame *f = XFRAME (w->frame);
-  struct device *d = XDEVICE (f->device);
   Lisp_Object window;
 
   XSETWINDOW (window, w);
-  DEVMETH (d, clear_region, (window, DEFAULT_INDEX,
-			     FRAME_RIGHT_BORDER_START (f),
-			     y, FRAME_BORDER_WIDTH (f), height));
+  redisplay_clear_region (window, DEFAULT_INDEX,
+		FRAME_RIGHT_BORDER_START (f),
+		y, FRAME_BORDER_WIDTH (f), height);
 }
 
 /*****************************************************************************
@@ -617,10 +615,8 @@
 		      XSETWINDOW (window, w);
 
 		      /* Clear the empty area. */
-		      DEVMETH (d, clear_region,
-			       (window, get_builtin_face_cache_index (w,
-								      face),
-				x, y, width, height));
+		      redisplay_clear_region (window, get_builtin_face_cache_index (w, face),
+				    x, y, width, height);
 
 		      /* Mark that we should clear the border.  This is
 			 necessary because italic fonts may leave
@@ -985,6 +981,208 @@
   redraw_cursor_in_window (XWINDOW (window), run_end_begin_meths);
 }
 
+/****************************************************************************
+ redisplay_unmap_subwindows
+
+ Remove subwindows from the area in the box defined by the given
+ parameters.
+ ****************************************************************************/
+static void redisplay_unmap_subwindows (struct frame* f, int x, int y, int width, int height)
+{
+  int elt;
+
+  for (elt = 0; elt < Dynarr_length (f->subwindow_cachels); elt++)
+    {
+      struct subwindow_cachel *cachel =
+	Dynarr_atp (f->subwindow_cachels, elt);
+
+      if (cachel->being_displayed
+	  &&
+	  cachel->x + cachel->width > x && cachel->x < x + width
+	  &&
+	  cachel->y + cachel->height > y && cachel->y < y + height)
+	{
+	  unmap_subwindow (cachel->subwindow);
+	}
+    }
+}
+
+/****************************************************************************
+ redisplay_output_subwindow
+
+
+ output a subwindow.  This code borrows heavily from the pixmap stuff,
+ although is much simpler not needing to account for partial
+ pixmaps, backgrounds etc.
+ ****************************************************************************/
+void
+redisplay_output_subwindow (struct window *w, struct display_line *dl,
+			    Lisp_Object image_instance, int xpos, int xoffset,
+			    int start_pixpos, int width, face_index findex,
+			    int cursor_start, int cursor_width, int cursor_height)
+{
+  struct Lisp_Image_Instance *p = XIMAGE_INSTANCE (image_instance);
+  Lisp_Object window;
+
+  int lheight = dl->ascent + dl->descent - dl->clip;
+  int pheight = ((int) IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight ? lheight :
+		 IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p));
+
+  XSETWINDOW (window, w);
+
+  /* Clear the area the subwindow is going into.  The subwindow itself
+     will always take care of the full width.  We don't want to clear
+     where it is going to go in order to avoid flicker.  So, all we
+     have to take care of is any area above or below the subwindow. Of
+     course this is rubbish if the subwindow has transparent areas
+     (for instance with frames). */
+  /* #### We take a shortcut for now.  We know that since we have
+     subwindow_offset hardwired to 0 that the subwindow is against the top
+     edge so all we have to worry about is below it. */
+  if ((int) (dl->ypos - dl->ascent + pheight) <
+      (int) (dl->ypos + dl->descent - dl->clip))
+    {
+      int clear_x, clear_width;
+
+      int clear_y = dl->ypos - dl->ascent + pheight;
+      int clear_height = lheight - pheight;
+
+      if (start_pixpos >= 0 && start_pixpos > xpos)
+	{
+	  clear_x = start_pixpos;
+	  clear_width = xpos + width - start_pixpos;
+	}
+      else
+	{
+	  clear_x = xpos;
+	  clear_width = width;
+	}
+
+      redisplay_clear_region (window, findex, clear_x, clear_y,
+			      clear_width, clear_height);
+    }
+#if 0
+  redisplay_clear_region (window, findex, xpos - xoffset, dl->ypos - dl->ascent,
+			  width, lheight);
+#endif
+  /* if we can't view the whole window we can't view any of it */
+  if (IMAGE_INSTANCE_SUBWINDOW_HEIGHT (p) > lheight
+      ||
+      IMAGE_INSTANCE_SUBWINDOW_WIDTH (p) > width)
+    {
+      redisplay_clear_region (window, findex, xpos - xoffset, dl->ypos - dl->ascent,
+			      width, lheight);
+      unmap_subwindow (image_instance);
+    }
+  else
+    map_subwindow (image_instance, xpos - xoffset, dl->ypos - dl->ascent);
+}
+
+/****************************************************************************
+ redisplay_clear_region
+
+ Clear the area in the box defined by the given parameters using the
+ given face. This has been generalised so that subwindows can be
+ coped with effectively.
+ ****************************************************************************/
+void
+redisplay_clear_region (Lisp_Object locale, face_index findex, int x, int y,
+			int width, int height)
+{
+  struct window *w = NULL;
+  struct frame *f = NULL;
+  struct device *d;
+  Lisp_Object background_pixmap = Qunbound;
+  Lisp_Object fcolor = Qnil, bcolor = Qnil;
+
+  if (!width || !height)
+     return;
+
+  if (WINDOWP (locale))
+    {
+      w = XWINDOW (locale);
+      f = XFRAME (w->frame);
+    }
+  else if (FRAMEP (locale))
+    {
+      w = NULL;
+      f = XFRAME (locale);
+    }
+  else
+    abort ();
+
+  d = XDEVICE (f->device);
+
+  /* if we have subwindows in the region we have to unmap them */
+  if (Dynarr_length (FRAME_SUBWINDOW_CACHE (f)))
+    {
+      redisplay_unmap_subwindows (f, x, y, width, height);
+    }
+
+  /* #### This isn't quite right for when this function is called
+     from the toolbar code. */
+  
+  /* Don't use a backing pixmap in the border area */
+  if (x >= FRAME_LEFT_BORDER_END (f)
+      && x < FRAME_RIGHT_BORDER_START (f)
+      && y >= FRAME_TOP_BORDER_END (f)
+      && y < FRAME_BOTTOM_BORDER_START (f))
+    {
+      Lisp_Object temp;
+      
+      if (w)
+	{
+	  temp = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, findex);
+	  
+	  if (IMAGE_INSTANCEP (temp)
+	      && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp)))
+	    {
+	      /* #### maybe we could implement such that a string
+		 can be a background pixmap? */
+	      background_pixmap = temp;
+	    }
+	}
+      else
+	{
+	  temp = FACE_BACKGROUND_PIXMAP (Vdefault_face, locale);
+	  
+	  if (IMAGE_INSTANCEP (temp)
+	      && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp)))
+	    {
+	      background_pixmap = temp;
+	    }
+	}
+    }      
+
+  if (!UNBOUNDP (background_pixmap) &&
+      XIMAGE_INSTANCE_PIXMAP_DEPTH (background_pixmap) == 0)
+    {
+      if (w)
+	{
+	  fcolor = WINDOW_FACE_CACHEL_FOREGROUND (w, findex);
+	  bcolor = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
+	}
+      else
+	{
+	  fcolor = FACE_FOREGROUND (Vdefault_face, locale);
+	  bcolor = FACE_BACKGROUND (Vdefault_face, locale);
+	}
+    }
+  else
+    {
+      fcolor = (w ?
+		WINDOW_FACE_CACHEL_BACKGROUND (w, findex) :
+		FACE_BACKGROUND (Vdefault_face, locale));
+      
+    }
+  
+  if (UNBOUNDP (background_pixmap))
+    background_pixmap = Qnil;
+  
+  DEVMETH (d, clear_region, 
+	   (locale, d, f, findex, x, y, width, height, fcolor, bcolor, background_pixmap));
+}
+
 /*****************************************************************************
  redisplay_clear_top_of_window
 
@@ -999,7 +1197,6 @@
   if (!NILP (Fwindow_highest_p (window)))
     {
       struct frame *f = XFRAME (w->frame);
-      struct device *d = XDEVICE (f->device);
       int x, y, width, height;
 
       x = w->pixel_left;
@@ -1016,7 +1213,7 @@
       y = FRAME_TOP_BORDER_START (f) - 1;
       height = FRAME_BORDER_HEIGHT (f) + 1;
 
-      DEVMETH (d, clear_region, (window, DEFAULT_INDEX, x, y, width, height));
+      redisplay_clear_region (window, DEFAULT_INDEX, x, y, width, height);
     }
 }
 
--- a/src/redisplay-tty.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/redisplay-tty.c	Mon Aug 13 11:08:24 2007 +0200
@@ -391,6 +391,7 @@
 		  case IMAGE_MONO_PIXMAP:
 		  case IMAGE_COLOR_PIXMAP:
 		  case IMAGE_SUBWINDOW:
+		  case IMAGE_WIDGET:
 		    /* just do nothing here */
 		    break;
 
@@ -461,16 +462,14 @@
  Clear the area in the box defined by the given parameters.
  ****************************************************************************/
 static void
-tty_clear_region (Lisp_Object window, face_index findex, int x, int y,
-		  int width, int height)
+tty_clear_region (Lisp_Object window, struct device* d, struct frame * f,
+		  face_index findex, int x, int y,
+		  int width, int height, Lisp_Object fcolor, Lisp_Object bcolor, 
+		  Lisp_Object background_pixmap)
 {
-  struct window *w = XWINDOW (window);
-  struct frame *f = XFRAME (w->frame);
   struct console *c = XCONSOLE (FRAME_CONSOLE (f));
   int line;
-
-  if (!width || !height)
-     return;
+  struct window* w = XWINDOW (window);
 
   tty_turn_on_face (w, findex);
   for (line = y; line < y + height; line++)
@@ -534,7 +533,7 @@
       Lisp_Object window;
 
       XSETWINDOW (window, w);
-      tty_clear_region (window, DEFAULT_INDEX, x, ypos1, width, ypos2 - ypos1);
+      redisplay_clear_region (window, DEFAULT_INDEX, x, ypos1, width, ypos2 - ypos1);
     }
 }
 
@@ -959,7 +958,7 @@
 	  struct frame *f = XFRAME (frm);
 
 	  /* Clear the bottom line of the frame. */
-	  tty_clear_region (FRAME_SELECTED_WINDOW (f), DEFAULT_INDEX, 0,
+	  redisplay_clear_region (FRAME_SELECTED_WINDOW (f), DEFAULT_INDEX, 0,
 			    f->height, f->width, 1);
 
 	  /* And then stick the cursor there. */
--- a/src/redisplay-x.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/redisplay-x.c	Mon Aug 13 11:08:24 2007 +0200
@@ -74,8 +74,6 @@
 				     int width, int height);
 static void x_redraw_exposed_windows (Lisp_Object window, int x, int y,
 				      int width, int height);
-static void x_clear_region (Lisp_Object window, face_index findex, int x,
-			    int y, int width, int height);
 static void x_output_eol_cursor (struct window *w, struct display_line *dl,
 				 int xpos, face_index findex);
 static void x_clear_frame (struct frame *f);
@@ -416,7 +414,7 @@
 		  /* Clear in case a cursor was formerly here. */
 		  int height = dl->ascent + dl->descent - dl->clip;
 
-		  x_clear_region (window, findex, xpos, dl->ypos - dl->ascent,
+		  redisplay_clear_region (window, findex, xpos, dl->ypos - dl->ascent,
 				  rb->width, height);
 		  elt++;
 		}
@@ -490,9 +488,12 @@
 		  case IMAGE_POINTER:
 		    abort ();
 
+		  case IMAGE_WIDGET:
 		  case IMAGE_SUBWINDOW:
-		    /* #### implement me */
-		    break;
+		    redisplay_output_subwindow (w, dl, instance, xpos,
+						rb->object.dglyph.xoffset, start_pixpos,
+						rb->width, findex, cursor_start,
+						cursor_width, cursor_height);
 
 		  case IMAGE_NOTHING:
 		    /* nothing is as nothing does */
@@ -902,21 +903,21 @@
 
 	      if (ypos1_line < ypos1_string)
 		{
-		  x_clear_region (window, findex, clear_start, ypos1_line,
+		  redisplay_clear_region (window, findex, clear_start, ypos1_line,
 				  clear_end - clear_start,
 				  ypos1_string - ypos1_line);
 		}
 
 	      if (ypos2_line > ypos2_string)
 		{
-		  x_clear_region (window, findex, clear_start, ypos2_string,
+		  redisplay_clear_region (window, findex, clear_start, ypos2_string,
 				  clear_end - clear_start,
 				  ypos2_line - ypos2_string);
 		}
 	    }
 	  else
 	    {
-	      x_clear_region (window, findex, clear_start,
+	      redisplay_clear_region (window, findex, clear_start,
 			      dl->ypos - dl->ascent, clear_end - clear_start,
 			      height);
 	    }
@@ -1334,7 +1335,7 @@
 	  clear_width = width;
 	}
 
-      x_clear_region (window, findex, clear_x, clear_y,
+      redisplay_clear_region (window, findex, clear_x, clear_y,
 		      clear_width, clear_height);
     }
 
@@ -1836,27 +1837,27 @@
       XSETWINDOW (window, w);
 
       if (window_is_leftmost (w))
-	x_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f),
+	redisplay_clear_region (window, DEFAULT_INDEX, FRAME_LEFT_BORDER_START (f),
 			ypos1, FRAME_BORDER_WIDTH (f), height);
 
       if (bounds.left_in - bounds.left_out > 0)
-	x_clear_region (window,
+	redisplay_clear_region (window,
 			get_builtin_face_cache_index (w, Vleft_margin_face),
 			bounds.left_out, ypos1,
 			bounds.left_in - bounds.left_out, height);
 
       if (bounds.right_in - bounds.left_in > 0)
-	x_clear_region (window, DEFAULT_INDEX, bounds.left_in, ypos1,
+	redisplay_clear_region (window, DEFAULT_INDEX, bounds.left_in, ypos1,
 			bounds.right_in - bounds.left_in, height);
 
       if (bounds.right_out - bounds.right_in > 0)
-	x_clear_region (window,
+	redisplay_clear_region (window,
 			get_builtin_face_cache_index (w, Vright_margin_face),
 			bounds.right_in, ypos1,
 			bounds.right_out - bounds.right_in, height);
 
       if (window_is_rightmost (w))
-	x_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f),
+	redisplay_clear_region (window, DEFAULT_INDEX, FRAME_RIGHT_BORDER_START (f),
 			ypos1, FRAME_BORDER_WIDTH (f), height);
     }
 }
@@ -1996,110 +1997,27 @@
  given face.
  ****************************************************************************/
 static void
-x_clear_region (Lisp_Object locale, face_index findex, int x, int y,
-		int width, int height)
+x_clear_region (Lisp_Object locale, struct device* d, struct frame* f, face_index findex,
+		int x, int y,
+		int width, int height, Lisp_Object fcolor, Lisp_Object bcolor,
+		Lisp_Object background_pixmap)
 {
-  struct window *w = NULL;
-  struct frame *f = NULL;
-  struct device *d;
-  Lisp_Object background_pixmap;
-
   Display *dpy;
   Window x_win;
+  GC gc = NULL;
 
-  if (WINDOWP (locale))
-    {
-      w = XWINDOW (locale);
-      f = XFRAME (w->frame);
-    }
-  else if (FRAMEP (locale))
-    {
-      w = NULL;
-      f = XFRAME (locale);
-    }
-  else
-    abort ();
-
-  d = XDEVICE (f->device);
   dpy = DEVICE_X_DISPLAY (d);
   x_win = XtWindow (FRAME_X_TEXT_WIDGET (f));
 
-  /* #### This function is going to have to be made cursor aware. */
-  if (width && height)
+    if (!UNBOUNDP (background_pixmap))
     {
-      GC gc = NULL;
-
-      /* #### This isn't quite right for when this function is called
-         from the toolbar code. */
-      background_pixmap = Qunbound;
-
-      /* Don't use a backing pixmap in the border area */
-      if (x >= FRAME_LEFT_BORDER_END (f)
-	  && x < FRAME_RIGHT_BORDER_START (f)
-	  && y >= FRAME_TOP_BORDER_END (f)
-	  && y < FRAME_BOTTOM_BORDER_START (f))
-	{
-	  Lisp_Object temp;
-
-	  if (w)
-	    {
-	      temp = WINDOW_FACE_CACHEL_BACKGROUND_PIXMAP (w, findex);
-
-	      if (IMAGE_INSTANCEP (temp)
-		  && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp)))
-		{
-		  /* #### maybe we could implement such that a string
-		     can be a background pixmap? */
-		  background_pixmap = temp;
-		}
-	    }
-	  else
-	    {
-	      temp = FACE_BACKGROUND_PIXMAP (Vdefault_face, locale);
+      gc = x_get_gc (d, Qnil, fcolor, bcolor, background_pixmap, Qnil);
+    }
 
-	      if (IMAGE_INSTANCEP (temp)
-		  && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (temp)))
-		{
-		  background_pixmap = temp;
-		}
-	    }
-
-	  if (!UNBOUNDP (background_pixmap) &&
-	      XIMAGE_INSTANCE_PIXMAP_DEPTH (background_pixmap) == 0)
-	    {
-	      Lisp_Object fcolor, bcolor;
-
-	      if (w)
-		{
-		  fcolor = WINDOW_FACE_CACHEL_FOREGROUND (w, findex);
-		  bcolor = WINDOW_FACE_CACHEL_BACKGROUND (w, findex);
-		}
-	      else
-		{
-		  fcolor = FACE_FOREGROUND (Vdefault_face, locale);
-		  bcolor = FACE_BACKGROUND (Vdefault_face, locale);
-		}
-
-	      gc = x_get_gc (d, Qnil, fcolor, bcolor, background_pixmap, Qnil);
-	    }
-	  else
-	    {
-	      Lisp_Object color = (w ?
-				   WINDOW_FACE_CACHEL_BACKGROUND (w, findex) :
-				   FACE_BACKGROUND (Vdefault_face, locale));
-
-	      if (UNBOUNDP (background_pixmap))
-		background_pixmap = Qnil;
-
-	      gc = x_get_gc (d, Qnil, color, Qnil, background_pixmap, Qnil);
-	    }
-	}
-
-      if (gc)
-	XFillRectangle (dpy, x_win, gc, x, y, width, height);
-      else
-	XClearArea (dpy, x_win, x, y, width, height, False);
-    }
+  if (gc)
+    XFillRectangle (dpy, x_win, gc, x, y, width, height);
+  else
+    XClearArea (dpy, x_win, x, y, width, height, False);
 }
 
 /*****************************************************************************
@@ -2134,7 +2052,7 @@
   int defheight, defascent;
 
   XSETWINDOW (window, w);
-  x_clear_region (window, findex, x, y, width, height);
+  redisplay_clear_region (window, findex, x, y, width, height);
 
   if (NILP (w->text_cursor_visible_p))
     return;
--- a/src/redisplay.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/redisplay.c	Mon Aug 13 11:08:24 2007 +0200
@@ -256,7 +256,8 @@
 					  struct glyph_cachel *cachel);
 static Bytind create_text_block (struct window *w, struct display_line *dl,
 				 Bytind bi_start_pos, int start_col,
-				 prop_block_dynarr **prop, int type);
+				 prop_block_dynarr **prop,
+				 int type);
 static int create_overlay_glyph_block (struct window *w,
 				       struct display_line *dl);
 static void create_left_glyph_block (struct window *w,
@@ -365,6 +366,11 @@
 int glyphs_changed;
 int glyphs_changed_set;
 
+/* non-zero if any displayed subwindow is in need of updating
+   somewhere. */
+int subwindows_changed;
+int subwindows_changed_set;
+
 /* This variable is 1 if the icon has to be updated.
  It is set to 1 when `frame-icon-glyph' changes. */
 int icon_changed;
@@ -681,7 +687,8 @@
 static Bufpos
 generate_display_line (struct window *w, struct display_line *dl, int bounds,
 		       Bufpos start_pos, int start_col,
-		       prop_block_dynarr **prop, int type)
+		       prop_block_dynarr **prop,
+		       int type)
 {
   Bufpos ret_bufpos;
   int overlay_width;
@@ -1233,66 +1240,12 @@
     }
 }
 
-/* Given a display table entry, call the appropriate functions to
-   display each element of the entry. */
-
 static prop_block_dynarr *
-add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
+add_disp_table_entry_runes_1 (pos_data *data, Lisp_Object entry)
 {
   prop_block_dynarr *prop = NULL;
 
-  if (VECTORP (entry))
-    {
-      struct Lisp_Vector *de = XVECTOR (entry);
-      long len = vector_length (de);
-      int elt;
-
-      for (elt = 0; elt < len; elt++)
-	{
-	  if (NILP (de->contents[elt]))
-	    continue;
-	  else if (STRINGP (de->contents[elt]))
-	    {
-	      prop =
-		add_bufbyte_string_runes
-		  (data,
-		   XSTRING_DATA   (de->contents[elt]),
-		   XSTRING_LENGTH (de->contents[elt]),
-		   0);
-	    }
-	  else if (GLYPHP (de->contents[elt]))
-	    {
-	      if (data->start_col)
-		data->start_col--;
-
-	      if (!data->start_col && data->bi_start_col_enabled)
-		{
-		  prop = add_hscroll_rune (data);
-		}
-	      else
-		{
-		  struct glyph_block gb;
-
-		  gb.glyph = de->contents[elt];
-		  gb.extent = Qnil;
-		  prop = add_glyph_rune (data, &gb, BEGIN_GLYPHS, 0, 0);
-		}
-	    }
-	  else if (CHAR_OR_CHAR_INTP (de->contents[elt]))
-	    {
-	      data->ch = XCHAR_OR_CHAR_INT (de->contents[elt]);
-	      prop = add_emchar_rune (data);
-	    }
-	  /* Else blow it off because someone added a bad entry and we
-             don't have any safe way of signaling an error. */
-
-	  /* #### Still need to add any remaining elements to the
-             propagation information. */
-	  if (prop)
-	    return prop;
-	}
-    }
-  else if (STRINGP (entry))
+  if (STRINGP (entry))
     {
       prop = add_bufbyte_string_runes (data,
 				       XSTRING_DATA   (entry),
@@ -1322,10 +1275,79 @@
       data->ch = XCHAR_OR_CHAR_INT (entry);
       prop = add_emchar_rune (data);
     }
+  else if (CONSP (entry))
+    {
+      if (EQ (XCAR (entry), Qformat)
+	  && CONSP (XCDR (entry))
+	  && STRINGP (XCAR (XCDR (entry))))
+	{
+	  Lisp_Object format = XCAR (XCDR (entry));
+	  Bytind len = XSTRING_LENGTH (format);
+	  Bufbyte *src = XSTRING_DATA (format), *end = src + len;
+	  Bufbyte *result = alloca_array (Bufbyte, len);
+	  Bufbyte *dst = result;
+
+	  while (src < end)
+	    {
+	      Emchar c = charptr_emchar (src);
+	      INC_CHARPTR (src);
+	      if (c != '%' || src == end)
+		dst += set_charptr_emchar (dst, c);
+	      else
+		{
+		  c = charptr_emchar (src);
+		  INC_CHARPTR (src);
+		  switch (c)
+		    {
+		      /*case 'x':
+		      dst += long_to_string_base ((char *)dst, data->ch, 16);
+		      break;*/
+		    case '%':
+		      dst += set_charptr_emchar (dst, '%');
+		      break;
+		    }
+		}
+	    }
+	  prop = add_bufbyte_string_runes (data, result, dst - result, 0);
+	}
+    }
 
   /* Else blow it off because someone added a bad entry and we don't
-     have any safe way of signaling an error.  Hey, this comment
-     sounds familiar. */
+     have any safe way of signaling an error. */
+  return prop;
+}
+
+/* Given a display table entry, call the appropriate functions to
+   display each element of the entry. */
+
+static prop_block_dynarr *
+add_disp_table_entry_runes (pos_data *data, Lisp_Object entry)
+{
+  prop_block_dynarr *prop = NULL;
+  if (VECTORP (entry))
+    {
+      struct Lisp_Vector *de = XVECTOR (entry);
+      EMACS_INT len = vector_length (de);
+      int elt;
+
+      for (elt = 0; elt < len; elt++)
+	{
+	  if (NILP (vector_data (de)[elt]))
+	    continue;
+	  else
+	    prop = add_disp_table_entry_runes_1 (data, vector_data (de)[elt]);
+	  /* Else blow it off because someone added a bad entry and we
+	     don't have any safe way of signaling an error.  Hey, this
+	     comment sounds familiar. */
+
+	  /* #### Still need to add any remaining elements to the
+             propagation information. */
+	  if (prop)
+	    return prop;
+	}
+    }
+  else
+    prop = add_disp_table_entry_runes_1 (data, entry);
   return prop;
 }
 
@@ -1744,14 +1766,14 @@
 static Bytind
 create_text_block (struct window *w, struct display_line *dl,
 		   Bytind bi_start_pos, int start_col,
-		   prop_block_dynarr **prop, int type)
+		   prop_block_dynarr **prop,
+		   int type)
 {
   struct frame *f = XFRAME (w->frame);
   struct buffer *b = XBUFFER (w->buffer);
   struct device *d = XDEVICE (f->device);
 
   pos_data data;
-  struct Lisp_Vector *dt = 0;
 
   /* Don't display anything in the minibuffer if this window is not on
      a selected frame.  We consider all other windows to be active
@@ -1784,46 +1806,41 @@
      into a more general conversion mechanism.  Ideally you
      could specify a Lisp function that converts characters,
      but this violates the Second Golden Rule and besides would
-     make things way way way way slow.  An idea I like is to
-     be able to specify multiple display tables instead of just
-     one.  Each display table can specify conversions for some
-     characters and leave others unchanged.  The way the
-     character gets displayed is determined by the first display
-     table with a binding for that character.  This way, you
-     could call a function `enable-hex-display' that adds a
-     pre-defined hex display-table (or maybe computes one if
-     you give weird parameters to the function) and adds it
-     to the list of display tables for the current buffer.
-
-     Unfortunately there are still problems dealing with Mule
-     characters.  For example, maybe I want to specify that
-     all extended characters (i.e. >= 256) are displayed in hex.
-     It's not reasonable to create a mapping for all possible
-     such characters, because there are about 2^19 of them.
-     One way of dealing with this is to extend the concept
-     of what a display table is.  Currently it's only allowed
-     to be a 256-entry vector.  Instead, it should be something
-     like:
-
-     a) A 256-entry vector, for backward compatibility
-     b) Some sort of hash table, mapping characters to values
-     c) A list that specifies a range of values and the
-        mapping to provide for those values.
-
-     Also, extend the concept of "mapping" to include a
-     printf-like spec.  Then, you could make all extended
-     characters show up as hex with a display table like
-
-     ((256 . 524288) . "%x")
+     make things way way way way slow.
+
+     So instead, we extend the display-table concept, which was
+     historically limited to 256-byte vectors, to one of the
+     following:
+
+     a) A 256-entry vector, for backward compatibility;
+     b) char-table, mapping characters to values;
+     c) range-table, mapping ranges of characters to values;
+     d) a list of the above.
+
+     The (d) option allows you to specify multiple display tables
+     instead of just one.  Each display table can specify conversions
+     for some characters and leave others unchanged.  The way the
+     character gets displayed is determined by the first display table
+     with a binding for that character.  This way, you could call a
+     function `enable-hex-display' that adds a hex display-table to
+     the list of display tables for the current buffer.
+
+     #### ...not yet implemented...  Also, we extend the concept of
+     "mapping" to include a printf-like spec.  Thus you can make all
+     extended characters show up as hex with a display table like
+     this:
+
+         #s(range-table data ((256 524288) (format "%x")))
 
      Since more than one display table is possible, you have
-     great flexibility in mapping ranges of characters.
-     */
+     great flexibility in mapping ranges of characters.  */
   Emchar printable_min = (CHAR_OR_CHAR_INTP (b->ctl_arrow)
 			  ? XCHAR_OR_CHAR_INT (b->ctl_arrow)
 			  : ((EQ (b->ctl_arrow, Qt) || EQ (b->ctl_arrow, Qnil))
 			     ? 255 : 160));
 
+  Lisp_Object face_dt, window_dt;
+
   /* The text display block for this display line. */
   struct display_block *db = get_display_block_from_line (dl, TEXT);
 
@@ -1962,10 +1979,10 @@
 	    /* Remember that the extent-fragment routines deal in Bytind's. */
 	    extent_fragment_update (w, data.ef, data.bi_bufpos);
 
+	  get_display_tables (w, data.findex, &face_dt, &window_dt);
+
 	  if (data.bi_bufpos == data.ef->end)
 	    no_more_frags = 1;
-
-	  dt = get_display_table (w, data.findex);
 	}
       initial = 0;
 
@@ -2077,16 +2094,17 @@
 
       else
 	{
+	  Lisp_Object entry = Qnil;
 	  /* Get the character at the current buffer position. */
 	  data.ch = BI_BUF_FETCH_CHAR (b, data.bi_bufpos);
+	  if (!NILP (face_dt) || !NILP (window_dt))
+	    entry = display_table_entry (data.ch, face_dt, window_dt);
 
 	  /* If there is a display table entry for it, hand it off to
              add_disp_table_entry_runes and let it worry about it. */
-	  if (dt && !NILP (DISP_CHAR_ENTRY (dt, data.ch)))
+	  if (!NILP (entry) && !EQ (entry, make_char (data.ch)))
 	    {
-	      *prop =
-		add_disp_table_entry_runes (&data,
-					    DISP_CHAR_ENTRY (dt, data.ch));
+	      *prop = add_disp_table_entry_runes (&data, entry);
 
 	      if (*prop)
 		goto done;
@@ -4310,7 +4328,7 @@
     }
 
   if (prop)
-      Dynarr_free (prop);
+    Dynarr_free (prop);
 
   /* #### More not quite right, but close enough. */
   /* #### Ben sez: apparently window_end_pos[] is measured
@@ -4625,11 +4643,9 @@
   /* If the changes are below the visible area then if point hasn't
      moved return success otherwise fail in order to be safe. */
   if (line > dla_end)
-    {
-      return regenerate_window_extents_only_changed (w, startp, pointm,
-						     extent_beg_unchanged,
-						     extent_end_unchanged);
-    }
+    return regenerate_window_extents_only_changed (w, startp, pointm,
+						   extent_beg_unchanged,
+						   extent_end_unchanged);
   else
     /* At this point we know what line the changes first affect.  We
        now redraw that line.  If the changes are contained within it
@@ -4753,12 +4769,9 @@
 	      && extent_end_unchanged != -1
 	      && ((extent_beg_unchanged < ddl->bufpos)
 		  || (extent_end_unchanged > ddl->end_bufpos)))
-	    {
-	      return
-		regenerate_window_extents_only_changed (w, startp, pointm,
-							extent_beg_unchanged,
-							extent_end_unchanged);
-	    }
+	    return regenerate_window_extents_only_changed (w, startp, pointm,
+							   extent_beg_unchanged,
+							   extent_end_unchanged);
 	  else
 	    return 1;
 	}
@@ -5081,6 +5094,7 @@
 	  && !f->extents_changed
 	  && !f->faces_changed
 	  && !f->glyphs_changed
+	  && !f->subwindows_changed
 	  && !f->point_changed
 	  && !f->windows_structure_changed)
 	{
@@ -5101,6 +5115,7 @@
 	      && !f->extents_changed
 	      && !f->faces_changed
 	      && !f->glyphs_changed
+	      && !f->subwindows_changed
 	      && !f->windows_structure_changed)
 	    {
 	      if (point_visible (w, pointm, CURRENT_DISP)
@@ -5158,6 +5173,7 @@
 	   && !f->clip_changed
 	   && !f->faces_changed
 	   && !f->glyphs_changed
+	   && !f->subwindows_changed
 	   && !f->windows_structure_changed
 	   && !f->frame_changed
 	   && !truncation_changed
@@ -5374,7 +5390,11 @@
      being handled. */
   update_frame_menubars (f);
 #endif /* HAVE_MENUBARS */
-
+  /* widgets are similar to menus in that they can call lisp to
+     determine activation etc. Therefore update them before we get
+     into redisplay. This is primarily for connected widgets such as
+     radio buttons. */
+  update_frame_subwindows (f);
 #ifdef HAVE_TOOLBARS
   /* Update the toolbars. */
   update_frame_toolbars (f);
@@ -5412,7 +5432,20 @@
 
   /* Erase the frame before outputting its contents. */
   if (f->clear)
-    DEVMETH (d, clear_frame, (f));
+    {
+      DEVMETH (d, clear_frame, (f));
+    }
+
+  /* invalidate the subwindow cache. we are going to reuse the glyphs
+     flag here to cause subwindows to get instantiated. This is
+     because subwindows changed is less strict - dealing with things
+     like the clicked state of button. */
+  if (!Dynarr_length (f->subwindow_cachels)
+      || f->glyphs_changed
+      || f->frame_changed)
+    reset_subwindow_cachels (f);
+  else
+    mark_subwindow_cachels_as_not_updated (f);
 
   /* Do the selected window first. */
   redisplay_window (FRAME_SELECTED_WINDOW (f), 0);
@@ -5434,6 +5467,7 @@
   f->faces_changed    = 0;
   f->frame_changed    = 0;
   f->glyphs_changed   = 0;
+  f->subwindows_changed   = 0;
   f->icon_changed     = 0;
   f->menubar_changed  = 0;
   f->modeline_changed = 0;
@@ -5497,7 +5531,7 @@
 	  f->faces_changed    || f->frame_changed || f->menubar_changed ||
 	  f->modeline_changed || f->point_changed || f->size_changed    ||
 	  f->toolbar_changed  || f->windows_changed || f->size_slipped  ||
-	  f->windows_structure_changed || f->glyphs_changed)
+	  f->windows_structure_changed || f->glyphs_changed || f->subwindows_changed)
 	{
 	  preempted = redisplay_frame (f, 0);
 	}
@@ -5532,7 +5566,7 @@
 	      f->modeline_changed || f->point_changed || f->size_changed    ||
 	      f->toolbar_changed  || f->windows_changed ||
 	      f->windows_structure_changed ||
-	      f->glyphs_changed)
+	      f->glyphs_changed || f->subwindows_changed)
 	    {
 	      preempted = redisplay_frame (f, 0);
 	    }
@@ -5553,6 +5587,7 @@
   d->faces_changed    = 0;
   d->frame_changed    = 0;
   d->glyphs_changed   = 0;
+  d->subwindows_changed   = 0;
   d->icon_changed     = 0;
   d->menubar_changed  = 0;
   d->modeline_changed = 0;
@@ -5598,7 +5633,7 @@
       !faces_changed   && !frame_changed    && !icon_changed    &&
       !menubar_changed && !modeline_changed && !point_changed   &&
       !size_changed    && !toolbar_changed  && !windows_changed &&
-      !glyphs_changed  &&
+      !glyphs_changed  && !subwindows_changed &&
       !windows_structure_changed && !disable_preemption &&
       preemption_count < max_preempts)
     goto done;
@@ -5613,7 +5648,7 @@
 	  d->menubar_changed  || d->modeline_changed || d->point_changed   ||
 	  d->size_changed     || d->toolbar_changed  || d->windows_changed ||
 	  d->windows_structure_changed ||
-	  d->glyphs_changed)
+	  d->glyphs_changed || d->subwindows_changed)
 	{
 	  preempted = redisplay_device (d);
 
@@ -5637,6 +5672,7 @@
   extents_changed  = 0;
   frame_changed    = 0;
   glyphs_changed   = 0;
+  subwindows_changed   = 0;
   icon_changed     = 0;
   menubar_changed  = 0;
   modeline_changed = 0;
--- a/src/redisplay.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/redisplay.h	Mon Aug 13 11:08:24 2007 +0200
@@ -350,6 +350,11 @@
 extern int glyphs_changed;
 extern int glyphs_changed_set;
 
+/* True if any displayed subwindow is in need of updating
+   somewhere. */
+extern int subwindows_changed;
+extern int subwindows_changed_set;
+
 /* True if an icon is in need of updating somewhere. */
 extern int icon_changed;
 extern int icon_changed_set;
@@ -417,6 +422,7 @@
 #define MARK_POINT_CHANGED MARK_TYPE_CHANGED (point)
 #define MARK_TOOLBAR_CHANGED MARK_TYPE_CHANGED (toolbar)
 #define MARK_GLYPHS_CHANGED MARK_TYPE_CHANGED (glyphs)
+#define MARK_SUBWINDOWS_CHANGED MARK_TYPE_CHANGED (subwindows)
 
 /* Anytime a console, device or frame is added or deleted we need to reset
    these flags. */
@@ -431,6 +437,7 @@
     point_changed_set = 0;		\
     toolbar_changed_set = 0;		\
     glyphs_changed_set = 0;		\
+    subwindows_changed_set = 0;		\
   } while (0)
 
 
@@ -547,6 +554,13 @@
 int get_next_display_block (layout_bounds bounds,
 			    display_block_dynarr *dba, int start_pos,
 			    int *next_start);
+void redisplay_output_subwindow (struct window *w, struct display_line *dl,
+				 Lisp_Object image_instance, int xpos,
+				 int xoffset, int start_pixpos, int width,
+				 face_index findex, int cursor_start, 
+				 int cursor_width, int cursor_height);
+void redisplay_clear_region (Lisp_Object window, face_index findex, int x,
+			     int y, int width, int height);
 void redisplay_clear_bottom_of_window (struct window *w,
 				       display_line_dynarr *ddla,
 				       int min_start, int max_end);
--- a/src/sound.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/sound.c	Mon Aug 13 11:08:24 2007 +0200
@@ -68,8 +68,9 @@
 DEFUN ("play-sound-file", Fplay_sound_file, 1, 3, "fSound file name: ", /*
 Play the named sound file on DEVICE's speaker at the specified volume
 \(0-100, default specified by the `bell-volume' variable).
-The sound file must be in the Sun/NeXT U-LAW format except under Linux
-where WAV files are also supported.
+On Unix machines the sound file must be in the Sun/NeXT U-LAW format
+except under Linux where WAV files are also supported.  On Microsoft 
+Windows the sound file must be in WAV format.
   DEVICE defaults to the selected device.
 */
      (file, volume, device))
--- a/src/specifier.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/specifier.c	Mon Aug 13 11:08:24 2007 +0200
@@ -37,7 +37,8 @@
 #include "opaque.h"
 #include "specifier.h"
 #include "window.h"
-#include "glyphs.h"  /* for DISP_TABLE_SIZE definition */
+#include "chartab.h"
+#include "rangetab.h"
 
 Lisp_Object Qspecifierp;
 Lisp_Object Qprepend, Qappend, Qremove_tag_set_prepend, Qremove_tag_set_append;
@@ -2998,14 +2999,38 @@
 
 DEFINE_SPECIFIER_TYPE (display_table);
 
+#define VALID_SINGLE_DISPTABLE_INSTANTIATOR_P(instantiator)			\
+  (VECTORP (instantiator)							\
+   || (CHAR_TABLEP (instantiator)						\
+       && (XCHAR_TABLE_TYPE (instantiator) == CHAR_TABLE_TYPE_CHAR		\
+	   || XCHAR_TABLE_TYPE (instantiator) == CHAR_TABLE_TYPE_GENERIC))	\
+   || RANGE_TABLEP (instantiator))
+
 static void
 display_table_validate (Lisp_Object instantiator)
 {
-  if (!NILP(instantiator) &&
-      (!VECTORP (instantiator) ||
-       XVECTOR_LENGTH (instantiator) != DISP_TABLE_SIZE))
-    dead_wrong_type_argument (display_table_specifier_methods->predicate_symbol,
-			      instantiator);
+  if (NILP (instantiator))
+    /* OK */
+    ;
+  else if (CONSP (instantiator))
+    {
+      Lisp_Object tail;
+      EXTERNAL_LIST_LOOP (tail, instantiator)
+	{
+	  Lisp_Object car = XCAR (tail);
+	  if (!VALID_SINGLE_DISPTABLE_INSTANTIATOR_P (car))
+	    goto lose;
+	}
+    }
+  else
+    {
+      if (!VALID_SINGLE_DISPTABLE_INSTANTIATOR_P (instantiator))
+	{
+	lose:
+	  dead_wrong_type_argument (display_table_specifier_methods->predicate_symbol,
+				    instantiator);
+	}
+    }
 }
 
 DEFUN ("display-table-specifier-p", Fdisplay_table_specifier_p, 1, 1, 0, /*
--- a/src/strftime.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/strftime.c	Mon Aug 13 11:08:24 2007 +0200
@@ -234,7 +234,7 @@
 
 #if !defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME)
 char *
-zone_name (struct tm *tp)
+zone_name (CONST struct tm *tp)
 {
   char *timezone ();
   struct timeval tv;
--- a/src/symsinit.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/symsinit.h	Mon Aug 13 11:08:24 2007 +0200
@@ -93,6 +93,7 @@
 void syms_of_general (void);
 void syms_of_glyphs_x (void);
 void syms_of_glyphs_eimage (void);
+void syms_of_glyphs_widget (void);
 void syms_of_glyphs_mswindows (void);
 void syms_of_glyphs (void);
 void syms_of_gui_x (void);
@@ -192,6 +193,7 @@
 
 void image_instantiator_format_create (void);
 void image_instantiator_format_create_glyphs_eimage (void);
+void image_instantiator_format_create_glyphs_widget (void);
 void image_instantiator_format_create_glyphs_x (void);
 void image_instantiator_format_create_glyphs_mswindows (void);
 
@@ -260,6 +262,7 @@
 void vars_of_frame (void);
 void vars_of_glyphs_x (void);
 void vars_of_glyphs_eimage (void);
+void vars_of_glyphs_widget (void);
 void vars_of_glyphs_mswindows (void);
 void vars_of_glyphs (void);
 void vars_of_gui_x (void);
--- a/src/toolbar-x.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/toolbar-x.c	Mon Aug 13 11:08:24 2007 +0200
@@ -504,9 +504,9 @@
       Lisp_Object frame;
 
       XSETFRAME (frame, f);
-      DEVMETH (d, clear_region, (frame,
-				 DEFAULT_INDEX, FRAME_PIXWIDTH (f) - 1, y, 1,
-				 bar_height));
+      redisplay_clear_region (frame,
+			      DEFAULT_INDEX, FRAME_PIXWIDTH (f) - 1, y, 1,
+			      bar_height);
     }
 
   SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 1);
@@ -542,7 +542,7 @@
 
   SET_TOOLBAR_WAS_VISIBLE_FLAG (f, pos, 0);
 
-  DEVMETH (d, clear_region, (frame, DEFAULT_INDEX, x, y, width, height));
+  redisplay_clear_region (frame, DEFAULT_INDEX, x, y, width, height);
   XFlush (DEVICE_X_DISPLAY (d));
 }
 
--- a/src/window.c	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/window.c	Mon Aug 13 11:08:24 2007 +0200
@@ -36,6 +36,8 @@
 #include "glyphs.h"
 #include "redisplay.h"
 #include "window.h"
+#include "elhash.h"
+#include "commands.h"
 
 Lisp_Object Qwindowp, Qwindow_live_p, Qwindow_configurationp;
 Lisp_Object Qscroll_up, Qscroll_down, Qdisplay_buffer;
@@ -161,6 +163,8 @@
   MARK_DISP_VARIABLE (last_facechange);
   markobj (window->line_cache_last_updated);
   markobj (window->redisplay_end_trigger);
+  markobj (window->subwindow_instance_cache);
+
   mark_face_cachels (window->face_cachels, markobj);
   mark_glyph_cachels (window->glyph_cachels, markobj);
 
@@ -273,6 +277,9 @@
   p->face_cachels     = Dynarr_new (face_cachel);
   p->glyph_cachels    = Dynarr_new (glyph_cachel);
   p->line_start_cache = Dynarr_new (line_start_cache);
+  p->subwindow_instance_cache = make_lisp_hash_table (10,
+						      HASH_TABLE_KEY_WEAK,
+						      HASH_TABLE_EQ);
   p->line_cache_last_updated = Qzero;
   INIT_DISP_VARIABLE (last_point_x, 0);
   INIT_DISP_VARIABLE (last_point_y, 0);
--- a/src/window.h	Mon Aug 13 11:07:40 2007 +0200
+++ b/src/window.h	Mon Aug 13 11:08:24 2007 +0200
@@ -145,8 +145,14 @@
   face_cachel_dynarr *face_cachels;
   /* glyph cache elements correct for this window and its current buffer */
   glyph_cachel_dynarr *glyph_cachels;
-
-
+  /* we cannot have a per-device cache of widgets / subwindows because
+     each visible instance needs to be a separate instance. The lowest
+     level of granularity we can get easily is the window that the
+     subwindow is in. This will fail if we attach the same subwindow
+     twice to a buffer. However, we are quite unlikely to do this,
+     especially with buttons which will need individual callbacks. The
+     proper solution is probably not worth the effort. */
+  Lisp_Object subwindow_instance_cache;
   /* List of starting positions for display lines.  Only valid if
      buffer has not changed. */
   line_start_cache_dynarr *line_start_cache;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/automated/byte-compiler-tests.el	Mon Aug 13 11:08:24 2007 +0200
@@ -0,0 +1,93 @@
+;; Copyright (C) 1998 Free Software Foundation, Inc.
+
+;; Author: Martin Buchholz <martin@xemacs.org>
+;; Maintainer: Martin Buchholz <martin@xemacs.org>
+;; Created: 1998
+;; Keywords: tests
+
+;; This file is part of XEmacs.
+
+;; XEmacs is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with XEmacs; see the file COPYING.  If not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+;;; Synched up with: not in FSF Emacs.
+
+;;; Commentary:
+
+;;; Test byte-compiler functionality
+;;; See test-harness.el
+
+(condition-case err
+    (require 'test-harness)
+  (file-error
+   (when (and (boundp 'load-file-name) (stringp load-file-name))
+     (push (file-name-directory load-file-name) load-path)
+     (require 'test-harness))))
+
+(require 'bytecomp)
+
+;; test constant symbol warnings
+(defmacro check-byte-compiler-message (message-regexp &rest body)
+  `(Check-Message ,message-regexp (byte-compile '(lambda () ,@body))))
+
+(check-byte-compiler-message "Attempt to set non-symbol" (setq 1 1))
+(check-byte-compiler-message "Attempt to set constant symbol" (setq t 1))
+(check-byte-compiler-message "Attempt to set constant symbol" (setq nil 1))
+(check-byte-compiler-message "^$" (defconst :foo 1))
+
+(check-byte-compiler-message "Attempt to let-bind non-symbol" (let ((1 'x)) 1))
+(check-byte-compiler-message "Attempt to let-bind constant symbol" (let ((t 'x)) (foo)))
+(check-byte-compiler-message "Attempt to let-bind constant symbol" (let ((nil 'x)) (foo)))
+(check-byte-compiler-message "Attempt to let-bind constant symbol" (let ((:foo 'x)) (foo)))
+
+
+(check-byte-compiler-message "bound but not referenced" (let ((foo 'x)) 1))
+(Assert (not (boundp 'free-variable)))
+(Assert (boundp 'byte-compile-warnings))
+(check-byte-compiler-message "assignment to free variable" (setq free-variable 1))
+(check-byte-compiler-message "reference to free variable" (car free-variable))
+(check-byte-compiler-message "called with 2 args, but requires 1" (car 'x 'y))
+
+(check-byte-compiler-message "^$" (setq :foo 1))
+(let ((fun '(lambda () (setq :foo 1))))
+  (fset 'test-byte-compiler-fun fun))
+(Check-Error setting-constant (test-byte-compiler-fun))
+(byte-compile 'test-byte-compiler-fun)
+(Check-Error setting-constant (test-byte-compiler-fun))
+
+(eval-when-compile (defvar setq-test-foo nil) (defvar setq-test-bar nil))
+(progn
+  (check-byte-compiler-message "set called with 1 arg, but requires 2" (setq setq-test-foo))
+  (check-byte-compiler-message "set called with 1 arg, but requires 2" (setq setq-test-foo 1 setq-test-bar))
+  (check-byte-compiler-message "set-default called with 1 arg, but requires 2" (setq-default setq-test-foo))
+  (check-byte-compiler-message "set-default called with 1 arg, but requires 2" (setq-default setq-test-foo 1 setq-test-bar))
+  )
+
+;;-----------------------------------------------------
+;; let, let*
+;;-----------------------------------------------------
+
+;; Test interpreted and compiled lisp separately here
+(check-byte-compiler-message "malformed let binding" (let  ((x 1 2)) 3))
+(check-byte-compiler-message "malformed let binding" (let* ((x 1 2)) 3))
+
+(Check-Error-Message
+ error "`let' bindings can have only one value-form"
+ (eval '(let ((x 1 2)) 3)))
+
+(Check-Error-Message
+ error "`let' bindings can have only one value-form"
+ (eval '(let* ((x 1 2)) 3)))
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/automated/database-tests.el	Mon Aug 13 11:08:24 2007 +0200
@@ -0,0 +1,62 @@
+;; Copyright (C) 1998 Free Software Foundation, Inc.
+
+;; Author: Martin Buchholz <martin@xemacs.org>
+;; Maintainer: Martin Buchholz <martin@xemacs.org>
+;; Created: 1998
+;; Keywords: tests, database
+
+;; This file is part of XEmacs.
+
+;; XEmacs is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with XEmacs; see the file COPYING.  If not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+;;; Synched up with: not in FSF Emacs.
+
+;;; Commentary:
+
+;;; Test database functionality
+;;; See test-harness.el
+
+(condition-case err
+    (require 'test-harness)
+  (file-error
+   (when (and (boundp 'load-file-name) (stringp load-file-name))
+     (push (file-name-directory load-file-name) load-path)
+     (require 'test-harness))))
+
+(flet ((test-database
+	(db)
+	(Assert (databasep db))
+	(put-database "key1" "val1" db)
+	(Assert (equal "val1" (get-database "key1" db)))
+	(remove-database "key1" db)
+	(Assert (equal nil (get-database "key1" db)))
+	(close-database db)
+	(Assert (not (database-live-p db)))
+	(Assert (databasep db))
+	(let ((filename (database-file-name db)))
+	  (dolist (fn (list filename (concat filename ".db")))
+	    (condition-case nil (delete-file fn) (file-error nil))))))
+
+  (let ((filename (expand-file-name "test-harness" (temp-directory))))
+
+    (dolist (fn (list filename (concat filename ".db")))
+      (condition-case nil (delete-file fn) (file-error nil)))
+
+    (dolist (db-type `(dbm berkeley-db))
+      (when (featurep db-type)
+	(princ "\n")
+	(test-database (open-database filename db-type))))
+    ))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/automated/hash-table-tests.el	Mon Aug 13 11:08:24 2007 +0200
@@ -0,0 +1,269 @@
+;; Copyright (C) 1998 Free Software Foundation, Inc.
+
+;; Author: Martin Buchholz <martin@xemacs.org>
+;; Maintainer: Martin Buchholz <martin@xemacs.org>
+;; Created: 1998
+;; Keywords: tests, database
+
+;; This file is part of XEmacs.
+
+;; XEmacs is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with XEmacs; see the file COPYING.  If not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+;;; Synched up with: not in FSF Emacs.
+
+;;; Commentary:
+
+;;; Test database functionality
+;;; See test-harness.el
+
+(condition-case err
+    (require 'test-harness)
+  (file-error
+   (when (and (boundp 'load-file-name) (stringp load-file-name))
+     (push (file-name-directory load-file-name) load-path)
+     (require 'test-harness))))
+
+;; Test all combinations of make-hash-table keywords
+(dolist (type `(non-weak weak key-weak value-weak))
+  (dolist (test `(eq eql equal))
+    (dolist (size `(0 1 100))
+      (dolist (rehash-size `(1.1 9.9))
+	(dolist (rehash-threshold `(0.2 .9))
+	  (dolist (data `(() (1 2) (1 2 3 4)))
+	    (let ((ht (make-hash-table :test test
+				       :type type
+				       :size size
+				       :rehash-size rehash-size
+				       :rehash-threshold rehash-threshold)))
+	      (Assert (equal ht (car (let ((print-readably t))
+				       (read-from-string (prin1-to-string ht))))))
+	      (Assert (eq test (hash-table-test ht)))
+	      (Assert (eq type (hash-table-type ht)))
+	      (Assert (<= size (hash-table-size ht)))
+	      (Assert (eql rehash-size (hash-table-rehash-size ht)))
+	      (Assert (eql rehash-threshold (hash-table-rehash-threshold ht))))))))))
+
+(loop for (fun type) in `((make-hashtable non-weak)
+			  (make-weak-hashtable weak)
+			  (make-key-weak-hashtable key-weak)
+			  (make-value-weak-hashtable value-weak))
+  do (Assert (eq type (hash-table-type (funcall fun 10)))))
+
+(let ((ht (make-hash-table :size 20 :rehash-threshold .75 :test 'eq))
+      (size 80))
+  (Assert (hashtablep ht))
+  (Assert (hash-table-p ht))
+  (Assert (eq 'eq (hash-table-test ht)))
+  (Assert (eq 'non-weak (hash-table-type ht)))
+  (Assert (eq 'non-weak (hashtable-type ht)))
+  (dotimes (j size)
+    (puthash j (- j) ht)
+    (Assert (eq (gethash j ht) (- j)))
+    (Assert (= (hash-table-count ht) (1+ j)))
+    (Assert (= (hashtable-fullness ht) (hash-table-count ht)))
+    (puthash j j ht)
+    (Assert (eq (gethash j ht 'foo) j))
+    (Assert (= (hash-table-count ht) (1+ j)))
+    (setf (gethash j ht) (- j))
+    (Assert (eq (gethash j ht) (- j)))
+    (Assert (= (hash-table-count ht) (1+ j))))
+
+  (clrhash ht)
+  (Assert (= 0 (hash-table-count ht)))
+
+  (dotimes (j size)
+    (puthash j (- j) ht)
+    (Assert (eq (gethash j ht) (- j)))
+    (Assert (= (hash-table-count ht) (1+ j))))
+
+  (let ((k-sum 0) (v-sum 0))
+    (maphash #'(lambda (k v) (incf k-sum k) (incf v-sum v)) ht)
+    (print k-sum)
+    (print v-sum)
+    (Assert (= k-sum (/ (* size (- size 1)) 2)))
+    (Assert (= v-sum (- k-sum))))
+
+  (let ((count size))
+    (dotimes (j size)
+      (remhash j ht)
+      (Assert (eq (gethash j ht) nil))
+      (Assert (eq (gethash j ht 'foo) 'foo))
+      (Assert (= (hash-table-count ht) (decf count))))))
+
+(let ((ht (make-hash-table :size 30 :rehash-threshold .25 :test 'equal))
+      (size 70))
+  (Assert (hashtablep ht))
+  (Assert (hash-table-p ht))
+  (Assert (>= (hash-table-size ht) (/ 30 .25)))
+  (Assert (eql .25 (hash-table-rehash-threshold ht)))
+  (Assert (eq 'equal (hash-table-test ht)))
+  (Assert (eq (hash-table-test ht) (hashtable-test-function ht)))
+  (Assert (eq 'non-weak (hash-table-type ht)))
+  (dotimes (j size)
+    (puthash (int-to-string j) (- j) ht)
+    (Assert (eq (gethash (int-to-string j) ht) (- j)))
+    (Assert (= (hash-table-count ht) (1+ j)))
+    (puthash (int-to-string j) j ht)
+    (Assert (eq (gethash (int-to-string j) ht 'foo) j))
+    (Assert (= (hash-table-count ht) (1+ j))))
+
+  (clrhash ht)
+  (Assert (= 0 (hash-table-count ht)))
+  (Assert (equal ht (copy-hash-table ht)))
+
+  (dotimes (j size)
+    (setf (gethash (int-to-string j) ht) (- j))
+    (Assert (eq (gethash (int-to-string j) ht) (- j)))
+    (Assert (= (hash-table-count ht) (1+ j))))
+
+  (let ((count size))
+    (dotimes (j size)
+      (remhash (int-to-string j) ht)
+      (Assert (eq (gethash (int-to-string j) ht) nil))
+      (Assert (eq (gethash (int-to-string j) ht 'foo) 'foo))
+      (Assert (= (hash-table-count ht) (decf count))))))
+
+(let ((iterations 5) (one 1.0) (two 2.0))
+  (flet ((check-copy
+	  (ht)
+	  (let ((copy-of-ht (copy-hash-table ht)))
+	    (Assert (equal ht copy-of-ht))
+	    (Assert (not (eq ht copy-of-ht)))
+	    (Assert (eq  (hash-table-count ht) (hash-table-count copy-of-ht)))
+	    (Assert (eq  (hash-table-type  ht) (hash-table-type  copy-of-ht)))
+	    (Assert (eq  (hash-table-size  ht) (hash-table-size  copy-of-ht)))
+	    (Assert (eql (hash-table-rehash-size ht) (hash-table-rehash-size copy-of-ht)))
+	    (Assert (eql (hash-table-rehash-threshold ht) (hash-table-rehash-threshold copy-of-ht))))))
+
+  (let ((ht (make-hash-table :size 100 :rehash-threshold .6 :test 'eq)))
+    (dotimes (j iterations)
+      (puthash (+ one 0.0) t ht)
+      (puthash (+ two 0.0) t ht)
+      (puthash (concat "1" "2") t ht)
+      (puthash (concat "3" "4") t ht))
+    (Assert (eq (hashtable-test-function ht) 'eq))
+    (Assert (eq (hash-table-test ht) 'eq))
+    (Assert (= (* iterations 4) (hash-table-count ht)))
+    (Assert (eq nil (gethash 1.0 ht)))
+    (Assert (eq nil (gethash "12" ht)))
+    (check-copy ht)
+    )
+
+  (let ((ht (make-hash-table :size 100 :rehash-threshold .6 :test 'eql)))
+    (dotimes (j iterations)
+      (puthash (+ one 0.0) t ht)
+      (puthash (+ two 0.0) t ht)
+      (puthash (concat "1" "2") t ht)
+      (puthash (concat "3" "4") t ht))
+    (Assert (eq (hashtable-test-function ht) 'eql))
+    (Assert (eq (hash-table-test ht) 'eql))
+    (Assert (= (+ 2 (* 2 iterations)) (hash-table-count ht)))
+    (Assert (eq t (gethash 1.0 ht)))
+    (Assert (eq nil (gethash "12" ht)))
+    (check-copy ht)
+    )
+
+  (let ((ht (make-hash-table :size 100 :rehash-threshold .6 :test 'equal)))
+    (dotimes (j iterations)
+      (puthash (+ one 0.0) t ht)
+      (puthash (+ two 0.0) t ht)
+      (puthash (concat "1" "2") t ht)
+      (puthash (concat "3" "4") t ht))
+    (Assert (eq (hashtable-test-function ht) 'equal))
+    (Assert (eq (hash-table-test ht) 'equal))
+    (Assert (= 4 (hash-table-count ht)))
+    (Assert (eq t (gethash 1.0 ht)))
+    (Assert (eq t (gethash "12" ht)))
+    (check-copy ht)
+    )
+
+  ))
+
+;; Test that weak hash-tables are properly handled
+(loop for (type expected-count expected-k-sum expected-v-sum) in
+  `((non-weak 6 38 25)
+    (weak 3 6 9)
+    (key-weak 4 38 9)
+    (value-weak 4 6 25))
+  do
+  (let* ((ht (make-hash-table :type type))
+       (my-obj (cons ht ht)))
+  (garbage-collect)
+  (puthash my-obj 1 ht)
+  (puthash 2 my-obj ht)
+  (puthash 4 8 ht)
+  (puthash (cons ht ht) 16 ht)
+  (puthash 32 (cons ht ht) ht)
+  (puthash (cons ht ht) (cons ht ht) ht)
+  (let ((k-sum 0) (v-sum 0))
+    (maphash #'(lambda (k v)
+		 (when (integerp k) (incf k-sum k))
+		 (when (integerp v) (incf v-sum v)))
+	     ht)
+    (Assert (eq 38 k-sum))
+    (Assert (eq 25 v-sum)))
+  (Assert (eq 6 (hash-table-count ht)))
+  (garbage-collect)
+  (Assert (eq expected-count (hash-table-count ht)))
+  (let ((k-sum 0) (v-sum 0))
+    (maphash #'(lambda (k v)
+		 (when (integerp k) (incf k-sum k))
+		 (when (integerp v) (incf v-sum v)))
+	     ht)
+    (Assert (eq expected-k-sum k-sum))
+    (Assert (eq expected-v-sum v-sum)))))
+
+;;; Test the ability to puthash and remhash the current elt of a maphash
+(let ((ht (make-hash-table :test 'eql)))
+  (dotimes (j 100) (setf (gethash j ht) (- j)))
+  (maphash #'(lambda (k v)
+	       (if (oddp k) (remhash k ht) (puthash k (- v) ht)))
+	   ht)
+  (let ((k-sum 0) (v-sum 0))
+    (maphash #'(lambda (k v) (incf k-sum k) (incf v-sum v)) ht)
+    (Assert (= (* 50 49) k-sum))
+    (Assert (= v-sum k-sum))))
+
+;;; Test reading and printing of hash-table objects
+(let ((h1 #s(hashtable  type weak rehash-size 3.0 rehash-threshold .2 test eq data (1 2 3 4)))
+      (h2 #s(hash-table type weak rehash-size 3.0 rehash-threshold .2 test eq data (1 2 3 4)))
+      (h3 (make-hash-table :type 'weak :rehash-size 3.0 :rehash-threshold .2 :test 'eq)))
+  (Assert (equal h1 h2))
+  (Assert (not (equal h1 h3)))
+  (puthash 1 2 h3)
+  (puthash 3 4 h3)
+  (Assert (equal h1 h3)))
+
+;;; Testing equality of hash tables
+(Assert (equal (make-hash-table :test 'eql :size 300 :rehash-threshold .9 :rehash-size 3.0)
+	       (make-hash-table :test 'eql)))
+(Assert (not (equal (make-hash-table :test 'eq)
+		    (make-hash-table :test 'equal))))
+(let ((h1 (make-hash-table))
+      (h2 (make-hash-table)))
+  (Assert (equal h1 h2))
+  (Assert (not (eq h1 h2)))
+  (puthash 1 2 h1)
+  (Assert (not (equal h1 h2)))
+  (puthash 1 2 h2)
+  (Assert (equal h1 h2))
+  (puthash 1 3 h2)
+  (Assert (not (equal h1 h2)))
+  (clrhash h1)
+  (Assert (not (equal h1 h2)))
+  (clrhash h2)
+  (Assert (equal h1 h2))
+  )
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/automated/lisp-tests.el	Mon Aug 13 11:08:24 2007 +0200
@@ -0,0 +1,778 @@
+;; Copyright (C) 1998 Free Software Foundation, Inc.
+
+;; Author: Martin Buchholz <martin@xemacs.org>
+;; Maintainer: Martin Buchholz <martin@xemacs.org>
+;; Created: 1998
+;; Keywords: tests
+
+;; This file is part of XEmacs.
+
+;; XEmacs is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with XEmacs; see the file COPYING.  If not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+;;; Synched up with: not in FSF Emacs.
+
+;;; Commentary:
+
+;;; Test basic Lisp engine functionality
+;;; See test-harness.el for instructions on how to run these tests.
+
+(eval-when-compile
+  (condition-case nil
+      (require 'test-harness)
+    (file-error
+     (push "." load-path)
+     (when (and (boundp 'load-file-name) (stringp load-file-name))
+       (push (file-name-directory load-file-name) load-path))
+     (require 'test-harness))))
+
+(Check-Error wrong-number-of-arguments (setq setq-test-foo))
+(Check-Error wrong-number-of-arguments (setq setq-test-foo 1 setq-test-bar))
+(Check-Error wrong-number-of-arguments (setq-default setq-test-foo))
+(Check-Error wrong-number-of-arguments (setq-default setq-test-foo 1 setq-test-bar))
+(Assert (eq (setq)         nil))
+(Assert (eq (setq-default) nil))
+(Assert (eq (setq         setq-test-foo 42) 42))
+(Assert (eq (setq-default setq-test-foo 42) 42))
+(Assert (eq (setq         setq-test-foo 42 setq-test-bar 99) 99))
+(Assert (eq (setq-default setq-test-foo 42 setq-test-bar 99) 99))
+
+(macrolet ((test-setq (expected-result &rest body)
+		      `(progn
+			 (defun test-setq-fun () ,@body)
+			 (Assert (eq ,expected-result (test-setq-fun)))
+			 (byte-compile 'test-setq-fun)
+			 (Assert (eq ,expected-result (test-setq-fun))))))
+  (test-setq nil (setq))
+  (test-setq nil (setq-default))
+  (test-setq 42  (setq         test-setq-var 42))
+  (test-setq 42  (setq-default test-setq-var 42))
+  (test-setq 42  (setq         test-setq-bar 99 test-setq-var 42))
+  (test-setq 42  (setq-default test-setq-bar 99 test-setq-var 42))
+  )
+
+(let ((my-vector [1 2 3 4])
+      (my-bit-vector (bit-vector 1 0 1 0))
+      (my-string "1234")
+      (my-list '(1 2 3 4)))
+
+  ;;(Assert (fooooo)) ;; Generate Other failure
+  ;;(Assert (eq 1 2)) ;; Generate Assertion failure
+
+  (dolist (sequence (list my-vector my-bit-vector my-string my-list))
+    (Assert (sequencep sequence))
+    (Assert (eq 4 (length sequence))))
+
+  (dolist (array (list my-vector my-bit-vector my-string))
+    (Assert (arrayp array)))
+
+  (Assert (eq (elt my-vector 0) 1))
+  (Assert (eq (elt my-bit-vector 0) 1))
+  (Assert (eq (elt my-string 0) ?1))
+  (Assert (eq (elt my-list 0) 1))
+
+  (fillarray my-vector 5)
+  (fillarray my-bit-vector 1)
+  (fillarray my-string ?5)
+
+  (dolist (array (list my-vector my-bit-vector))
+    (Assert (eq 4 (length array))))
+
+  (Assert (eq (elt my-vector 0) 5))
+  (Assert (eq (elt my-bit-vector 0) 1))
+  (Assert (eq (elt my-string 0) ?5))
+
+  (Assert (eq (elt my-vector 3) 5))
+  (Assert (eq (elt my-bit-vector 3) 1))
+  (Assert (eq (elt my-string 3) ?5))
+
+  (fillarray my-bit-vector 0)
+  (Assert (eq 4 (length my-bit-vector)))
+  (Assert (eq (elt my-bit-vector 2) 0))
+  )
+
+(defun make-circular-list (length)
+  "Create evil emacs-crashing circular list of length LENGTH"
+  (let ((circular-list
+	 (make-list
+	  length
+	  'you-are-trapped-in-a-twisty-maze-of-cons-cells-all-alike)))
+    (setcdr (last circular-list) circular-list)
+    circular-list))
+
+;;-----------------------------------------------------
+;; Test `nconc'
+;;-----------------------------------------------------
+(defun make-list-012 () (list 0 1 2))
+
+(Check-Error wrong-type-argument (nconc 'foo nil))
+
+(dolist (length `(1 2 3 4 1000 2000))
+  (Check-Error circular-list (nconc (make-circular-list length) 'foo))
+  (Check-Error circular-list (nconc '(1 . 2) (make-circular-list length) 'foo))
+  (Check-Error circular-list (nconc '(1 . 2) '(3 . 4) (make-circular-list length) 'foo)))
+
+(Assert (eq (nconc) nil))
+(Assert (eq (nconc nil) nil))
+(Assert (eq (nconc nil nil) nil))
+(Assert (eq (nconc nil nil nil) nil))
+
+(let ((x (make-list-012))) (Assert (eq (nconc nil x) x)))
+(let ((x (make-list-012))) (Assert (eq (nconc x nil) x)))
+(let ((x (make-list-012))) (Assert (eq (nconc nil x nil) x)))
+(let ((x (make-list-012))) (Assert (eq (nconc x) x)))
+(let ((x (make-list-012))) (Assert (eq (nconc x (make-circular-list 3)) x)))
+
+(Assert (equal (nconc '(1 . 2) '(3 . 4) '(5 . 6)) '(1 3 5 . 6)))
+
+(let ((y (nconc (make-list-012) nil (list 3 4 5) nil)))
+  (Assert (eq (length y) 6))
+  (Assert (eq (nth 3 y) 3)))
+
+;;-----------------------------------------------------
+;; Test `last'
+;;-----------------------------------------------------
+(Check-Error wrong-type-argument (last 'foo))
+(Check-Error wrong-number-of-arguments (last))
+(Check-Error wrong-number-of-arguments (last '(1 2) 1 1))
+(Check-Error circular-list (last (make-circular-list 1)))
+(Check-Error circular-list (last (make-circular-list 2000)))
+(let ((x (list 0 1 2 3)))
+  (Assert (eq (last nil) nil))
+  (Assert (eq (last x 0) nil))
+  (Assert (eq (last x  ) (cdddr x)))
+  (Assert (eq (last x 1) (cdddr x)))
+  (Assert (eq (last x 2) (cddr x)))
+  (Assert (eq (last x 3) (cdr x)))
+  (Assert (eq (last x 4) x))
+  (Assert (eq (last x 9) x))
+  (Assert (eq (last `(1 . 2) 0) 2))
+  )
+
+;;-----------------------------------------------------
+;; Test `butlast' and `nbutlast'
+;;-----------------------------------------------------
+(Check-Error wrong-type-argument (butlast  'foo))
+(Check-Error wrong-type-argument (nbutlast 'foo))
+(Check-Error wrong-number-of-arguments (butlast))
+(Check-Error wrong-number-of-arguments (nbutlast))
+(Check-Error wrong-number-of-arguments (butlast  '(1 2) 1 1))
+(Check-Error wrong-number-of-arguments (nbutlast '(1 2) 1 1))
+(Check-Error circular-list (butlast  (make-circular-list 1)))
+(Check-Error circular-list (nbutlast (make-circular-list 1)))
+(Check-Error circular-list (butlast  (make-circular-list 2000)))
+(Check-Error circular-list (nbutlast (make-circular-list 2000)))
+
+(let* ((x (list 0 1 2 3))
+       (y (butlast x))
+       (z (nbutlast x)))
+  (Assert (eq z x))
+  (Assert (not (eq y x)))
+  (Assert (equal y '(0 1 2)))
+  (Assert (equal z y)))
+
+(let* ((x (list 0 1 2 3 4))
+       (y (butlast x 2))
+       (z (nbutlast x 2)))
+  (Assert (eq z x))
+  (Assert (not (eq y x)))
+  (Assert (equal y '(0 1 2)))
+  (Assert (equal z y)))
+
+(let* ((x (list 0 1 2 3))
+       (y (butlast x 0))
+       (z (nbutlast x 0)))
+  (Assert (eq z x))
+  (Assert (not (eq y x)))
+  (Assert (equal y '(0 1 2 3)))
+  (Assert (equal z y)))
+
+(Assert (eq (butlast  '(x)) nil))
+(Assert (eq (nbutlast '(x)) nil))
+(Assert (eq (butlast  '()) nil))
+(Assert (eq (nbutlast '()) nil))
+
+;;-----------------------------------------------------
+;; Test `copy-list'
+;;-----------------------------------------------------
+(Check-Error wrong-type-argument (copy-list 'foo))
+(Check-Error wrong-number-of-arguments (copy-list))
+(Check-Error wrong-number-of-arguments (copy-list '(1 2) 1))
+(Check-Error circular-list (copy-list (make-circular-list 1)))
+(Check-Error circular-list (copy-list (make-circular-list 2000)))
+(Assert (eq '() (copy-list '())))
+(dolist (x `((1) (1 2) (1 2 3) (1 2 . 3)))
+  (let ((y (copy-list x)))
+    (Assert (and (equal x y) (not (eq x y))))))
+
+;;-----------------------------------------------------
+;; Arithmetic operations
+;;-----------------------------------------------------
+
+;; Test `+'
+(Assert (eq (+ 1 1) 2))
+(Assert (= (+ 1.0 1.0) 2.0))
+(Assert (= (+ 1.0 3.0 0.0) 4.0))
+(Assert (= (+ 1 1.0) 2.0))
+(Assert (= (+ 1.0 1) 2.0))
+(Assert (= (+ 1.0 1 1) 3.0))
+(Assert (= (+ 1 1 1.0) 3.0))
+
+;; Test `-'
+(Check-Error wrong-number-of-arguments (-))
+(Assert (eq (- 0) 0))
+(Assert (eq (- 1) -1))
+(dolist (one `(1 1.0 ?\1 ,(Int-to-Marker 1)))
+  (Assert (= (+ 1 one) 2))
+  (Assert (= (+ one) 1))
+  (Assert (= (+ one) one))
+  (Assert (= (- one) -1))
+  (Assert (= (- one one) 0))
+  (Assert (= (- one one one) -1))
+  (Assert (= (+ one 1) 2))
+  (dolist (zero `(0 0.0 ?\0))
+    (Assert (= (+ 1 zero) 1))
+    (Assert (= (+ zero 1) 1))
+    (Assert (= (- zero) zero))
+    (Assert (= (- zero) 0))
+    (Assert (= (- zero zero) 0))
+    (Assert (= (- zero one one) -2))))
+
+(Assert (= (- 1.5 1) .5))
+(Assert (= (- 1 1.5) (- .5)))
+
+;; Test `/'
+
+;; Test division by zero errors
+(dolist (zero `(0 0.0 ?\0))
+  (Check-Error arith-error (/ zero))
+  (dolist (n1 `(42 42.0 ?\042 ,(Int-to-Marker 42)))
+    (Check-Error arith-error (/ n1 zero))
+    (dolist (n2 `(3 3.0 ?\03 ,(Int-to-Marker 3)))
+      (Check-Error arith-error (/ n1 n2 zero)))))
+
+;; Other tests for `/'
+(Check-Error wrong-number-of-arguments (/))
+(let (x)
+  (Assert (= (/ (setq x 2))   0))
+  (Assert (= (/ (setq x 2.0)) 0.5)))
+
+(dolist (six `(6 6.0 ?\06))
+  (dolist (two `(2 2.0 ?\02))
+    (dolist (three `(3 3.0 ?\03))
+      (Assert (= (/ six two) three)))))
+
+(dolist (three `(3 3.0 ?\03))
+  (Assert (= (/ three 2.0) 1.5)))
+(dolist (two `(2 2.0 ?\02))
+  (Assert (= (/ 3.0 two) 1.5)))
+
+;; Test `*'
+(Assert (= 1 (*)))
+
+(dolist (one `(1 1.0 ?\01 ,(Int-to-Marker 1)))
+  (Assert (= 1 (* one))))
+
+(dolist (two `(2 2.0 ?\02))
+  (Assert (= 2 (* two))))
+
+(dolist (six `(6 6.0 ?\06))
+  (dolist (two `(2 2.0 ?\02))
+    (dolist (three `(3 3.0 ?\03))
+      (Assert (= (* three two) six)))))
+
+(dolist (three `(3 3.0 ?\03))
+  (dolist (two `(2 2.0 ?\02))
+    (Assert (= (* 1.5 two) three))
+    (dolist (five `(5 5.0 ?\05))
+      (Assert (= 30 (* five two three))))))
+
+;; Test `+'
+(Assert (= 0 (+)))
+
+(dolist (one `(1 1.0 ?\01 ,(Int-to-Marker 1)))
+  (Assert (= 1 (+ one))))
+
+(dolist (two `(2 2.0 ?\02))
+  (Assert (= 2 (+ two))))
+
+(dolist (five `(5 5.0 ?\05))
+  (dolist (two `(2 2.0 ?\02))
+    (dolist (three `(3 3.0 ?\03))
+      (Assert (= (+ three two) five))
+      (Assert (= 10 (+ five two three))))))
+
+;; Test `max', `min'
+(dolist (one `(1 1.0 ?\01 ,(Int-to-Marker 1)))
+  (Assert (= one (max one)))
+  (Assert (= one (max one one)))
+  (Assert (= one (max one one one)))
+  (Assert (= one (min one)))
+  (Assert (= one (min one one)))
+  (Assert (= one (min one one one)))
+  (dolist (two `(2 2.0 ?\02 ,(Int-to-Marker 2)))
+    (Assert (= one (min one two)))
+    (Assert (= one (min one two two)))
+    (Assert (= one (min two two one)))
+    (Assert (= two (max one two)))
+    (Assert (= two (max one two two)))
+    (Assert (= two (max two two one)))))
+
+;;-----------------------------------------------------
+;; Logical bit-twiddling operations
+;;-----------------------------------------------------
+(Assert (= (logxor)  0))
+(Assert (= (logior)  0))
+(Assert (= (logand) -1))
+
+(Check-Error wrong-type-argument (logxor 3.0))
+(Check-Error wrong-type-argument (logior 3.0))
+(Check-Error wrong-type-argument (logand 3.0))
+
+(dolist (three `(3 ?\03))
+  (Assert (eq 3 (logand three)))
+  (Assert (eq 3 (logxor three)))
+  (Assert (eq 3 (logior three)))
+  (Assert (eq 3 (logand three three)))
+  (Assert (eq 0 (logxor three three)))
+  (Assert (eq 3 (logior three three))))
+
+(dolist (one `(1 ?\01 ,(Int-to-Marker 1)))
+  (dolist (two `(2 ?\02))
+    (Assert (eq 0 (logand one two)))
+    (Assert (eq 3 (logior one two)))
+    (Assert (eq 3 (logxor one two))))
+  (dolist (three `(3 ?\03))
+    (Assert (eq 1 (logand one three)))
+    (Assert (eq 3 (logior one three)))
+    (Assert (eq 2 (logxor one three)))))
+
+;;-----------------------------------------------------
+;; Test `%', mod
+;;-----------------------------------------------------
+(Check-Error wrong-number-of-arguments (%))
+(Check-Error wrong-number-of-arguments (% 1))
+(Check-Error wrong-number-of-arguments (% 1 2 3))
+
+(Check-Error wrong-number-of-arguments (mod))
+(Check-Error wrong-number-of-arguments (mod 1))
+(Check-Error wrong-number-of-arguments (mod 1 2 3))
+
+(Check-Error wrong-type-argument (% 10.0 2))
+(Check-Error wrong-type-argument (% 10 2.0))
+
+(dotimes (j 30)
+  (let ((x (- (random) (random))))
+    (Assert (eq x (+ (% x 17) (* (/ x 17) 17))))
+    (Assert (eq (- x) (+ (% (- x) 17) (* (/ (- x) 17) 17))))
+    (Assert (eq (% x -17) (- (% (- x) 17))))
+    ))
+
+(macrolet
+    ((division-test (seven)
+    `(progn
+       (Assert (eq (% ,seven      2)  1))
+       (Assert (eq (% ,seven     -2)  1))
+       (Assert (eq (% (- ,seven)  2) -1))
+       (Assert (eq (% (- ,seven) -2) -1))
+
+       (Assert (eq (% ,seven      4)  3))
+       (Assert (eq (% ,seven     -4)  3))
+       (Assert (eq (% (- ,seven)  4) -3))
+       (Assert (eq (% (- ,seven) -4) -3))
+
+       (Assert (eq (%  35 ,seven)     0))
+       (Assert (eq (% -35 ,seven)     0))
+       (Assert (eq (%  35 (- ,seven)) 0))
+       (Assert (eq (% -35 (- ,seven)) 0))
+
+       (Assert (eq (mod ,seven      2)  1))
+       (Assert (eq (mod ,seven     -2) -1))
+       (Assert (eq (mod (- ,seven)  2)  1))
+       (Assert (eq (mod (- ,seven) -2) -1))
+
+       (Assert (eq (mod ,seven      4)  3))
+       (Assert (eq (mod ,seven     -4) -1))
+       (Assert (eq (mod (- ,seven)  4)  1))
+       (Assert (eq (mod (- ,seven) -4) -3))
+
+       (Assert (eq (mod  35 ,seven)     0))
+       (Assert (eq (mod -35 ,seven)     0))
+       (Assert (eq (mod  35 (- ,seven)) 0))
+       (Assert (eq (mod -35 (- ,seven)) 0))
+
+       (Assert (= (mod ,seven      2.0)  1.0))
+       (Assert (= (mod ,seven     -2.0) -1.0))
+       (Assert (= (mod (- ,seven)  2.0)  1.0))
+       (Assert (= (mod (- ,seven) -2.0) -1.0))
+
+       (Assert (= (mod ,seven      4.0)  3.0))
+       (Assert (= (mod ,seven     -4.0) -1.0))
+       (Assert (= (mod (- ,seven)  4.0)  1.0))
+       (Assert (= (mod (- ,seven) -4.0) -3.0))
+
+       (Assert (eq (% 0 ,seven) 0))
+       (Assert (eq (% 0 (- ,seven)) 0))
+
+       (Assert (eq (mod 0 ,seven) 0))
+       (Assert (eq (mod 0 (- ,seven)) 0))
+
+       (Assert (= (mod 0.0 ,seven) 0.0))
+       (Assert (= (mod 0.0 (- ,seven)) 0.0)))))
+
+  (division-test 7)
+  (division-test ?\07)
+  (division-test (Int-to-Marker 7)))
+
+
+
+;;-----------------------------------------------------
+;; Arithmetic comparison operations
+;;-----------------------------------------------------
+(Check-Error wrong-number-of-arguments (=))
+(Check-Error wrong-number-of-arguments (<))
+(Check-Error wrong-number-of-arguments (>))
+(Check-Error wrong-number-of-arguments (<=))
+(Check-Error wrong-number-of-arguments (>=))
+(Check-Error wrong-number-of-arguments (/=))
+
+;; One argument always yields t
+(loop for x in `(1 1.0 ,(Int-to-Marker 1) ?z) do
+  (Assert (eq t (=  x)))
+  (Assert (eq t (<  x)))
+  (Assert (eq t (>  x)))
+  (Assert (eq t (>= x)))
+  (Assert (eq t (<= x)))
+  (Assert (eq t (/= x)))
+  )
+
+;; Type checking
+(Check-Error wrong-type-argument (=  'foo 1))
+(Check-Error wrong-type-argument (<= 'foo 1))
+(Check-Error wrong-type-argument (>= 'foo 1))
+(Check-Error wrong-type-argument (<  'foo 1))
+(Check-Error wrong-type-argument (>  'foo 1))
+(Check-Error wrong-type-argument (/= 'foo 1))
+
+;; Meat
+(dolist (one `(1 1.0 ,(Int-to-Marker 1) ?\01))
+  (dolist (two `(2 2.0 ?\02))
+    (Assert (<  one two))
+    (Assert (<= one two))
+    (Assert (<= two two))
+    (Assert (>  two one))
+    (Assert (>= two one))
+    (Assert (>= two two))
+    (Assert (/= one two))
+    (Assert (not (/= two two)))
+    (Assert (not (< one one)))
+    (Assert (not (> one one)))
+    (Assert (<= one one two two))
+    (Assert (not (< one one two two)))
+    (Assert (>= two two one one))
+    (Assert (not (> two two one one)))
+    (Assert (= one one one))
+    (Assert (not (= one one one two)))
+    (Assert (not (/= one two one)))
+    ))
+
+(dolist (one `(1 1.0 ,(Int-to-Marker 1) ?\01))
+  (dolist (two `(2 2.0 ?\02))
+    (Assert (<  one two))
+    (Assert (<= one two))
+    (Assert (<= two two))
+    (Assert (>  two one))
+    (Assert (>= two one))
+    (Assert (>= two two))
+    (Assert (/= one two))
+    (Assert (not (/= two two)))
+    (Assert (not (< one one)))
+    (Assert (not (> one one)))
+    (Assert (<= one one two two))
+    (Assert (not (< one one two two)))
+    (Assert (>= two two one one))
+    (Assert (not (> two two one one)))
+    (Assert (= one one one))
+    (Assert (not (= one one one two)))
+    (Assert (not (/= one two one)))
+    ))
+
+;; ad-hoc
+(Assert (< 1 2))
+(Assert (< 1 2 3 4 5 6))
+(Assert (not (< 1 1)))
+(Assert (not (< 2 1)))
+
+
+(Assert (not (< 1 1)))
+(Assert (< 1 2 3 4 5 6))
+(Assert (<= 1 2 3 4 5 6))
+(Assert (<= 1 2 3 4 5 6 6))
+(Assert (not (< 1 2 3 4 5 6 6)))
+(Assert (<= 1 1))
+
+(Assert (not (eq (point) (point-marker))))
+(Assert (= 1 (Int-to-Marker 1)))
+(Assert (= (point) (point-marker)))
+
+;;-----------------------------------------------------
+;; testing list-walker functions
+;;-----------------------------------------------------
+(macrolet
+    ((test-fun
+      (fun)
+      `(progn
+	 (Check-Error wrong-number-of-arguments (,fun))
+	 (Check-Error wrong-number-of-arguments (,fun nil))
+	 (Check-Error malformed-list (,fun nil 1))
+	 ,@(loop for n in `(1 2 2000)
+	     collect `(Check-Error circular-list (,fun 1 (make-circular-list ,n))))))
+     (test-funs (&rest funs) `(progn ,@(loop for fun in funs collect `(test-fun ,fun)))))
+
+  (test-funs member old-member
+	     memq   old-memq
+	     assoc  old-assoc
+	     rassoc old-rassoc
+	     rassq  old-rassq
+	     delete old-delete
+	     delq   old-delq
+	     remassoc remassq remrassoc remrassq))
+
+(let ((x '((1 . 2) 3 (4 . 5))))
+  (Assert (eq (assoc  1 x) (car x)))
+  (Assert (eq (assq   1 x) (car x)))
+  (Assert (eq (rassoc 1 x) nil))
+  (Assert (eq (rassq  1 x) nil))
+  (Assert (eq (assoc  2 x) nil))
+  (Assert (eq (assq   2 x) nil))
+  (Assert (eq (rassoc 2 x) (car x)))
+  (Assert (eq (rassq  2 x) (car x)))
+  (Assert (eq (assoc  3 x) nil))
+  (Assert (eq (assq   3 x) nil))
+  (Assert (eq (rassoc 3 x) nil))
+  (Assert (eq (rassq  3 x) nil))
+  (Assert (eq (assoc  4 x) (caddr x)))
+  (Assert (eq (assq   4 x) (caddr x)))
+  (Assert (eq (rassoc 4 x) nil))
+  (Assert (eq (rassq  4 x) nil))
+  (Assert (eq (assoc  5 x) nil))
+  (Assert (eq (assq   5 x) nil))
+  (Assert (eq (rassoc 5 x) (caddr x)))
+  (Assert (eq (rassq  5 x) (caddr x)))
+  (Assert (eq (assoc  6 x) nil))
+  (Assert (eq (assq   6 x) nil))
+  (Assert (eq (rassoc 6 x) nil))
+  (Assert (eq (rassq  6 x) nil)))
+
+(let ((x '(("1" . "2") "3" ("4" . "5"))))
+  (Assert (eq (assoc  "1" x) (car x)))
+  (Assert (eq (assq   "1" x) nil))
+  (Assert (eq (rassoc "1" x) nil))
+  (Assert (eq (rassq  "1" x) nil))
+  (Assert (eq (assoc  "2" x) nil))
+  (Assert (eq (assq   "2" x) nil))
+  (Assert (eq (rassoc "2" x) (car x)))
+  (Assert (eq (rassq  "2" x) nil))
+  (Assert (eq (assoc  "3" x) nil))
+  (Assert (eq (assq   "3" x) nil))
+  (Assert (eq (rassoc "3" x) nil))
+  (Assert (eq (rassq  "3" x) nil))
+  (Assert (eq (assoc  "4" x) (caddr x)))
+  (Assert (eq (assq   "4" x) nil))
+  (Assert (eq (rassoc "4" x) nil))
+  (Assert (eq (rassq  "4" x) nil))
+  (Assert (eq (assoc  "5" x) nil))
+  (Assert (eq (assq   "5" x) nil))
+  (Assert (eq (rassoc "5" x) (caddr x)))
+  (Assert (eq (rassq  "5" x) nil))
+  (Assert (eq (assoc  "6" x) nil))
+  (Assert (eq (assq   "6" x) nil))
+  (Assert (eq (rassoc "6" x) nil))
+  (Assert (eq (rassq  "6" x) nil)))
+
+(flet ((a () (list '(1 . 2) 3 '(4 . 5))))
+  (Assert (let* ((x (a)) (y (remassoc  1 x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
+  (Assert (let* ((x (a)) (y (remassq   1 x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
+  (Assert (let* ((x (a)) (y (remrassoc 1 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassq  1 x))) (and (eq x y) (equal y (a)))))
+
+  (Assert (let* ((x (a)) (y (remassoc  2 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remassq   2 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc 2 x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
+  (Assert (let* ((x (a)) (y (remrassq  2 x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
+
+  (Assert (let* ((x (a)) (y (remassoc  3 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remassq   3 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc 3 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassq  3 x))) (and (eq x y) (equal y (a)))))
+
+  (Assert (let* ((x (a)) (y (remassoc  4 x))) (and (eq x y) (equal y '((1 . 2) 3)))))
+  (Assert (let* ((x (a)) (y (remassq   4 x))) (and (eq x y) (equal y '((1 . 2) 3)))))
+  (Assert (let* ((x (a)) (y (remrassoc 4 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassq  4 x))) (and (eq x y) (equal y (a)))))
+
+  (Assert (let* ((x (a)) (y (remassoc  5 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remassq   5 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc 5 x))) (and (eq x y) (equal y '((1 . 2) 3)))))
+  (Assert (let* ((x (a)) (y (remrassq  5 x))) (and (eq x y) (equal y '((1 . 2) 3)))))
+
+  (Assert (let* ((x (a)) (y (remassoc  6 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remassq   6 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc 6 x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassq  6 x))) (and (eq x y) (equal y (a)))))
+
+  (Assert (let* ((x (a)) (y (delete     3 x))) (and (eq x y) (equal y '((1 . 2) (4 . 5))))))
+  (Assert (let* ((x (a)) (y (delq       3 x))) (and (eq x y) (equal y '((1 . 2) (4 . 5))))))
+  (Assert (let* ((x (a)) (y (old-delete 3 x))) (and (eq x y) (equal y '((1 . 2) (4 . 5))))))
+  (Assert (let* ((x (a)) (y (old-delq   3 x))) (and (eq x y) (equal y '((1 . 2) (4 . 5))))))
+
+  (Assert (let* ((x (a)) (y (delete     '(1 . 2) x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
+  (Assert (let* ((x (a)) (y (delq       '(1 . 2) x))) (and      (eq x y)  (equal y (a)))))
+  (Assert (let* ((x (a)) (y (old-delete '(1 . 2) x))) (and (not (eq x y)) (equal y '(3 (4 . 5))))))
+  (Assert (let* ((x (a)) (y (old-delq   '(1 . 2) x))) (and      (eq x y)  (equal y (a)))))
+  )
+
+
+
+(flet ((a () (list '("1" . "2") "3" '("4" . "5"))))
+  (Assert (let* ((x (a)) (y (remassoc  "1" x))) (and (not (eq x y)) (equal y '("3" ("4" . "5"))))))
+  (Assert (let* ((x (a)) (y (remassq   "1" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc "1" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassq  "1" x))) (and (eq x y) (equal y (a)))))
+
+  (Assert (let* ((x (a)) (y (remassoc  "2" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remassq   "2" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc "2" x))) (and (not (eq x y)) (equal y '("3" ("4" . "5"))))))
+  (Assert (let* ((x (a)) (y (remrassq  "2" x))) (and (eq x y) (equal y (a)))))
+
+  (Assert (let* ((x (a)) (y (remassoc  "3" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remassq   "3" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc "3" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassq  "3" x))) (and (eq x y) (equal y (a)))))
+
+  (Assert (let* ((x (a)) (y (remassoc  "4" x))) (and (eq x y) (equal y '(("1" . "2") "3")))))
+  (Assert (let* ((x (a)) (y (remassq   "4" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc "4" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassq  "4" x))) (and (eq x y) (equal y (a)))))
+
+  (Assert (let* ((x (a)) (y (remassoc  "5" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remassq   "5" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc "5" x))) (and (eq x y) (equal y '(("1" . "2") "3")))))
+  (Assert (let* ((x (a)) (y (remrassq  "5" x))) (and (eq x y) (equal y (a)))))
+
+  (Assert (let* ((x (a)) (y (remassoc  "6" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remassq   "6" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassoc "6" x))) (and (eq x y) (equal y (a)))))
+  (Assert (let* ((x (a)) (y (remrassq  "6" x))) (and (eq x y) (equal y (a))))))
+
+;;-----------------------------------------------------
+;; function-max-args, function-min-args
+;;-----------------------------------------------------
+(defmacro check-function-argcounts (fun min max)
+  `(progn
+     (Assert (eq (function-min-args ,fun) ,min))
+     (Assert (eq (function-max-args ,fun) ,max))))
+
+(check-function-argcounts 'prog1 1 nil)         ; special form
+(check-function-argcounts 'command-execute 1 3)	; normal subr
+(check-function-argcounts 'funcall 1 nil)       ; `MANY' subr
+(check-function-argcounts 'garbage-collect 0 0) ; no args subr
+
+;; Test interpreted and compiled functions
+(loop for (arglist min max) in
+  '(((arg1 arg2 &rest args) 2 nil)
+    ((arg1 arg2 &optional arg3 arg4) 2 4)
+    ((arg1 arg2 &optional arg3 arg4 &rest args) 2 nil)
+    (() 0 0))
+  do
+  (eval
+   `(progn
+      (defun test-fun ,arglist nil)
+      (check-function-argcounts '(lambda ,arglist nil) ,min ,max)
+      (check-function-argcounts (byte-compile '(lambda ,arglist nil)) ,min ,max))))
+
+;;-----------------------------------------------------
+;; Detection of cyclic variable indirection loops
+;;-----------------------------------------------------
+(fset 'test-sym1 'test-sym1)
+(Check-Error cyclic-function-indirection (test-sym1))
+
+(fset 'test-sym1 'test-sym2)
+(fset 'test-sym2 'test-sym1)
+(Check-Error cyclic-function-indirection (test-sym1))
+(fmakunbound 'test-sym1) ; else macroexpand-internal infloops!
+(fmakunbound 'test-sym2)
+
+;;-----------------------------------------------------
+;; Test `type-of'
+;;-----------------------------------------------------
+(Assert (eq (type-of load-path) 'cons))
+(Assert (eq (type-of obarray) 'vector))
+(Assert (eq (type-of 42) 'integer))
+(Assert (eq (type-of ?z) 'character))
+(Assert (eq (type-of "42") 'string))
+(Assert (eq (type-of 'foo) 'symbol))
+(Assert (eq (type-of (selected-device)) 'device))
+
+;;-----------------------------------------------------
+;; Test mapping functions
+;;-----------------------------------------------------
+(Check-Error wrong-type-argument (mapcar #'identity (current-buffer)))
+(Assert (equal (mapcar #'identity load-path) load-path))
+(Assert (equal (mapcar #'identity '(1 2 3)) '(1 2 3)))
+(Assert (equal (mapcar #'identity "123") '(?1 ?2 ?3)))
+(Assert (equal (mapcar #'identity [1 2 3]) '(1 2 3)))
+(Assert (equal (mapcar #'identity #*010) '(0 1 0)))
+
+(let ((z 0) (list (make-list 1000 1)))
+  (mapc (lambda (x) (incf z x)) list)
+  (Assert (eq 1000 z)))
+
+(Check-Error wrong-type-argument (mapvector #'identity (current-buffer)))
+(Assert (equal (mapvector #'identity '(1 2 3)) [1 2 3]))
+(Assert (equal (mapvector #'identity "123") [?1 ?2 ?3]))
+(Assert (equal (mapvector #'identity [1 2 3]) [1 2 3]))
+(Assert (equal (mapvector #'identity #*010) [0 1 0]))
+
+(Check-Error wrong-type-argument (mapconcat #'identity (current-buffer) "foo"))
+(Assert (equal (mapconcat #'identity '("1" "2" "3") "|") "1|2|3"))
+(Assert (equal (mapconcat #'identity ["1" "2" "3"]  "|") "1|2|3"))
+
+;;-----------------------------------------------------
+;; Test vector functions
+;;-----------------------------------------------------
+(Assert (equal [1 2 3] [1 2 3]))
+(Assert (equal [] []))
+(Assert (not (equal [1 2 3] [])))
+(Assert (not (equal [1 2 3] [1 2 4])))
+(Assert (not (equal [0 2 3] [1 2 3])))
+(Assert (not (equal [1 2 3] [1 2 3 4])))
+(Assert (not (equal [1 2 3 4] [1 2 3])))
+(Assert (equal (vector 1 2 3) [1 2 3]))
+(Assert (equal (make-vector 3 1) [1 1 1]))
+
+;;-----------------------------------------------------
+;; Test bit-vector functions
+;;-----------------------------------------------------
+(Assert (equal #*010 #*010))
+(Assert (equal #* #*))
+(Assert (not (equal #*010 #*011)))
+(Assert (not (equal #*010 #*)))
+(Assert (not (equal #*110 #*010)))
+(Assert (not (equal #*010 #*0100)))
+(Assert (not (equal #*0101 #*010)))
+(Assert (equal (bit-vector 0 1 0) #*010))
+(Assert (equal (make-bit-vector 3 1) #*111))
+(Assert (equal (make-bit-vector 3 0) #*000))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/automated/md5-tests.el	Mon Aug 13 11:08:24 2007 +0200
@@ -0,0 +1,96 @@
+;; Copyright (C) 1998 Free Software Foundation, Inc.
+
+;; Author: Hrvoje Niksic <hniksic@srce.hr>
+;; Maintainer: Hrvoje Niksic <hniksic@srce.hr>
+;; Created: 1998
+;; Keywords: tests
+
+;; This file is part of XEmacs.
+
+;; XEmacs is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with XEmacs; see the file COPYING.  If not, write to the Free
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
+
+;;; Synched up with: not in FSF Emacs.
+
+;;; Commentary:
+
+;; Test basic md5 functionality.
+;; See test-harness.el for instructions on how to run these tests.
+
+(eval-when-compile
+  (condition-case nil
+      (require 'test-harness)
+    (file-error
+     (push "." load-path)
+     (when (and (boundp 'load-file-name) (stringp load-file-name))
+       (push (file-name-directory load-file-name) load-path))
+     (require 'test-harness))))
+
+(defconst md5-tests
+  '(
+    ;; Test samples from rfc1321:
+    ("" . "d41d8cd98f00b204e9800998ecf8427e")
+    ("a" . "0cc175b9c0f1b6a831c399e269772661")
+    ("abc" . "900150983cd24fb0d6963f7d28e17f72")
+    ("message digest" . "f96b697d7cb7938d525a2f31aaf161d0")
+    ("abcdefghijklmnopqrstuvwxyz" . "c3fcd3d76192e4007dfb496cca67e13b")
+    ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
+     . "d174ab98d277d9f5a5611c2c9f419d9f")
+    ("12345678901234567890123456789012345678901234567890123456789012345678901234567890"
+     . "57edf4a22be3c955ac49da2e2107b67a")))
+
+;;-----------------------------------------------------
+;; Test `md5' on strings
+;;-----------------------------------------------------
+
+(mapcar (lambda (x)
+	  (Assert (equal (md5 (car x)) (cdr x))))
+	md5-tests)
+
+;;-----------------------------------------------------
+;; Test `md5' on portions of strings
+;;-----------------------------------------------------
+
+(let ((large-string (mapconcat #'car md5-tests "")))
+  (let ((count 0))
+    (mapcar (lambda (x)
+	      (Assert (equal (md5 large-string count (+ count (length (car x))))
+			     (cdr x)))
+	      (incf count (length (car x))))
+	    md5-tests)))
+
+;;-----------------------------------------------------
+;; Test `md5' on buffer
+;;-----------------------------------------------------
+
+(with-temp-buffer
+  (mapcar (lambda (x)
+	    (erase-buffer)
+	    (insert (car x))
+	    (Assert (equal (md5 (current-buffer)) (cdr x))))
+	  md5-tests))
+
+;;-----------------------------------------------------
+;; Test `md5' on portions of buffer
+;;-----------------------------------------------------
+
+(with-temp-buffer
+  (insert (mapconcat #'car md5-tests ""))
+  (let ((point 1))
+    (mapcar (lambda (x)
+	      (Assert (equal (md5 (current-buffer) point (+ point (length (car x))))
+			     (cdr x)))
+	      (incf point (length (car x))))
+	    md5-tests)))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/automated/test-harness.el	Mon Aug 13 11:08:24 2007 +0200
@@ -0,0 +1,367 @@
+;; test-harness.el --- Run Emacs Lisp test suites.
+
+;;; Copyright (C) 1998 Free Software Foundation, Inc.
+
+;; Author: Martin Buchholz
+;; Keywords: testing
+
+;; This file is part of XEmacs.
+
+;; XEmacs is free software; you can redistribute it and/or modify it
+;; under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; XEmacs is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with XEmacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Synched up with: Not in FSF
+
+;;; Commentary:
+
+;;; A test suite harness for testing XEmacs.
+;;; The actual tests are in other files in this directory.
+;;; Basically you just create files of emacs-lisp, and use the
+;;; Assert, Check-Error, and Check-Message functions to create tests.
+;;; You run the tests using M-x test-emacs-test-file,
+;;; or $(EMACS) -l .../test-harness.el -f batch-test-emacs file ...
+;;; which is run for you by the `make check' target in the top-level Makefile.
+
+(require 'bytecomp)
+
+(defvar test-harness-verbose
+  (and (not noninteractive) (> (device-baud-rate) search-slow-speed))
+  "*Non-nil means print messages describing progress of emacs-tester.")
+
+(defvar test-harness-current-file nil)
+
+(defvar emacs-lisp-file-regexp (purecopy "\\.el$")
+  "*Regexp which matches Emacs Lisp source files.")
+
+;;;###autoload
+(defun test-emacs-test-file (filename)
+  "Test a file of Lisp code named FILENAME.
+The output file's name is made by appending `c' to the end of FILENAME."
+  (interactive
+   (let ((file buffer-file-name)
+	 (file-name nil)
+	 (file-dir nil))
+     (and file
+	  (eq (cdr (assq 'major-mode (buffer-local-variables)))
+	      'emacs-lisp-mode)
+	  (setq file-name (file-name-nondirectory file)
+		file-dir (file-name-directory file)))
+     (list (read-file-name "Test file: " file-dir nil nil file-name))))
+  ;; Expand now so we get the current buffer's defaults
+  (setq filename (expand-file-name filename))
+
+  ;; If we're testing a file that's in a buffer and is modified, offer
+  ;; to save it first.
+  (or noninteractive
+      (let ((b (get-file-buffer (expand-file-name filename))))
+	(if (and b (buffer-modified-p b)
+		 (y-or-n-p (format "save buffer %s first? " (buffer-name b))))
+	    (save-excursion (set-buffer b) (save-buffer)))))
+
+  (if (or noninteractive test-harness-verbose)
+      (message "Testing %s..." filename))
+  (let ((test-harness-current-file filename)
+	input-buffer)
+    (save-excursion
+      (setq input-buffer (get-buffer-create " *Test Input*"))
+      (set-buffer input-buffer)
+      (erase-buffer)
+      (insert-file-contents filename)
+      ;; Run hooks including the uncompression hook.
+      ;; If they change the file name, then change it for the output also.
+      (let ((buffer-file-name filename)
+	    (default-major-mode 'emacs-lisp-mode)
+	    (enable-local-eval nil))
+        (normal-mode)
+        (setq filename buffer-file-name)))
+    (test-harness-from-buffer input-buffer filename)
+    (kill-buffer input-buffer)
+    ))
+
+(defun test-harness-read-from-buffer (buffer)
+  "Read forms from BUFFER, and turn it into a lambda test form."
+  (let ((body nil))
+    (goto-char (point-min) buffer)
+    (condition-case error-info
+	(while t
+	  (setq body (cons (read buffer) body)))
+      (end-of-file nil)
+      (error
+       (princ "Unexpected error %S reading forms from buffer\n" error-info)))
+    `(lambda ()
+       (defvar passes)
+       (defvar assertion-failures)
+       (defvar no-error-failures)
+       (defvar wrong-error-failures)
+       (defvar missing-message-failures)
+       (defvar other-failures)
+
+       (defvar unexpected-test-suite-failure)
+       (defvar trick-optimizer)
+
+       ,@(nreverse body))))
+
+(defun test-harness-from-buffer (inbuffer filename)
+  "Run tests in buffer INBUFFER, visiting FILENAME."
+  (defvar trick-optimizer)
+  (let ((passes 0)
+	(assertion-failures 0)
+	(no-error-failures 0)
+	(wrong-error-failures 0)
+	(missing-message-failures 0)
+	(other-failures 0)
+
+	(trick-optimizer nil)
+	(unexpected-test-suite-failure nil)
+	(debug-on-error t))
+    (with-output-to-temp-buffer "*Test-Log*"
+
+      (defmacro Assert (assertion)
+	`(condition-case error-info
+	     (progn
+	       (assert ,assertion)
+	       (princ (format "PASS: %S" (quote ,assertion)))
+	       (terpri)
+	       (incf passes))
+	   (cl-assertion-failed
+	    (princ (format "FAIL: Assertion failed: %S\n" (quote ,assertion)))
+	    (incf assertion-failures))
+	   (t (princ (format "FAIL: %S ==> error: %S\n" (quote ,assertion) error-info))
+	      (incf other-failures)
+	      )))
+
+      (defmacro Check-Error (expected-error &rest body)
+	(let ((quoted-body (if (= 1 (length body))
+			       `(quote ,(car body)) `(quote (progn ,@body)))))
+	  `(condition-case error-info
+	       (progn
+		 (setq trick-optimizer (progn ,@body))
+		 (princ (format "FAIL: %S executed successfully, but expected error %S\n"
+				,quoted-body
+				',expected-error))
+		 (incf no-error-failures))
+	     (,expected-error
+	      (princ (format "PASS: %S ==> error %S, as expected\n"
+			     ,quoted-body ',expected-error))
+	      (incf passes))
+	     (error
+	      (princ (format "FAIL: %S ==> expected error %S, got error %S instead\n"
+			     ,quoted-body ',expected-error error-info))
+	      (incf wrong-error-failures)))))
+
+      (defmacro Check-Error-Message (expected-error expected-error-regexp &rest body)
+	(let ((quoted-body (if (= 1 (length body))
+			       `(quote ,(car body)) `(quote (progn ,@body)))))
+	  `(condition-case error-info
+	       (progn
+		 (setq trick-optimizer (progn ,@body))
+		 (princ (format "FAIL: %S executed successfully, but expected error %S\n"
+				,quoted-body
+				',expected-error))
+		 (incf no-error-failures))
+	     (,expected-error
+	      (let ((error-message (second error-info)))
+		(if (string-match ,expected-error-regexp error-message)
+		    (progn
+		      (princ (format "PASS: %S ==> error %S %S, as expected\n"
+				     ,quoted-body error-message ',expected-error))
+		      (incf passes))
+		  (princ (format "FAIL: %S ==> got error %S as expected, but error message %S did not match regexp %S\n"
+				 ,quoted-body ',expected-error error-message ,expected-error-regexp))
+		  (incf wrong-error-failures))))
+	     (error
+	      (princ (format "FAIL: %S ==> expected error %S, got error %S instead\n"
+			     ,quoted-body ',expected-error error-info))
+	      (incf wrong-error-failures)))))
+
+
+      (defmacro Check-Message (expected-message-regexp &rest body)
+	(let ((quoted-body (if (= 1 (length body))
+			       `(quote ,(car body)) `(quote (progn ,@body)))))
+	  `(let ((messages ""))
+	     (defadvice message (around collect activate)
+	       (defvar messages)
+	       (let ((msg-string (apply 'format (ad-get-args 0))))
+		 (setq messages (concat messages msg-string))
+		 msg-string))
+	     (condition-case error-info
+		 (progn
+		   (setq trick-optimizer (progn ,@body))
+		   (if (string-match ,expected-message-regexp messages)
+		       (progn
+			 (princ (format "PASS: %S ==> value %S, message %S, matching %S, as expected\n"
+					,quoted-body trick-optimizer messages ',expected-message-regexp))
+			 (incf passes))
+		     (princ (format "FAIL: %S ==> value %S, message %S, NOT matching expected %S\n"
+				    ,quoted-body  trick-optimizer messages ',expected-message-regexp))
+		     (incf missing-message-failures)))
+	       (error
+		(princ (format "FAIL: %S ==> unexpected error %S\n"
+			       ,quoted-body error-info))
+		(incf other-failures)))
+	     (ad-unadvise 'message))))
+
+      (defmacro Ignore-Ebola (&rest body)
+	`(let ((debug-issue-ebola-notices -42)) ,@body))
+
+      (defun Int-to-Marker (pos)
+	(save-excursion
+	  (set-buffer standard-output)
+	  (save-excursion
+	    (goto-char pos)
+	    (point-marker))))
+
+      (princ "Testing Interpreted Lisp\n\n")
+      (condition-case error-info
+	  (funcall (test-harness-read-from-buffer inbuffer))
+	(error
+	 (setq unexpected-test-suite-failure t)
+	 (princ (format "Unexpected error %S while executing interpreted code\n"
+		error-info))
+	 (message "Unexpected error %S while executing interpreted code." error-info)
+	 (message "Test suite execution aborted." error-info)
+	 ))
+      (princ "\nTesting Compiled Lisp\n\n")
+      (let (code)
+	(condition-case error-info
+	    (setq code (let ((byte-compile-warnings nil))
+			 (byte-compile (test-harness-read-from-buffer inbuffer))))
+	  (error
+	   (princ (format "Unexpected error %S while byte-compiling code\n"
+			  error-info))))
+	(condition-case error-info
+	    (if code (funcall code))
+	  (error
+	   (princ (format "Unexpected error %S while executing byte-compiled code\n"
+			  error-info))
+	   (message "Unexpected error %S while executing byte-compiled code." error-info)
+	   (message "Test suite execution aborted." error-info)
+	   )))
+      (princ "\nSUMMARY:\n")
+      (princ (format "\t%5d passes\n" passes))
+      (princ (format "\t%5d assertion failures\n" assertion-failures))
+      (princ (format "\t%5d errors that should have been generated, but weren't\n" no-error-failures))
+      (princ (format "\t%5d wrong-error failures\n" wrong-error-failures))
+      (princ (format "\t%5d missing-message failures\n" missing-message-failures))
+      (princ (format "\t%5d other failures\n" other-failures))
+      (let* ((total (+ passes
+		       assertion-failures
+		       no-error-failures
+		       wrong-error-failures
+		       missing-message-failures
+		       other-failures))
+	     (basename (file-name-nondirectory filename))
+	     (summary-msg
+	      (if (> total 0)
+		  (format "%s: %d of %d (%d%%) tests successful."
+			  basename passes total (/ (* 100 passes) total))
+		(format "%s: No tests run" basename))))
+	(message "%s" summary-msg))
+      (when unexpected-test-suite-failure
+	(message "Test suite execution failed unexpectedly."))
+      (fmakunbound 'Assert)
+      (fmakunbound 'Check-Error)
+      (fmakunbound 'Ignore-Ebola)
+      (fmakunbound 'Int-to-Marker)
+      )))
+
+(defvar test-harness-results-point-max nil)
+(defmacro displaying-emacs-test-results (&rest body)
+  `(let ((test-harness-results-point-max test-harness-results-point-max))
+     ;; Log the file name.
+     (test-harness-log-file)
+     ;; Record how much is logged now.
+     ;; We will display the log buffer if anything more is logged
+     ;; before the end of BODY.
+     (or test-harness-results-point-max
+	 (save-excursion
+	   (set-buffer (get-buffer-create "*Test-Log*"))
+	   (setq test-harness-results-point-max (point-max))))
+     (unwind-protect
+	 (condition-case error-info
+	     (progn ,@body)
+	   (error
+	    (test-harness-report-error error-info)))
+       (save-excursion
+	 ;; If there were compilation warnings, display them.
+	 (set-buffer "*Test-Log*")
+	 (if (= test-harness-results-point-max (point-max))
+	     nil
+	   (if temp-buffer-show-function
+	       (let ((show-buffer (get-buffer-create "*Test-Log-Show*")))
+		 (save-excursion
+		   (set-buffer show-buffer)
+		   (setq buffer-read-only nil)
+		   (erase-buffer))
+		 (copy-to-buffer show-buffer
+				 (save-excursion
+				   (goto-char test-harness-results-point-max)
+				   (forward-line -1)
+				   (point))
+				 (point-max))
+		 (funcall temp-buffer-show-function show-buffer))
+              (select-window
+               (prog1 (selected-window)
+                 (select-window (display-buffer (current-buffer)))
+                 (goto-char test-harness-results-point-max)
+                 (recenter 1)))))))))
+
+(defun batch-test-emacs-1 (file)
+  (condition-case error-info
+      (progn (test-emacs-test-file file) t)
+    (error
+     (princ ">>Error occurred processing ")
+     (princ file)
+     (princ ": ")
+     (display-error error-info nil)
+     (terpri)
+     nil)))
+
+(defun batch-test-emacs ()
+  "Run `test-harness' on the files remaining on the command line.
+Use this from the command line, with `-batch';
+it won't work in an interactive Emacs.
+Each file is processed even if an error occurred previously.
+For example, invoke \"xemacs -batch -f batch-test-emacs tests/*.el\""
+  ;; command-line-args-left is what is left of the command line (from
+  ;; startup.el)
+  (defvar command-line-args-left)	;Avoid 'free variable' warning
+  (defvar debug-issue-ebola-notices)
+  (if (not noninteractive)
+      (error "`batch-test-emacs' is to be used only with -batch"))
+  (let ((error nil))
+    (loop for file in command-line-args-left
+      do
+      (if (file-directory-p (expand-file-name file))
+	  (let ((files (directory-files file))
+		source)
+	    (while files
+	      (if (and (string-match emacs-lisp-file-regexp (car files))
+		       (not (auto-save-file-name-p (car files)))
+		       (setq source (expand-file-name
+				     (car files)
+				     file))
+		       (if (null (batch-test-emacs-1 source))
+			   (setq error t)))
+		  (setq files (cdr files)))))
+	(if (null (batch-test-emacs-1 file))
+	    (setq error t))))
+    ;;(message "%s" (buffer-string nil nil "*Test-Log*"))
+    (message "Done")
+    (kill-emacs (if error 1 0))))
+
+(provide 'test-harness)
+
+;;; test-harness.el ends here
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/glyph-test.el	Mon Aug 13 11:08:24 2007 +0200
@@ -0,0 +1,56 @@
+(set-extent-begin-glyph 
+ (make-extent (point) (point))
+ (make-glyph [xpm :file "../etc/xemacs-icon.xpm"]))
+
+(defun foo ()
+  (interactive) 
+  (setq ok-select (not ok-select)))
+
+;; button in a group
+(setq ok-select nil)
+(set-extent-begin-glyph 
+ (make-extent (point) (point))
+ (make-glyph [button :descriptor ["ok     " (setq ok-select t)
+				  :style radio :selected ok-select]]))
+;; button in a group
+(set-extent-begin-glyph 
+ (make-extent (point) (point))
+ (make-glyph [button :descriptor ["ok" (setq ok-select nil) :style radio 
+				  :selected (not ok-select)]]))
+;; normal pushbutton
+(set-extent-begin-glyph 
+ (make-extent (point) (point))
+ (setq pbutton (make-glyph [button :width 10 :height 2 
+				   :face modeline-mousable
+				   :descriptor ["ok" foo :selected t]])))
+;; normal pushbutton
+(set-extent-begin-glyph 
+ (make-extent (point) (point))
+ (make-glyph [button :descriptor ["A Big Button" foo ]]))
+;; edit box
+(set-extent-begin-glyph 
+ (make-extent (point) (point)) 
+ (setq hedit (make-glyph [edit :pixel-width 50 :pixel-height 30
+			       :face bold-italic
+			       :descriptor ["Hello"]])))
+;; combo box
+(set-extent-begin-glyph 
+ (make-extent (point) (point))
+ (setq hcombo (make-glyph 
+	       [combo :width 10 :height 3 :descriptor ["Hello"] 
+		      :properties (:items ("One" "Two" "Three"))])))
+
+;; line
+(set-extent-begin-glyph 
+ (make-extent (point) (point))
+ (make-glyph [label :pixel-width 150 :descriptor "Hello"]))
+
+;; scrollbar
+;(set-extent-begin-glyph 
+; (make-extent (point) (point))
+; (make-glyph [scrollbar :width 50 :height 20 :descriptor ["Hello"]]))
+
+;; generic subwindow
+(setq sw (make-glyph [subwindow :pixel-width 50 :pixel-height 50]))
+(set-extent-begin-glyph (make-extent (point) (point)) sw)
+
--- a/version.sh	Mon Aug 13 11:07:40 2007 +0200
+++ b/version.sh	Mon Aug 13 11:08:24 2007 +0200
@@ -1,8 +1,8 @@
 #!/bin/sh
 emacs_major_version=21
 emacs_minor_version=2
-emacs_beta_version=6
-xemacs_codename="Apollo"
+emacs_beta_version=7
+xemacs_codename="Ares"
 infodock_major_version=4
 infodock_minor_version=0
 infodock_build_version=1