changeset 249:83b3d10dcba9 r20-5b23

Import from CVS: tag r20-5b23
author cvs
date Mon, 13 Aug 2007 10:19:09 +0200
parents ad40ac2754d8
children f385a461c9aa
files CHANGES-beta ChangeLog configure configure.in etc/NEWS etc/aliases.ksh lisp/ChangeLog lisp/about.el lisp/help-nomule.el lisp/help.el lisp/loadup.el lisp/mouse.el lisp/msw-select.el nt/ChangeLog nt/xemacs.mak src/ChangeLog src/Makefile.in.in src/alloc.c src/chartab.c src/console-msw.c src/console-msw.h src/device-msw.c src/device.h src/emacsfns.h src/eval.c src/event-msw.c src/event-msw.h src/event-stream.c src/events.c src/events.h src/faces.c src/frame-msw.c src/frame.c src/glyphs.c src/keymap.c src/lread.c src/md5.c src/menubar-msw.c src/msw-proc.c src/mule-ccl.c src/mule-coding.c src/mule-coding.h src/objects-msw.c src/redisplay-msw.c src/redisplay.c src/s/sunos4-0.h src/scrollbar-msw.c src/select-msw.c src/toolbar.c src/unexcw.cc version.sh
diffstat 51 files changed, 1674 insertions(+), 1926 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES-beta	Mon Aug 13 10:18:22 2007 +0200
+++ b/CHANGES-beta	Mon Aug 13 10:19:09 2007 +0200
@@ -1,4 +1,8 @@
 							-*- indented-text -*-
+to 20.5 beta23 "Jining Grey"
+-- MS Windows DnD stuffs courtesy of Jonathon Harris
+-- Miscellaneous bug fixes
+
 to 20.5 beta22 "Grison's Striped"
 -- Port to mklinux courtesy of Kaoru Fukui
 -- Miscellaneous bug fixes
--- a/ChangeLog	Mon Aug 13 10:18:22 2007 +0200
+++ b/ChangeLog	Mon Aug 13 10:19:09 2007 +0200
@@ -1,3 +1,19 @@
+1998-02-03  SL Baur  <steve@altair.xemacs.org>
+
+	* XEmacs 20.5-beta23 is released.
+
+1998-02-01  SL Baur  <steve@altair.xemacs.org>
+
+	* etc/aliases.ksh: igrep from the shell command line.
+	From Karl M. Hegbloom <karlheg@bittersweet.inetarena.com>
+
+1998-01-31  SL Baur  <steve@altair.xemacs.org>
+
+	* etc/aliases.ksh: Add `mak' function to create beta.err for
+	build-report.
+	From Adrian Aichner <aichner@ecf.teradyne.com>
+	Suggested by Karl M. Hegbloom <karlheg@bittersweet.inetarena.com>
+
 1998-01-27  SL Baur  <steve@altair.xemacs.org>
 
 	* XEmacs 20.5-beta22 is released.
--- a/configure	Mon Aug 13 10:18:22 2007 +0200
+++ b/configure	Mon Aug 13 10:19:09 2007 +0200
@@ -4888,8 +4888,8 @@
     with_dialogs=msw
     with_toolbars=no
     with_tty=no
-    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 msw-proc.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 msw-proc.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" &&  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\""
  fi
   fi
 fi
--- a/configure.in	Mon Aug 13 10:18:22 2007 +0200
+++ b/configure.in	Mon Aug 13 10:19:09 2007 +0200
@@ -2125,7 +2125,7 @@
     with_dialogs=msw
     with_toolbars=no
     with_tty=no
-    XE_ADD_OBJS(console-msw.o device-msw.o event-msw.o frame-msw.o objects-msw.o select-msw.o redisplay-msw.o msw-proc.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)
   fi
 fi
 
--- a/etc/NEWS	Mon Aug 13 10:18:22 2007 +0200
+++ b/etc/NEWS	Mon Aug 13 10:19:09 2007 +0200
@@ -86,6 +86,12 @@
 This information is used to control the customize-changed-options
 command.
 
+** The new command `add-log-convert' can be used to convert the
+old-style (pre-20.3) ChangeLog buffers to new style, for
+consistency.  A reminder: if you wish to revert to old-style
+ChangeLogs instead, customize the value of `add-log-time-format'
+variable.
+
 ** XEmacs/Mule (internationalization) changes.
 
 *** Egg/SJ3 input method is now officially supported.  Quail and
--- a/etc/aliases.ksh	Mon Aug 13 10:18:22 2007 +0200
+++ b/etc/aliases.ksh	Mon Aug 13 10:19:09 2007 +0200
@@ -24,6 +24,8 @@
 
 # Shortcuts for sh-derived Unix shells (ksh, zsh, bash)
 
+# From Steve Baur <steve@altair.xemacs.org>
+# Run temacs as XEmacs
 function runtemacs
 {
 	if [ ! -x temacs ]; then
@@ -33,3 +35,26 @@
 
 	./temacs -batch -l loadup.el run-temacs "$@"
 }
+
+# From Adrian Aichner <aichner@ecf.teradyne.com>
+# Convenience function for running build-report
+function mak
+{
+	make "$@" 2>&1 | tee beta.err
+}
+# export -f mak
+
+# From Karl Hegbloom <karlheg@bittersweet.inetarena.com>
+# igrep from the shell command line
+function listargs
+{
+	for arg in "$@"; do
+		echo " \"$arg\""
+	done
+}
+
+function igrep
+{
+	exp="$1"; shift
+	gnudoit -q "(igrep nil \"$exp\" '($(listargs "$@")))"
+}
--- a/lisp/ChangeLog	Mon Aug 13 10:18:22 2007 +0200
+++ b/lisp/ChangeLog	Mon Aug 13 10:19:09 2007 +0200
@@ -1,3 +1,21 @@
+1997-12-30  Colin Rafferty  <colin@xemacs.org>
+
+	* help.el (describe-beta): Made it use `locate-data-file'.
+	(describe-distribution): Ditto.
+	(describe-copying): Ditto.
+	(describe-project): Ditto.
+	(view-emacs-news): Ditto.
+
+	* help-nomule.el (help-with-tutorial): Made it use
+ 	`locate-data-file' to find tutorial.
+
+1998-01-28  Jonathon Harris  <jhar@tardis.ed.ac.uk>
+
+	* about.el: Corrected my email address.
+
+	* mouse.el: Added 'mouse-mswindows-drop' similar to
+	'mouse-offix-drop'.
+
 1998-01-27  SL Baur  <steve@altair.xemacs.org>
 
 	* loadup.el (running-xemacs): Spelling fix.
--- a/lisp/about.el	Mon Aug 13 10:18:22 2007 +0200
+++ b/lisp/about.el	Mon Aug 13 10:19:09 2007 +0200
@@ -1303,7 +1303,7 @@
        (print-short "ChangGil Han" "cghan@phys401.phys.pusan.ac.kr")
        (print-short "Derek Harding" "dharding@lssec.bt.co.uk")
        (print-short "Michael Harnois" "mharnois@sbt.net")
-       (print-short "Jonathan Harris" "jharris@tardis.co.uk")
+       (print-short "Jonathan Harris" "jhar@tardis.ed.ac.uk")
        (print-short "John Haxby" "J.Haxby@isode.com")
        (print-short "Karl M. Hegbloom" "karlheg@inetarena.com")
        (print-short "Benedikt Heinen" "beh@icemark.thenet.ch")
--- a/lisp/help-nomule.el	Mon Aug 13 10:18:22 2007 +0200
+++ b/lisp/help-nomule.el	Mon Aug 13 10:19:09 2007 +0200
@@ -70,8 +70,7 @@
 	    ;; independently, so we must guess the coding according to
 	    ;; the language.
 	    (let ((coding-system-for-read (nth 2 language)))
-	      (insert-file-contents (expand-file-name tutorial
-						      data-directory)))
+	      (insert-file-contents (locate-data-file tutorial)))
 	    (goto-char (point-min))
 	    ;; The 'didactic' blank lines: possibly insert blank lines
 	    ;; around <<nya nya nya>> and replace << >> with [ ].
--- a/lisp/help.el	Mon Aug 13 10:18:22 2007 +0200
+++ b/lisp/help.el	Mon Aug 13 10:19:09 2007 +0200
@@ -552,20 +552,20 @@
   "Display info on how to obtain the latest version of XEmacs."
   (interactive)
   (find-file-read-only
-   (expand-file-name "DISTRIB" data-directory)))
+   (locate-data-file "DISTRIB")))
 
 (defun describe-beta ()
   "Display info on how to deal with Beta versions of XEmacs."
   (interactive)
   (find-file-read-only
-   (expand-file-name "BETA" data-directory))
+   (locate-data-file "BETA"))
   (goto-char (point-min)))
 
 (defun describe-copying ()
   "Display info on how you may redistribute copies of XEmacs."
   (interactive)
   (find-file-read-only
-   (expand-file-name "COPYING" data-directory))
+   (locate-data-file "COPYING"))
   (goto-char (point-min)))
 
 (defun describe-pointer ()
@@ -577,7 +577,7 @@
   "Display info on the GNU project."
   (interactive)
   (find-file-read-only
-   (expand-file-name "GNU" data-directory))
+   (locate-data-file "GNU"))
   (goto-char (point-min)))
 
 (defun describe-no-warranty ()
@@ -660,7 +660,7 @@
 (defun view-emacs-news ()
   "Display info on recent changes to XEmacs."
   (interactive)
-  (find-file (expand-file-name "NEWS" data-directory)))
+  (find-file (locate-data-file "NEWS")))
 
 (defun xemacs-www-page ()
   "Go to the XEmacs World Wide Web page."
--- a/lisp/loadup.el	Mon Aug 13 10:18:22 2007 +0200
+++ b/lisp/loadup.el	Mon Aug 13 10:19:09 2007 +0200
@@ -184,10 +184,13 @@
     (message "Dumping under the name xemacs")
     ;; This is handled earlier in the build process.
     ;; (condition-case () (delete-file "xemacs") (file-error nil))
-  (when (fboundp 'really-free)
-    (really-free))
-  (dump-emacs "xemacs" "temacs")
-  (kill-emacs))
+    (test-atoms)
+    (when (fboundp 'really-free)
+      (really-free))
+    (test-atoms)
+    (dump-emacs "xemacs" "temacs")
+    (test-atoms)
+    (kill-emacs))
 
 (when (member "run-temacs" command-line-args)
   (message "\nBootstrapping from temacs...")
--- a/lisp/mouse.el	Mon Aug 13 10:18:22 2007 +0200
+++ b/lisp/mouse.el	Mon Aug 13 10:19:09 2007 +0200
@@ -42,16 +42,21 @@
 
 ;; enable drag regions (ograf@fga.de)
 ;; if button2 is dragged from within a region, this becomes a drop
-(if (featurep '(or offix cde))
+(if (featurep '(or offix cde mswindows))
     (global-set-key 'button2 'mouse-drag-or-yank)
   (global-set-key 'button2 'mouse-yank))
 
-;; enable drops from OffiX (ograf@fga.de)
-;; accept any button1,2,3 drop with `mouse-offix-drop'
+;; enable drops from OffiX (ograf@fga.de) or mswindows
+;; accept any button1,2,3 drop with `mouse-offix-drop' or 'mswindows-mouse-drop'
 (cond ((featurep 'offix)
        (global-set-key 'drop1 'mouse-offix-drop)
        (global-set-key 'drop2 'mouse-offix-drop)
-       (global-set-key 'drop3 'mouse-offix-drop)))
+       (global-set-key 'drop3 'mouse-offix-drop))
+      ((featurep 'mswindows)
+       (global-set-key 'drop0 'mouse-mswindows-drop)
+       (global-set-key 'drop1 'mouse-mswindows-drop)
+       (global-set-key 'drop2 'mouse-mswindows-drop)
+       (global-set-key 'drop3 'mouse-mswindows-drop)))
 
 (defgroup mouse nil
   "Window system-independent mouse support."
@@ -247,6 +252,44 @@
 	     (make-frame-visible frame))))
     (undo-boundary)))
 
+(defun mouse-mswindows-drop (event)
+  "Do something with a drop event. Inserts Text drops and
+ executes appropriate commands for specific drops.
+ Text drops follow the `mouse-yank-at-point' variable."
+  (interactive "e")
+  (let* ((type (car (event-drag-and-drop-data event)))
+	(data (cadr (event-drag-and-drop-data event)))
+	(frame (event-channel event))
+	(window (if frame (event-window event) (frame-selected-window))))
+    (cond ((= type 2)	;; file
+	   (let ((x pop-up-windows))
+	     (setq pop-up-windows nil)
+	     (cond (window
+		    (select-window window)))
+	     (switch-to-buffer (find-file-noselect data))
+	     (make-frame-visible frame)
+	     (setq pop-up-windows x)))
+	  ((= type 3)	;; files
+	   (let ((x pop-up-windows))
+	     (setq pop-up-windows nil)
+	     (while (not (eq data ()))
+	       (pop-to-buffer (find-file-noselect (car data)) nil frame)
+	       (setq data (cdr data)))
+	     (make-frame-visible frame)
+	     (setq pop-up-windows x)))
+	  ((= type 4)	;; text
+	   (and (not mouse-yank-at-point)
+		(mouse-set-point event))
+	   (insert data))
+	  (t ;; this is raw data or unknown stuff
+	   (let ((buf (generate-new-buffer "DndRawData")))
+	     (set-buffer buf)
+	     (pop-to-buffer buf nil frame)
+	     (insert data)
+	     (hexlify-buffer)
+	     (make-frame-visible frame))))
+    (undo-boundary)))
+
 (defun mouse-eval-sexp (click force-window)
   "Evaluate the sexp under the mouse.  Usually, this is the last sexp before
 the click, but if you click on a left paren, then it is the sexp beginning
--- a/lisp/msw-select.el	Mon Aug 13 10:18:22 2007 +0200
+++ b/lisp/msw-select.el	Mon Aug 13 10:19:09 2007 +0200
@@ -32,16 +32,6 @@
 
 ;;; Code:
 
-;(defun mswindows-paste-clipboard ()
-;  "Insert the current contents of the Clipboard at point."
-;  (interactive "*")
-;  (setq last-command nil)
-;  (setq this-command 'yank) ; so that yank-pop works.
-; (let ((clip (mswindows-get-clipboard)))
-;    (or clip (error "there is no clipboard selection"))
-;    (push-mark)
-;    (insert clip)))
-
 (defun mswindows-paste-clipboard ()
   "Insert the current contents of the mswindows clipboard at point,
 replacing the active selection if there is one."
--- a/nt/ChangeLog	Mon Aug 13 10:18:22 2007 +0200
+++ b/nt/ChangeLog	Mon Aug 13 10:19:09 2007 +0200
@@ -1,3 +1,8 @@
+1998-01-28  Jonathon Harris  <jhar@tardis.ed.ac.uk>
+
+	* xemacs.mak: Updated accordingly.
+	Creates the MSVC browse info immediately after the link.
+
 1997-12-29  Kirill M. Katsnelson  <kkm@kis.ru>
 
 	* config.h: Suppressed MSVC warning 'relational' : signed/unsigned
--- a/nt/xemacs.mak	Mon Aug 13 10:18:22 2007 +0200
+++ b/nt/xemacs.mak	Mon Aug 13 10:19:09 2007 +0200
@@ -294,8 +294,7 @@
  $(XEMACS)\src\objects-msw.c \
  $(XEMACS)\src\redisplay-msw.c \
  $(XEMACS)\src\scrollbar-msw.c \
- $(XEMACS)\src\select-msw.c \
- $(XEMACS)\src\msw-proc.c
+ $(XEMACS)\src\select-msw.c
 !endif
 
 !if $(HAVE_MULE)
@@ -396,8 +395,7 @@
 	$(OUTDIR)\objects-msw.obj \
 	$(OUTDIR)\redisplay-msw.obj \
 	$(OUTDIR)\scrollbar-msw.obj \
-	$(OUTDIR)\select-msw.obj \
-	$(OUTDIR)\msw-proc.obj
+	$(OUTDIR)\select-msw.obj
 !endif
 
 !if $(HAVE_MULE)
@@ -536,7 +534,6 @@
 	link.exe @<<
   $(TEMACS_LFLAGS) $(TEMACS_OBJS) $(TEMACS_LIBS)
 <<
-	!$(TEMACS) -batch -l update-elc.el
 
 xemacs.res: xemacs.rc
 	rc xemacs.rc
@@ -566,7 +563,7 @@
 	!$(LIB_SRC)\make-docfile.exe -a $(DOC) -d $(TEMACS_SRC) $(DOC_SRC8)
 	!$(LIB_SRC)\make-docfile.exe -a $(DOC) -d $(TEMACS_SRC) $(DOC_SRC9)
 
-update-elc: $(LOADPATH)\startup.el
+update-elc:
 	!$(TEMACS) -batch -l update-elc.el
 
 rebuild: $(TEMACS_DIR)\puresize-adjust.h
@@ -584,7 +581,7 @@
 #------------------------------------------------------------------------------
 
 # use this rule to build the complete system
-all: $(LASTFILE) $(LWLIB) $(SUPPORT_PROGS) $(TEMACS) $(TEMACS_BROWSE) $(DOC) dump-xemacs
+all: $(LASTFILE) $(LWLIB) $(SUPPORT_PROGS) $(TEMACS) $(TEMACS_BROWSE) update-elc $(DOC) dump-xemacs
 	-del rebuild
 
 temacs:  $(TEMACS)
@@ -626,7 +623,7 @@
 	-del /s /q *.bak *.elc *.orig *.rej
 
 depend:
-	mkdepend -f xemacs.mak -p$(OUTDIR)\ -o.obj -w9999 -- $(TEMACS_CPP_FLAGS) --  $(DOC_SRC1) $(DOC_SRC2) $(DOC_SRC3) $(DOC_SRC4) $(DOC_SRC5) $(DOC_SRC6) $(DOC_SRC7) $(DOC_SRC8) $(LASTFILE_SRC)\lastfile.c $(LIB_SRC)\make-docfile.c .\runemacs.c
+	mkdepend -f xemacs.mak -p$(OUTDIR)\ -o.obj -w2048 -- $(TEMACS_CPP_FLAGS) --  $(DOC_SRC1) $(DOC_SRC2) $(DOC_SRC3) $(DOC_SRC4) $(DOC_SRC5) $(DOC_SRC6) $(DOC_SRC7) $(DOC_SRC8) $(LASTFILE_SRC)\lastfile.c $(LIB_SRC)\make-docfile.c .\runemacs.c
 
 # DO NOT DELETE THIS LINE -- make depend depends on it.
 	mkdepend -f xemacs.mak -p$(OUTDIR)\ -o.obj -w9999 -- $(TEMACS_CPP_FLAGS) --  $(DOC_SRC1) $(DOC_SRC2) $(DOC_SRC3) $(DOC_SRC4) $(DOC_SRC5) $(DOC_SRC6) $(DOC_SRC7) $(DOC_SRC8) $(DOC_SRC9) $(LASTFILE_SRC)\lastfile.c $(LIB_SRC)\make-docfile.c .\runemacs.c
--- a/src/ChangeLog	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/ChangeLog	Mon Aug 13 10:19:09 2007 +0200
@@ -1,5 +1,102 @@
+1998-02-01  Kyle Jones  <kyle_jones@wonderworks.com>
+
+	* redisplay.c (redisplay_window): After outputting
+	  the window, invalidate its the line start cache if the
+	  we're displaying the minibuffer window and the echo
+	  area is active.  The cache is only valid for the echo
+	  area buffer, and that buffer isn't associated with the
+	  minibuffer window anymore.
+
+1998-01-31  SL Baur  <steve@altair.xemacs.org>
+
+	* alloc.c (disksave_object_finalization): Additional checking for
+	sanity when zeroing out unused portions of string_chars_block's.
+	(Fpurecopy): Spelling fixes in comment.
+	(PURESIZE_SLOP): Set default slop to 0.
+
+1998-01-31  Kyle Jones  <kyle_jones@wonderworks.com>
+
+	* chartab.c (make_char_table): Initialize mirror
+	  tables with Spunct in all the slots.  Syntax table
+	  initialization doesn't touch slots for nonexistent
+	  characters sets.  If character sets corresponding to
+	  those slots are created later Qnil values in the slots
+	  will cause crashes.
+	(copy_char_table_entry): Return copy not original.
+
+1998-01-28  Jonathon Harris  <jhar@tardis.ed.ac.uk>
+
+	* msw-proc.c:
+	* event-msw.h:
+	* event-msw.c:
+	* console-msw.h:
+	Deleted the first two and merged them into the last two files.
+
+	* device-msw.c:
+	* event-msw.c:
+ 	* frame-msw.c:
+	Added file-based drag and drop support. The "System/Open" DDE command
+	is also implemented as if it were a drag and drop operation.
+	
+	* emacsfns.h:
+	* event-stream.c:
+	* events.c:
+	* events.h:
+	* frame.c:
+	* keymap.c:
+	Replaced all "#ifdef HAVE_OFFIX_DND" with
+	"#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)"
+
+	* device.h: Added DEVICE_MSWINDOWS_P and related macros.
+
+	* objects-msw.c:
+	* select-msw.c:
+	Eliminated warnings.
+
+	* redisplay-msw.c: Changed color of "dead" box between scrollbars
+	to windows' "button" color for compatibility with other windows apps.
+
+1998-01-20  Stephen Turnbull  <turnbull@sk.tsukuba.ac.jp>
+
+	* Makefile.in.in: move `rm puresize-adjust.h' from distclean
+	  to mostlyclean
+
+1998-01-29  SL Baur  <steve@altair.xemacs.org>
+
+	* Makefile.in.in (dlopen.o): Add dependencies.
+
+	* s/sunos4-0.h: Conditionalize use of broken-sun.h for old Gccs.
+	Suggested by Amir J Katz <amir@ndsoft.com>
+
+1998-01-28  SL Baur  <steve@altair.xemacs.org>
+
+	* faces.c (init_device_faces): This function can call lisp.
+
+1998-01-28  P. E. Jareth Hein  <jareth@camelot-soft.com>
+
+	* mule-coding.h:
+	* mule-coding.c: (determine_real_coding_system): removed the
+	static declaration to allow reuse.
+
+	* md5.c (Fmd5): Rewrote to fully support MULE, as well as streamline
+	the code.
+
+	* mule-ccl.c (ccl_driver): Set initial values of variables to shut up
+ 	the compiler and to give better error message if a quit happens before
+	any ccl_code is generated.
+
+1998-01-28  SL Baur  <steve@altair.xemacs.org>
+
+	* glyphs.c (allocate_glyph): This function can GC.
+	Wrap GCPRO around unprotected function calls.
+	(specifier_vars_of_glyphs): Comment change -- Can we GC here?
+
 1998-01-27  SL Baur  <steve@altair.xemacs.org>
 
+	* lread.c (Fload_internal): Add extra GCPRO around call to
+	Fassoc.
+	Enable purespace usage counts always.
+
 	* m/powerpc.h: Isolate changes for mklinux from AIX.
 
 1998-01-27  Hrvoje Niksic  <hniksic@srce.hr>
--- a/src/Makefile.in.in	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/Makefile.in.in	Mon Aug 13 10:19:09 2007 +0200
@@ -614,13 +614,14 @@
 
 .PHONY: mostlyclean clean distclean realclean versionclean extraclean
 mostlyclean:
-	$(RM) temacs puremacs quantmacs prefix-args depend.* *.o *.i core
+	$(RM) temacs puremacs quantmacs prefix-args depend.* *.o *.i \
+	  core puresize-adjust.h
 clean: mostlyclean versionclean
 	$(RM) libextcli* update-elc.stamp
 ## This is used in making a distribution.
 ## Do not use it on development directories!
 distclean: clean
-	$(RM) config.h paths.h puresize-adjust.h Emacs.ad.h \
+	$(RM) config.h paths.h Emacs.ad.h \
 	  Makefile Makefile.in TAGS xemacs.*
 realclean: distclean
 versionclean:
@@ -1325,6 +1326,8 @@
 dired.o: regex.h
 dired.o: sysdir.h
 dired.o: sysfile.h
+dlopen.o: config.h
+dlopen.o: buffer.h
 doc.o: blocktype.h
 doc.o: buffer.h
 doc.o: bufslots.h
--- a/src/alloc.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/alloc.c	Mon Aug 13 10:19:09 2007 +0200
@@ -2794,13 +2794,13 @@
 	     * But purified aggregate objects like lists and vectors
 	     * can contain uninterned symbols.  If there are no
 	     * other non-pure references to the symbol, then the
-	     * symbol is not proteted from garabge colelction
+	     * symbol is not protected from garbage collection
 	     * because the collector does not mark the contents of
 	     * purified objects.  So to protect the symbols, an impure
 	     * reference has to be kept for each uninterned symbol
 	     * that is referenced by a pure object.  All such
 	     * symbols are stored in the hashtable pointed to by
-	     * Vpure_uninterened_symbol_table, which is itself
+	     * Vpure_uninterned_symbol_table, which is itself
 	     * staticpro'd.
 	     */
 	    if (EQ (XSYMBOL (obj)->obarray, Vobarray))
@@ -2858,14 +2858,14 @@
       extern Lisp_Object Vemacs_beta_version;
       /* This used to be NILP(Vemacs_beta_version) ? 512 : 4; */
 #ifndef PURESIZE_SLOP
-#define PURESIZE_SLOP 4
+#define PURESIZE_SLOP 0
 #endif
       int slop = PURESIZE_SLOP;
 
       sprintf (buf, "Purespace usage: %ld of %ld (%d%%",
                pureptr, (long) get_PURESIZE(),
                (int) (pureptr / (get_PURESIZE() / 100.0) + 0.5));
-      if (lost > 2) {
+      if (lost > ((slop ? slop : 1) / 1024)) {
         sprintf (buf + strlen (buf), " -- %dk wasted", lost);
 	if (die_if_pure_storage_exceeded) {
 	  puresize_adjust_h (pureptr + slop);
@@ -4222,20 +4222,28 @@
   /* Run the disksave finalization methods of all live objects. */
   disksave_object_finalization_1 ();
 
+#if 0 /* I don't see any point in this.  The purespace starts out all 0's */
   /* Zero out the unused portion of purespace */
   if (!pure_lossage)
     memset (  (char *) (PUREBEG + pureptr), 0,
 	    (((char *) (PUREBEG + get_PURESIZE())) -
 	     ((char *) (PUREBEG + pureptr))));
+#endif
 
   /* Zero out the uninitialized (really, unused) part of the containers
      for the live strings. */
   {
     struct string_chars_block *scb;
     for (scb = first_string_chars_block; scb; scb = scb->next)
-      /* from the block's fill ptr to the end */
-      memset ((scb->string_chars + scb->pos), 0,
-              sizeof (scb->string_chars) - scb->pos);
+      {
+	int count = sizeof (scb->string_chars) - scb->pos;
+
+	assert (count >= 0 && count < STRING_CHARS_BLOCK_SIZE);
+	if (count != 0) {
+	  /* from the block's fill ptr to the end */
+	  memset ((scb->string_chars + scb->pos), 0, count);
+	}
+      }
   }
 
   /* There, that ought to be enough... */
--- a/src/chartab.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/chartab.c	Mon Aug 13 10:19:09 2007 +0200
@@ -595,6 +595,8 @@
   if (ty == CHAR_TABLE_TYPE_SYNTAX)
     {
       ct->mirror_table = Fmake_char_table (Qgeneric);
+      fill_char_table (XCHAR_TABLE (ct->mirror_table), 
+                       make_int (Spunct)); 
     }
   else
     ct->mirror_table = Qnil;
@@ -645,7 +647,7 @@
 	ctenew->level2[i] = new;
     }
 
-  XSETCHAR_TABLE_ENTRY (obj, cte);
+  XSETCHAR_TABLE_ENTRY (obj, ctenew);
   return obj;
 }
 
--- a/src/console-msw.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/console-msw.c	Mon Aug 13 10:19:09 2007 +0200
@@ -31,6 +31,7 @@
 
 #include "console-msw.h"
 
+
 DEFINE_CONSOLE_TYPE (mswindows);
 
 
@@ -73,3 +74,74 @@
 {
   Fprovide (Qmswindows);
 }
+
+
+#ifdef DEBUG_XEMACS
+#include "events.h"
+#include "opaque.h"
+/*
+ * Random helper functions for debugging.
+ * Intended for use in the MSVC "Watch" window which doesn't like
+ * the aborts that the error_check_foo() functions can make.
+ */
+struct lrecord_header *DHEADER(Lisp_Object obj)
+{
+  return (LRECORDP (obj)) ? XRECORD_LHEADER (obj) : NULL;
+}
+
+int *DOPAQUE_DATA (Lisp_Object obj)
+{
+  return (OPAQUEP (obj)) ? OPAQUE_DATA (XOPAQUE (obj)) : NULL;
+}
+
+struct Lisp_Event *DEVENT(Lisp_Object obj)
+{
+  return (EVENTP (obj)) ? XEVENT (obj) : NULL;
+}
+
+struct Lisp_Cons *DCONS(Lisp_Object obj)
+{
+  return (CONSP (obj)) ? XCONS (obj) : NULL;
+}
+
+Lisp_Object DCAR(Lisp_Object obj)
+{
+  return (CONSP (obj)) ? XCAR (obj) : 0;
+}
+
+Lisp_Object DCDR(Lisp_Object obj)
+{
+  return (CONSP (obj)) ? XCDR (obj) : 0;
+}
+
+struct Lisp_Cons *DCONSCDR(Lisp_Object obj)
+{
+  return ((CONSP (obj)) && (CONSP (XCDR (obj)))) ? XCONS (XCDR (obj)) : 0;
+}
+
+Lisp_Object DCARCDR(Lisp_Object obj)
+{
+  return ((CONSP (obj)) && (CONSP (XCDR (obj)))) ? XCAR (XCDR (obj)) : 0;
+}
+
+char *DSTRING(Lisp_Object obj)
+{
+  return (STRINGP (obj)) ? XSTRING_DATA (obj) : NULL;
+}
+
+struct Lisp_Vector *DVECTOR(Lisp_Object obj)
+{
+  return (VECTORP (obj)) ? XVECTOR (obj) : NULL;
+}
+
+struct Lisp_Symbol *DSYMBOL(Lisp_Object obj)
+{
+  return (SYMBOLP (obj)) ? XSYMBOL (obj) : NULL;
+}
+
+char *DSYMNAME(Lisp_Object obj)
+{
+  return (SYMBOLP (obj)) ? XSYMBOL (obj)->name->_data : NULL;
+}
+
+#endif
--- a/src/console-msw.h	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/console-msw.h	Mon Aug 13 10:19:09 2007 +0200
@@ -1,4 +1,4 @@
-/* Define mswindowsindows-specific console, device, and frame object for XEmacs.
+/* Define mswindows-specific console, device, and frame object for XEmacs.
    Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
    Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
 
@@ -35,6 +35,32 @@
 #include "console.h"
 
 #include "windows.h"
+#include "ddeml.h"	/* DDE management library */
+#include "shellapi.h"	/* FileManager/Explorer drag and drop */
+
+/*
+ * XXX FIXME: The following X modifier defs in events-mod.h clash with win32
+ * hotkey defs in winuser.h. For the moment lose the win32 versions.
+ * Maybe we should rename all of MOD_* to something that doesn't clash.
+ */
+#ifdef MOD_CONTROL
+#  undef MOD_CONTROL
+#endif  
+#ifdef MOD_ALT
+#  undef MOD_ALT
+#endif  
+#ifdef MOD_SHIFT
+#  undef MOD_SHIFT
+#endif  
+
+
+/* The name of the main window class */
+#define XEMACS_CLASS "XEmacs"
+
+
+/*
+ * Console
+ */
 
 DECLARE_CONSOLE_TYPE (mswindows);
 
@@ -44,6 +70,10 @@
 };
 
 
+/*
+ * Device
+ */
+
 struct mswindows_device
 {
   int logpixelsx, logpixelsy;
@@ -63,6 +93,10 @@
 #define DEVICE_MSWINDOWS_VERTSIZE(d) 	(DEVICE_MSWINDOWS_DATA (d)->vertsize)
 
 
+/*
+ * Frame
+ */
+
 struct mswindows_frame
 {
   /* win32 window handle */
@@ -99,10 +133,48 @@
 #define FRAME_MSWINDOWS_MENU_HASHTABLE(f) (FRAME_MSWINDOWS_DATA (f)->menu_hashtable)
 #define FRAME_MSWINDOWS_MENU_CHECKSUM(f)  (FRAME_MSWINDOWS_DATA (f)->menu_checksum)
 
+/* win32 window LONG indices */
+#define XWL_FRAMEOBJ	0
+#define XWL_COUNT	1	/* Number of LONGs that we use */
+#define MSWINDOWS_WINDOW_EXTRA_BYTES	(XWL_COUNT*4)
+
+
 /*
- * Redisplay functions
+ * Events
+ */
+
+/* win32 messages / magic event types */
+#define EVENT_MSWINDOWS_MAGIC_TYPE(e)	\
+	((e)->event.magic.underlying_mswindows_event)
+#define XM_BUMPQUEUE	(WM_USER + 101)
+#define XM_MAPFRAME	(WM_USER + 102)
+#define XM_UNMAPFRAME	(WM_USER + 103)
+
+
+/*
+ * Random globals
  */
+
+/* win32 "Windows" procedure */
+LRESULT WINAPI mswindows_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam,
+				   LPARAM lParam);
+
 void mswindows_redraw_exposed_area (struct frame *f, int x, int y, 
-			      int width, int height);
+				    int width, int height);
+
+/* win32 DDE management library */
+#define MSWINDOWS_DDE_ITEM_OPEN "Open"
+extern DWORD mswindows_dde_mlid;
+extern HSZ mswindows_dde_service;
+extern HSZ mswindows_dde_topic_system;
+extern HSZ mswindows_dde_item_open;
+HDDEDATA CALLBACK mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv,
+					  HSZ hszTopic, HSZ hszItem, HDDEDATA hdata,
+					  DWORD dwData1, DWORD dwData2);
+
+void mswindows_enqueue_dispatch_event (Lisp_Object event);
+void mswindows_enqueue_magic_event (HWND hwnd, UINT message);
+Lisp_Object mswindows_cancel_dispatch_event (struct Lisp_Event* event);
+Lisp_Object mswindows_pump_outstanding_events (void);
 
 #endif /* _XEMACS_CONSOLE_MSW_H_ */
--- a/src/device-msw.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/device-msw.c	Mon Aug 13 10:19:09 2007 +0200
@@ -35,16 +35,22 @@
 #include "console-msw.h"
 #include "console-stream.h"
 #include "events.h"
-#include "event-msw.h"
 #include "faces.h"
 #include "frame.h"
+#include "sysdep.h"
+
+/* win32 DDE management library globals */
+DWORD mswindows_dde_mlid;
+HSZ mswindows_dde_service;
+HSZ mswindows_dde_topic_system;
+HSZ mswindows_dde_item_open;
 
 Lisp_Object Qinit_pre_mswindows_win, Qinit_post_mswindows_win;
 
 static void
 mswindows_init_device (struct device *d, Lisp_Object props)
 {
-  WNDCLASS wc;
+  WNDCLASSEX wc;
   HWND desktop;
   HDC hdc;
 
@@ -71,6 +77,7 @@
   DEVICE_CLASS(d) = Qcolor;
 
   /* Register the main window class */
+  wc.cbSize = sizeof (WNDCLASSEX);
   wc.style = CS_OWNDC;	/* One DC per window */
   wc.lpfnWndProc = (WNDPROC) mswindows_wnd_proc;
   wc.cbClsExtra = 0;
@@ -83,7 +90,32 @@
   wc.hbrBackground = (HBRUSH)(COLOR_APPWORKSPACE + 1);
   wc.lpszMenuName = NULL;
   wc.lpszClassName = XEMACS_CLASS;
-  RegisterClass(&wc);		/* XXX FIXME: Should use RegisterClassEx */
+  wc.hIconSm = LoadImage (GetModuleHandle (NULL), XEMACS_CLASS,
+			  IMAGE_ICON, 16, 16, 0);
+  RegisterClassEx (&wc);
+}
+
+static void
+mswindows_finish_init_device (struct device *d, Lisp_Object props)
+{
+  /* Initialise DDE management library and our related globals */
+  mswindows_dde_mlid = 0;
+  DdeInitialize (&mswindows_dde_mlid, mswindows_dde_callback,
+		 APPCMD_FILTERINITS|CBF_FAIL_SELFCONNECTIONS|CBF_FAIL_ADVISES|
+		 CBF_FAIL_POKES|CBF_FAIL_REQUESTS|CBF_SKIP_ALLNOTIFICATIONS, 0);
+  
+  mswindows_dde_service = DdeCreateStringHandle (mswindows_dde_mlid, XEMACS_CLASS, 0);
+  mswindows_dde_topic_system = DdeCreateStringHandle (mswindows_dde_mlid, SZDDESYS_TOPIC, 0);
+  mswindows_dde_item_open = DdeCreateStringHandle (mswindows_dde_mlid,
+						   TEXT(MSWINDOWS_DDE_ITEM_OPEN), 0);
+  DdeNameService (mswindows_dde_mlid, mswindows_dde_service, 0L, DNS_REGISTER);
+}
+
+static void
+mswindows_delete_device (struct device *d)
+{
+  DdeNameService (mswindows_dde_mlid, 0L, 0L, DNS_REGISTER);
+  DdeUninitialize (mswindows_dde_mlid);
 }
 
 static int
@@ -138,9 +170,9 @@
 console_type_create_device_mswindows (void)
 {
   CONSOLE_HAS_METHOD (mswindows, init_device);
-/*  CONSOLE_HAS_METHOD (mswindows, finish_init_device); */
+  CONSOLE_HAS_METHOD (mswindows, finish_init_device);
 /*  CONSOLE_HAS_METHOD (mswindows, mark_device); */
-/*  CONSOLE_HAS_METHOD (mswindows, delete_device); */
+  CONSOLE_HAS_METHOD (mswindows, delete_device);
   CONSOLE_HAS_METHOD (mswindows, device_pixel_width);
   CONSOLE_HAS_METHOD (mswindows, device_pixel_height);
   CONSOLE_HAS_METHOD (mswindows, device_mm_width);
--- a/src/device.h	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/device.h	Mon Aug 13 10:19:09 2007 +0200
@@ -275,6 +275,10 @@
 #define CHECK_X_DEVICE(z) CHECK_DEVICE_TYPE (z, x)
 #define CONCHECK_X_DEVICE(z) CONCHECK_DEVICE_TYPE (z, x)
 
+#define DEVICE_MSWINDOWS_P(dev) CONSOLE_TYPESYM_MSWINDOWS_P (DEVICE_TYPE (dev))
+#define CHECK_MSWINDOWS_DEVICE(z) CHECK_DEVICE_TYPE (z, mswindows)
+#define CONCHECK_MSWINDOWS_DEVICE(z) CONCHECK_DEVICE_TYPE (z, mswindows)
+
 #define DEVICE_TTY_P(dev) CONSOLE_TYPESYM_TTY_P (DEVICE_TYPE (dev))
 #define CHECK_TTY_DEVICE(z) CHECK_DEVICE_TYPE (z, tty)
 #define CONCHECK_TTY_DEVICE(z) CONCHECK_DEVICE_TYPE (z, tty)
--- a/src/emacsfns.h	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/emacsfns.h	Mon Aug 13 10:19:09 2007 +0200
@@ -1202,7 +1202,7 @@
 extern Lisp_Object Qdevice;
 extern Lisp_Object Qdimension;
 extern Lisp_Object Qdisplay;
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 extern Lisp_Object Qdnd_data;
 #endif
 extern Lisp_Object Qdoc_string;
--- a/src/eval.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/eval.c	Mon Aug 13 10:19:09 2007 +0200
@@ -4926,6 +4926,7 @@
 */
        (stream, detailed))
 {
+  /* This function can GC */
   struct backtrace *backlist = backtrace_list;
   struct catchtag *catches = catchlist;
   int speccount = specpdl_depth_counter;
--- a/src/event-msw.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/event-msw.c	Mon Aug 13 10:19:09 2007 +0200
@@ -33,8 +33,17 @@
 #include <config.h>
 #include "lisp.h"
 
+#include "console-msw.h"
+
+#ifdef HAVE_SCROLLBARS
+# include "scrollbar-msw.h"
+#endif
+
+#ifdef HAVE_MENUBARS
+# include "menubar-msw.h"
+#endif
+
 #include "device.h"
-#include "console-msw.h"
 #include "emacsfns.h"
 #include "events.h"
 #include "frame.h"
@@ -44,7 +53,35 @@
 #include "syswait.h"
 #include "systime.h"
 
-#include "event-msw.h"
+#include "events-mod.h"
+
+#ifdef HAVE_MENUBARS
+#define ADJR_MENUFLAG TRUE
+#else
+#define ADJR_MENUFLAG FALSE
+#endif
+
+/* Fake key modifier which is attached to a quit char event.
+   Removed upon dequeueing an event */
+#define FAKE_MOD_QUIT	0x80
+
+/* Timer ID used for button2 emulation */
+#define BUTTON_2_TIMER_ID 1
+
+/* Drag and drop event data types (subset of types in offix-types.h) */
+#define DndFile		2
+#define	DndFiles	3
+#define	DndText		4
+
+
+static Lisp_Object mswindows_find_frame (HWND hwnd);
+static Lisp_Object mswindows_find_console (HWND hwnd);
+static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods);
+static int mswindows_modifier_state (BYTE* keymap, int has_AltGr);
+static void mswindows_set_chord_timer (HWND hwnd);
+static int mswindows_button2_near_enough (POINTS p1, POINTS p2);
+static int mswindows_current_layout_has_AltGr (void);
+
 
 static struct event_stream *mswindows_event_stream;
 
@@ -57,19 +94,14 @@
 static Lisp_Object mswindows_u_dispatch_event_queue, mswindows_u_dispatch_event_queue_tail;
 static Lisp_Object mswindows_s_dispatch_event_queue, mswindows_s_dispatch_event_queue_tail;
 
-/*
- * List of mswindows waitable handles.
- * Apart from the dispatch queue semaphore, all of these handles may be waited
- * on multiple times in emacs_mswindows_next_event before being processed and so
- * must be manual-reset events.
- */
+/* The number of things we can wait on */
+#define MAX_WAITABLE (MAXIMUM_WAIT_OBJECTS - 1)
+
+/* List of mswindows waitable handles. */
 static HANDLE mswindows_waitable[MAX_WAITABLE];
 
-/* random emacs info associated with each of the wait handles */
-static mswindows_waitable_info_type mswindows_waitable_info[MAX_WAITABLE];
-
 /* Count of quit chars currently in the queue */
-/* Incremented in WM_CHAR handler in msw-proc.c
+/* Incremented in WM_[SYS]KEYDOWN handler in the mswindows_wnd_proc()
    Decremented in mswindows_dequeue_dispatch_event() */
 int mswindows_quit_chars_count = 0;
 
@@ -96,10 +128,15 @@
 {
   return (sevt->event_type == key_press_event
 	  || sevt->event_type == button_press_event
-	  || sevt->event_type == button_release_event);
+	  || sevt->event_type == button_release_event
+	  || sevt->event_type == dnd_drop_event);
 }
 
-/*
+/************************************************************************/
+/*                     Dispatch queue management                        */
+/************************************************************************/
+
+/* 
  * Add an emacs event to the proper dispatch queue
  */
 void
@@ -117,6 +154,69 @@
   PostMessage (NULL, XM_BUMPQUEUE, 0, 0);
 }
 
+void
+mswindows_enqueue_magic_event (HWND hwnd, UINT message)
+{
+  Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
+  struct Lisp_Event* event = XEVENT (emacs_event);
+
+  event->channel = mswindows_find_frame (hwnd);
+  event->timestamp = GetMessageTime();
+  event->event_type = magic_event;
+  EVENT_MSWINDOWS_MAGIC_TYPE (event) = message;
+
+  mswindows_enqueue_dispatch_event (emacs_event);
+}
+
+static void
+mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWORD when)
+{
+
+  /* We always use last message time, because mouse button
+     events may get delayed, and XEmacs double click
+     recognition will fail */
+
+  Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
+  struct Lisp_Event* event = XEVENT(emacs_event);
+
+  event->channel = mswindows_find_frame(hwnd);
+  event->timestamp = when;
+  event->event.button.button =
+    (message==WM_LBUTTONDOWN || message==WM_LBUTTONUP) ? 1 :
+    ((message==WM_RBUTTONDOWN || message==WM_RBUTTONUP) ? 3 : 2);
+  event->event.button.x = where.x;
+  event->event.button.y = where.y;
+  event->event.button.modifiers = mswindows_modifier_state (NULL, 0);
+      
+  if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN ||
+      message==WM_RBUTTONDOWN)
+    {
+      event->event_type = button_press_event;
+      SetCapture (hwnd);
+    }
+  else
+    {
+      event->event_type = button_release_event;
+      ReleaseCapture ();
+    }
+  
+  mswindows_enqueue_dispatch_event (emacs_event);
+}
+
+static void
+mswindows_enqueue_keypress_event (HWND hwnd, Lisp_Object keysym, int mods)
+{
+  Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
+  struct Lisp_Event* event = XEVENT(emacs_event);
+
+  event->channel = mswindows_find_console(hwnd);
+  event->timestamp = GetMessageTime();
+  event->event_type = key_press_event;
+  event->event.key.keysym = keysym;
+  event->event.key.modifiers = mods;
+  mswindows_enqueue_dispatch_event (emacs_event);
+}
+
 /*
  * Remove and return the first emacs event on the dispatch queue.
  * Give a preference to user events over non-user ones.
@@ -204,6 +304,11 @@
   return Qnil;
 }
 
+
+/************************************************************************/
+/*                             Event pump                               */
+/************************************************************************/
+
 static Lisp_Object
 mswindows_modal_loop_error_handler (Lisp_Object cons_sig_data,
 				    Lisp_Object u_n_u_s_e_d)
@@ -312,98 +417,16 @@
   /* This function can call lisp */
 
   Lisp_Object result = Qt;
-
+  struct gcpro gcpro1;
+  GCPRO1 (result);
+  
   if (NILP(mswindows_error_caught_in_modal_loop))
       result = mswindows_protect_modal_loop (mswindows_unsafe_pump_events, Qnil);
+  UNGCPRO;
   return result;
 }
 
-/*
- * Find a free waitable slot
- */
-#if 0 /* NOTUSED */
-static int
-mswindows_find_free_waitable(void)
-{
-  int i;
-  for (i=0; i<mswindows_waitable_count; i++)
-    if (mswindows_waitable_info[i].type == mswindows_waitable_type_none)
-      return i;
-  assert (mswindows_waitable_count < MAX_WAITABLE);
-  return mswindows_waitable_count++;
-}
-#endif
 
-/*
- * Create a new waitable using the type and data passed in by the info structure
- * Returns a pointer to the info associated with the assigned waitable object
- */
-mswindows_waitable_info_type *
-mswindows_add_waitable(mswindows_waitable_info_type *info)
-{
-  int waitable;
-
-  switch (info->type)
-  {
-  case mswindows_waitable_type_dispatch:
-    assert (0); /* kkm - should not get here */
-    /* Can only have one waitable for the dispatch queue, and it's the first one */
-    assert (mswindows_waitable_count++ == 0);
-    waitable=0;
-#if 0
-    InitializeCriticalSection(&mswindows_dispatch_crit);
-#endif
-    assert (mswindows_waitable[0] = CreateSemaphore (NULL, 0, 0x7fffffff, NULL));
-    return mswindows_waitable_info+0;
-
-  default:
-    assert(0);
-  }
-  mswindows_waitable_info[waitable].type = info->type;
-  return mswindows_waitable_info+waitable;
-}
-
-/*
- * Remove a waitable using the type and data passed in by the info structure.
- */
-void
-mswindows_remove_waitable(mswindows_waitable_info_type *info)
-{
-  int waitable;
-
-  switch (info->type)
-  {
-
-  default:
-    assert(0);
-  }
-
-  CloseHandle(mswindows_waitable[waitable]);
-  mswindows_waitable[waitable] = 0;
-  mswindows_waitable_info[waitable].type = mswindows_waitable_type_none;
-  if (waitable == mswindows_waitable_count-1)
-    --mswindows_waitable_count;
-}
-
-/* 
- * Callback procedure for synchronous timer messages
- */
-static void CALLBACK
-mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime)
-{
-  Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
-  struct Lisp_Event *event = XEVENT (emacs_event);
-
-  if (KillTimer (NULL, id_timer))
-    --mswindows_pending_timers_count;
-
-  event->channel = Qnil;
-  event->timestamp = dwtime;
-  event->event_type = timeout_event;
-  event->event.timeout.interval_id = id_timer;
-
-  mswindows_enqueue_dispatch_event (emacs_event);
-}
 
 static void 
 mswindows_drain_windows_queue ()
@@ -523,20 +546,841 @@
       {
 	/* XXX FIXME: We should do some kind of round-robin scheme to ensure fairness */
 	int waitable = active - WAIT_OBJECT_0;
-	mswindows_waitable_info_type *info  = mswindows_waitable_info + waitable;
-
-	switch (info->type)
-	  {
-	    /* XXX FIXME: Should enque subprocess event here so that it is not lost */
-	  default:
-	    assert(0);
-	  }
+	assert(0);	/* #### */
       }
   } /* while */
 
   return;
 }
 
+/************************************************************************/
+/*                           Event generators                           */
+/************************************************************************/
+
+/* 
+ * Callback procedure for synchronous timer messages
+ */
+static void CALLBACK
+mswindows_wm_timer_callback (HWND hwnd, UINT umsg, UINT id_timer, DWORD dwtime)
+{
+  Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
+  struct Lisp_Event *event = XEVENT (emacs_event);
+
+  if (KillTimer (NULL, id_timer))
+    --mswindows_pending_timers_count;
+
+  event->channel = Qnil;
+  event->timestamp = dwtime;
+  event->event_type = timeout_event;
+  event->event.timeout.interval_id = id_timer;
+
+  mswindows_enqueue_dispatch_event (emacs_event);
+}
+
+/* 
+ * Callback procedure for dde messages
+ */
+HDDEDATA CALLBACK
+mswindows_dde_callback (UINT uType, UINT uFmt, HCONV hconv,
+			HSZ hszTopic, HSZ hszItem, HDDEDATA hdata,
+			DWORD dwData1, DWORD dwData2)
+{ 
+  switch (uType)
+    { 
+    case XTYP_CONNECT:
+      if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system))
+	return (HDDEDATA)TRUE;
+      return (HDDEDATA)FALSE;
+
+    case XTYP_WILDCONNECT:
+      {
+	/* We only support one {service,topic} pair */
+	HSZPAIR pairs[2] = {
+	  { mswindows_dde_service, mswindows_dde_topic_system }, { 0, 0 } };
+
+	if (!(hszItem  || DdeCmpStringHandles (hszItem, mswindows_dde_service)) &&
+	    !(hszTopic || DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system)));
+	  return (DdeCreateDataHandle (mswindows_dde_mlid, (LPBYTE)pairs,
+				       sizeof (pairs), 0L, 0, uFmt, 0));
+      }
+      return (HDDEDATA)NULL; 
+
+    case XTYP_EXECUTE:
+      if (!DdeCmpStringHandles (hszTopic, mswindows_dde_topic_system))
+	{
+	  DWORD len = DdeGetData (hdata, NULL, 0, 0);
+	  char *cmd = alloca (len+1);
+	  char *end;
+          Lisp_Object l_dndlist;
+	  Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
+	  struct Lisp_Event *event = XEVENT (emacs_event);
+
+	  DdeGetData (hdata, cmd, len, 0);
+	  cmd[len] = '\0';
+	  DdeFreeDataHandle (hdata);
+
+	  /* Check syntax & that it's an [Open("foo")] command */
+	  /* #### Ought to be generalised and accept some other commands */
+	  if (*cmd == '[')
+	    cmd++;
+	  if (strnicmp (cmd, MSWINDOWS_DDE_ITEM_OPEN,
+			strlen (MSWINDOWS_DDE_ITEM_OPEN)))
+	    return DDE_FNOTPROCESSED;
+	  cmd += strlen (MSWINDOWS_DDE_ITEM_OPEN);
+	  while (*cmd==' ')
+	    cmd++;
+	  if (*cmd!='(' || *(cmd+1)!='\"')
+	    return DDE_FNOTPROCESSED;
+	  end = (cmd+=2);
+	  while (*end && *end!='\"')
+	    end++;
+	  if (!*end)
+	    return DDE_FNOTPROCESSED;
+	  *end = '\0';
+	  if (*(++end)!=')')
+	    return DDE_FNOTPROCESSED;
+	  if (*(++end)==']')
+	    end++;
+	  if (*end)
+	    return DDE_FNOTPROCESSED;
+
+	  l_dndlist = make_ext_string (cmd, strlen(cmd), FORMAT_FILENAME);
+
+	  event->channel = Qnil;
+	  event->timestamp = GetTickCount();
+	  event->event_type = dnd_drop_event;
+	  event->event.dnd_drop.button = 0;
+	  event->event.dnd_drop.modifiers = 0;
+	  event->event.dnd_drop.x = -1;
+	  event->event.dnd_drop.y = -1;
+	  event->event.dnd_drop.data = Fcons (make_int (DndFile),
+					      Fcons (l_dndlist, Qnil));
+	  mswindows_enqueue_dispatch_event (emacs_event);
+
+	  return (HDDEDATA) DDE_FACK;
+	}
+      DdeFreeDataHandle (hdata); 
+      return (HDDEDATA) DDE_FNOTPROCESSED;
+
+    default: 
+      return (HDDEDATA) NULL; 
+    } 
+
+}
+
+/*
+ * The windows procedure for the window class XEMACS_CLASS
+ */
+LRESULT WINAPI
+mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+  /* Note: Remember to initialise emacs_event and event before use.
+     This code calls code that can GC. You must GCPRO before calling such code. */
+  Lisp_Object emacs_event = Qnil;
+  Lisp_Object fobj = Qnil;
+
+  struct Lisp_Event *event;
+  struct frame *frame;
+  struct mswindows_frame* msframe;
+
+  switch (message)
+  {
+  case WM_ERASEBKGND:
+    /* Erase background only during non-dynamic sizing */
+    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+    if (msframe->sizing && !mswindows_dynamic_frame_resize)
+      goto defproc;
+    return 1;
+
+  case WM_CLOSE:
+    fobj = mswindows_find_frame (hwnd);
+    enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt));
+    mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE);
+    break;
+
+  case WM_KEYDOWN:
+  case WM_SYSKEYDOWN:
+    {
+      BYTE keymap[256];
+      int has_AltGr = mswindows_current_layout_has_AltGr ();
+      int mods;
+      Lisp_Object keysym;
+
+      GetKeyboardState (keymap);
+      mods = mswindows_modifier_state (keymap, has_AltGr);
+
+      /* Handle those keys that TranslateMessage won't generate a WM_CHAR for */
+      if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods)))
+	mswindows_enqueue_keypress_event (hwnd, keysym, mods);
+      else
+	{
+	  int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
+	  BYTE keymap_orig[256];
+	  MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) };
+	  memcpy (keymap_orig, keymap, 256);
+
+	  /* Clear control and alt modifiers out of the keymap */
+	  keymap [VK_RCONTROL] = 0;
+	  keymap [VK_LMENU] = 0;
+	  if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80))
+	    {
+	      keymap [VK_LCONTROL] = 0;
+	      keymap [VK_CONTROL] = 0;
+	      keymap [VK_RMENU] = 0;
+	      keymap [VK_MENU] = 0;
+	    }
+	  SetKeyboardState (keymap);
+
+	  /* Have some WM_[SYS]CHARS in the queue */
+	  TranslateMessage (&msg);
+
+	  while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE)
+		 ||PeekMessage (&msg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE))
+	    {
+	      int ch = msg.wParam;
+	      /* CH is a character code for the key: 
+		 'C' for Shift+C and Ctrl+Shift+C
+		 'c' for c and Ctrl+c */
+
+	      /* #### If locale is not C, US or other latin-1,
+		 isalpha() maybe not what do we mean */
+	      
+	      /* XEmacs doesn't seem to like Shift on non-alpha keys */
+	      if (!isalpha(ch))
+		mods &= ~MOD_SHIFT;
+
+	      /* Un-capitalise alpha control keys */
+	      if ((mods & MOD_CONTROL) && isalpha(ch))
+		ch |= ('A' ^ 'a');
+
+	      /* If a quit char with no modifiers other than control and
+		 shift, then mark it with a fake modifier, which is removed
+		 upon dequeueing the event */
+	      /* #### This might also not withstand localization, if
+		 quit character is not a latin-1 symbol */
+	      if (((quit_ch < ' ' && (mods & MOD_CONTROL) && quit_ch + 'a' - 1 == ch)
+		   || (quit_ch >= ' ' && !(mods & MOD_CONTROL) && quit_ch == ch))
+		  && ((mods  & ~(MOD_CONTROL | MOD_SHIFT)) == 0))
+		{
+		  mods |= FAKE_MOD_QUIT;
+		  ++mswindows_quit_chars_count;
+		}
+
+	      mswindows_enqueue_keypress_event (hwnd, make_char(ch), mods);
+	    } /* while */
+	  SetKeyboardState (keymap_orig);
+	} /* else */
+    }
+    goto defproc;
+
+  case WM_MBUTTONDOWN:
+  case WM_MBUTTONUP:
+    /* Real middle mouse button has nothing to do with emulated one:
+       if one wants to exercise fingers playing chords on the mouse,
+       he is allowed to do that! */
+    mswindows_enqueue_mouse_button_event (hwnd, message,
+					  MAKEPOINTS (lParam), GetMessageTime());
+    break;
+    
+  case WM_LBUTTONUP:
+    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+    msframe->last_click_time =  GetMessageTime();
+
+    KillTimer (hwnd, BUTTON_2_TIMER_ID);
+    msframe->button2_need_lbutton = 0;
+    if (msframe->ignore_next_lbutton_up)
+      {
+	msframe->ignore_next_lbutton_up = 0;
+      }
+    else if (msframe->button2_is_down)
+      {
+	msframe->button2_is_down = 0;
+	msframe->ignore_next_rbutton_up = 1;
+	mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP,
+					      MAKEPOINTS (lParam), GetMessageTime());
+      }
+    else
+      {
+	if (msframe->button2_need_rbutton)
+	  {
+	    msframe->button2_need_rbutton = 0;
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
+						  MAKEPOINTS (lParam), GetMessageTime());
+	  }
+	mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONUP,
+					      MAKEPOINTS (lParam), GetMessageTime());
+      }
+    break;
+
+  case WM_RBUTTONUP:
+    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+    msframe->last_click_time =  GetMessageTime();
+
+    KillTimer (hwnd, BUTTON_2_TIMER_ID);
+    msframe->button2_need_rbutton = 0;
+    if (msframe->ignore_next_rbutton_up)
+      {
+	msframe->ignore_next_rbutton_up = 0;
+      }
+    else if (msframe->button2_is_down)
+      {
+	msframe->button2_is_down = 0;
+	msframe->ignore_next_lbutton_up = 1;
+	mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP,
+					      MAKEPOINTS (lParam), GetMessageTime());
+      }
+    else
+      {
+	if (msframe->button2_need_lbutton)
+	  {
+	    msframe->button2_need_lbutton = 0;
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
+						  MAKEPOINTS (lParam), GetMessageTime());
+	  }
+	mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONUP,
+					      MAKEPOINTS (lParam), GetMessageTime());
+      }
+    break;
+
+  case WM_LBUTTONDOWN:
+    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+
+    if (msframe->button2_need_lbutton)
+      {
+	KillTimer (hwnd, BUTTON_2_TIMER_ID);
+	msframe->button2_need_lbutton = 0;
+	msframe->button2_need_rbutton = 0;
+	if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam)))
+	  {
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN,
+						  MAKEPOINTS (lParam), GetMessageTime());
+	    msframe->button2_is_down = 1;
+	  }
+	else
+	  {
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
+			msframe->last_click_point, msframe->last_click_time);
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
+						  MAKEPOINTS (lParam), GetMessageTime());
+	  }
+      }
+    else
+      {
+	mswindows_set_chord_timer (hwnd);
+	msframe->button2_need_rbutton = 1;
+	msframe->last_click_point = MAKEPOINTS (lParam);
+      }
+    msframe->last_click_time =  GetMessageTime();
+    break;
+
+  case WM_RBUTTONDOWN:
+    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+
+    if (msframe->button2_need_rbutton)
+      {
+	KillTimer (hwnd, BUTTON_2_TIMER_ID);
+	msframe->button2_need_lbutton = 0;
+	msframe->button2_need_rbutton = 0;
+	if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam)))
+	  {
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN,
+						  MAKEPOINTS (lParam), GetMessageTime());
+	    msframe->button2_is_down = 1;
+	  }
+	else
+	  {
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
+				msframe->last_click_point, msframe->last_click_time);
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
+						  MAKEPOINTS (lParam), GetMessageTime());
+	  }
+      }
+    else
+      {
+	mswindows_set_chord_timer (hwnd);
+	msframe->button2_need_lbutton = 1;
+	msframe->last_click_point = MAKEPOINTS (lParam);
+      }
+    msframe->last_click_time =  GetMessageTime();
+    break;
+	
+  case WM_TIMER:
+    if (wParam == BUTTON_2_TIMER_ID)
+      {
+	msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+	KillTimer (hwnd, BUTTON_2_TIMER_ID);
+
+	if (msframe->button2_need_lbutton)
+	  {
+	    msframe->button2_need_lbutton = 0;
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
+				msframe->last_click_point, msframe->last_click_time);
+	  }
+	else if (msframe->button2_need_rbutton)
+	  {
+	    msframe->button2_need_rbutton = 0;
+	    mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
+				msframe->last_click_point, msframe->last_click_time);
+	  }
+      }
+    else
+      assert ("Spurious timer fired" == 0);
+    break;
+
+  case WM_MOUSEMOVE:
+    /* Optimization: don't report mouse movement while size is changind */
+    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+    if (!msframe->sizing)
+    {
+      /* When waiting for the second mouse button to finish
+	 button2 emulation, and have moved too far, just pretend
+	 as if timer has expired. This impoves drag-select feedback */
+      if ((msframe->button2_need_lbutton || msframe->button2_need_rbutton)
+	  && !mswindows_button2_near_enough (msframe->last_click_point,
+					     MAKEPOINTS (lParam)))
+	{
+	  KillTimer (hwnd, BUTTON_2_TIMER_ID);
+	  SendMessage (hwnd, WM_TIMER, BUTTON_2_TIMER_ID, 0);
+	}
+
+      emacs_event = Fmake_event (Qnil, Qnil);
+      event = XEVENT(emacs_event);
+
+      event->channel = mswindows_find_frame(hwnd);
+      event->timestamp = GetMessageTime();
+      event->event_type = pointer_motion_event;
+      event->event.motion.x = MAKEPOINTS(lParam).x;
+      event->event.motion.y = MAKEPOINTS(lParam).y;
+      event->event.motion.modifiers = mswindows_modifier_state (NULL, 0);
+      
+      mswindows_enqueue_dispatch_event (emacs_event);
+    }
+    break;
+
+  case WM_PAINT:
+    {
+      PAINTSTRUCT paintStruct;
+      
+      frame = XFRAME (mswindows_find_frame (hwnd));
+
+      BeginPaint (hwnd, &paintStruct);
+      mswindows_redraw_exposed_area (frame,
+			paintStruct.rcPaint.left, paintStruct.rcPaint.top,
+			paintStruct.rcPaint.right, paintStruct.rcPaint.bottom);
+      EndPaint (hwnd, &paintStruct);
+    }
+    break;
+
+  case WM_SIZE:
+    /* We only care about this message if our size has really changed */
+    if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED || wParam==SIZE_MINIMIZED)
+    {
+      RECT rect;
+      int columns, rows;
+
+      fobj = mswindows_find_frame (hwnd);
+      frame = XFRAME (fobj);
+      msframe  = FRAME_MSWINDOWS_DATA (frame);
+
+      /* We cannot handle frame map and unmap hooks right in
+	 this routine, because these may throw. We queue
+	 magic events to run these hooks instead - kkm */
+
+      if (wParam==SIZE_MINIMIZED)
+	{
+	  /* Iconified */
+	  FRAME_VISIBLE_P (frame) = 0;
+	  mswindows_enqueue_magic_event (hwnd, XM_UNMAPFRAME);
+	  Fframe_iconified_p (fobj);
+	}
+      else
+	{
+	  int was_visible = FRAME_VISIBLE_P (frame);
+	  if (!msframe->sizing && !was_visible)
+	    mswindows_enqueue_magic_event (hwnd, XM_MAPFRAME);
+	  
+	  GetClientRect(hwnd, &rect);
+      	  FRAME_VISIBLE_P(frame) = 1;
+	  FRAME_PIXWIDTH(frame) = rect.right;
+	  FRAME_PIXHEIGHT(frame) = rect.bottom;
+	  pixel_to_char_size (frame, rect.right, rect.bottom, &columns, &rows);
+	  change_frame_size (frame, rows, columns, 1);
+
+	  if (msframe->sizing && mswindows_dynamic_frame_resize)
+	    redisplay ();
+	}
+    }
+    break;
+
+  /* Misc magic events which only require that the frame be identified */
+  case WM_SETFOCUS:
+  case WM_KILLFOCUS:
+    mswindows_enqueue_magic_event (hwnd, message);
+    break;
+
+  case WM_WINDOWPOSCHANGING:
+    {
+      WINDOWPOS *wp = (LPWINDOWPOS) lParam;
+      WINDOWPLACEMENT wpl = { sizeof(WINDOWPLACEMENT) };
+      GetWindowPlacement(hwnd, &wpl);
+
+      /* Only interested if size is changing and we're not being iconified */
+      if ((wpl.showCmd != SW_SHOWMINIMIZED) && !(wp->flags & SWP_NOSIZE))
+      {
+	RECT ncsize = { 0, 0, 0, 0 };
+	int pixwidth, pixheight;
+ 	AdjustWindowRectEx (&ncsize, GetWindowLong (hwnd, GWL_STYLE),
+ 			    GetMenu(hwnd) != NULL,
+			    GetWindowLong (hwnd, GWL_EXSTYLE));
+
+	round_size_to_char (XFRAME (mswindows_find_frame (hwnd)),
+			    wp->cx - (ncsize.right - ncsize.left),
+			    wp->cy - (ncsize.bottom - ncsize.top),
+			    &pixwidth, &pixheight);
+
+	/* Convert client sizes to window sizes */
+	pixwidth += (ncsize.right - ncsize.left);
+	pixheight += (ncsize.bottom - ncsize.top);
+
+	if (wpl.showCmd != SW_SHOWMAXIMIZED)
+	  {
+	    /* Adjust so that the bottom or right doesn't move if it's
+	     * the top or left that's being changed */
+	    RECT rect;
+	    GetWindowRect (hwnd, &rect);
+
+	    if (rect.left != wp->x)
+	      wp->x += wp->cx - pixwidth;
+	    if (rect.top != wp->y)
+	      wp->y += wp->cy - pixheight;
+	  }
+
+	wp->cx = pixwidth;
+	wp->cy = pixheight;
+      }
+    }
+    break;
+
+  case WM_ENTERSIZEMOVE:
+    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+    msframe->sizing = 1;
+    return 0;
+
+  case WM_EXITSIZEMOVE:
+    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
+    msframe->sizing = 0;
+    /* Queue noop event */
+    mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE);
+    return 0;
+
+#ifdef HAVE_SCROLLBARS
+  case WM_VSCROLL:
+  case WM_HSCROLL:
+    {
+      /* Direction of scroll is determined by scrollbar instance. */
+      int code = (int) LOWORD(wParam);
+      int pos = (short int) HIWORD(wParam);
+      HWND hwndScrollBar = (HWND) lParam;
+      struct gcpro gcpro1, gcpro2;
+
+      mswindows_handle_scrollbar_event (hwndScrollBar, code,  pos);
+      GCPRO2 (emacs_event, fobj);
+      if (UNBOUNDP(mswindows_pump_outstanding_events()))	/* Can GC */
+	{
+	  /* Error during event pumping - cancel scroll */
+	  SendMessage (hwndScrollBar, WM_CANCELMODE, 0, 0);
+	}
+      UNGCPRO;
+      break;     
+    }
+#endif
+
+#ifdef HAVE_MENUBARS
+  case WM_INITMENU:
+    if (UNBOUNDP (mswindows_handle_wm_initmenu (
+			(HMENU) wParam,
+			XFRAME (mswindows_find_frame (hwnd)))))
+      SendMessage (hwnd, WM_CANCELMODE, 0, 0);
+    break;
+
+  case WM_INITMENUPOPUP:
+    if (!HIWORD(lParam))
+      {
+	if (UNBOUNDP (mswindows_handle_wm_initmenupopup (
+			(HMENU) wParam,
+			 XFRAME (mswindows_find_frame (hwnd)))))
+	  SendMessage (hwnd, WM_CANCELMODE, 0, 0);
+      }
+    break;
+
+  case WM_EXITMENULOOP:
+    if (UNBOUNDP (mswindows_handle_wm_exitmenuloop (
+			XFRAME (mswindows_find_frame (hwnd)))))
+      SendMessage (hwnd, WM_CANCELMODE, 0, 0);
+    break;
+
+#endif /* HAVE_MENUBARS */
+
+  case WM_COMMAND:
+    {
+      WORD id = LOWORD (wParam);
+      frame = XFRAME (mswindows_find_frame (hwnd));
+
+#ifdef HAVE_MENUBARS
+      if (!NILP (mswindows_handle_wm_command (frame, id)))
+	break;
+#endif
+
+#ifdef HAVE_TOOLBARS
+      O Toolbar Implementor, this place may have something for you!;
+#endif
+
+      /* Bite me - a spurious command. No abort(), for safety */
+      /* #### Perhaps, this message should be changed */
+      error ("Cannot decode command. Tell kkm he's a parallelogramm, if you know"
+	     " what does that mean!");
+    }
+  break;
+
+  case WM_DROPFILES:	/* implementation ripped-off from event-Xt.c */
+    {
+      UINT filecount, i, len;
+      POINT point;
+      char filename[MAX_PATH];
+      Lisp_Object l_type, l_dndlist = Qnil, l_item;
+
+      emacs_event = Fmake_event (Qnil, Qnil);
+      event = XEVENT(emacs_event);
+
+      if (!DragQueryPoint ((HANDLE) wParam, &point))
+	point.x = point.y = -1;		/* outside client area */
+
+      filecount = DragQueryFile ((HANDLE) wParam, -1, NULL, 0);
+      if (filecount == 1)
+	{
+      	  l_type = make_int (DndFile);
+	  len = DragQueryFile ((HANDLE) wParam, 0, filename, MAX_PATH);
+	  l_dndlist = make_ext_string (filename, len, FORMAT_FILENAME);
+	}
+      else
+	{
+	  l_type = make_int (DndFiles);	  
+	  for (i=0; i<filecount; i++)
+	    {
+  	      len = DragQueryFile ((HANDLE) wParam, i, filename, MAX_PATH);
+	      l_item = make_ext_string (filename, len, FORMAT_FILENAME);
+	      l_dndlist = Fcons (l_item, l_dndlist);	/* reverse order */
+	    }
+	}
+      DragFinish ((HANDLE) wParam);
+      
+      event->channel = mswindows_find_frame(hwnd);
+      event->timestamp = GetMessageTime();
+      event->event_type = dnd_drop_event;
+      event->event.dnd_drop.button = 1;		/* #### Should try harder */
+      event->event.dnd_drop.modifiers = mswindows_modifier_state (NULL, 0);
+      event->event.dnd_drop.x = point.x;
+      event->event.dnd_drop.y = point.y;
+      event->event.dnd_drop.data = Fcons (l_type, Fcons (l_dndlist, Qnil));
+
+      mswindows_enqueue_dispatch_event (emacs_event);
+    }
+  break;
+
+  defproc:
+  default:
+    return DefWindowProc (hwnd, message, wParam, lParam);
+  }
+  return (0);
+}
+
+
+/************************************************************************/
+/*      keyboard, mouse & other helpers for the windows procedure       */
+/************************************************************************/
+static void
+mswindows_set_chord_timer (HWND hwnd)
+{
+  int interval;
+
+  /* We get half system threshold as it seems to
+     long before drag-selection is shown */
+  if (mswindows_button2_chord_time <= 0)
+    interval = GetDoubleClickTime () / 2;
+  else
+    interval = mswindows_button2_chord_time;
+
+  SetTimer (hwnd, BUTTON_2_TIMER_ID, interval, 0);
+}
+
+static int
+mswindows_button2_near_enough (POINTS p1, POINTS p2)
+{
+  int dx, dy;
+  if (mswindows_button2_max_skew_x <= 0)
+    dx = GetSystemMetrics (SM_CXDOUBLECLK) / 2;
+  else
+    dx = mswindows_button2_max_skew_x;
+
+  if (mswindows_button2_max_skew_y <= 0)
+    dy = GetSystemMetrics (SM_CYDOUBLECLK) / 2;
+  else
+    dy = mswindows_button2_max_skew_y;
+
+  return abs (p1.x - p2.x) < dx && abs (p1.y- p2.y)< dy;
+}
+
+static int
+mswindows_current_layout_has_AltGr (void)
+{
+  /* This simple caching mechanism saves 10% of CPU
+     time when a key typed at autorepeat rate of 30 cps! */
+  static HKL last_hkl = 0;
+  static int last_hkl_has_AltGr;
+
+  HKL current_hkl = GetKeyboardLayout (0);
+  if (current_hkl != last_hkl)
+    {
+      TCHAR c;
+      last_hkl_has_AltGr = 0;
+      /* In this loop, we query whether a character requires
+	 AltGr to be down to generate it. If at least such one
+	 found, this means that the layout does regard AltGr */
+      for (c = ' '; c <= 0xFFU && c != 0 && !last_hkl_has_AltGr; ++c)
+	if (HIBYTE (VkKeyScan (c)) == 6)
+	  last_hkl_has_AltGr = 1;
+      last_hkl = current_hkl;
+    }
+  return last_hkl_has_AltGr;
+}
+
+
+/* Returns the state of the modifier keys in the format expected by the
+ * Lisp_Event key_data, button_data and motion_data modifiers member */
+int mswindows_modifier_state (BYTE* keymap, int has_AltGr)
+{
+  int mods = 0;
+
+  if (keymap == NULL)
+    {
+      keymap = (BYTE*) alloca(256);
+      GetKeyboardState (keymap);
+      has_AltGr = mswindows_current_layout_has_AltGr ();
+    }
+
+  if (has_AltGr && (keymap [VK_LCONTROL] & 0x80) && (keymap [VK_RMENU] & 0x80))
+    {
+      mods |= (keymap [VK_LMENU] & 0x80) ? MOD_META : 0;
+      mods |= (keymap [VK_RCONTROL] & 0x80) ? MOD_CONTROL : 0;
+    }
+  else
+    {
+      mods |= (keymap [VK_MENU] & 0x80) ? MOD_META : 0;
+      mods |= (keymap [VK_CONTROL] & 0x80) ? MOD_CONTROL : 0;
+    }
+
+  mods |= (keymap [VK_SHIFT] & 0x80) ? MOD_SHIFT : 0;
+
+  return mods;
+}
+
+/*
+ * Translate a mswindows virtual key to a keysym.
+ * Only returns non-Qnil for keys that don't generate WM_CHAR messages
+ * or whose ASCII codes (like space) xemacs doesn't like.
+ * Virtual key values are defined in winresrc.h
+ * XXX I'm not sure that KEYSYM("name") is the best thing to use here.
+ */
+Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods)
+{
+  switch (mswindows_key)
+  {
+  /* First the predefined ones */
+  case VK_BACK:		return QKbackspace;
+  case VK_TAB:		return QKtab;
+  case '\n':		return QKlinefeed;  /* No VK_LINEFEED in winresrc.h */
+  case VK_RETURN:	return QKreturn;
+  case VK_ESCAPE:	return QKescape;
+  case VK_SPACE:	return QKspace;
+  case VK_DELETE:	return QKdelete;
+
+  /* The rest */
+  case VK_CLEAR:	return KEYSYM ("clear");  /* Should do ^L ? */
+  case VK_PRIOR:	return KEYSYM ("prior");
+  case VK_NEXT:		return KEYSYM ("next");
+  case VK_END:		return KEYSYM ("end");
+  case VK_HOME:		return KEYSYM ("home");
+  case VK_LEFT:		return KEYSYM ("left");
+  case VK_UP:		return KEYSYM ("up");
+  case VK_RIGHT:	return KEYSYM ("right");
+  case VK_DOWN:		return KEYSYM ("down");
+  case VK_SELECT:	return KEYSYM ("select");
+  case VK_PRINT:	return KEYSYM ("print");
+  case VK_EXECUTE:	return KEYSYM ("execute");
+  case VK_SNAPSHOT:	return KEYSYM ("print");
+  case VK_INSERT:	return KEYSYM ("insert");
+  case VK_HELP:		return KEYSYM ("help");
+#if 0	/* XXX What are these supposed to do? */
+  case VK_LWIN		return KEYSYM ("");
+  case VK_RWIN		return KEYSYM ("");
+#endif
+  case VK_APPS:		return KEYSYM ("menu");
+  case VK_F1:		return KEYSYM ("f1");
+  case VK_F2:		return KEYSYM ("f2");
+  case VK_F3:		return KEYSYM ("f3");
+  case VK_F4:		return KEYSYM ("f4");
+  case VK_F5:		return KEYSYM ("f5");
+  case VK_F6:		return KEYSYM ("f6");
+  case VK_F7:		return KEYSYM ("f7");
+  case VK_F8:		return KEYSYM ("f8");
+  case VK_F9:		return KEYSYM ("f9");
+  case VK_F10:		return KEYSYM ("f10");
+  case VK_F11:		return KEYSYM ("f11");
+  case VK_F12:		return KEYSYM ("f12");
+  case VK_F13:		return KEYSYM ("f13");
+  case VK_F14:		return KEYSYM ("f14");
+  case VK_F15:		return KEYSYM ("f15");
+  case VK_F16:		return KEYSYM ("f16");
+  case VK_F17:		return KEYSYM ("f17");
+  case VK_F18:		return KEYSYM ("f18");
+  case VK_F19:		return KEYSYM ("f19");
+  case VK_F20:		return KEYSYM ("f20");
+  case VK_F21:		return KEYSYM ("f21");
+  case VK_F22:		return KEYSYM ("f22");
+  case VK_F23:		return KEYSYM ("f23");
+  case VK_F24:		return KEYSYM ("f24");
+  }
+  return Qnil;
+}
+
+/*
+ * Find the console that matches the supplied mswindows window handle
+ */
+Lisp_Object
+mswindows_find_console (HWND hwnd)
+{
+  Lisp_Object concons;
+
+  CONSOLE_LOOP (concons)
+    {
+      Lisp_Object console = XCAR (concons);
+      /* We only support one console so this must be it */
+      return console;
+    }
+
+  return Qnil;
+}
+
+/*
+ * Find the frame that matches the supplied mswindows window handle
+ */
+static Lisp_Object
+mswindows_find_frame (HWND hwnd)
+{
+  return (Lisp_Object) GetWindowLong (hwnd, XWL_FRAMEOBJ);
+}
+
+
 
 /************************************************************************/
 /*                            methods                                   */
@@ -554,7 +1398,8 @@
   if (milliseconds < 1)
     milliseconds = 1;
   ++mswindows_pending_timers_count;
-  return SetTimer (NULL, 0, milliseconds, mswindows_wm_timer_callback);
+  return SetTimer (NULL, 0, milliseconds,
+		   (TIMERPROC) mswindows_wm_timer_callback);
 }
 
 static void
@@ -617,11 +1462,6 @@
 static void
 emacs_mswindows_handle_magic_event (struct Lisp_Event *emacs_event)
 {
-#if 0  
-  stderr_out("magic %x, (%d,%d), (%d,%d)\n",
-	     EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event),
-	     rect->left, rect->top, rect->right, rect->bottom);
-#endif
   switch (EVENT_MSWINDOWS_MAGIC_TYPE(emacs_event))
   {
   case WM_SETFOCUS:
@@ -662,7 +1502,7 @@
     }
     break;
 			    
-      /* XXX What about Enter & Leave */
+      /* #### What about Enter & Leave */
 #if 0
       va_run_hook_with_args (in_p ? Qmouse_enter_frame_hook :
 			     Qmouse_leave_frame_hook, 1, frame);
--- a/src/event-msw.h	Mon Aug 13 10:18:22 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/* mswindows-specific defines for event-handling.
-   Copyright (C) 1997 Jonathan Harris.
-
-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. */
-
-/* Authorship:
-
-   Jonathan Harris, November 1997 for 20.4.
- */
-
-#ifndef _XEMACS_EVENT_MSW_H_
-#define _XEMACS_EVENT_MSW_H_
-
-#include <windows.h>
-
-/*
- * XXX FIXME: The following X modifier defs in events-mod.h clash with win32
- * hotkey defs in winuser.h. For the moment lose the win32 versions.
- * Maybe we should rename all of MOD_* to something that doesn't clash.
- */
-#ifdef MOD_CONTROL
-#  undef MOD_CONTROL
-#endif  
-#ifdef MOD_ALT
-#  undef MOD_ALT
-#endif  
-#ifdef MOD_SHIFT
-#  undef MOD_SHIFT
-#endif  
-#include "events-mod.h"
-
-/* The name of the main window class */
-#define XEMACS_CLASS "XEmacs"
-
-/* Granularity of timeouts in milliseconds & max number of active timeouts */
-#define MSW_TIMEOUT_GRANULARITY 25
-#define MSW_TIMEOUT_MAX	32
-
-/* Random globals */
-LRESULT WINAPI mswindows_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
-Lisp_Object mswindows_pump_outstanding_events (void);
-Lisp_Object mswindows_protect_modal_loop (Lisp_Object (*bfun) (Lisp_Object barg),
-					  Lisp_Object barg);
-void mswindows_unmodalize_signal_maybe (void);
-void mswindows_enqueue_dispatch_event (Lisp_Object event);
-void mswindows_enqueue_magic_event (HWND hwnd, UINT message);
-
-extern int mswindows_quit_chars_count;
-
-/* These are Lisp integer variables */
-/* Jonsthan, these need not to be globals after merge -- kkm */
-extern int mswindows_dynamic_frame_resize;
-extern int mswindows_num_mouse_buttons;
-extern int mswindows_button2_max_skew_x;
-extern int mswindows_button2_max_skew_y;
-extern int mswindows_button2_chord_time;
-
-/*
- * Event generating stuff
- */
-
-/* The number of things we can wait on */
-#define MAX_WAITABLE (MAXIMUM_WAIT_OBJECTS - 1)
-
-typedef enum mswindows_waitable_type
-{
-  mswindows_waitable_type_none,
-  mswindows_waitable_type_dispatch,
-  mswindows_waitable_type_timeout,
-  mswindows_waitable_type_process,
-  mswindows_waitable_type_socket
-} mswindows_waitable_type;
-
-typedef struct mswindows_timeout_data
-{
-  int milliseconds;
-  int id;
-} mswindows_timeout_data;
-
-typedef struct mswindows_waitable_info_type
-{
-  mswindows_waitable_type type;
-  union
-    {
-      mswindows_timeout_data	timeout;
-    } data;
-} mswindows_waitable_info_type;
-
-mswindows_waitable_info_type *mswindows_add_waitable(mswindows_waitable_info_type *info);
-void mswindows_remove_waitable(mswindows_waitable_info_type *info);
-
-/*
- * Some random function declarations in msw-proc.c
- */
-extern void mswindows_enqeue_dispatch_event (Lisp_Object event);
-Lisp_Object mswindows_cancel_dispatch_event (struct Lisp_Event* event);
-
-/*
- * Inside mswindows magic events
- */
-#define EVENT_MSWINDOWS_MAGIC_EVENT(e)	\
-	((e)->event.magic.underlying_mswindows_event)
-#define EVENT_MSWINDOWS_MAGIC_TYPE(e)	\
-	(EVENT_MSWINDOWS_MAGIC_EVENT(e).message)
-#define EVENT_MSWINDOWS_MAGIC_DATA(e)	\
-	(*((RECT *) (&(EVENT_MSWINDOWS_MAGIC_EVENT(e).data))))
-
-/*
- * Messages and magic events IDs
- */
-#define XM_BUMPQUEUE	(WM_USER + 101)
-#define XM_MAPFRAME	(WM_USER + 102)
-#define XM_UNMAPFRAME	(WM_USER + 103)
-
-/*
- * Window LONGs indices
- */
-#define XWL_FRAMEOBJ	0
-
-/* This must be number of the above long multiplied by 4 */
-#define MSWINDOWS_WINDOW_EXTRA_BYTES 4
-
-/* Fake key modifiers which attached to a quit char event.
-   Removed upon dequeueing an event */
-#define FAKE_MOD_QUIT	0x80
-
-#endif /* _XEMACS_EVENT_MSW_H_ */
--- a/src/event-stream.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/event-stream.c	Mon Aug 13 10:19:09 2007 +0200
@@ -2175,7 +2175,7 @@
     default:
       goto RETURN;
     case button_release_event:
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
 #endif
     case misc_user_event:
@@ -3969,7 +3969,7 @@
       if (EVENTP (event)
 	  && (XEVENT_TYPE (event) == button_press_event
 	      || XEVENT_TYPE (event) == button_release_event
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 	      || XEVENT_TYPE (event) == dnd_drop_event
 #endif
 	      || XEVENT_TYPE (event) == misc_user_event))
@@ -4003,7 +4003,7 @@
 	  {
 	  case button_press_event :
 	  case button_release_event :
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 	  case dnd_drop_event:
 #endif
 	  case misc_user_event :
@@ -4109,7 +4109,7 @@
 	else if (e->event_type == button_press_event
 		 || e->event_type == button_release_event)
 	  e->event.button.modifiers |= MOD_META;
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 	else if (e->event_type == dnd_drop_event)
 	  e->event.dnd_drop.modifiers |= MOD_META;
 #endif
@@ -4212,7 +4212,7 @@
       break;
     case button_press_event:
     case button_release_event:
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
 #endif
     case misc_user_event:
@@ -4442,7 +4442,7 @@
     {
     case button_press_event:
     case button_release_event:
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
 #endif
     case key_press_event:
--- a/src/events.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/events.c	Mon Aug 13 10:19:09 2007 +0200
@@ -66,7 +66,7 @@
 Lisp_Object Qkey_press, Qbutton_press, Qbutton_release, Qmisc_user;
 Lisp_Object Qascii_character;
 
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 Lisp_Object Qdnd_drop_event_p;
 Lisp_Object Qdnd_drop;
 #endif
@@ -135,7 +135,7 @@
     case magic_event:
     case empty_event:
     case dead_event:
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
 #endif
       break;
@@ -215,7 +215,7 @@
     case dead_event:
 	write_c_string ("#<DEALLOCATED-EVENT", printcharfun);
 	break;
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
       print_event_1 ("#<dnd-drop-event ", obj, printcharfun);
       break;
@@ -273,7 +273,7 @@
 	      internal_equal (e1->event.magic_eval.object,
 			      e2->event.magic_eval.object, 0));
 
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
       return (e1->event.dnd_drop.button    == e2->event.dnd_drop.button &&
 	      e1->event.dnd_drop.modifiers == e2->event.dnd_drop.modifiers &&
@@ -350,7 +350,7 @@
 		    (unsigned long) e->event.magic_eval.internal_function,
 		    internal_hash (e->event.magic_eval.object, depth + 1));
 
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
       return HASH4 (hash, e->event.dnd_drop.button, e->event.dnd_drop.modifiers,
 		    LISP_HASH(e->event.dnd_drop.data));
@@ -369,12 +369,7 @@
 #endif
 #ifdef HAVE_MS_WINDOWS
 	if (CONSOLE_MSWINDOWS_P (con))
-	 return HASH6 (hash, e->event.magic.underlying_mswindows_event.message,
-		       e->event.magic.underlying_mswindows_event.data[0],
-		       e->event.magic.underlying_mswindows_event.data[1],
-		       e->event.magic.underlying_mswindows_event.data[2],
-		       e->event.magic.underlying_mswindows_event.data[3]
-		       );
+	  return HASH2 (hash, e->event.magic.underlying_mswindows_event);
 #endif
       }
 
@@ -487,7 +482,7 @@
     e->event_type = button_release_event;
   else if (EQ (type, Qmotion))
     e->event_type = pointer_motion_event;
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
   else if (EQ (type, Qdnd_drop))
     {
       e->event_type = dnd_drop_event;
@@ -606,7 +601,7 @@
 	  CHECK_NATNUM (value);
 	  e->timestamp = XINT (value);
 	}
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
       else if (EQ (keyword, Qdnd_data))
 	{
 	  Lisp_Object dnd_tail;
@@ -630,7 +625,7 @@
 	      e->event.dnd_drop.data = Fcopy_tree (value, Qnil);
 	    }
 	}
-#endif /* HAVE_OFFIX_DND */
+#endif /* HAVE_OFFIX_DND || HAVE_MS_WINDOWS */
       else
 	signal_simple_error ("Invalid property", keyword);
     } /* while */
@@ -649,7 +644,7 @@
   if (e->event_type == pointer_motion_event
       || e->event_type == button_press_event
       || e->event_type == button_release_event
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
       || e->event_type == dnd_drop_event
 #endif
       )
@@ -666,7 +661,7 @@
 	}
       else if (e->event_type == button_press_event
 	       || e->event_type == button_release_event
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 	       || e->event_type == dnd_drop_event
 #endif
 	       )
@@ -685,14 +680,14 @@
       break;
     case button_press_event:
     case button_release_event:
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
 #endif
       if (!e->event.button.button)
 	error ("Undefined button for %s event",
 	       e->event_type == button_press_event
 	       ? "buton-press" :
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 	       e->event_type == button_release_event
 	       ? "button-release" : "dnd-drop"
 #else
@@ -956,7 +951,7 @@
     case button_press_event:
     case button_release_event:
     case misc_user_event:
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
 #endif
       return 1;
@@ -1216,7 +1211,7 @@
   int mouse_p = 0;
   int mod = 0;
   Lisp_Object key;
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
   int dnd_p = 0;
 #endif
 
@@ -1263,7 +1258,7 @@
 	else strcpy (buf, "???");
 	return;
       }
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
       {
 	dnd_p++;
@@ -1297,7 +1292,7 @@
       --mouse_p;
     }
 
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
   switch (dnd_p)
     {
     case 1:
@@ -1440,7 +1435,7 @@
     case process_event:		return Qprocess;
     case timeout_event:		return Qtimeout;
     case eval_event:		return Qeval;
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:	return Qdnd_drop;
 #endif
     case magic_event:
@@ -1497,7 +1492,7 @@
 */
        (event))
 {
-#ifndef HAVE_OFFIX_DND
+#if !defined(HAVE_OFFIX_DND) && !defined(HAVE_MS_WINDOWS)
 
   CHECK_EVENT_TYPE2 (event, button_press_event, button_release_event,
 		     Qbutton_event_p);
@@ -1507,7 +1502,7 @@
   return Qzero;
 #endif /* !HAVE_WINDOW_SYSTEM */
 
-#else /* HAVE_OFFIX_DND */
+#else /* HAVE_OFFIX_DND || HAVE_MS_WINDOWS */
 
   CHECK_LIVE_EVENT (event);
   if (XEVENT(event)->event_type == (button_press_event) ||
@@ -1541,7 +1536,7 @@
       return make_int (XEVENT (event)->event.button.modifiers);
     case pointer_motion_event:
       return make_int (XEVENT (event)->event.motion.modifiers);
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
       return make_int (XEVENT (event)->event.dnd_drop.modifiers);
 #endif
@@ -1586,7 +1581,7 @@
       *x = XEVENT (event)->event.button.x;
       *y = XEVENT (event)->event.button.y;
     }
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
   else if (XEVENT (event)->event_type == dnd_drop_event)
     {
       *x = XEVENT (event)->event.dnd_drop.x;
@@ -1743,7 +1738,7 @@
       pix_x = XEVENT (event)->event.button.x;
       pix_y = XEVENT (event)->event.button.y;
       break;
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event :
       pix_x = XEVENT (event)->event.dnd_drop.x;
       pix_y = XEVENT (event)->event.dnd_drop.y;
@@ -2103,7 +2098,7 @@
 */
        (event))
 {
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
  again:
   CHECK_LIVE_EVENT (event);
   switch (XEVENT (event)->event_type)
@@ -2114,9 +2109,9 @@
       event = wrong_type_argument (Qdnd_drop_event_p, event);
       goto again;
     }
-#else /* !HAVE_OFFIX_DND */
+#else /* !(HAVE_OFFIX_DND || HAVE_MS_WINDOWS) */
   return Qnil;
-#endif /* HAVE_OFFIX_DND */
+#endif /* HAVE_OFFIX_DND || HAVE_MS_WINDOWS */
 }
 
 DEFUN ("event-properties", Fevent_properties, 1, 1, 0, /*
@@ -2173,7 +2168,7 @@
       props = Fcons (Qfunction, Fcons (Fevent_function (event), props));
       break;
 
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
     case dnd_drop_event:
       props = Fcons (Qy, Fcons (Fevent_y_pixel (event), props));
       props = Fcons (Qx, Fcons (Fevent_x_pixel (event), props));
@@ -2262,7 +2257,7 @@
   defsymbol (&Qbutton_release, "button-release");
   defsymbol (&Qmisc_user, "misc-user");
   defsymbol (&Qascii_character, "ascii-character");
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
   defsymbol (&Qdnd_drop_event_p, "dnd-drop-event-p");
   defsymbol (&Qdnd_drop, "dnd-drop");
 #endif
--- a/src/events.h	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/events.h	Mon Aug 13 10:19:09 2007 +0200
@@ -255,7 +255,7 @@
 			a magic_event; the Lisp programmer need not know
 			anything more.
 
- #ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
  dnd_drop_event
  dnd_drag_event (* to be implemented *)
     button		What button went down or up.
@@ -302,7 +302,7 @@
   magic_eval_event,
   eval_event,
   misc_user_event,
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
   dnd_drop_event,
 #endif
   dead_event
@@ -355,7 +355,7 @@
   Lisp_Object	    object;
 };
 
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 struct dnd_drop_data
 {
   int               button;
@@ -378,11 +378,7 @@
   XEvent	    underlying_x_event;
 #endif
 #ifdef HAVE_MS_WINDOWS
-  struct
-    {
-      int	    message;
-      unsigned long data[4]; /* XXX Big enough for biggest thing? */
-    } underlying_mswindows_event;
+  int		    underlying_mswindows_event;
 #endif
 };
 
@@ -409,7 +405,7 @@
       struct eval_data		eval;	/* misc_user_event uses this too */
       union magic_data		magic;
       struct magic_eval_data	magic_eval;
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
       struct dnd_drop_data      dnd_drop;
 #endif
     } event;
--- a/src/faces.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/faces.c	Mon Aug 13 10:19:09 2007 +0200
@@ -872,6 +872,8 @@
 void
 init_device_faces (struct device *d)
 {
+  /* This function can call lisp */
+
   /* When making the initial terminal device, there is no Lisp code
      loaded, so we can't do this. */
   if (initialized)
--- a/src/frame-msw.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/frame-msw.c	Mon Aug 13 10:19:09 2007 +0200
@@ -32,7 +32,6 @@
 #include "lisp.h"
 
 #include "console-msw.h"
-#include "event-msw.h"
 
 #include "buffer.h"
 #include "faces.h"
@@ -132,6 +131,7 @@
   /* Don't do this earlier or we get a WM_PAINT before the frame is ready*/
   ShowWindow (FRAME_MSWINDOWS_HANDLE(f), SW_SHOWNORMAL);
   SetForegroundWindow (FRAME_MSWINDOWS_HANDLE(f));
+  DragAcceptFiles (FRAME_MSWINDOWS_HANDLE(f), TRUE);
 }
 
 static void
--- a/src/frame.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/frame.c	Mon Aug 13 10:19:09 2007 +0200
@@ -54,7 +54,7 @@
 Lisp_Object Vmap_frame_hook, Qmap_frame_hook;
 Lisp_Object Vunmap_frame_hook, Qunmap_frame_hook;
 int  allow_deletion_of_last_visible_frame;
-#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND)
+#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 Lisp_Object Vdrag_and_drop_functions, Qdrag_and_drop_functions;
 #endif
 Lisp_Object Vmouse_motion_handler;
@@ -2892,7 +2892,7 @@
   defsymbol (&Qmouse_leave_frame_hook, "mouse-leave-frame-hook");
   defsymbol (&Qmap_frame_hook, "map-frame-hook");
   defsymbol (&Qunmap_frame_hook, "unmap-frame-hook");
-#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND)
+#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
   defsymbol (&Qdrag_and_drop_functions, "drag-and-drop-functions");
 #endif
 
@@ -3082,7 +3082,7 @@
 */ );
   allow_deletion_of_last_visible_frame = 0;
 
-#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND)
+#if defined (HAVE_CDE) || defined (HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
   DEFVAR_LISP ("drag-and-drop-functions", &Vdrag_and_drop_functions /*
 Function or functions to run when an object is dropped on a frame.
 Each function is called with either two or three args.  If called with
@@ -3091,7 +3091,7 @@
 and the textual representation of the dragged object.
 */ );
   Vdrag_and_drop_functions = Qnil;
-#endif /* HAVE_CDE */
+#endif /* HAVE_CDE || HAVE_OFFIX_DND || HAVE_MS_WINDOWS */
 
   DEFVAR_LISP ("mouse-motion-handler", &Vmouse_motion_handler /*
 Handler for motion events.  One arg, the event.
--- a/src/glyphs.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/glyphs.c	Mon Aug 13 10:19:09 2007 +0200
@@ -2057,12 +2057,13 @@
 		void (*after_change) (Lisp_Object glyph, Lisp_Object property,
 				      Lisp_Object locale))
 {
+  /* This function can GC */
   Lisp_Object obj = Qnil;
   struct Lisp_Glyph *g =
     alloc_lcrecord_type (struct Lisp_Glyph, lrecord_glyph);
 
   g->type = type;
-  g->image = Fmake_specifier (Qimage);
+  g->image = Fmake_specifier (Qimage); /* This function can GC */
   switch (g->type)
     {
     case GLYPH_BUFFER:
@@ -2082,18 +2083,31 @@
       abort ();
     }
 
-  set_specifier_fallback (g->image, list1 (Fcons (Qnil, Vthe_nothing_vector)));
-  g->contrib_p = Fmake_specifier (Qboolean);
-  set_specifier_fallback (g->contrib_p, list1 (Fcons (Qnil, Qt)));
-  /* #### should have a specifier for the following */
-  g->baseline = Fmake_specifier (Qgeneric);
-  set_specifier_fallback (g->baseline, list1 (Fcons (Qnil, Qnil)));
-  g->face = Qnil;
-  g->plist = Qnil;
-  g->after_change = after_change;
-  XSETGLYPH (obj, g);
-
-  set_image_attached_to (g->image, obj, Qimage);
+  /* I think Fmake_specifier can GC.  I think set_specifier_fallback can GC. */
+  /* We're getting enough reports of odd behavior in this area it seems */
+  /* best to GCPRO everything. */
+  {
+    Lisp_Object tem1 = list1 (Fcons (Qnil, Vthe_nothing_vector));
+    Lisp_Object tem2 = list1 (Fcons (Qnil, Qt));
+    Lisp_Object tem3 = list1 (Fcons (Qnil, Qnil));
+    struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+
+    GCPRO4 (obj, tem1, tem2, tem3);
+
+    set_specifier_fallback (g->image, tem1);
+    g->contrib_p = Fmake_specifier (Qboolean);
+    set_specifier_fallback (g->contrib_p, tem2);
+    /* #### should have a specifier for the following */
+    g->baseline = Fmake_specifier (Qgeneric);
+    set_specifier_fallback (g->baseline, tem3);
+    g->face = Qnil;
+    g->plist = Qnil;
+    g->after_change = after_change;
+    XSETGLYPH (obj, g);
+
+    set_image_attached_to (g->image, obj, Qimage);
+    UNGCPRO;
+  }
 
   return obj;
 }
@@ -2853,6 +2867,8 @@
 void
 specifier_vars_of_glyphs (void)
 {
+  /* #### Can we GC here? The set_specifier_* calls definitely need */
+  /* protection. */
   /* display tables */
 
   DEFVAR_SPECIFIER ("current-display-table", &Vcurrent_display_table /*
--- a/src/keymap.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/keymap.c	Mon Aug 13 10:19:09 2007 +0200
@@ -239,7 +239,7 @@
   Qbutton6, Qbutton7;
 Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up, Qbutton4up,
   Qbutton5up, Qbutton6up, Qbutton7up;
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 Lisp_Object Qdrop0, Qdrop1, Qdrop2, Qdrop3, Qdrop4, Qdrop5, Qdrop6, Qdrop7;
 #endif
 Lisp_Object Qmenu_selection;
@@ -1432,7 +1432,7 @@
 	    returned_value->modifiers = XEVENT (spec)->event.button.modifiers;
 	    break;
 	  }
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
 	case dnd_drop_event:
 	  {
 	    switch (XEVENT (spec)->event.dnd_drop.button)
@@ -1553,7 +1553,7 @@
       EQ (raw_key.keysym, Qbutton5) || EQ (raw_key.keysym, Qbutton5up) ||
       EQ (raw_key.keysym, Qbutton6) || EQ (raw_key.keysym, Qbutton6up) ||
       EQ (raw_key.keysym, Qbutton7) || EQ (raw_key.keysym, Qbutton7up)
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
       || EQ (raw_key.keysym, Qdrop0)   || EQ (raw_key.keysym, Qdrop1)     ||
       EQ (raw_key.keysym, Qdrop2)   || EQ (raw_key.keysym, Qdrop3)     ||
       EQ (raw_key.keysym, Qdrop4)   || EQ (raw_key.keysym, Qdrop5)     ||
@@ -4290,7 +4290,7 @@
   defsymbol (&Qbutton5up, "button5up");
   defsymbol (&Qbutton6up, "button6up");
   defsymbol (&Qbutton7up, "button7up");
-#ifdef HAVE_OFFIX_DND
+#if defined(HAVE_OFFIX_DND) || defined(HAVE_MS_WINDOWS)
   defsymbol (&Qdrop0, "drop0");
   defsymbol (&Qdrop1, "drop1");
   defsymbol (&Qdrop2, "drop2");
--- a/src/lread.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/lread.c	Mon Aug 13 10:19:09 2007 +0200
@@ -566,10 +566,10 @@
   struct gcpro gcpro1, gcpro2, gcpro3;
   int reading_elc = 0;
   int message_p = NILP (nomessage);
-#ifdef DEBUG_XEMACS
+/*#ifdef DEBUG_XEMACS*/
   static Lisp_Object last_file_loaded;
   int pure_usage = 0;
-#endif
+/*#endif*/
 #ifdef DOS_NT
   int dosmode = O_TEXT;
 #endif /* DOS_NT */
@@ -578,14 +578,14 @@
 
   CHECK_STRING (file);
 
-#ifdef DEBUG_XEMACS
+/*#ifdef DEBUG_XEMACS*/
   if (purify_flag && noninteractive)
     {
       message_p = 1;
       last_file_loaded = file;
       pure_usage = purespace_usage ();
     }
-#endif /* DEBUG_XEMACS */
+/*#endif /* DEBUG_XEMACS */
 
   /* If file name is magic, call the handler.  */
   handler = Ffind_file_name_handler (file, Qload);
@@ -799,7 +799,7 @@
     /* #### Disgusting kludge */
     /* Run any load-hooks for this file.  */
     /* #### An even more disgusting kludge.  There is horrible code */
-    /* this is relying on the fact that dumped lisp files are found */
+    /* that is relying on the fact that dumped lisp files are found */
     /* via `load-path' search. */
     Lisp_Object name = file;
 
@@ -808,7 +808,13 @@
 	name = Ffile_name_nondirectory(file);
       }
 
-    tem = Fassoc (name, Vafter_load_alist);
+    {
+      struct gcpro ngcpro1;
+
+      NGCPRO1 (name);
+      tem = Fassoc (name, Vafter_load_alist);
+      NUNGCPRO;
+    }
     if (!NILP (tem))
       {
 	struct gcpro ngcpro1;
@@ -821,7 +827,7 @@
       }
   }
 
-#ifdef DEBUG_XEMACS
+/*#ifdef DEBUG_XEMACS*/
   if (purify_flag && noninteractive)
     {
       if (EQ (last_file_loaded, file))
@@ -830,7 +836,7 @@
 	message ("Loading %s ...done (%d)", XSTRING_DATA (file),
 		 purespace_usage() - pure_usage);
     }
-#endif /* DEBUG_XEMACS */
+/*#endif /* DEBUG_XEMACS */
 
   if (!noninteractive)
     PRINT_LOADING_MESSAGE ("done");
--- a/src/md5.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/md5.c	Mon Aug 13 10:19:09 2007 +0200
@@ -24,13 +24,17 @@
  */
 
 /* Synched up with: Not in FSF. */
-/* This file has been Mule-ized.  See comment at Fmd5(), though. */
+/* This file has been Mule-ized. */
 
 #include <config.h>
 #include "lisp.h"
 
 #include "buffer.h"
 #include "insdel.h"
+#include "lstream.h"
+#ifdef MULE
+#include "mule-coding.h"
+#endif
 
 typedef unsigned char *POINTER;/* POINTER defines a generic pointer type */
 typedef unsigned short int UINT2;/* UINT2 defines a two byte word */
@@ -355,24 +359,19 @@
 /* XEmacs interface code. */
 Lisp_Object Qmd5;
 
-/* #### There could be potential problems here with Mule.  I don't
-   know enough about the uses of MD5 to be able to tell for sure
-   whether this is a problem.  The basic potential problem is that
-   the hash value will be computed based on the internal representation
-   of the buffer; this would likely cause problems if the string
-   contains extended characters, because the extended characters
-   will get sent over the wire in an external form that is different
-   from their internal representation, and thus their MD5 hash would
-   be different. */
-
-DEFUN ("md5", Fmd5, 1, 3, 0, /*
+DEFUN ("md5", Fmd5, 1, 5, 0, /*
 Return the MD5 (a secure message digest algorithm) of an object.
 OBJECT is either a string or a buffer.
 Optional arguments START and END denote buffer positions for computing the
-hash of a portion of OBJECT.
+hash of a portion of OBJECT.  The optional CODING argument specifies the coding
+system the text is to be represented in while computing the digest.  This only
+has meaning with MULE, and defaults to the current format of the data.
+If ERROR-ME-NOT is nil, report an error if the coding system can't be
+determined.  Else assume binary coding if all else fails.
 */
-       (object, start, end))
+       (object, start, end, coding, error_me_not))
 {
+  /* This function can GC */
   MD_CTX context;
   unsigned char digest[16];
   unsigned char thehash[32];
@@ -384,31 +383,126 @@
     {
       MDUpdate (&context, (CONST unsigned char *) "", 0);
     }
-  else if (BUFFERP (object))
-    {
-      struct buffer *b = decode_buffer (object, 1);
-      Bufpos begv, endv;
-      Lisp_Object string;
-
-      /* Figure out where we need to get info from */
-      get_buffer_range_char (b, start, end, &begv, &endv, GB_ALLOW_NIL);
-
-      /* Get the string data from the buffer */
-      string = make_string_from_buffer (b, begv, endv - begv);
-
-    /* Compute the digest */
-      MDUpdate (&context, (unsigned char *) XSTRING_DATA (string),
-		XSTRING_LENGTH (string));
-    }
   else
     {
-      Bytecount len, bstart, bend;
-      CHECK_STRING (object);
-      get_string_range_byte (object, start, end, &bstart, &bend,
-			     GB_HISTORICAL_STRING_BEHAVIOR);
-      len = bend - bstart;
-      MDUpdate (&context, ((unsigned char *) XSTRING_DATA (object)
-			   + bstart), len);
+      Lisp_Object instream, outstream;
+      Lstream *istr, *ostr;
+      static Extbyte_dynarr *conversion_out_dynarr;
+      char tempbuf[1024]; /* some random amount */
+      struct gcpro gcpro1, gcpro2;
+#ifdef MULE
+      Lisp_Object conv_out_stream, coding_system;
+      Lstream *costr;
+      struct gcpro gcpro3;
+#endif
+
+      if (!conversion_out_dynarr)
+	conversion_out_dynarr = Dynarr_new (Extbyte);
+      else
+	Dynarr_reset (conversion_out_dynarr);
+
+      /* set up the in stream */
+      if (BUFFERP (object))
+	{
+	  struct buffer *b = decode_buffer (object, 1);
+	  Bufpos begv, endv;
+	  /* Figure out where we need to get info from */
+	  get_buffer_range_char (b, start, end, &begv, &endv, GB_ALLOW_NIL);
+
+	  instream = make_lisp_buffer_input_stream (b, begv, endv, 0);
+	}
+      else
+	{
+	  Bytecount bstart, bend;
+	  CHECK_STRING (object);
+	  get_string_range_byte (object, start, end, &bstart, &bend,
+				 GB_HISTORICAL_STRING_BEHAVIOR);
+	  instream = make_lisp_string_input_stream (object, bstart, bend);
+	}
+      istr = XLSTREAM (instream);
+
+#ifdef MULE
+      /* Find out what format the buffer will be saved in, so we can make
+	 the digest based on what it will look like on disk */
+      if (NILP(coding))
+	{
+	  if (BUFFERP(object)) 
+	    {
+	      /* Use the file coding for this buffer by default */
+	      coding_system = XBUFFER(object)->buffer_file_coding_system;
+	    }
+	  else
+	    {
+	      /* attempt to autodetect the coding of the string.  Note: this VERY hit-and-miss */
+	      enum eol_type eol = EOL_AUTODETECT;
+	      coding_system = Fget_coding_system(Qundecided);
+	      determine_real_coding_system(istr, &coding_system, &eol);
+	    }
+	  if (NILP(coding_system)) 
+	    coding_system = Fget_coding_system(Qbinary);
+	  else
+	    {
+	      coding_system = Ffind_coding_system (coding_system);
+	      if (NILP(coding_system))
+		coding_system = Fget_coding_system(Qbinary);
+	    }
+	}
+      else
+	{
+	  coding_system = Ffind_coding_system (coding);
+	  if (NILP(coding_system))
+	    if (NILP(error_me_not))
+	      signal_simple_error("No such coding system", coding);
+	    else
+	      coding_system = Fget_coding_system(Qbinary); /* default to binary */
+	}
+#endif
+      
+      /* setup the out stream */
+      outstream = make_dynarr_output_stream((unsigned_char_dynarr *)conversion_out_dynarr);
+      ostr = XLSTREAM (outstream);
+#ifdef MULE
+      /* setup the conversion stream */
+      conv_out_stream = make_encoding_output_stream (ostr, coding_system);
+      costr = XLSTREAM (conv_out_stream);
+      GCPRO3 (instream, outstream, conv_out_stream);
+#else
+      GCPRO2 (instream, outstream);
+#endif
+
+      /* Get the data while doing the conversion */
+      while (1) {
+	int size_in_bytes = Lstream_read (istr, tempbuf, sizeof (tempbuf));
+	if (!size_in_bytes)
+	  break;
+	/* It does seem the flushes are necessary... */
+#ifdef MULE
+	Lstream_write (costr, tempbuf, size_in_bytes);
+	Lstream_flush (costr);
+#else
+	Lstream_write (ostr, tempbuf, size_in_bytes);
+#endif
+	Lstream_flush (ostr);
+
+	/* Update the digest */
+	
+	MDUpdate (&context, (unsigned char *)Dynarr_atp(conversion_out_dynarr, 0), 
+		  Dynarr_length(conversion_out_dynarr));
+	/* reset the dynarr */
+	Lstream_rewind(ostr);
+      }
+      Lstream_close (istr);
+#ifdef MULE
+      Lstream_close (costr);
+#endif
+      Lstream_close (ostr);
+
+      UNGCPRO;
+      Lstream_delete (istr);
+      Lstream_delete (ostr);
+#ifdef MULE
+      Lstream_delete (costr);
+#endif
     }
 
   MDFinal (digest, &context);
--- a/src/menubar-msw.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/menubar-msw.c	Mon Aug 13 10:19:09 2007 +0200
@@ -83,7 +83,6 @@
 #include "console-msw.h"
 #include "emacsfns.h"
 #include "elhash.h"
-#include "event-msw.h"
 #include "events.h"
 #include "frame.h"
 #include "gui.h"
--- a/src/msw-proc.c	Mon Aug 13 10:18:22 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,876 +0,0 @@
-/* mswindows specific event-handling.
-   Copyright (C) 1997 Jonathan Harris.
-
-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. */
-
-/* Authorship:
-
-   Jonathan Harris, November 1997 for 20.4.
- */
-
-#include <config.h>
-#include "lisp.h"
-
-#include "console-msw.h"
-#include "device.h"
-#include "frame.h"
-#include "events.h"
-#include "event-msw.h"
-#include "redisplay.h"
-
-#ifdef HAVE_SCROLLBARS
-# include "scrollbar-msw.h"
-#endif
-
-#ifdef HAVE_MENUBARS
-# include "menubar-msw.h"
-#endif
-
-#ifdef DEBUG_XEMACS
-# include "opaque.h"	/* For the debug functions at the end of this file */
-# undef DEBUG_MESSAGES
-# undef DEBUG_TIMEOUTS
-#endif
-
-#ifdef HAVE_MENUBARS
-#define ADJR_MENUFLAG TRUE
-#else
-#define ADJR_MENUFLAG FALSE
-#endif
-
-/* Timer ID used for button2 emulation */
-#define BUTTON_2_TIMER_ID 1
-
-static Lisp_Object mswindows_find_frame (HWND hwnd);
-static Lisp_Object mswindows_find_console (HWND hwnd);
-static Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods);
-static int mswindows_modifier_state (BYTE* keymap, int has_AltGr);
-#if 0 /* NOTUSED */
-static int mswindows_enqueue_timeout (int milliseconds);
-static void mswindows_dequeue_timeout (int interval_id);
-
-/* Timeout queue */
-struct mswindows_timeout
-{
-  int ticks;
-  int interval_id;
-  struct mswindows_timeout *next;
-};
-typedef struct mswindows_timeout mswindows_timeout;
-static mswindows_timeout timeout_pool[MSW_TIMEOUT_MAX];
-static mswindows_timeout *timeout_head = NULL;
-
-static int timeout_mswindows_id;
-#endif
-
-/*----------------------------------------------------------------------------*/
-/* Enqueue helpers                                                            */
-/*----------------------------------------------------------------------------*/
-
-void
-mswindows_enqueue_magic_event (HWND hwnd, UINT message)
-{
-  Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
-  struct Lisp_Event* event = XEVENT (emacs_event);
-
-  event->channel = mswindows_find_frame (hwnd);
-  event->timestamp = GetMessageTime();
-  event->event_type = magic_event;
-  EVENT_MSWINDOWS_MAGIC_TYPE (event) = message;
-
-  mswindows_enqueue_dispatch_event (emacs_event);
-}
-
-static void
-mswindows_enqueue_mouse_button_event (HWND hwnd, UINT message, POINTS where, DWORD when)
-{
-
-  /* We always use last message time, because mouse button
-     events may get delayed, and XEmacs double click
-     recognition will fail */
-
-  Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
-  struct Lisp_Event* event = XEVENT(emacs_event);
-
-  event->channel = mswindows_find_frame(hwnd);
-  event->timestamp = when;
-  event->event.button.button =
-    (message==WM_LBUTTONDOWN || message==WM_LBUTTONUP) ? 1 :
-    ((message==WM_RBUTTONDOWN || message==WM_RBUTTONUP) ? 3 : 2);
-  event->event.button.x = where.x;
-  event->event.button.y = where.y;
-  event->event.button.modifiers = mswindows_modifier_state (NULL, 0);
-      
-  if (message==WM_LBUTTONDOWN || message==WM_MBUTTONDOWN ||
-      message==WM_RBUTTONDOWN)
-    {
-      event->event_type = button_press_event;
-      SetCapture (hwnd);
-    }
-  else
-    {
-      event->event_type = button_release_event;
-      ReleaseCapture ();
-    }
-  
-  mswindows_enqueue_dispatch_event (emacs_event);
-}
-
-static void
-mswindows_enqueue_keypress_event (HWND hwnd, Lisp_Object keysym, int mods)
-{
-  Lisp_Object emacs_event = Fmake_event (Qnil, Qnil);
-  struct Lisp_Event* event = XEVENT(emacs_event);
-
-  event->channel = mswindows_find_console(hwnd);
-  event->timestamp = GetMessageTime();
-  event->event_type = key_press_event;
-  event->event.key.keysym = keysym;
-  event->event.key.modifiers = mods;
-  mswindows_enqueue_dispatch_event (emacs_event);
-}
-
-static void
-mswindows_set_chord_timer (HWND hwnd)
-{
-  int interval;
-
-  /* We get half system threshold as it seems to
-     long before drag-selection is shown */
-  if (mswindows_button2_chord_time <= 0)
-    interval = GetDoubleClickTime () / 2;
-  else
-    interval = mswindows_button2_chord_time;
-
-  SetTimer (hwnd, BUTTON_2_TIMER_ID, interval, 0);
-}
-
-static int
-mswindows_button2_near_enough (POINTS p1, POINTS p2)
-{
-  int dx, dy;
-  if (mswindows_button2_max_skew_x <= 0)
-    dx = GetSystemMetrics (SM_CXDOUBLECLK) / 2;
-  else
-    dx = mswindows_button2_max_skew_x;
-
-  if (mswindows_button2_max_skew_y <= 0)
-    dy = GetSystemMetrics (SM_CYDOUBLECLK) / 2;
-  else
-    dy = mswindows_button2_max_skew_y;
-
-  return abs (p1.x - p2.x) < dx && abs (p1.y- p2.y)< dy;
-}
-
-static int
-mswindows_current_layout_has_AltGr ()
-{
-  /* This simple caching mechanism saves 10% of CPU
-     time when a key typed at autorepeat rate of 30 cps! */
-  static HKL last_hkl = 0;
-  static int last_hkl_has_AltGr;
-
-  HKL current_hkl = GetKeyboardLayout (0);
-  if (current_hkl != last_hkl)
-    {
-      TCHAR c;
-      last_hkl_has_AltGr = 0;
-      /* In this loop, we query whether a character requires
-	 AltGr to be down to generate it. If at least such one
-	 found, this means that the layout does regard AltGr */
-      for (c = ' '; c <= 0xFFU && c != 0 && !last_hkl_has_AltGr; ++c)
-	if (HIBYTE (VkKeyScan (c)) == 6)
-	  last_hkl_has_AltGr = 1;
-      last_hkl = current_hkl;
-    }
-  return last_hkl_has_AltGr;
-}
-
-/*
- * The windows procedure for the window class XEMACS_CLASS
- * Stuffs messages in the mswindows event queue
- */
-LRESULT WINAPI
-mswindows_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-  /* Note: Remember to initialise these before use */
-  Lisp_Object emacs_event;
-  struct Lisp_Event *event;
-  Lisp_Object fobj;
-  struct frame *frame;
-  struct mswindows_frame* msframe;
-
-  switch (message)
-  {
-  case WM_ERASEBKGND:
-    /* Erase background only during non-dynamic sizing */
-    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
-    if (msframe->sizing && !mswindows_dynamic_frame_resize)
-      goto defproc;
-    return 1;
-
-  case WM_CLOSE:
-    fobj = mswindows_find_frame (hwnd);
-    enqueue_misc_user_event (fobj, Qeval, list3 (Qdelete_frame, fobj, Qt));
-    mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE);
-    break;
-
-  case WM_KEYDOWN:
-  case WM_SYSKEYDOWN:
-    {
-      BYTE keymap[256];
-      int has_AltGr = mswindows_current_layout_has_AltGr ();
-      int mods;
-      Lisp_Object keysym;
-
-      GetKeyboardState (keymap);
-      mods = mswindows_modifier_state (keymap, has_AltGr);
-
-      /* Handle those keys that TranslateMessage won't generate a WM_CHAR for */
-      if (!NILP (keysym = mswindows_key_to_emacs_keysym(wParam, mods)))
-	mswindows_enqueue_keypress_event (hwnd, keysym, mods);
-      else
-	{
-	  int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
-	  BYTE keymap_orig[256];
-	  MSG msg = { hwnd, message, wParam, lParam, GetMessageTime(), (GetMessagePos()) };
-	  memcpy (keymap_orig, keymap, 256);
-
-	  /* Clear control and alt modifiers out of the keymap */
-	  keymap [VK_RCONTROL] = 0;
-	  keymap [VK_LMENU] = 0;
-	  if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80) || !(keymap [VK_RMENU] & 0x80))
-	    {
-	      keymap [VK_LCONTROL] = 0;
-	      keymap [VK_CONTROL] = 0;
-	      keymap [VK_RMENU] = 0;
-	      keymap [VK_MENU] = 0;
-	    }
-	  SetKeyboardState (keymap);
-
-	  /* Have some WM_[SYS]CHARS in the queue */
-	  TranslateMessage (&msg);
-
-	  while (PeekMessage (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE)
-		 ||PeekMessage (&msg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE))
-	    {
-	      int ch = msg.wParam;
-	      /* CH is a character code for the key: 
-		 'C' for Shift+C and Ctrl+Shift+C
-		 'c' for c and Ctrl+c */
-
-	      /* #### If locale is not C, US or other latin-1,
-		 isalpha() maybe not what do we mean */
-	      
-	      /* XEmacs doesn't seem to like Shift on non-alpha keys */
-	      if (!isalpha(ch))
-		mods &= ~MOD_SHIFT;
-
-	      /* Un-capitalise alpha control keys */
-	      if ((mods & MOD_CONTROL) && isalpha(ch))
-		ch |= ('A' ^ 'a');
-
-	      /* If a quit char with no modifiers other than control and
-		 shift, then mark it with a fake modifier, which is removed
-		 upon dequeueing the event */
-	      /* #### This might also not withstand localization, if
-		 quit character is not a latin-1 symbol */
-	      if (((quit_ch < ' ' && (mods & MOD_CONTROL) && quit_ch + 'a' - 1 == ch)
-		   || (quit_ch >= ' ' && !(mods & MOD_CONTROL) && quit_ch == ch))
-		  && ((mods  & ~(MOD_CONTROL | MOD_SHIFT)) == 0))
-		{
-		  mods |= FAKE_MOD_QUIT;
-		  ++mswindows_quit_chars_count;
-		}
-
-	      mswindows_enqueue_keypress_event (hwnd, make_char(ch), mods);
-	    } /* while */
-	  SetKeyboardState (keymap_orig);
-	} /* else */
-    }
-    goto defproc;
-
-  case WM_MBUTTONDOWN:
-  case WM_MBUTTONUP:
-    /* Real middle mouse button has nothing to do with emulated one:
-       if one wants to exercise fingers playing chords on the mouse,
-       he is allowed to do that! */
-    mswindows_enqueue_mouse_button_event (hwnd, message,
-					  MAKEPOINTS (lParam), GetMessageTime());
-    break;
-    
-  case WM_LBUTTONUP:
-    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
-    msframe->last_click_time =  GetMessageTime();
-
-    KillTimer (hwnd, BUTTON_2_TIMER_ID);
-    msframe->button2_need_lbutton = 0;
-    if (msframe->ignore_next_lbutton_up)
-      {
-	msframe->ignore_next_lbutton_up = 0;
-      }
-    else if (msframe->button2_is_down)
-      {
-	msframe->button2_is_down = 0;
-	msframe->ignore_next_rbutton_up = 1;
-	mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP,
-					      MAKEPOINTS (lParam), GetMessageTime());
-      }
-    else
-      {
-	if (msframe->button2_need_rbutton)
-	  {
-	    msframe->button2_need_rbutton = 0;
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
-						  MAKEPOINTS (lParam), GetMessageTime());
-	  }
-	mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONUP,
-					      MAKEPOINTS (lParam), GetMessageTime());
-      }
-    break;
-
-  case WM_RBUTTONUP:
-    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
-    msframe->last_click_time =  GetMessageTime();
-
-    KillTimer (hwnd, BUTTON_2_TIMER_ID);
-    msframe->button2_need_rbutton = 0;
-    if (msframe->ignore_next_rbutton_up)
-      {
-	msframe->ignore_next_rbutton_up = 0;
-      }
-    else if (msframe->button2_is_down)
-      {
-	msframe->button2_is_down = 0;
-	msframe->ignore_next_lbutton_up = 1;
-	mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONUP,
-					      MAKEPOINTS (lParam), GetMessageTime());
-      }
-    else
-      {
-	if (msframe->button2_need_lbutton)
-	  {
-	    msframe->button2_need_lbutton = 0;
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
-						  MAKEPOINTS (lParam), GetMessageTime());
-	  }
-	mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONUP,
-					      MAKEPOINTS (lParam), GetMessageTime());
-      }
-    break;
-
-  case WM_LBUTTONDOWN:
-    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
-
-    if (msframe->button2_need_lbutton)
-      {
-	KillTimer (hwnd, BUTTON_2_TIMER_ID);
-	msframe->button2_need_lbutton = 0;
-	msframe->button2_need_rbutton = 0;
-	if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam)))
-	  {
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN,
-						  MAKEPOINTS (lParam), GetMessageTime());
-	    msframe->button2_is_down = 1;
-	  }
-	else
-	  {
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
-			msframe->last_click_point, msframe->last_click_time);
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
-						  MAKEPOINTS (lParam), GetMessageTime());
-	  }
-      }
-    else
-      {
-	mswindows_set_chord_timer (hwnd);
-	msframe->button2_need_rbutton = 1;
-	msframe->last_click_point = MAKEPOINTS (lParam);
-      }
-    msframe->last_click_time =  GetMessageTime();
-    break;
-
-  case WM_RBUTTONDOWN:
-    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
-
-    if (msframe->button2_need_rbutton)
-      {
-	KillTimer (hwnd, BUTTON_2_TIMER_ID);
-	msframe->button2_need_lbutton = 0;
-	msframe->button2_need_rbutton = 0;
-	if (mswindows_button2_near_enough (msframe->last_click_point, MAKEPOINTS (lParam)))
-	  {
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_MBUTTONDOWN,
-						  MAKEPOINTS (lParam), GetMessageTime());
-	    msframe->button2_is_down = 1;
-	  }
-	else
-	  {
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
-				msframe->last_click_point, msframe->last_click_time);
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
-						  MAKEPOINTS (lParam), GetMessageTime());
-	  }
-      }
-    else
-      {
-	mswindows_set_chord_timer (hwnd);
-	msframe->button2_need_lbutton = 1;
-	msframe->last_click_point = MAKEPOINTS (lParam);
-      }
-    msframe->last_click_time =  GetMessageTime();
-    break;
-	
-  case WM_TIMER:
-    if (wParam == BUTTON_2_TIMER_ID)
-      {
-	msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
-	KillTimer (hwnd, BUTTON_2_TIMER_ID);
-
-	if (msframe->button2_need_lbutton)
-	  {
-	    msframe->button2_need_lbutton = 0;
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_RBUTTONDOWN,
-				msframe->last_click_point, msframe->last_click_time);
-	  }
-	else if (msframe->button2_need_rbutton)
-	  {
-	    msframe->button2_need_rbutton = 0;
-	    mswindows_enqueue_mouse_button_event (hwnd, WM_LBUTTONDOWN,
-				msframe->last_click_point, msframe->last_click_time);
-	  }
-      }
-    else
-      assert ("Spurious timer fired" == 0);
-    break;
-
-  case WM_MOUSEMOVE:
-    /* Optimization: don't report mouse movement while size is changind */
-    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
-    if (!msframe->sizing)
-    {
-      /* When waiting for the second mouse button to finish
-	 button2 emulation, and have moved too far, just pretend
-	 as if timer has expired. This impoves drag-select feedback */
-      if ((msframe->button2_need_lbutton || msframe->button2_need_rbutton)
-	  && !mswindows_button2_near_enough (msframe->last_click_point,
-					     MAKEPOINTS (lParam)))
-	{
-	  KillTimer (hwnd, BUTTON_2_TIMER_ID);
-	  SendMessage (hwnd, WM_TIMER, BUTTON_2_TIMER_ID, 0);
-	}
-
-      emacs_event = Fmake_event (Qnil, Qnil);
-      event = XEVENT(emacs_event);
-
-      event->channel = mswindows_find_frame(hwnd);
-      event->timestamp = GetMessageTime();
-      event->event_type = pointer_motion_event;
-      event->event.motion.x = MAKEPOINTS(lParam).x;
-      event->event.motion.y = MAKEPOINTS(lParam).y;
-      event->event.motion.modifiers = mswindows_modifier_state (NULL, 0);
-      
-      mswindows_enqueue_dispatch_event (emacs_event);
-    }
-    break;
-
-  case WM_PAINT:
-    {
-      PAINTSTRUCT paintStruct;
-      
-      frame = XFRAME (mswindows_find_frame (hwnd));
-
-      BeginPaint (hwnd, &paintStruct);
-      mswindows_redraw_exposed_area (frame,
-			paintStruct.rcPaint.left, paintStruct.rcPaint.top,
-			paintStruct.rcPaint.right, paintStruct.rcPaint.bottom);
-      EndPaint (hwnd, &paintStruct);
-    }
-    break;
-
-  case WM_SIZE:
-    /* We only care about this message if our size has really changed */
-    if (wParam==SIZE_RESTORED || wParam==SIZE_MAXIMIZED || wParam==SIZE_MINIMIZED)
-    {
-      RECT rect;
-      int columns, rows;
-
-      fobj = mswindows_find_frame (hwnd);
-      frame = XFRAME (fobj);
-      msframe  = FRAME_MSWINDOWS_DATA (frame);
-
-      /* We cannot handle frame map and unmap hooks right in
-	 this routine, because these may throw. We queue
-	 magic events to run these hooks instead - kkm */
-
-      if (wParam==SIZE_MINIMIZED)
-	{
-	  /* Iconified */
-	  FRAME_VISIBLE_P (frame) = 0;
-	  mswindows_enqueue_magic_event (hwnd, XM_UNMAPFRAME);
-	  Fframe_iconified_p (fobj);
-	}
-      else
-	{
-	  int was_visible = FRAME_VISIBLE_P (frame);
-	  if (!msframe->sizing && !was_visible)
-	    mswindows_enqueue_magic_event (hwnd, XM_MAPFRAME);
-	  
-	  GetClientRect(hwnd, &rect);
-      	  FRAME_VISIBLE_P(frame) = 1;
-	  FRAME_PIXWIDTH(frame) = rect.right;
-	  FRAME_PIXHEIGHT(frame) = rect.bottom;
-	  pixel_to_char_size (frame, rect.right, rect.bottom, &columns, &rows);
-	  change_frame_size (frame, rows, columns, 1);
-
-	  if (msframe->sizing && mswindows_dynamic_frame_resize)
-	    redisplay ();
-	}
-    }
-    break;
-
-  /* Misc magic events which only require that the frame be identified */
-  case WM_SETFOCUS:
-  case WM_KILLFOCUS:
-    mswindows_enqueue_magic_event (hwnd, message);
-    break;
-
-  case WM_WINDOWPOSCHANGING:
-    {
-      WINDOWPOS *wp = (LPWINDOWPOS) lParam;
-      WINDOWPLACEMENT wpl = { sizeof(WINDOWPLACEMENT) };
-      GetWindowPlacement(hwnd, &wpl);
-
-      /* Only interested if size is changing and we're not being iconified */
-      if ((wpl.showCmd != SW_SHOWMINIMIZED) && !(wp->flags & SWP_NOSIZE))
-      {
-	RECT ncsize = { 0, 0, 0, 0 };
-	int pixwidth, pixheight;
- 	AdjustWindowRectEx (&ncsize, GetWindowLong (hwnd, GWL_STYLE),
- 			    GetMenu(hwnd) != NULL,
-			    GetWindowLong (hwnd, GWL_EXSTYLE));
-
-	round_size_to_char (XFRAME (mswindows_find_frame (hwnd)),
-			    wp->cx - (ncsize.right - ncsize.left),
-			    wp->cy - (ncsize.bottom - ncsize.top),
-			    &pixwidth, &pixheight);
-
-	/* Convert client sizes to window sizes */
-	pixwidth += (ncsize.right - ncsize.left);
-	pixheight += (ncsize.bottom - ncsize.top);
-
-	if (wpl.showCmd != SW_SHOWMAXIMIZED)
-	  {
-	    /* Adjust so that the bottom or right doesn't move if it's
-	     * the top or left that's being changed */
-	    RECT rect;
-	    GetWindowRect (hwnd, &rect);
-
-	    if (rect.left != wp->x)
-	      wp->x += wp->cx - pixwidth;
-	    if (rect.top != wp->y)
-	      wp->y += wp->cy - pixheight;
-	  }
-
-	wp->cx = pixwidth;
-	wp->cy = pixheight;
-      }
-    }
-    break;
-
-  case WM_ENTERSIZEMOVE:
-    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
-    msframe->sizing = 1;
-    return 0;
-
-  case WM_EXITSIZEMOVE:
-    msframe  = FRAME_MSWINDOWS_DATA (XFRAME (mswindows_find_frame (hwnd)));
-    msframe->sizing = 0;
-    /* Queue noop event */
-    mswindows_enqueue_magic_event (hwnd, XM_BUMPQUEUE);
-    return 0;
-
-#ifdef HAVE_SCROLLBARS
-  case WM_VSCROLL:
-  case WM_HSCROLL:
-    {
-      /* Direction of scroll is determined by scrollbar instance. */
-      int code = (int) LOWORD(wParam);
-      int pos = (short int) HIWORD(wParam);
-      HWND hwndScrollBar = (HWND) lParam;
-      mswindows_handle_scrollbar_event (hwndScrollBar, code,  pos);
-
-      if (UNBOUNDP(mswindows_pump_outstanding_events()))
-	{
-	  /* Error during event pumping - cancel scroll */
-	  SendMessage (hwndScrollBar, WM_CANCELMODE, 0, 0);
-	}
-
-      break;     
-    }
-#endif
-
-#ifdef HAVE_MENUBARS
-  case WM_INITMENU:
-    if (UNBOUNDP (mswindows_handle_wm_initmenu (
-			(HMENU) wParam,
-			XFRAME (mswindows_find_frame (hwnd)))))
-      SendMessage (hwnd, WM_CANCELMODE, 0, 0);
-    break;
-
-  case WM_INITMENUPOPUP:
-    if (!HIWORD(lParam))
-      {
-	if (UNBOUNDP (mswindows_handle_wm_initmenupopup (
-			(HMENU) wParam,
-			 XFRAME (mswindows_find_frame (hwnd)))))
-	  SendMessage (hwnd, WM_CANCELMODE, 0, 0);
-      }
-    break;
-
-  case WM_EXITMENULOOP:
-    if (UNBOUNDP (mswindows_handle_wm_exitmenuloop (
-			XFRAME (mswindows_find_frame (hwnd)))))
-      SendMessage (hwnd, WM_CANCELMODE, 0, 0);
-    break;
-
-#endif /* HAVE_MENUBARS */
-
-  case WM_COMMAND:
-    {
-      WORD id = LOWORD (wParam);
-      frame = XFRAME (mswindows_find_frame (hwnd));
-
-#ifdef HAVE_MENUBARS
-      if (!NILP (mswindows_handle_wm_command (frame, id)))
-	break;
-#endif
-
-#ifdef HAVE_TOOLBARS
-      O Toolbar Implementor, this place may have something for you!;
-#endif
-
-      /* Bite me - a spurious command. No abort(), for safety */
-      /* #### Perhaps, this message should be changed */
-      error ("Cannot decode command. Tell kkm he's a parallelogramm, if you know"
-	     " what does that mean!");
-    }
-  break;
-
-  defproc:
-  default:
-    return DefWindowProc (hwnd, message, wParam, lParam);
-  }
-  return (0);
-}
-
-/* Returns the state of the modifier keys in the format expected by the
- * Lisp_Event key_data, button_data and motion_data modifiers member */
-int mswindows_modifier_state (BYTE* keymap, int has_AltGr)
-{
-  int mods = 0;
-
-  if (keymap == NULL)
-    {
-      keymap = (BYTE*) alloca(256);
-      GetKeyboardState (keymap);
-      has_AltGr = mswindows_current_layout_has_AltGr ();
-    }
-
-  if (has_AltGr && (keymap [VK_LCONTROL] & 0x80) && (keymap [VK_RMENU] & 0x80))
-    {
-      mods |= (keymap [VK_LMENU] & 0x80) ? MOD_META : 0;
-      mods |= (keymap [VK_RCONTROL] & 0x80) ? MOD_CONTROL : 0;
-    }
-  else
-    {
-      mods |= (keymap [VK_MENU] & 0x80) ? MOD_META : 0;
-      mods |= (keymap [VK_CONTROL] & 0x80) ? MOD_CONTROL : 0;
-    }
-
-  mods |= (keymap [VK_SHIFT] & 0x80) ? MOD_SHIFT : 0;
-
-  return mods;
-}
-
-/*
- * Translate a mswindows virtual key to a keysym.
- * Only returns non-Qnil for keys that don't generate WM_CHAR messages
- * or whose ASCII codes (like space) xemacs doesn't like.
- * Virtual key values are defined in winresrc.h
- * XXX I'm not sure that KEYSYM("name") is the best thing to use here.
- */
-Lisp_Object mswindows_key_to_emacs_keysym(int mswindows_key, int mods)
-{
-  switch (mswindows_key)
-  {
-  /* First the predefined ones */
-  case VK_BACK:		return QKbackspace;
-  case VK_TAB:		return QKtab;
-  case '\n':		return QKlinefeed;  /* No VK_LINEFEED in winresrc.h */
-  case VK_RETURN:	return QKreturn;
-  case VK_ESCAPE:	return QKescape;
-  case VK_SPACE:	return QKspace;
-  case VK_DELETE:	return QKdelete;
-
-  /* The rest */
-  case VK_CLEAR:	return KEYSYM ("clear");  /* Should do ^L ? */
-  case VK_PRIOR:	return KEYSYM ("prior");
-  case VK_NEXT:		return KEYSYM ("next");
-  case VK_END:		return KEYSYM ("end");
-  case VK_HOME:		return KEYSYM ("home");
-  case VK_LEFT:		return KEYSYM ("left");
-  case VK_UP:		return KEYSYM ("up");
-  case VK_RIGHT:	return KEYSYM ("right");
-  case VK_DOWN:		return KEYSYM ("down");
-  case VK_SELECT:	return KEYSYM ("select");
-  case VK_PRINT:	return KEYSYM ("print");
-  case VK_EXECUTE:	return KEYSYM ("execute");
-  case VK_SNAPSHOT:	return KEYSYM ("print");
-  case VK_INSERT:	return KEYSYM ("insert");
-  case VK_HELP:		return KEYSYM ("help");
-#if 0	/* XXX What are these supposed to do? */
-  case VK_LWIN		return KEYSYM ("");
-  case VK_RWIN		return KEYSYM ("");
-#endif
-  case VK_APPS:		return KEYSYM ("menu");
-  case VK_F1:		return KEYSYM ("f1");
-  case VK_F2:		return KEYSYM ("f2");
-  case VK_F3:		return KEYSYM ("f3");
-  case VK_F4:		return KEYSYM ("f4");
-  case VK_F5:		return KEYSYM ("f5");
-  case VK_F6:		return KEYSYM ("f6");
-  case VK_F7:		return KEYSYM ("f7");
-  case VK_F8:		return KEYSYM ("f8");
-  case VK_F9:		return KEYSYM ("f9");
-  case VK_F10:		return KEYSYM ("f10");
-  case VK_F11:		return KEYSYM ("f11");
-  case VK_F12:		return KEYSYM ("f12");
-  case VK_F13:		return KEYSYM ("f13");
-  case VK_F14:		return KEYSYM ("f14");
-  case VK_F15:		return KEYSYM ("f15");
-  case VK_F16:		return KEYSYM ("f16");
-  case VK_F17:		return KEYSYM ("f17");
-  case VK_F18:		return KEYSYM ("f18");
-  case VK_F19:		return KEYSYM ("f19");
-  case VK_F20:		return KEYSYM ("f20");
-  case VK_F21:		return KEYSYM ("f21");
-  case VK_F22:		return KEYSYM ("f22");
-  case VK_F23:		return KEYSYM ("f23");
-  case VK_F24:		return KEYSYM ("f24");
-  }
-  return Qnil;
-}
-
-/*
- * Find the console that matches the supplied mswindows window handle
- */
-Lisp_Object
-mswindows_find_console (HWND hwnd)
-{
-  Lisp_Object concons;
-
-  CONSOLE_LOOP (concons)
-    {
-      Lisp_Object console = XCAR (concons);
-      /* We only support one console so this must be it */
-      return console;
-    }
-
-  return Qnil;
-}
-
-/*
- * Find the frame that matches the supplied mswindows window handle
- */
-static Lisp_Object
-mswindows_find_frame (HWND hwnd)
-{
-  return (Lisp_Object) GetWindowLong (hwnd, XWL_FRAMEOBJ);
-}
-
-
-#ifdef DEBUG_XEMACS
-/*
- * Random helper functions for debugging.
- * Intended for use in the MSVC "Watch" window which doesn't like
- * the aborts that the error_check_foo() functions can make.
- */
-struct lrecord_header *DHEADER(Lisp_Object obj)
-{
-  return (LRECORDP (obj)) ? XRECORD_LHEADER (obj) : NULL;
-}
-
-int *DOPAQUE_DATA (Lisp_Object obj)
-{
-  return (OPAQUEP (obj)) ? OPAQUE_DATA (XOPAQUE (obj)) : NULL;
-}
-
-struct Lisp_Event *DEVENT(Lisp_Object obj)
-{
-  return (EVENTP (obj)) ? XEVENT (obj) : NULL;
-}
-
-struct Lisp_Cons *DCONS(Lisp_Object obj)
-{
-  return (CONSP (obj)) ? XCONS (obj) : NULL;
-}
-
-Lisp_Object DCAR(Lisp_Object obj)
-{
-  return (CONSP (obj)) ? XCAR (obj) : 0;
-}
-
-Lisp_Object DCDR(Lisp_Object obj)
-{
-  return (CONSP (obj)) ? XCDR (obj) : 0;
-}
-
-struct Lisp_Cons *DCONSCDR(Lisp_Object obj)
-{
-  return ((CONSP (obj)) && (CONSP (XCDR (obj)))) ? XCONS (XCDR (obj)) : 0;
-}
-
-Lisp_Object DCARCDR(Lisp_Object obj)
-{
-  return ((CONSP (obj)) && (CONSP (XCDR (obj)))) ? XCAR (XCDR (obj)) : 0;
-}
-
-char *DSTRING(Lisp_Object obj)
-{
-  return (STRINGP (obj)) ? XSTRING_DATA (obj) : NULL;
-}
-
-struct Lisp_Vector *DVECTOR(Lisp_Object obj)
-{
-  return (VECTORP (obj)) ? XVECTOR (obj) : NULL;
-}
-
-struct Lisp_Symbol *DSYMBOL(Lisp_Object obj)
-{
-  return (SYMBOLP (obj)) ? XSYMBOL (obj) : NULL;
-}
-
-char *DSYMNAME(Lisp_Object obj)
-{
-  return (SYMBOLP (obj)) ? XSYMBOL (obj)->name->_data : NULL;
-}
-
-#endif
--- a/src/mule-ccl.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/mule-ccl.c	Mon Aug 13 10:19:09 2007 +0200
@@ -530,10 +530,11 @@
 {
   int *reg = ccl->reg;
   int ic = ccl->ic;
-  int code, field1, field2;
+  int code = -1; /* init to illegal value,  */
+  int field1, field2;
   Lisp_Object *ccl_prog = ccl->prog;
   unsigned char *src = source, *src_end = src + src_bytes;
-  int jump_address;
+  int jump_address = 0; /* shut up the compiler */
   int i, j, op;
   int stack_idx = 0;
   /* For the moment, we only support depth 256 of stack.  */ 
--- a/src/mule-coding.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/mule-coding.c	Mon Aug 13 10:19:09 2007 +0200
@@ -1452,7 +1452,7 @@
    This function does not automatically fetch subsidiary coding systems;
    that should be unnecessary with the explicit eol-type argument. */
 
-static void
+void
 determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out,
 			      enum eol_type *eol_type_in_out)
 {
--- a/src/mule-coding.h	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/mule-coding.h	Mon Aug 13 10:19:09 2007 +0200
@@ -451,4 +451,6 @@
 					       Lisp_Object codesys);
 extern void set_encoding_stream_coding_system (Lstream *stream,
 					       Lisp_Object codesys);
+extern void determine_real_coding_system (Lstream *stream, Lisp_Object *codesys_in_out,
+					  enum eol_type *eol_type_in_out);
 #endif /* _XEMACS_MULE_CODING_H_ */
--- a/src/objects-msw.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/objects-msw.c	Mon Aug 13 10:19:09 2007 +0200
@@ -1050,10 +1050,10 @@
     GetTextMetrics(hdc, &metrics);
     SelectObject(hdc, holdfont);
     ReleaseDC(hwnd, hdc);
-    f->width = metrics.tmAveCharWidth;
-    f->height = metrics.tmHeight;
-    f->ascent = metrics.tmAscent;
-    f->descent = metrics.tmDescent;
+    f->width = (unsigned short) metrics.tmAveCharWidth;
+    f->height = (unsigned short) metrics.tmHeight;
+    f->ascent = (unsigned short) metrics.tmAscent;
+    f->descent = (unsigned short) metrics.tmDescent;
     f->proportional_p = (metrics.tmPitchAndFamily & TMPF_FIXED_PITCH);
   }
 
--- a/src/redisplay-msw.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/redisplay-msw.c	Mon Aug 13 10:19:09 2007 +0200
@@ -538,7 +538,7 @@
       
   if (IntersectRect (&rect_paint, &rect_dead, prc))
     FillRect (FRAME_MSWINDOWS_DC (f), &rect_paint,
-	      (HBRUSH)GetClassLong (FRAME_MSWINDOWS_HANDLE(f), GCL_HBRBACKGROUND));
+	      (HBRUSH) (COLOR_BTNFACE+1));
 }
 
 #endif /* HAVE_SCROLLBARS */
--- a/src/redisplay.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/redisplay.c	Mon Aug 13 10:19:09 2007 +0200
@@ -5250,6 +5250,13 @@
 
       update_line_start_cache (w, start, end, pointm, 1);
       redisplay_output_window (w);
+      /*
+       * If we just displayed the echo area, the line start cache is
+       * no longer valid, because the minibuffer window is assocaited
+       * with the window now.
+       */
+      if (echo_active)
+	w->line_cache_last_updated = make_int (-1);
     }
 
   /* #### This should be dependent on face changes and will need to be
--- a/src/s/sunos4-0.h	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/s/sunos4-0.h	Mon Aug 13 10:19:09 2007 +0200
@@ -54,7 +54,25 @@
  */
 /* Since lcc is not going to be heavily used anymore if it ever was, I'm
    putting broken-sun.h back in. */
+/* Since Gcc 2.8 appears to have fixed the problem, I'm conditionalizing */
+/* this ugly hack. */
+
+#if defined (__GNUC__)
+#if defined (__GNUC_MINOR__)
+#if ((__GNUC__ == 2) && (__GNUC_MINOR__ > 7)) || ((__GNUC__ > 2))
+/* Don't include for gcc 2.8.0*/
+#else
 #include "../broken-sun.h"
+#endif
+
+#else /* __GNUC_MINOR__ is undefined */
+#include "../broken-sun.h"
+#endif
+
+#else
+/* Not GNU C */
+#endif
+
 extern char *strdup ();
 extern char *ttyname (int);
 extern void tzsetwall (void);
--- a/src/scrollbar-msw.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/scrollbar-msw.c	Mon Aug 13 10:19:09 2007 +0200
@@ -27,11 +27,11 @@
 #include "lisp.h"
 
 #include "console-msw.h"
+#include "scrollbar-msw.h"
+
 #include "frame.h"
 #include "window.h"
-#include "scrollbar-msw.h"
 #include "events.h"
-#include "event-msw.h"
 
 /* This has really different semantics in Windows than in Motif.
    There's no corresponding method; we just do not change slider
--- a/src/select-msw.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/select-msw.c	Mon Aug 13 10:19:09 2007 +0200
@@ -84,7 +84,7 @@
     
   GlobalUnlock (h);
   
-  i = SetClipboardData (CF_TEXT, h);
+  i = (SetClipboardData (CF_TEXT, h) != NULL);
   
   CloseClipboard ();
   GlobalFree (h);
--- a/src/toolbar.c	Mon Aug 13 10:18:22 2007 +0200
+++ b/src/toolbar.c	Mon Aug 13 10:19:09 2007 +0200
@@ -269,6 +269,7 @@
       /* The following calls will automatically cause the dirty
 	 flags to be set; we delay frame size changes to avoid
 	 lots of frame flickering. */
+      /* #### I think this should be GC protected. -sb */
       hold_frame_size_changes ();
       set_specifier_fallback (Vtoolbar[cur], list1 (Fcons (Qnil, Qnil)));
       set_specifier_fallback (Vtoolbar[new], Vdefault_toolbar);
--- a/src/unexcw.cc	Mon Aug 13 10:18:22 2007 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,606 +0,0 @@
-/* unexec for GNU Emacs on Cygwin32.
-   Copyright (C) 1994, 1998 Free Software Foundation, Inc.
-
-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.
-
-*/
-
-/* Adapted from unexnt.c Andy Piper (andyp@parallax.co.uk) 13-1-98 */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <config.h>
-#include <string.h>
-
-#define PERROR(arg) perror(arg);exit(-1) 
-
-#ifndef HAVE_COFF_H
-extern "C" void
-unexec (char *, char *, void *, void *,	void *)
-{
-  PERROR("cannot unexec() coff.h not installed");
-}
-
-extern "C" void run_time_remap (char *)
-{}
-#else
-
-#include <windows.h>
-/* 
- * unfortunately we need this c++ to get at the internals of cygwin
- */
-class pinfo;
-class per_process
-{
- public:
-  char *initial_sp;
-
-  /* The offset of these 3 values can never change.  */
-  /* magic_biscuit is the size of this class and should never change.  */
-  int magic_biscuit;
-  int version_major;
-  int version_minor;
-
-  struct _reent **impure_ptr_ptr;
-  char ***envptr;
-
-  /* Used to point to the memory machine we should use -
-     usually points back into the dll, but can be overridden by the user.  */
-  void *(*malloc)(size_t);
-  void (*free)(void *);
-  void *(*realloc)(void *, size_t);
-
-  int *fmode_ptr;
-
-  int (*main)(int, char **, char **);
-  void (**ctors)();
-  void (**dtors)();
-
-  /* For fork */
-  void *data_start;
-  void *data_end;
-  void *bss_start;
-  void *bss_end;
-
-  /* For future expansion of values set by the app.  */
-  void *public_reserved[4];
-
-  /* The rest are *internal* to cygwin.dll.
-     Those that are here because we want the child to inherit the value from
-     the parent (which happens when bss is copied) are marked as such.  */
-
-  /* FIXME: Which of these can go elsewhere?  */
-
-  /* FIXME: Delete, make `self' a global.  */
-  pinfo *self;		/* pointer only valid in self process */
-
-  /* non-zero of ctors have been run.  Inherited from parent.  */
-  int run_ctors_p;
-
-  /* These will be non-zero if the above (malloc,free,realloc) have been
-     overridden.  */
-  /* FIXME: not currently used */
-  int __imp_malloc;
-  int __imp_free;
-  int __imp_realloc;
-
-  /* Heap management.  Inherited from parent.  */
-  void *base;			/* bottom of the heap */
-  void *ptr;			/* current index into heap */
-  int  size;			/* current size of heap */
-
-  /* Mask of what to trace.  Inherited from parent.
-     See sys/strace.h for details.  The value of this is changeable from other
-     tasks via the `cygwin' utility so we want this in the shared data area
-     (and thus the process table since there's one of these per task).
-     However, we also want to turn on stracing as soon as possible and
-     therefore before we know which process table entry to use.  So we put it
-     here, and have a pointer to it in the process table.  */
-  int strace_mask;
-
-  /* Non-zero means the task was forked.  The value is the pid.
-     Inherited from parent.  */
-  int forkee;
-
-  void *hmodule;
-
-  void* /*HANDLE*/ signal_arrived;
-  /* For future expansion, so apps won't have to be relinked if we
-     add an item.  */
-  void *internal_reserved[9];
-
-  /*  struct file_queue *dq;	 !!! this may need to be nuked ? */
-};
-
-extern per_process cygwin_statu; /* pointer into the application's static data */
-
-#include <coff.h>
-
-#define ALLOC_UNIT 0xFFFF
-#define ALLOC_MASK ~((unsigned long)(ALLOC_UNIT))
-#define ALIGN_ALLOC(addr) \
-((((unsigned long)addr) + ALLOC_UNIT) & ALLOC_MASK)
-#define SIZEOF_PER_PROCESS (42 * 4)
-
-/*
- * Heap related stuff.
- */
-#define get_reserved_heap_size()	(*heap_size)
-#define get_committed_heap_size()	\
-(int)((unsigned char*)(*heap_index)-(unsigned char*)(*heap_base))
-#define get_heap_start()		(*heap_base)
-#define get_heap_end()			(*heap_index)
-
-extern "C" {
-void** heap_base = &cygwin_statu.base;
-void** heap_index = &cygwin_statu.ptr;
-int*   heap_size = &cygwin_statu.size;
-int*   heap_flag = &cygwin_statu.forkee;
-void*  per_process_data = &cygwin_statu;
-/* To prevent zero-initialized variables from being placed into the bss
-   section, use non-zero values to represent an uninitialized state.  */
-#define UNINIT_PTR ((void *) 0xF0A0F0A0)
-#define UNINIT_LONG (0xF0A0F0A0L)
-
-void* local_heap_base=UNINIT_PTR;
-void* local_heap_index=UNINIT_PTR;
-unsigned long local_heap_size=UNINIT_LONG;
-
-/* Recreate the heap created during dumping.  */
-
-enum {
-  HEAP_UNINITIALIZED = 1,
-  HEAP_UNLOADED,
-  HEAP_LOADED
-};
-
-/* Basically, our "initialized" flag.  */
-int heap_state = HEAP_UNINITIALIZED;
-
-/* So we can find our heap in the file to recreate it.  */
-unsigned long heap_index_in_executable = UNINIT_LONG;
-
-static void get_section_info (int a_out, char* a_name);
-static void copy_executable_and_dump_data_section (int a_out, int a_new);
-static void dump_heap (int a_out, int a_new);
-static void dup_file_area(int a_out, int a_new, long size);
-
-/* Cached info about the .data section in the executable.  */
-void* data_start_va = UNINIT_PTR;
-unsigned long  data_size = UNINIT_LONG;
-
-/* Cached info about the .bss section in the executable.  */
-void* bss_start = UNINIT_PTR;
-unsigned long  bss_size = UNINIT_LONG;
-FILHDR f_hdr;
-PEAOUTHDR f_ohdr;
-SCNHDR f_data, f_bss, f_text, f_idata;
-}
-#define PERROR(arg) perror(arg);exit(-1) 
-#define CHECK_AOUT_POS(a) \
-if (lseek(a_out, 0, SEEK_CUR) != a) \
-{ \
-  printf("we are at %lx, should be at %lx\n", \
-	 lseek(a_out, 0, SEEK_CUR), a); \
-  exit(-1); \
-}
-
-/* Dump out .data and .bss sections into a new executable.  */
-extern "C" void
-unexec (char *out_name, char *in_name, void *start_data, void *,	void *)
-{
-  /* ugly nt hack - should be in lisp */
-  char new_name[MAX_PATH], a_name[MAX_PATH];
-  char *ptr;
-  
-  /* Make sure that the input and output filenames have the
-     ".exe" extension...patch them up if they don't.  */
-  strcpy (a_name, in_name);
-  ptr = a_name + strlen (a_name) - 4;
-  if (strcmp (ptr, ".exe"))
-    strcat (a_name, ".exe");
-
-  strcpy (new_name, out_name);
-  ptr = new_name + strlen (new_name) - 4;
-  if (strcmp (ptr, ".exe"))
-    strcat (new_name, ".exe");
-  /* save heap info in our data segment so that we can recreate after
-     dumping */
-
-  local_heap_base = *heap_base;
-  local_heap_size = *heap_size;
-  local_heap_index = *heap_index;
-  
-  /* We need to round off our heap to NT's allocation unit (64KB).  */
-  /* round_heap (get_allocation_unit ()); */
-
-  int a_new, a_out = -1;
-
-  if (a_name && (a_out = open (a_name, O_RDONLY)) < 0)
-    {
-      PERROR (a_name);
-    }
-  if ((a_new = creat (new_name, 0666)) < 0)
-    {
-      PERROR (new_name);
-    }
-
-  /* Get the interesting section info, like start and size of .bss...  */
-  get_section_info (a_out, a_name);
-
-  /* Set the flag (before dumping).  */
-  heap_state = HEAP_UNLOADED;
-
-  copy_executable_and_dump_data_section (a_out, a_new);
-  dump_heap (a_out, a_new);
-
-  close(a_out);
-  close(a_new);
-}
-
-/* Flip through the executable and cache the info necessary for dumping.  */
-static void get_section_info (int a_out, char* a_name)
-{
-  if (read (a_out, &f_hdr, sizeof (f_hdr)) != sizeof (f_hdr))
-    {
-      PERROR (a_name);
-    }
-
-  if (f_hdr.e_magic != DOSMAGIC) 
-    {
-      PERROR("unknown exe header");
-    }
-
-  /* Check the NT header signature ...  */
-  if (f_hdr.nt_signature != NT_SIGNATURE) 
-    {
-      PERROR("invalid nt header");
-    }
-
-  /* Flip through the sections for .data and .bss ...  */
-  if (f_hdr.f_opthdr > 0)
-    {
-      if (read (a_out, &f_ohdr, AOUTSZ) != AOUTSZ)
-	{
-	  PERROR (a_name);
-	}
-    }
-  /* Loop through .data & .bss section headers, copying them in */
-  lseek (a_out, sizeof (f_hdr) + f_hdr.f_opthdr, 0);
-
-  if (read (a_out, &f_text, sizeof (f_text)) != sizeof (f_text)
-      &&
-      strcmp (f_text.s_name, ".text"))
-    {
-      PERROR ("no .text section");
-    }
-
-  /* The .bss section.  */
-  if (read (a_out, &f_bss, sizeof (f_bss)) != sizeof (f_bss)
-      &&
-      strcmp (f_bss.s_name, ".bss"))
-    {
-      PERROR ("no .bss section");
-    }
-  extern int my_ebss;
-  bss_start = (void *) ((char*)f_ohdr.ImageBase + f_bss.s_vaddr);
-  bss_size = (unsigned long)((char*)&my_ebss-(char*)bss_start);
-  
-  /* must keep bss data that we want to be blank as blank */
-  printf("found bss - keeping %lx of %lx bytes\n", bss_size, f_ohdr.bsize);
-
-  /* The .data section.  */
-  if (read (a_out, &f_data, sizeof (f_data)) != sizeof (f_data)
-      &&
-      strcmp (f_data.s_name, ".data"))
-    {
-      PERROR ("no .data section");
-    }
-
-  /* From lastfile.c  */
-  extern char my_edata[];
-
-  /* The .data section.  */
-  data_start_va = (void *) ((char*)f_ohdr.ImageBase + f_data.s_vaddr);
-
-  /* We want to only write Emacs data back to the executable,
-     not any of the library data (if library data is included,
-     then a dumped Emacs won't run on system versions other
-     than the one Emacs was dumped on).  */
-  data_size = my_edata - data_start_va;
-
-  /* The .idata section.  */
-  if (read (a_out, &f_idata, sizeof (f_idata)) != sizeof (f_idata)
-      &&
-      strcmp (f_idata.s_name, ".idata"))
-    {
-      PERROR ("no .idata section");
-    }
-}
-
-/* The dump routines.  */
-
-static void
-copy_executable_and_dump_data_section (int a_out, int a_new)
-{
-  long size=0;
-  unsigned long new_data_size, new_bss_size, f_data_s_vaddr,
-    file_sz_change, f_data_s_scnptr, bss_padding;
-  int i;
-  SCNHDR section;
-  /* calculate new sizes f_ohdr.dsize is the total initalized data
-     size on disk which is f_data.s_size + f_idata.s_size. 
-     f_ohdr.data_start is the base addres of all data and so should 
-     not be changed. *.s_vaddr is the virtual address of the start
-     of the section normalzed from f_ohdr.ImageBase. *.s_paddr
-     appears to be the number of bytes in the section actually used
-     (whereas *.s_size is aligned).
-
-     bsize is now 0 since subsumed into .data
-     dsize is dsize + (f_data.s_vaddr - f_bss.s_vaddr)
-     f_data.s_vaddr is f_bss.s_vaddr
-     f_data.s_size is new dsize maybe.
-     what about s_paddr & s_scnptr?  */
-  /* this is the amount the file increases in size */
-  *heap_flag=1;			// kludge to get mem to remap
-  new_bss_size=f_data.s_vaddr - f_bss.s_vaddr;
-  file_sz_change=new_bss_size;
-  new_data_size=f_ohdr.dsize + new_bss_size;
-  f_data_s_scnptr = f_data.s_scnptr;
-  f_data_s_vaddr = f_data.s_vaddr;
-  f_data.s_vaddr = f_bss.s_vaddr;
-  f_data.s_paddr += new_bss_size;
-
-  if (f_data.s_size + f_idata.s_size != f_ohdr.dsize)
-    {
-      printf("section size doesn't tally with dsize %lx != %lx\n", 
-	     f_data.s_size + f_idata.s_size, f_ohdr.dsize);
-    }
-  f_data.s_size += new_bss_size;
-  lseek (a_new, 0, SEEK_SET);
-  /* write file header */
-  f_hdr.f_symptr += file_sz_change;
-  f_hdr.f_nscns--;
-  printf("writing file header\n");
-  if (write(a_new, &f_hdr, sizeof(f_hdr)) != sizeof(f_hdr))
-    {
-      PERROR("failed to write file header");
-    }
-  /* write optional header fixing dsize & bsize*/
-  printf("writing optional header\n");
-  printf("new data size is %lx, >= %lx\n", new_data_size,
-	 f_ohdr.dsize + f_ohdr.bsize);
-  if (new_data_size < f_ohdr.dsize + f_ohdr.bsize )
-    {
-      PERROR("new data size is < approx");
-    }
-  f_ohdr.dsize=new_data_size;
-  f_ohdr.bsize=0;
-  if (write(a_new, &f_ohdr, sizeof(f_ohdr)) != sizeof(f_ohdr))
-    {
-      PERROR("failed to write optional header");
-    }
-  /* write text as is */
-  printf("writing text header (unchanged)\n");
-
-  if (write(a_new, &f_text, sizeof(f_text)) != sizeof(f_text))
-    {
-      PERROR("failed to write text header");
-    }
-
-  /* write new data header */
-  printf("writing .data header\n");
-
-  if (write(a_new, &f_data, sizeof(f_data)) != sizeof(f_data))
-    {
-      PERROR("failed to write data header");
-    }
-  
-  printf("writing .idata header\n");
-  f_idata.s_scnptr += file_sz_change;
-  if (f_idata.s_lnnoptr != 0) f_idata.s_lnnoptr += file_sz_change;
-  if (f_idata.s_relptr != 0) f_idata.s_relptr += file_sz_change;
-  if (write(a_new, &f_idata, sizeof(f_idata)) != sizeof(f_idata))
-    {
-      PERROR("failed to write idata header");
-    }
-  
-  /* copy other section headers adjusting the file offset */
-  for (i=0; i<(f_hdr.f_nscns-3); i++)
-    {
-      if (read (a_out, &section, sizeof (section)) != sizeof (section))
-	{
-	  PERROR ("no .data section");
-	}
-      
-      section.s_scnptr += file_sz_change;
-      if (section.s_lnnoptr != 0) section.s_lnnoptr += file_sz_change;
-      if (section.s_relptr != 0) section.s_relptr += file_sz_change;
-
-      if (write(a_new, &section, sizeof(section)) != sizeof(section))
-	{
-	  PERROR("failed to write data header");
-	}
-    }
-
-  /* dump bss to maintain offsets */
-  memset(&f_bss, 0, sizeof(f_bss));
-  if (write(a_new, &f_bss, sizeof(f_bss)) != sizeof(f_bss))
-    {
-      PERROR("failed to write bss header");
-    }
-
-  
-  size=lseek(a_new, 0, SEEK_CUR);
-  CHECK_AOUT_POS(size);
-
-  /* copy eveything else until start of data */
-  size = f_data_s_scnptr - lseek (a_out, 0, SEEK_CUR);
-
-  printf ("copying executable up to data section ... %lx bytes\n", 
-	  size);
-  dup_file_area(a_out, a_new, size);
-
-  CHECK_AOUT_POS(f_data_s_scnptr);
-
-  /* dump bss + padding between sections */
-  printf ("dumping .bss into executable... %lx bytes\n", bss_size);
-  if (write(a_new, bss_start, bss_size) != (int)bss_size)
-    {
-      PERROR("failed to write bss section");
-    }
-  /* pad, needs to be zero */
-  bss_padding = new_bss_size - bss_size;
-  printf ("padding .bss ... %lx bytes\n", bss_padding);
-  void* empty_space = malloc(bss_padding);
-  memset(empty_space, 0, bss_padding);
-  if (write(a_new, empty_space, bss_padding) != (int)bss_padding)
-    {
-      PERROR("failed to write bss section");
-    }
-  free(empty_space);
-
-  /* Get a pointer to the raw data in our address space.  */
-  printf ("dumping .data section... %lx bytes\n", data_size);
-  if (write(a_new, data_start_va, data_size) != (int)data_size)
-    {
-      PERROR("failed to write data section");
-    }
-  
-  lseek(a_out, f_data_s_scnptr + data_size, SEEK_SET);
-
-  size = (((unsigned long)per_process_data-f_ohdr.ImageBase)-f_data_s_vaddr)
-    - data_size;
-  /* write rest of .data to cygwin per process */
-  printf ("copying from .data to cygwin per_process... %lx bytes\n", size);
-  dup_file_area(a_out, a_new, size);
-
-  /* now write out the per process information */
-  printf ("dumping to cygwin per_process... %x bytes at %p\n", 
-	  SIZEOF_PER_PROCESS, per_process_data);
-
-  per_process newpp;
-  memset(&newpp, 0, SIZEOF_PER_PROCESS);
-  newpp.base = cygwin_statu.base;
-  newpp.ptr = cygwin_statu.ptr;
-  newpp.size = cygwin_statu.size;
-
-  if (write(a_new, &newpp, SIZEOF_PER_PROCESS)
-      != (int)SIZEOF_PER_PROCESS)
-    {
-      PERROR("failed to write per_process info");
-    }
-  free(empty_space);
-
-  /* dump the rest */
-  size = lseek(a_out, SIZEOF_PER_PROCESS, SEEK_CUR);
-  size = f_idata.s_scnptr - size;
-  dup_file_area(a_out, a_new, size);
-
-  //  lseek(a_out, f_idata.s_scnptr, SEEK_CUR);
-  CHECK_AOUT_POS(f_idata.s_scnptr);
-  /* now dump - idata don't need to do this cygwin ds is in .data! */
-  printf ("dumping .idata section... %lx bytes\n", f_idata.s_size);
-
-  dup_file_area(a_out,a_new,f_idata.s_size);
-
-  /* write rest of file */
-  printf ("writing rest of file\n");
-  size = lseek(a_out, 0, SEEK_END);
-  size = size - (f_idata.s_scnptr + f_idata.s_size); /* length remaining in a_out */
-  lseek(a_out, f_idata.s_scnptr + f_idata.s_size, SEEK_SET);
-
-  dup_file_area(a_out, a_new, size);
-}
-
-/*
- * copy from aout to anew
- */
-static void dup_file_area(int a_out, int a_new, long size)
-{
-  char page[BUFSIZ];
-  long n;
-  for (; size > 0; size -= sizeof (page))
-    {
-      n = size > sizeof (page) ? sizeof (page) : size;
-      if (read (a_out, page, n) != n || write (a_new, page, n) != n)
-	{
-	  PERROR ("dump_out()");
-	}
-    }
-}
-
-static void dump_heap (int a_out, int a_new)
-{
-    void *heap_data;
-    unsigned long heap_size;
-
-    printf ("Dumping heap into executable...\n");
-
-    heap_size = get_committed_heap_size ();
-    heap_data = get_heap_start ();
-
-    printf ("heap start in process - %p \n", heap_data);
-    printf ("heap size in bytes %lx\n", heap_size);
-    
-    /* nt version rounds heap start - don't see why we should */    
-    heap_index_in_executable = lseek(a_new, 0, SEEK_CUR);
-
-    if (write(a_new, heap_data, heap_size) != (int)heap_size)
-      {
-	PERROR("failed to write data section");
-      }
-}
-
-extern "C" void run_time_remap (char *a_name)
-{
-  int a_out=-1;
-
-  if ((*heap_base)!=local_heap_base
-      ||(*heap_index)<local_heap_index
-      ||(*heap_size)<local_heap_size)
-    {
-      PERROR("heap parameters not in bss");
-    }
-  
-  if (a_name && (a_out = open (a_name, O_RDONLY)) < 0)
-    {
-      PERROR (a_name);
-    }
-
-  /* load the heap */
-  lseek(a_out, heap_index_in_executable, SEEK_SET);
-  
-  if (read (a_out, get_heap_start(), 
-	    (int)((unsigned char*)(local_heap_index)
-		  -(unsigned char*)(local_heap_base))) < 0)
-    {
-      PERROR (a_name);
-    }
-  close(a_out);
-
-  /* switch to new heap */
-  heap_state=HEAP_LOADED;
-  *heap_flag=0;
-  
-  close(a_out);
-}
-
-#endif /* HAVE_COFF_H */
--- a/version.sh	Mon Aug 13 10:18:22 2007 +0200
+++ b/version.sh	Mon Aug 13 10:19:09 2007 +0200
@@ -1,5 +1,5 @@
 #!/bin/sh
 emacs_major_version=20
 emacs_minor_version=5
-emacs_beta_version=22
-xemacs_codename="Grison's Striped"
+emacs_beta_version=23
+xemacs_codename="Jining Grey"