Release 961208

Sun Dec  8 14:51:57 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [configure.in]
	Added check to see if the compiler supports building a DLL when
	the --with-dll option is used.

	* [controls/listbox.c]
	Don't send LBN_SELCHANGE too often.
	Added WM_CHARTOITEM support.

	* [Make.rules.in] [library/Makefile.in]
	Build winestub.o and link it with Winelib programs.

	* [objects/text.c]
	Added support for '&&' in DrawText().

	* [tools/build.c]
	Added -o option.

Sat Dec 7 12:07:07 1996  Andrew Lewycky <plewycky@oise.utoronto.ca>

	* [win32/thread.c]
	GetCurrentThread(): return -2 (current thread pseudo-handle).
	GetCurrentThreadId(): return GetCurrentTask().

	* [objects/font.c] [if1632/gdi32.spec]
	GetTextExtentPoint32{A,W}Buggy(): for future bug-compatibility.

	* [win32/findfile.c]
	FindClose(): ignore INVALID_HANDLE_VALUE (like Win95).

	* [windows/hook.c] [include/hook.h] [if1632/user.spec]
	  [if1632/user32.spec] [windows/focus.c] [windows/message.c]
	  [windows/nonclient.c] [windows/win.c] [windows/winpos.c]
	Hooks rewritten to support Win32.

	* [misc/winsock.c]
	WINSOCK_select(): need to put sockets with errors into exceptfds.
	WINSOCK_socket(): fix error return.

	* [windows/win.c]
	SetWindowWord(): call SetParent on GWW_HWNDPARENT.

Wed Dec  4 22:03:05 1996  Andrew Taylor <andrew@riscan.com>

	* [files/dos_fs.c]
	Check if buf is NULL before copying string in GetFullPathName32A().

Wed Dec  4 21:40:59 1996  Robert Pouliot <krynos@clic.net>

        * [graphics/wing.c] [if1632/wing.spec]
	Implemented many WinG functions, but some don't seem to
	work correctly (probably due to the one not done).
	
Wed Dec  4 03:38:25 1996  Lee Jaekil <juria@puma.kaitech.re.kr>

	* [misc/main.c]
	Implemented a few more of the SystemParametersInfo() cases.

Sun Dec  1 22:30:00 1996  Alex Korobka <alex@trantor.pharm.sunysb.edu> 

	* [controls/button.c]
	Improved focus rectangle painting.

	* [windows/dialog.c] [windows/defdlg.c]
	Fixed IE3.0 problems with DWL_MSGRESULT.

Sun Dec  1 20:49:32 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [files/profile.c]
	Changed error handling in PROFILE_SetString().
diff --git a/ANNOUNCE b/ANNOUNCE
index 38e3e59..a1d8978 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,15 +1,13 @@
-This is release 961201 of Wine, the MS Windows emulator.  This is still a
+This is release 961208 of Wine, the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work correctly.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-961201: (see ChangeLog for details)
-	- Better Winsock.
-	- Rewritten listboxes.
-	- Windows 3.1 registry loader.
-	- Improved keyboard support.
+WHAT'S NEW with Wine-961208: (see ChangeLog for details)
+	- Win32 hooks.
+	- fnt2bdf font conversion tool.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -18,10 +16,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-961201.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-961201.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-961201.tar.gz
-  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-961201.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-961208.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-961208.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-961208.tar.gz
+  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-961208.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/BUGS b/BUGS
index 4785851..46fba4c 100644
--- a/BUGS
+++ b/BUGS
@@ -5,18 +5,13 @@
 add new entries and, more importantly, remove those for the 
 bugs you fixed ;-)
 ------------------------------------------------------------
-As of Nov 8 1996 -
+As of Dec 1 1996 -
 
 General:
 
  * Combobox code is very inadequate (no notification messages,
    dropdown listboxes often stay visible, etc... ).
 
- * Multicolumn and/or LBS_EXTENDEDSEL style listboxes are still 
-   screwed up. [julliard@lrc.epfl.ch]
-
- * Winsock asynchronous functions do not work.
-
  * Font mapping is too generic. No soft font loading, no rotated 
    text support. [alex@amadeus.pharm.sunysb.edu]
 
@@ -31,12 +26,16 @@
 
 Miscellaneous:
 
+ * Simple OLE actions were working in October release, got
+   broken in November (in Winword "Insert Object" now results in 
+   segfault right after the call to LoadModule()).
+ * Write and other applications have problems with displaying partially
+   obscured bitmaps. 
+ * Asynchronous Winsock services sometimes produce zombie processes.
  * AllocCSToDSAlias() shouldn't alloc alias for the same segment multiple
    times.
  * ScrollWindowEx() is outdated.
  * HCBT_CLICKSKIPPED/HCBT_KEYSKIPPED hook actions are not implemented.
- * Write sometimes segfaults in StretchDIBits() (when inside BITBLT_GetRow)
-   when only lower part of the resulting image is visible.
 
 Where to look in source files:
 
diff --git a/ChangeLog b/ChangeLog
index 0ef8d33..fbff2bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,77 @@
 ----------------------------------------------------------------------
+Sun Dec  8 14:51:57 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [configure.in]
+	Added check to see if the compiler supports building a DLL when
+	the --with-dll option is used.
+
+	* [controls/listbox.c]
+	Don't send LBN_SELCHANGE too often.
+	Added WM_CHARTOITEM support.
+
+	* [Make.rules.in] [library/Makefile.in]
+	Build winestub.o and link it with Winelib programs.
+
+	* [objects/text.c]
+	Added support for '&&' in DrawText().
+
+	* [tools/build.c]
+	Added -o option.
+
+Sat Dec 7 12:07:07 1996  Andrew Lewycky <plewycky@oise.utoronto.ca>
+
+	* [win32/thread.c]
+	GetCurrentThread(): return -2 (current thread pseudo-handle).
+	GetCurrentThreadId(): return GetCurrentTask().
+
+	* [objects/font.c] [if1632/gdi32.spec]
+	GetTextExtentPoint32{A,W}Buggy(): for future bug-compatibility.
+
+	* [win32/findfile.c]
+	FindClose(): ignore INVALID_HANDLE_VALUE (like Win95).
+
+	* [windows/hook.c] [include/hook.h] [if1632/user.spec]
+	  [if1632/user32.spec] [windows/focus.c] [windows/message.c]
+	  [windows/nonclient.c] [windows/win.c] [windows/winpos.c]
+	Hooks rewritten to support Win32.
+
+	* [misc/winsock.c]
+	WINSOCK_select(): need to put sockets with errors into exceptfds.
+	WINSOCK_socket(): fix error return.
+
+	* [windows/win.c]
+	SetWindowWord(): call SetParent on GWW_HWNDPARENT.
+
+Wed Dec  4 22:03:05 1996  Andrew Taylor <andrew@riscan.com>
+
+	* [files/dos_fs.c]
+	Check if buf is NULL before copying string in GetFullPathName32A().
+
+Wed Dec  4 21:40:59 1996  Robert Pouliot <krynos@clic.net>
+
+        * [graphics/wing.c] [if1632/wing.spec]
+	Implemented many WinG functions, but some don't seem to
+	work correctly (probably due to the one not done).
+	
+Wed Dec  4 03:38:25 1996  Lee Jaekil <juria@puma.kaitech.re.kr>
+
+	* [misc/main.c]
+	Implemented a few more of the SystemParametersInfo() cases.
+
+Sun Dec  1 22:30:00 1996  Alex Korobka <alex@trantor.pharm.sunysb.edu> 
+
+	* [controls/button.c]
+	Improved focus rectangle painting.
+
+	* [windows/dialog.c] [windows/defdlg.c]
+	Fixed IE3.0 problems with DWL_MSGRESULT.
+
+Sun Dec  1 20:49:32 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [files/profile.c]
+	Changed error handling in PROFILE_SetString().
+
+----------------------------------------------------------------------
 Sat Nov 30 19:21:17 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [configure]
diff --git a/Make.rules.in b/Make.rules.in
index 2599eda..88b5f79 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -1,14 +1,15 @@
 # Global rules shared by all makefiles     -*-Makefile-*-
 #
 # Each individual makefile should define the following variables:
-# TOPSRCDIR  : top-level source directory
-# TOPOBJDIR  : top-level object directory
-# SRCDIR     : source directory for this module
-# MODULE     : name of the module being built
-# C_SRCS     : C sources for the module
-# GEN_C_SRCS : generated C sources (optional)
-# ASM_SRCS   : assembly sources (optional)
-# EXTRA_OBJS : extra object files (optional)
+# TOPSRCDIR    : top-level source directory
+# TOPOBJDIR    : top-level object directory
+# SRCDIR       : source directory for this module
+# MODULE       : name of the module being built
+# C_SRCS       : C sources for the module
+# GEN_C_SRCS   : generated C sources (optional)
+# ASM_SRCS     : assembly sources (optional)
+# GEN_ASM_SRCS : generated assembly sources (optional)
+# EXTRA_OBJS   : extra object files (optional)
 
 # First some useful definitions
 
@@ -21,7 +22,7 @@
 X_LIBS    = @X_LIBS@
 XPM_LIB   = -lXpm
 XLIB      = @X_PRE_LIBS@ -lXext -lX11 @X_EXTRA_LIBS@
-WINELIB   = -L$(TOPOBJDIR) -lwine
+WINELIB   = $(WINESTUB) $(TOPOBJDIR)/@MAIN_TARGET@
 LDLIBS    = @LDLIBS@
 YACC      = @YACC@
 LEX       = @LEX@
@@ -33,10 +34,12 @@
 BUILD     = $(TOPOBJDIR)/tools/build
 MAKEDEP   = $(TOPOBJDIR)/tools/makedep
 WINERC    = $(TOPOBJDIR)/rc/winerc
+WINESTUB  = $(TOPOBJDIR)/library/winestub.o
 SUBMAKE   = $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'OPTIONS=$(OPTIONS)'
 @SET_MAKE@
 
-OBJS = $(GEN_C_SRCS:.c=.o) $(C_SRCS:.c=.o) $(ASM_SRCS:.S=.o) $(EXTRA_OBJS)
+OBJS = $(GEN_C_SRCS:.c=.o) $(C_SRCS:.c=.o) \
+       $(GEN_ASM_SRCS:.s=.o) $(ASM_SRCS:.S=.o) $(EXTRA_OBJS)
 
 # Implicit rules
 
@@ -45,6 +48,9 @@
 .c.o:
 	$(CC) -c $(ALLCFLAGS) -o $*.o $<
 
+.s.o:
+	$(CC) -c -o $*.o $<  
+
 .S.o:
 	$(CC) -c -o $*.o $<  
 
@@ -85,7 +91,7 @@
 	$(MAKEDEP) $(DIVINCL) -C. $(GEN_C_SRCS) -C$(SRCDIR) $(C_SRCS)
 
 clean::
-	$(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc winerctmp.c $(GEN_C_SRCS) $(GEN_C_SRCS:.c=.h) $(PROGRAMS)
+	$(RM) *.o \#*\# *~ *.bak *.orig *.rej *.flc winerctmp.c $(GEN_C_SRCS) $(GEN_C_SRCS:.c=.h) $(GEN_ASM_SRCS) $(PROGRAMS)
 
 dummy:
 
diff --git a/configure b/configure
index e6d67cf..b7d6163 100755
--- a/configure
+++ b/configure
@@ -2,7 +2,7 @@
 
 # From configure.in configure.in 1.00
 # Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.11 
+# Generated automatically using autoconf version 2.12 
 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
 #
 # This configure script is free software; the Free Software Foundation
@@ -341,7 +341,7 @@
     verbose=yes ;;
 
   -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 2.11"
+    echo "configure generated by autoconf version 2.12"
     exit 0 ;;
 
   -with-* | --with-*)
@@ -443,11 +443,14 @@
 done
 
 # NLS nuisances.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
 if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
 
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
 rm -rf conftest* confdefs.h
@@ -509,6 +512,7 @@
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
 ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
 
 if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
   # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
@@ -560,7 +564,7 @@
 # Check whether --with-dll or --without-dll was given.
 if test "${with_dll+set}" = set; then
   withval="$with_dll"
-  OPTIONS="-DWINELIB -DWINELIBDLL" MAIN_TARGET="libwine.so.1.0" CFLAGS="$CFLAGS -fPIC"
+  OPTIONS="-DWINELIB" MAIN_TARGET="libwine.so.1.0"
 fi
 
 
@@ -576,7 +580,7 @@
 
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:580: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:584: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -605,7 +609,7 @@
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:609: checking for $ac_word" >&5
+echo "configure:613: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -634,7 +638,7 @@
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:638: checking for $ac_word" >&5
+echo "configure:642: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -682,41 +686,46 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
-echo "configure:686: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:690: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
 ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
 
 cat > conftest.$ac_ext <<EOF
-#line 695 "configure"
+#line 700 "configure"
 #include "confdefs.h"
-
-int main() {
-
-; return 0; }
+main(){return(0);}
 EOF
-if { (eval echo configure:702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
-  rm -rf conftest*
+if { (eval echo configure:704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
-  rm -rf conftest*
   ac_cv_prog_cc_works=no
 fi
-rm -f conftest*
-
+rm -fr conftest*
 
 echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
 if test $ac_cv_prog_cc_works = no; then
-  { echo "configure: error: Installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
 fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:724: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:720: checking whether we are using GNU C" >&5
+echo "configure:729: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -725,7 +734,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:729: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:738: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -740,24 +749,24 @@
   ac_save_CFLAGS="$CFLAGS"
   CFLAGS=
   echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:744: checking whether ${CC-cc} accepts -g" >&5
-if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then
+echo "configure:753: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   echo 'void f(){}' > conftest.c
 if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
-  ac_cv_prog_gcc_g=yes
+  ac_cv_prog_cc_g=yes
 else
-  ac_cv_prog_gcc_g=no
+  ac_cv_prog_cc_g=no
 fi
 rm -f conftest*
 
 fi
 
-echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
   if test "$ac_test_CFLAGS" = set; then
     CFLAGS="$ac_save_CFLAGS"
-  elif test $ac_cv_prog_gcc_g = yes; then
+  elif test $ac_cv_prog_cc_g = yes; then
     CFLAGS="-g -O2"
   else
     CFLAGS="-O2"
@@ -768,7 +777,7 @@
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:772: checking how to run the C preprocessor" >&5
+echo "configure:781: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -783,13 +792,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 787 "configure"
+#line 796 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:793: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:802: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -800,13 +809,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 804 "configure"
+#line 813 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:810: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:819: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -833,7 +842,7 @@
 # Uses ac_ vars as temps to allow command line to override cache and checks.
 # --without-x overrides everything else, but does not touch the cache.
 echo $ac_n "checking for X""... $ac_c" 1>&6
-echo "configure:837: checking for X" >&5
+echo "configure:846: checking for X" >&5
 
 # Check whether --with-x or --without-x was given.
 if test "${with_x+set}" = set; then
@@ -895,12 +904,12 @@
 
   # First, try using that file with no special directory specified.
 cat > conftest.$ac_ext <<EOF
-#line 899 "configure"
+#line 908 "configure"
 #include "confdefs.h"
 #include <$x_direct_test_include>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:904: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:913: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -969,14 +978,14 @@
   ac_save_LIBS="$LIBS"
   LIBS="-l$x_direct_test_library $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 973 "configure"
+#line 982 "configure"
 #include "confdefs.h"
 
 int main() {
 ${x_direct_test_function}()
 ; return 0; }
 EOF
-if { (eval echo configure:980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:989: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   LIBS="$ac_save_LIBS"
 # We can link X programs with no special library path.
@@ -1034,7 +1043,6 @@
 done
 fi
 rm -f conftest*
-
 fi # $ac_x_libraries = NO
 
 if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
@@ -1083,17 +1091,17 @@
     case "`(uname -sr) 2>/dev/null`" in
     "SunOS 5"*)
       echo $ac_n "checking whether -R must be followed by a space""... $ac_c" 1>&6
-echo "configure:1087: checking whether -R must be followed by a space" >&5
+echo "configure:1095: checking whether -R must be followed by a space" >&5
       ac_xsave_LIBS="$LIBS"; LIBS="$LIBS -R$x_libraries"
       cat > conftest.$ac_ext <<EOF
-#line 1090 "configure"
+#line 1098 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:1097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_R_nospace=yes
 else
@@ -1103,21 +1111,20 @@
   ac_R_nospace=no
 fi
 rm -f conftest*
-
       if test $ac_R_nospace = yes; then
 	echo "$ac_t""no" 1>&6
 	X_LIBS="$X_LIBS -R$x_libraries"
       else
 	LIBS="$ac_xsave_LIBS -R $x_libraries"
 	cat > conftest.$ac_ext <<EOF
-#line 1114 "configure"
+#line 1121 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:1121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1128: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_R_space=yes
 else
@@ -1127,7 +1134,6 @@
   ac_R_space=no
 fi
 rm -f conftest*
-
 	if test $ac_R_space = yes; then
 	  echo "$ac_t""yes" 1>&6
 	  X_LIBS="$X_LIBS -R $x_libraries"
@@ -1150,7 +1156,7 @@
     # libraries were built with DECnet support.  And karl@cs.umb.edu says
     # the Alpha needs dnet_stub (dnet does not exist).
     echo $ac_n "checking for dnet_ntoa in -ldnet""... $ac_c" 1>&6
-echo "configure:1154: checking for dnet_ntoa in -ldnet" >&5
+echo "configure:1160: checking for dnet_ntoa in -ldnet" >&5
 ac_lib_var=`echo dnet'_'dnet_ntoa | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1158,7 +1164,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1162 "configure"
+#line 1168 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1169,7 +1175,7 @@
 dnet_ntoa()
 ; return 0; }
 EOF
-if { (eval echo configure:1173: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1191,7 +1197,7 @@
 
     if test $ac_cv_lib_dnet_dnet_ntoa = no; then
       echo $ac_n "checking for dnet_ntoa in -ldnet_stub""... $ac_c" 1>&6
-echo "configure:1195: checking for dnet_ntoa in -ldnet_stub" >&5
+echo "configure:1201: checking for dnet_ntoa in -ldnet_stub" >&5
 ac_lib_var=`echo dnet_stub'_'dnet_ntoa | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1199,7 +1205,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet_stub  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1203 "configure"
+#line 1209 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1210,7 +1216,7 @@
 dnet_ntoa()
 ; return 0; }
 EOF
-if { (eval echo configure:1214: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1239,12 +1245,12 @@
     # The nsl library prevents programs from opening the X display
     # on Irix 5.2, according to dickey@clark.net.
     echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6
-echo "configure:1243: checking for gethostbyname" >&5
+echo "configure:1249: checking for gethostbyname" >&5
 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1248 "configure"
+#line 1254 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char gethostbyname(); below.  */
@@ -1267,7 +1273,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1271: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_gethostbyname=yes"
 else
@@ -1277,8 +1283,8 @@
   eval "ac_cv_func_gethostbyname=no"
 fi
 rm -f conftest*
-
 fi
+
 if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   :
@@ -1288,7 +1294,7 @@
 
     if test $ac_cv_func_gethostbyname = no; then
       echo $ac_n "checking for gethostbyname in -lnsl""... $ac_c" 1>&6
-echo "configure:1292: checking for gethostbyname in -lnsl" >&5
+echo "configure:1298: checking for gethostbyname in -lnsl" >&5
 ac_lib_var=`echo nsl'_'gethostbyname | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1296,7 +1302,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1300 "configure"
+#line 1306 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1307,7 +1313,7 @@
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:1311: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1317: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1337,12 +1343,12 @@
     # -lsocket must be given before -lnsl if both are needed.
     # We assume that if connect needs -lnsl, so does gethostbyname.
     echo $ac_n "checking for connect""... $ac_c" 1>&6
-echo "configure:1341: checking for connect" >&5
+echo "configure:1347: checking for connect" >&5
 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1346 "configure"
+#line 1352 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char connect(); below.  */
@@ -1365,7 +1371,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_connect=yes"
 else
@@ -1375,8 +1381,8 @@
   eval "ac_cv_func_connect=no"
 fi
 rm -f conftest*
-
 fi
+
 if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   :
@@ -1386,7 +1392,7 @@
 
     if test $ac_cv_func_connect = no; then
       echo $ac_n "checking for connect in -lsocket""... $ac_c" 1>&6
-echo "configure:1390: checking for connect in -lsocket" >&5
+echo "configure:1396: checking for connect in -lsocket" >&5
 ac_lib_var=`echo socket'_'connect | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1394,7 +1400,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket $X_EXTRA_LIBS $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1398 "configure"
+#line 1404 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1405,7 +1411,7 @@
 connect()
 ; return 0; }
 EOF
-if { (eval echo configure:1409: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1415: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1429,12 +1435,12 @@
 
     # gomez@mi.uni-erlangen.de says -lposix is necessary on A/UX.
     echo $ac_n "checking for remove""... $ac_c" 1>&6
-echo "configure:1433: checking for remove" >&5
+echo "configure:1439: checking for remove" >&5
 if eval "test \"`echo '$''{'ac_cv_func_remove'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1438 "configure"
+#line 1444 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char remove(); below.  */
@@ -1457,7 +1463,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1467: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_remove=yes"
 else
@@ -1467,8 +1473,8 @@
   eval "ac_cv_func_remove=no"
 fi
 rm -f conftest*
-
 fi
+
 if eval "test \"`echo '$ac_cv_func_'remove`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   :
@@ -1478,7 +1484,7 @@
 
     if test $ac_cv_func_remove = no; then
       echo $ac_n "checking for remove in -lposix""... $ac_c" 1>&6
-echo "configure:1482: checking for remove in -lposix" >&5
+echo "configure:1488: checking for remove in -lposix" >&5
 ac_lib_var=`echo posix'_'remove | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1486,7 +1492,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lposix  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1490 "configure"
+#line 1496 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1497,7 +1503,7 @@
 remove()
 ; return 0; }
 EOF
-if { (eval echo configure:1501: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1507: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1521,12 +1527,12 @@
 
     # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay.
     echo $ac_n "checking for shmat""... $ac_c" 1>&6
-echo "configure:1525: checking for shmat" >&5
+echo "configure:1531: checking for shmat" >&5
 if eval "test \"`echo '$''{'ac_cv_func_shmat'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1530 "configure"
+#line 1536 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char shmat(); below.  */
@@ -1549,7 +1555,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1553: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1559: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_shmat=yes"
 else
@@ -1559,8 +1565,8 @@
   eval "ac_cv_func_shmat=no"
 fi
 rm -f conftest*
-
 fi
+
 if eval "test \"`echo '$ac_cv_func_'shmat`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   :
@@ -1570,7 +1576,7 @@
 
     if test $ac_cv_func_shmat = no; then
       echo $ac_n "checking for shmat in -lipc""... $ac_c" 1>&6
-echo "configure:1574: checking for shmat in -lipc" >&5
+echo "configure:1580: checking for shmat in -lipc" >&5
 ac_lib_var=`echo ipc'_'shmat | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1578,7 +1584,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lipc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1582 "configure"
+#line 1588 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1589,7 +1595,7 @@
 shmat()
 ; return 0; }
 EOF
-if { (eval echo configure:1593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1599: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1622,7 +1628,7 @@
   # libraries we check for below, so use a different variable.
   #  --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
   echo $ac_n "checking for IceConnectionNumber in -lICE""... $ac_c" 1>&6
-echo "configure:1626: checking for IceConnectionNumber in -lICE" >&5
+echo "configure:1632: checking for IceConnectionNumber in -lICE" >&5
 ac_lib_var=`echo ICE'_'IceConnectionNumber | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1630,7 +1636,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lICE  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1634 "configure"
+#line 1640 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1641,7 +1647,7 @@
 IceConnectionNumber()
 ; return 0; }
 EOF
-if { (eval echo configure:1645: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1651: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1670,7 +1676,7 @@
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1674: checking for $ac_word" >&5
+echo "configure:1680: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1702,7 +1708,7 @@
 # Extract the first word of "flex", so it can be a program name with args.
 set dummy flex; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1706: checking for $ac_word" >&5
+echo "configure:1712: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1735,7 +1741,7 @@
   *) ac_lib=l ;;
   esac
   echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
-echo "configure:1739: checking for yywrap in -l$ac_lib" >&5
+echo "configure:1745: checking for yywrap in -l$ac_lib" >&5
 ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1743,7 +1749,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-l$ac_lib  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1747 "configure"
+#line 1753 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1754,7 +1760,7 @@
 yywrap()
 ; return 0; }
 EOF
-if { (eval echo configure:1758: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1779,7 +1785,7 @@
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1783: checking for $ac_word" >&5
+echo "configure:1789: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1816,12 +1822,12 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:1820: checking for a BSD compatible install" >&5
+echo "configure:1826: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
-    IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS="${IFS}:"
   for ac_dir in $PATH; do
     # Account for people who put trailing slashes in PATH elements.
     case "$ac_dir/" in
@@ -1844,7 +1850,7 @@
       ;;
     esac
   done
-  IFS="$ac_save_ifs"
+  IFS="$ac_save_IFS"
 
 fi
   if test "${ac_cv_path_install+set}" = set; then
@@ -1866,7 +1872,7 @@
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking for i386_set_ldt in -li386""... $ac_c" 1>&6
-echo "configure:1870: checking for i386_set_ldt in -li386" >&5
+echo "configure:1876: checking for i386_set_ldt in -li386" >&5
 ac_lib_var=`echo i386'_'i386_set_ldt | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1874,7 +1880,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-li386  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1878 "configure"
+#line 1884 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1885,7 +1891,7 @@
 i386_set_ldt()
 ; return 0; }
 EOF
-if { (eval echo configure:1889: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1895: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1910,39 +1916,8 @@
 if test "x${GCC}" = "xyes"
 then
   CFLAGS="$CFLAGS -Wall"
-  # If we cannot run a trivial program, we are probably using a cross compiler.
-echo $ac_n "checking whether using a cross-compiler""... $ac_c" 1>&6
-echo "configure:1916: checking whether using a cross-compiler" >&5
-if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  if test "$cross_compiling" = yes; then
-  ac_cv_c_cross=yes
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1924 "configure"
-#include "confdefs.h"
-main(){return(0);}
-EOF
-{ (eval echo configure:1928: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
-  ac_cv_c_cross=no
-else
-  echo "configure: failed program was:" >&5
-  cat conftest.$ac_ext >&5
-  rm -fr conftest*
-  ac_cv_c_cross=yes
-fi
-rm -fr conftest*
-fi
-
-fi
-
-echo "$ac_t""$ac_cv_c_cross" 1>&6
-cross_compiling=$ac_cv_c_cross
-
   echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6
-echo "configure:1946: checking "for gcc strength-reduce bug"" >&5
+echo "configure:1921: checking "for gcc strength-reduce bug"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_gcc_strength_bug'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1950,7 +1925,7 @@
   ac_cv_c_gcc_strength_bug="yes"
 else
   cat > conftest.$ac_ext <<EOF
-#line 1954 "configure"
+#line 1929 "configure"
 #include "confdefs.h"
 
 int main(void) {
@@ -1961,8 +1936,8 @@
   exit( Array[1] != -2 );
 }
 EOF
-{ (eval echo configure:1965: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:1940: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
   ac_cv_c_gcc_strength_bug="no"
 else
   echo "configure: failed program was:" >&5
@@ -1984,7 +1959,7 @@
 
 
 echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6
-echo "configure:1988: checking "whether external symbols need an underscore prefix"" >&5
+echo "configure:1963: checking "whether external symbols need an underscore prefix"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_extern_prefix'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1996,14 +1971,14 @@
 	.long 0
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2000 "configure"
+#line 1975 "configure"
 #include "confdefs.h"
 extern int ac_test;
 int main() {
 if (ac_test) return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2007: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:1982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_extern_prefix="yes"
 else
@@ -2013,7 +1988,6 @@
   ac_cv_c_extern_prefix="no"
 fi
 rm -f conftest*
-
 LIBS=$saved_libs
 fi
 
@@ -2027,15 +2001,56 @@
 fi
 
 
+if test "$MAIN_TARGET" = "libwine.so.1.0"
+then
+  echo $ac_n "checking "whether we can build a dll"""... $ac_c" 1>&6
+echo "configure:2008: checking "whether we can build a dll"" >&5
+if eval "test \"`echo '$''{'ac_cv_c_dll'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  saved_cflags=$CFLAGS
+  CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0"
+  cat > conftest.$ac_ext <<EOF
+#line 2015 "configure"
+#include "confdefs.h"
+
+int main() {
+return 1
+; return 0; }
+EOF
+if { (eval echo configure:2022: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+  rm -rf conftest*
+  ac_cv_c_dll="yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_dll="no"
+fi
+rm -f conftest*
+  CFLAGS=$saved_cflags
+  
+fi
+
+echo "$ac_t""$ac_cv_c_dll" 1>&6
+  if test "$ac_cv_c_dll" = "yes"
+  then
+    CFLAGS="$CFLAGS -fPIC"
+  else
+    MAIN_TARGET="libwine.a"
+  fi
+fi
+
+
 for ac_func in memmove tcgetattr usleep
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2034: checking for $ac_func" >&5
+echo "configure:2049: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2039 "configure"
+#line 2054 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2058,7 +2073,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2062: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2068,8 +2083,8 @@
   eval "ac_cv_func_$ac_func=no"
 fi
 rm -f conftest*
-
 fi
+
 if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
   echo "$ac_t""yes" 1>&6
     ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
@@ -2083,12 +2098,12 @@
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:2087: checking whether stat file-mode macros are broken" >&5
+echo "configure:2102: checking whether stat file-mode macros are broken" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2092 "configure"
+#line 2107 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2139,12 +2154,12 @@
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2143: checking for working const" >&5
+echo "configure:2158: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2148 "configure"
+#line 2163 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2193,7 +2208,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2197: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2212: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2203,7 +2218,6 @@
   ac_cv_c_const=no
 fi
 rm -f conftest*
-
 fi
 
 echo "$ac_t""$ac_cv_c_const" 1>&6
@@ -2215,12 +2229,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2219: checking for ANSI C header files" >&5
+echo "configure:2233: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2224 "configure"
+#line 2238 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2228,7 +2242,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2232: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2246: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2245,7 +2259,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2249 "configure"
+#line 2263 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2263,7 +2277,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 2267 "configure"
+#line 2281 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2284,7 +2298,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2288 "configure"
+#line 2302 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2295,8 +2309,8 @@
 exit (0); }
 
 EOF
-{ (eval echo configure:2299: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
-if test -s conftest && (./conftest; exit) 2>/dev/null; then
+if { (eval echo configure:2313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+then
   :
 else
   echo "configure: failed program was:" >&5
@@ -2319,12 +2333,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:2323: checking for size_t" >&5
+echo "configure:2337: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2328 "configure"
+#line 2342 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2373,12 +2387,25 @@
 # --recheck option to rerun configure.
 #
 EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
 # Ultrix sh set writes to stderr and can't be redirected directly,
 # and sets the high bit in the cache file unless we assign to the vars.
-# HP-UX 10.01 sh prints single quotes around any value that contains spaces.
 (set) 2>&1 |
-sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)='*\([^']*\)'*/\1=\${\1='\2'}/p"\
-  >> confcache
+  case `(ac_space=' '; set) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
 if cmp -s $cache_file confcache; then
   :
 else
@@ -2433,7 +2460,7 @@
     echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
     exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
   -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 2.11"
+    echo "$CONFIG_STATUS generated by autoconf version 2.12"
     exit 0 ;;
   -help | --help | --hel | --he | --h)
     echo "\$ac_cs_usage"; exit 0 ;;
@@ -2590,9 +2617,9 @@
 EOF
 cat >> $CONFIG_STATUS <<\EOF
 for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
-  # Support "outfile[:infile]", defaulting infile="outfile.in".
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
   case "$ac_file" in
-  *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
        ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
   *) ac_file_in="${ac_file}.in" ;;
   esac
@@ -2634,12 +2661,14 @@
 # $configure_input" ;;
   *) ac_comsub= ;;
   esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
   sed -e "$ac_comsub
 s%@configure_input@%$configure_input%g
 s%@srcdir@%$srcdir%g
 s%@top_srcdir@%$top_srcdir%g
 s%@INSTALL@%$INSTALL%g
-" $ac_given_srcdir/$ac_file_in | eval "$ac_sed_cmds" > $ac_file
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
 fi; done
 rm -f conftest.s*
 
@@ -2662,7 +2691,7 @@
 ac_eC=' '
 ac_eD='%g'
 
-if test -z "$CONFIG_HEADERS"; then
+if test "${CONFIG_HEADERS+set}" != set; then
 EOF
 cat >> $CONFIG_STATUS <<EOF
   CONFIG_HEADERS="include/config.h"
@@ -2670,9 +2699,9 @@
 cat >> $CONFIG_STATUS <<\EOF
 fi
 for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
-  # Support "outfile[:infile]", defaulting infile="outfile.in".
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
   case "$ac_file" in
-  *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
        ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
   *) ac_file_in="${ac_file}.in" ;;
   esac
@@ -2680,7 +2709,8 @@
   echo creating $ac_file
 
   rm -f conftest.frag conftest.in conftest.out
-  cp $ac_given_srcdir/$ac_file_in conftest.in
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
 
 EOF
 
@@ -2749,7 +2779,11 @@
   fi
 fi; done
 
+EOF
+cat >> $CONFIG_STATUS <<EOF
 
+EOF
+cat >> $CONFIG_STATUS <<\EOF
 
 exit 0
 EOF
diff --git a/configure.in b/configure.in
index 8e49105..273f842 100644
--- a/configure.in
+++ b/configure.in
@@ -18,7 +18,7 @@
 
 AC_ARG_WITH(dll,
 [  --with-dll              build Wine as a DLL instead of an emulator],
-[OPTIONS="-DWINELIB -DWINELIBDLL" MAIN_TARGET="libwine.so.1.0" CFLAGS="$CFLAGS -fPIC"])
+[OPTIONS="-DWINELIB" MAIN_TARGET="libwine.so.1.0"])
 
 AC_ARG_WITH(ipc,
 [  --with-ipc              use inter-process communication for DDE],
@@ -45,7 +45,6 @@
 if test "x${GCC}" = "xyes"
 then
   CFLAGS="$CFLAGS -Wall"
-  AC_C_CROSS
   AC_CACHE_CHECK( "for gcc strength-reduce bug", ac_cv_c_gcc_strength_bug,
                   AC_TRY_RUN([
 int main(void) {
@@ -83,6 +82,25 @@
   AC_DEFINE(NEED_UNDERSCORE_PREFIX)
 fi
 
+dnl **** Check for working dll ****
+
+if test "$MAIN_TARGET" = "libwine.so.1.0"
+then
+  AC_CACHE_CHECK("whether we can build a dll",
+                 ac_cv_c_dll,
+  [saved_cflags=$CFLAGS
+  CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0"
+  AC_TRY_LINK(,[return 1],ac_cv_c_dll="yes",ac_cv_c_dll="no")
+  CFLAGS=$saved_cflags
+  ])
+  if test "$ac_cv_c_dll" = "yes"
+  then
+    CFLAGS="$CFLAGS -fPIC"
+  else
+    MAIN_TARGET="libwine.a"
+  fi
+fi
+
 dnl **** Check for functions and header files ****
 
 AC_CHECK_FUNCS(memmove tcgetattr usleep)
diff --git a/controls/button.c b/controls/button.c
index 1c4df7e..e53b4c0 100644
--- a/controls/button.c
+++ b/controls/button.c
@@ -427,11 +427,15 @@
     {
 	/* again, this is what CTL3D expects */
 
-        DWORD tm = (textlen) ? GetTextExtent( hDC, wndPtr->text, textlen) : 0x00020002;
-        delta = (rtext.bottom - rtext.top - HIWORD(tm) - 1)/2;
-
-        rbox.bottom = (rbox.top = rtext.top + delta - 1) + HIWORD(tm) + 2;
-        rbox.right = (rbox.left = --rtext.left) + LOWORD(tm) + 2;
+        SetRectEmpty16(&rbox);
+        if( textlen )
+            DrawText16( hDC, wndPtr->text, textlen, &rbox,
+                        DT_SINGLELINE | DT_CALCRECT );
+        textlen = rbox.bottom - rbox.top;
+        delta = ((rtext.bottom - rtext.top) - textlen)/2;
+        rbox.bottom = (rbox.top = rtext.top + delta - 1) + textlen + 2;
+        textlen = rbox.right - rbox.left;
+        rbox.right = (rbox.left += --rtext.left) + textlen + 2;
         IntersectRect16(&rbox, &rbox, &rtext);
         DrawFocusRect16( hDC, &rbox );
     }
diff --git a/controls/listbox.c b/controls/listbox.c
index bad86a7..a39048b 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -1130,8 +1130,6 @@
             LISTBOX_RepaintItem( wnd, descr, i, ODA_SELECT );
         }
     }
-    if (descr->style & LBS_NOTIFY)
-        SEND_NOTIFICATION( wnd, descr, LBN_SELCHANGE );
     return LB_OKAY;
 }
 
@@ -1180,7 +1178,6 @@
         if (oldsel != -1) descr->items[oldsel].selected = FALSE;
         if (index != -1) descr->items[index].selected = TRUE;
         descr->selected_item = index;
-/* FIXME    if (index != -1) LISTBOX_MakeItemVisible( wnd, descr, index );*/
         if (oldsel != -1) LISTBOX_RepaintItem( wnd, descr, oldsel, ODA_SELECT);
         if (index != -1) LISTBOX_RepaintItem( wnd, descr, index, ODA_SELECT );
         if (send_notify) SEND_NOTIFICATION( wnd, descr,
@@ -1214,8 +1211,7 @@
     else if (!(descr->style & LBS_MULTIPLESEL) && (descr->selected_item != -1))
     {
         /* Set selection to new caret item */
-        LISTBOX_SetSelection( wnd, descr, index, TRUE,
-                              (descr->style & LBS_NOTIFY) != 0 );
+        LISTBOX_SetSelection( wnd, descr, index, TRUE, FALSE );
     }
 }
 
@@ -1683,8 +1679,7 @@
             {
                 LISTBOX_SetCaretIndex( wnd, descr, index, FALSE );
                 LISTBOX_SetSelection( wnd, descr, index,
-                                      !descr->items[index].selected,
-                                      (descr->style & LBS_NOTIFY) != 0 );
+                                      !descr->items[index].selected, FALSE );
             }
             else LISTBOX_MoveCaret( wnd, descr, index, FALSE );
         }
@@ -1693,8 +1688,7 @@
             LISTBOX_MoveCaret( wnd, descr, index, FALSE );
             LISTBOX_SetSelection( wnd, descr, index,
                                   (!(descr->style & LBS_MULTIPLESEL) || 
-                                   !descr->items[index].selected),
-                                  (descr->style & LBS_NOTIFY) != 0 );
+                                   !descr->items[index].selected), FALSE );
         }
     }
     SetFocus32( wnd->hwndSelf );
@@ -1716,6 +1710,21 @@
 
 
 /***********************************************************************
+ *           LISTBOX_HandleLButtonUp
+ */
+static LRESULT LISTBOX_HandleLButtonUp( WND *wnd, LB_DESCR *descr )
+{
+    if (LISTBOX_Timer != LB_TIMER_NONE)
+        KillSystemTimer32( wnd->hwndSelf, LB_TIMER_ID );
+    LISTBOX_Timer = LB_TIMER_NONE;
+    if (GetCapture32() == wnd->hwndSelf) ReleaseCapture();
+    if (descr->style & LBS_NOTIFY)
+        SEND_NOTIFICATION( wnd, descr, LBN_SELCHANGE );
+    return 0;
+}
+
+
+/***********************************************************************
  *           LISTBOX_HandleTimer
  *
  * Handle scrolling upon a timer event.
@@ -1883,16 +1892,13 @@
         caret = descr->nb_items - 1;
         break;
     case VK_SPACE:
-        if (descr->style & LBS_EXTENDEDSEL)
-        {
-            if (!(GetKeyState(VK_SHIFT) & 0x8000))
-                descr->anchor_item = descr->focus_item;
-            LISTBOX_MoveCaret( wnd, descr, descr->focus_item, TRUE );
-        }
+        if (descr->style & LBS_EXTENDEDSEL) caret = descr->focus_item;
         else if (descr->style & LBS_MULTIPLESEL)
+        {
             LISTBOX_SetSelection( wnd, descr, descr->focus_item,
                                   !descr->items[descr->focus_item].selected,
                                   (descr->style & LBS_NOTIFY) != 0 );
+        }
         break;
     }
     if (caret >= 0)
@@ -1901,6 +1907,8 @@
             !(GetKeyState( VK_SHIFT ) & 0x8000))
             descr->anchor_item = caret;
         LISTBOX_MoveCaret( wnd, descr, caret, TRUE );
+        if (descr->style & LBS_NOTIFY)
+            SEND_NOTIFICATION( wnd, descr, LBN_SELCHANGE );
     }
     return 0;
 }
@@ -1912,11 +1920,24 @@
 static LRESULT LISTBOX_HandleChar( WND *wnd, LB_DESCR *descr,
                                    WPARAM32 wParam )
 {
-    INT32 index;
+    INT32 caret = -1;
     char str[2] = { wParam & 0xff, '\0' };
 
-    index = LISTBOX_FindString( wnd, descr, descr->focus_item, str, FALSE );
-    if (index != LB_ERR) LISTBOX_MoveCaret( wnd, descr, index, TRUE );
+    if (descr->style & LBS_WANTKEYBOARDINPUT)
+    {
+        caret = SendMessage32A( descr->owner, WM_CHARTOITEM,
+                                MAKEWPARAM(LOWORD(wParam), descr->focus_item),
+                                wnd->hwndSelf );
+        if (caret == -2) return 0;
+    }
+    if (caret == -1)
+        caret = LISTBOX_FindString( wnd, descr, descr->focus_item, str, FALSE);
+    if (caret != -1)
+    {
+        LISTBOX_MoveCaret( wnd, descr, caret, TRUE );
+        if (descr->style & LBS_NOTIFY)
+            SEND_NOTIFICATION( wnd, descr, LBN_SELCHANGE );
+    }
     return 0;
 }
 
@@ -2159,8 +2180,7 @@
             INT32 index = LISTBOX_FindString( wnd, descr, wParam,
                                               (LPCSTR)lParam, FALSE );
             if (index == LB_ERR) return LB_ERR;
-            LISTBOX_SetSelection( wnd, descr, index, TRUE,
-                                  (descr->style & LBS_NOTIFY) != 0 );
+            LISTBOX_SetSelection( wnd, descr, index, TRUE, FALSE );
             return index;
         }
 
@@ -2176,13 +2196,13 @@
         lParam = (INT32)(INT16)lParam;
         /* fall through */
     case LB_SETSEL32:
-        return LISTBOX_SetSelection( wnd, descr, lParam, wParam,
-                                     (descr->style & LBS_NOTIFY) != 0 );
+        return LISTBOX_SetSelection( wnd, descr, lParam, wParam, FALSE );
 
     case LB_SETCURSEL16:
         wParam = (INT32)(INT16)wParam;
         /* fall through */
     case LB_SETCURSEL32:
+        if (wParam != -1) LISTBOX_MakeItemVisible( wnd, descr, wParam, TRUE );
         return LISTBOX_SetSelection( wnd, descr, wParam, TRUE, FALSE );
 
     case LB_GETSELCOUNT16:
@@ -2344,11 +2364,7 @@
         return 0;
 
     case WM_LBUTTONUP:
-        if (LISTBOX_Timer != LB_TIMER_NONE)
-            KillSystemTimer32( hwnd, LB_TIMER_ID );
-        LISTBOX_Timer = LB_TIMER_NONE;
-        if (GetCapture32() == hwnd) ReleaseCapture();
-        return 0;
+        return LISTBOX_HandleLButtonUp( wnd, descr );
 
     case WM_KEYDOWN:
         return LISTBOX_HandleKeyDown( wnd, descr, wParam );
diff --git a/debugger/break.c b/debugger/break.c
index 283d6fa..7375a75 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -137,7 +137,9 @@
     {
         if (breakpoints[i].in_use && breakpoints[i].enabled)
         {
-            if (DEBUG_IsBadWritePtr( &breakpoints[i].addr, 1 ))
+            /* Note: we check for read here, because if reading is allowed */
+            /*       writing permission will be forced in DEBUG_SetOpcode. */
+            if (DEBUG_IsBadReadPtr( &breakpoints[i].addr, 1 ))
             {
                 fprintf( stderr, "Invalid address for breakpoint %d, disabling it\n", i );
                 breakpoints[i].enabled = FALSE;
diff --git a/files/dos_fs.c b/files/dos_fs.c
index 77aa5ed..f07a117 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -888,12 +888,15 @@
 /***********************************************************************
  *           GetFullPathNameA   (KERNEL32.272)
  */
-DWORD GetFullPathName32A( LPCSTR fn, DWORD buflen, LPSTR buf, LPSTR *lastpart) {
+DWORD GetFullPathName32A( LPCSTR fn, DWORD buflen, LPSTR buf, LPSTR *lastpart)
+{
 	dprintf_file(stddeb,"GetFullPathNameA(%s)\n",fn);
 	/* FIXME */
-	lstrcpyn32A(buf,fn,buflen);
-	if (lastpart)
-		*lastpart=strrchr(buf,'\\');
+        if (buf)
+        {
+            lstrcpyn32A(buf,fn,buflen);
+            if (lastpart) *lastpart = strrchr(buf,'\\');
+	}
 	return strlen(fn);
 }
 
diff --git a/files/profile.c b/files/profile.c
index d1a8426..8b6bf27 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -506,22 +506,21 @@
 static BOOL32 PROFILE_SetString( LPCSTR section_name, LPCSTR key_name,
                                  LPCSTR value )
 {
-    BOOL32 ret;
-
     if (!key_name)  /* Delete a whole section */
     {
         dprintf_profile(stddeb, "PROFILE_DeleteSection('%s')\n", section_name);
-        ret = PROFILE_DeleteSection( &CurProfile.section, section_name );
-        CurProfile.changed |= ret;
-        return ret;
+        CurProfile.changed |= PROFILE_DeleteSection( &CurProfile.section,
+                                                     section_name );
+        return TRUE;         /* Even if PROFILE_DeleteSection() has failed,
+                                this is not an error on application's level.*/
     }
     else if (!value)  /* Delete a key */
     {
         dprintf_profile( stddeb, "PROFILE_DeleteKey('%s','%s')\n",
                          section_name, key_name );
-        ret = PROFILE_DeleteKey( &CurProfile.section, section_name, key_name );
-        CurProfile.changed |= ret;
-        return ret;
+        CurProfile.changed |= PROFILE_DeleteKey( &CurProfile.section,
+                                                 section_name, key_name );
+        return TRUE;          /* same error handling as above */
     }
     else  /* Set the key value */
     {
@@ -542,8 +541,8 @@
         else dprintf_profile( stddeb, "creating key\n" );
         key->value = xstrdup( value );
         CurProfile.changed = TRUE;
-        return TRUE;
     }
+    return TRUE;
 }
 
 
diff --git a/graphics/Makefile.in b/graphics/Makefile.in
index cc14f5f..0db59ed 100644
--- a/graphics/Makefile.in
+++ b/graphics/Makefile.in
@@ -6,9 +6,9 @@
 MODULE    = graphics
 
 C_SRCS = \
-	wing.c \
 	bitblt.c \
-	driver.c
+	driver.c \
+	wing.c
 
 all: $(MODULE).o
 
diff --git a/graphics/wing.c b/graphics/wing.c
index 4f3b29d..3bae489 100644
--- a/graphics/wing.c
+++ b/graphics/wing.c
@@ -5,19 +5,10 @@
  */
 
 #include "gdi.h"
+#include "windows.h"
 #include "stddebug.h"
 #include "debug.h"
 
-/* I dunno if this structure can be put here... Maybe copyright, I'm no lawyer... */
-typedef enum WING_DITHER_TYPE
-{
-    WING_DISPERSED_4x4,
-    WING_DISPERSED_8x8,
-
-    WING_CLUSTERED_4x4
-
-} WING_DITHER_TYPE;
-
 /***********************************************************************
  *          WingCreateDC16	(WING.1001)
  */
@@ -33,8 +24,21 @@
  */
 BOOL16 WinGRecommendDIBFormat16(BITMAPINFO *fmt)
 {
-        fprintf(stdnimp,"WinGRecommendDIBFormat: empty stub!\n");
-	return 0;
+	HDC16 i=GetDC16(0);
+
+	fmt->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+	fmt->bmiHeader.biWidth=0;
+	fmt->bmiHeader.biHeight=1; /* The important part */
+	fmt->bmiHeader.biPlanes=GetDeviceCaps(i, PLANES);
+	fmt->bmiHeader.biBitCount=GetDeviceCaps(i, BITSPIXEL);
+	fmt->bmiHeader.biCompression=BI_RGB;
+	fmt->bmiHeader.biSizeImage=0;
+	fmt->bmiHeader.biXPelsPerMeter=1000/25.4*GetDeviceCaps(i,LOGPIXELSX);
+	fmt->bmiHeader.biYPelsPerMeter=1000/25.4*GetDeviceCaps(i,LOGPIXELSY);
+	fmt->bmiHeader.biClrUsed=0;
+	fmt->bmiHeader.biClrImportant=0;
+	ReleaseDC16(0, i);
+	return 1;
 }
 
 /***********************************************************************
@@ -42,26 +46,82 @@
  */
 HBITMAP16 WinGCreateBitmap16(HDC16 winDC, BITMAPINFO *header, void **bits)
 {
-        fprintf(stdnimp,"WinGCreateBitmap: empty stub! (expect failure)\n");
-	*bits=0;
+        fprintf(stdnimp,"WinGCreateBitmap: almost empty stub! (expect failure)\n");
+	/* Assume RGB color */
+	if(bits==NULL)
+		return CreateDIBitmap(winDC, header, 0, bits, header, 0);
+	else
+		return CreateDIBitmap(winDC, header, 1, bits, header, 0);
 	return 0;
 }
 
 /***********************************************************************
+ *  WinGGetDIBPointer16   (WING.1004)
+ */
+void* WinGGetDIBPointer16(HBITMAP16 bmap, BITMAPINFO *header)
+{
+        fprintf(stdnimp,"WinGGetDIBPointer16: empty stub!\n");
+	return NULL;
+}
+
+/***********************************************************************
+ *  WinGGetDIBColorTable16   (WING.1005)
+ */
+UINT16 WinGGetDIBColorTable16(HDC16 winDC, UINT16 start, UINT16 numentry, 
+                            RGBQUAD* colors)
+{
+	return GetPaletteEntries(winDC, start, numentry, colors);
+}
+
+/***********************************************************************
+ *  WinGSetDIBColorTable16   (WING.1006)
+ */
+UINT16 WinGSetDIBColorTable16(HDC16 winDC, UINT16 start, UINT16 numentry,
+                              RGBQUAD* colors)
+{
+	return SetPaletteEntries(winDC, start, numentry, colors);
+}
+
+
+/***********************************************************************
  *  WinGCreateHalfTonePalette16   (WING.1007)
  */
 HPALETTE16 WinGCreateHalfTonePalette16(void)
 {
-        fprintf(stdnimp,"WinGCreateHalfTonePalette: empty stub!\n");
+        fprintf(stdnimp,"WinGCreateHalfTonePalette16: empty stub!\n");
 	return 0;
 }
 
 /***********************************************************************
  *  WinGCreateHalfToneBrush16   (WING.1008)
  */
-HPALETTE16 WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col, WING_DITHER_TYPE type)
+HPALETTE16 WinGCreateHalfToneBrush16(HDC16 winDC, COLORREF col, INT16 dithertype)
 {
-        fprintf(stdnimp,"WinGCreateHalfToneBrush: empty stub!\n");
+        fprintf(stdnimp,"WinGCreateHalfToneBrush16: empty stub!\n");
 	return 0;
 }
 
+/***********************************************************************
+ *  WinGStretchBlt16   (WING.1009)
+ */
+BOOL16 WinGStretchBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest, 
+                        INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc, 
+			INT16 widSrc, INT16 heiSrc)
+{
+
+	return StretchBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, widSrc, heiSrc, SRCCOPY);
+/*        fprintf(stdnimp,"WinGStretchBlt16: empty stub!\n");*/
+/*	return 0; */
+}
+
+/***********************************************************************
+ *  WinGBitBlt16   (WING.1010)
+ */
+BOOL16 WinGBitBlt16(HDC16 destDC, INT16 xDest, INT16 yDest, INT16 widDest,
+                    INT16 heiDest, HDC16 srcDC, INT16 xSrc, INT16 ySrc)
+{
+	return BitBlt16(destDC, xDest, yDest, widDest, heiDest, srcDC, xSrc, ySrc, SRCCOPY);
+/*        fprintf(stdnimp,"WinGBitBlt16: empty stub!\n");*/
+/*	return 0;*/
+}
+
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index 9efa8c9..1df513d 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -11,7 +11,7 @@
 	comdlg32.spec \
 	commdlg.spec \
 	compobj.spec \
-	crtdll.spec	\
+	crtdll.spec \
 	ddeml.spec \
 	gdi.spec \
 	gdi32.spec \
@@ -23,7 +23,7 @@
 	mmsystem.spec \
 	mouse.spec \
 	mpr.spec \
-	ntdll.spec	\
+	ntdll.spec \
 	ole2.spec \
 	ole2conv.spec \
 	ole2disp.spec \
@@ -52,7 +52,7 @@
 	wprocs.spec \
 	wsock32.spec
 
-SPEC_FILES = $(DLLS:.spec=.S)
+SPEC_FILES = $(DLLS:.spec=.s)
 
 C_SRCS = \
 	dummy.c \
@@ -60,17 +60,19 @@
 	thunk.c
 
 ASM_SRCS = \
-	$(SPEC_FILES) \
-	callfrom16.S \
-	callfrom32.S \
-	callto16.S \
-	callto32.S \
 	except.S
 
+GEN_ASM_SRCS = \
+	$(SPEC_FILES) \
+	callfrom16.s \
+	callfrom32.s \
+	callto16.s \
+	callto32.s \
+
 .SUFFIXES: .spec
 
-.spec.S:
-	$(BUILD) -spec $< > $*.S
+.spec.s:
+	$(BUILD) -o $@ -spec $<
 
 all: checkbuild $(MODULE).o
 
@@ -81,22 +83,19 @@
 $(BUILD) checkbuild:
 	cd $(TOPOBJDIR)/tools; $(SUBMAKE) build
 
-callfrom16.S: $(SPEC_FILES)
-	$(BUILD) -callfrom16 `cat $(SPEC_FILES) | grep CallFrom16_ | sed 's/.*CallFrom16_\(.*\)/\1/' | sort | uniq` > callfrom16.S
+callfrom16.s: $(SPEC_FILES)
+	$(BUILD) -o $@ -callfrom16 `cat $(SPEC_FILES) | grep CallFrom16_ | sed 's/.*CallFrom16_\(.*\)/\1/' | sort | uniq`
 
-callfrom32.S: $(SPEC_FILES)
-	$(BUILD) -callfrom32 `cat $(SPEC_FILES) | grep CallFrom32_ | sed 's/.*CallFrom32_\(.*\)/\1/' | sort | uniq` > callfrom32.S
+callfrom32.s: $(SPEC_FILES)
+	$(BUILD) -o $@ -callfrom32 `cat $(SPEC_FILES) | grep CallFrom32_ | sed 's/.*CallFrom32_\(.*\)/\1/' | sort | uniq`
 
-callto16.S: $(TOPSRCDIR)/include/callback.h $(BUILD)
-	$(BUILD) -callto16 `cat $(TOPSRCDIR)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq` > callto16.S
+callto16.s: $(TOPSRCDIR)/include/callback.h $(BUILD)
+	$(BUILD) -o $@ -callto16 `cat $(TOPSRCDIR)/include/callback.h | grep "extern.*CallTo16_" | sed 's/.*CallTo16_\(.*\)(.*/\1/' | sort | uniq`
 
-callto32.S: $(TOPSRCDIR)/include/callback.h $(BUILD)
-	$(BUILD) -callto32 `cat $(TOPSRCDIR)/include/callback.h | grep "extern.*CallTo32_" | sed 's/.*CallTo32_\(.*\)(.*/\1/' | sort | uniq` > callto32.S
+callto32.s: $(TOPSRCDIR)/include/callback.h $(BUILD)
+	$(BUILD) -o $@ -callto32 `cat $(TOPSRCDIR)/include/callback.h | grep "extern.*CallTo32_" | sed 's/.*CallTo32_\(.*\)(.*/\1/' | sort | uniq`
 
 except.o: except.S $(TOPOBJDIR)/include/config.h
 	$(CC) -c $(DIVINCL) -o $*.o $(SRCDIR)/except.S
 
-clean::
-	$(RM) $(SPEC_FILES) callfrom16.S callfrom32.S callto16.S callto32.S
-
 ### Dependencies:
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 3fd6b1e..55654d2 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -272,8 +272,8 @@
 410 pascal16 IsValidMetaFile (word) IsValidMetaFile
 411 pascal16 GetCurLogFont(word) GetCurLogFont
 412 pascal16 IsDCCurrentPalette(word) IsDCCurrentPalette
-439 pascal16 StretchDIBits (word s_word s_word word word word word
-                               word word ptr ptr word long) StretchDIBits
+439 pascal16 StretchDIBits (word s_word s_word s_word s_word s_word s_word
+                            s_word s_word ptr ptr word long) StretchDIBits16
 440 pascal16 SetDIBits(word word word word ptr ptr word) SetDIBits
 441 pascal16 GetDIBits(word word word word ptr ptr word) GetDIBits
 442 pascal16 CreateDIBitmap(word ptr long ptr ptr word) CreateDIBitmap
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index c84bf4a..d013da5 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -236,9 +236,9 @@
 0228 stub GetTextExtentExPointA
 0229 stub GetTextExtentExPointW
 0230 stdcall GetTextExtentPoint32A(long ptr long ptr) GetTextExtentPoint32A
-0231 stub GetTextExtentPoint32W
-0232 stdcall GetTextExtentPointA(long ptr long ptr) GetTextExtentPoint32A
-0233 stdcall GetTextExtentPointW(long ptr long ptr) GetTextExtentPoint32W
+0231 stdcall GetTextExtentPoint32W(long ptr long ptr) GetTextExtentPoint32W
+0232 stdcall GetTextExtentPointA(long ptr long ptr) GetTextExtentPoint32ABuggy
+0233 stdcall GetTextExtentPointW(long ptr long ptr) GetTextExtentPoint32WBuggy
 0234 stdcall GetTextFaceA(long long ptr) GetTextFace
 0235 stub GetTextFaceW
 0236 stdcall GetTextMetricsA(long ptr) GetTextMetrics32A
@@ -358,8 +358,8 @@
 0349 stub StartPage
 0350 stdcall StretchBlt(long long long long long long long long long long long)
              StretchBlt32
-0351 stdcall StretchDIBits(long long long long long long long
-                               long long long long long long) StretchDIBits
+0351 stdcall StretchDIBits(long long long long long long long long long
+                           ptr ptr long long) StretchDIBits32
 0352 stub StrokeAndFillPath
 0353 stub StrokePath
 0354 stub SwapBuffers
diff --git a/if1632/user.spec b/if1632/user.spec
index 20ab847..91a3792 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -122,7 +122,7 @@
 120 pascal   GetMessageTime() GetMessageTime
 121 pascal   SetWindowsHook(s_word segptr) THUNK_SetWindowsHook16
 122 pascal   CallWindowProc(segptr word word word long) CallWindowProc16
-123 pascal16 CallMsgFilter(segptr s_word) CallMsgFilter
+123 pascal16 CallMsgFilter(segptr s_word) CallMsgFilter16
 124 pascal16 UpdateWindow(word) UpdateWindow
 125 pascal16 InvalidateRect(word ptr word) InvalidateRect16
 126 pascal16 InvalidateRgn(word word word) InvalidateRgn
@@ -235,7 +235,7 @@
 232 pascal16 SetWindowPos(word word word word word word word) SetWindowPos
 233 pascal16 SetParent(word word) SetParent
 234 pascal16 UnhookWindowsHook(s_word segptr) THUNK_UnhookWindowsHook16
-235 pascal   DefHookProc(s_word word long ptr) DefHookProc
+235 pascal   DefHookProc(s_word word long ptr) DefHookProc16
 236 pascal16 GetCapture() GetCapture16
 237 pascal16 GetUpdateRgn(word word word) GetUpdateRgn
 238 pascal16 ExcludeUpdateRgn(word word) ExcludeUpdateRgn
@@ -296,7 +296,7 @@
 290 pascal16 RedrawWindow(word ptr word word) RedrawWindow16
 291 pascal   SetWindowsHookEx(s_word segptr word word) THUNK_SetWindowsHookEx16
 292 pascal16 UnhookWindowsHookEx(segptr) THUNK_UnhookWindowsHookEx16
-293 pascal   CallNextHookEx(segptr s_word word long) CallNextHookEx
+293 pascal   CallNextHookEx(segptr s_word word long) CallNextHookEx16
 294 stub LockWindowUpdate
 299 register Mouse_Event() Mouse_Event
 300 stub UnloadInstalledDrivers
diff --git a/if1632/user32.spec b/if1632/user32.spec
index e4c871d..75b8b0f 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -16,9 +16,9 @@
 0011 stub BroadcastSystemMessage
 0012 stub CalcChildScroll
 0013 stub CallMsgFilter
-0014 stub CallMsgFilterA
-0015 stub CallMsgFilterW
-0016 stub CallNextHookEx
+0014 stdcall CallMsgFilterA(ptr long) CallMsgFilter32A
+0015 stdcall CallMsgFilterW(ptr long) CallMsgFilter32W
+0016 stdcall CallNextHookEx(long long long long) CallNextHookEx32
 0017 stdcall CallWindowProcA(ptr long long long long) CallWindowProc32A
 0018 stdcall CallWindowProcW(ptr long long long long) CallWindowProc32W
 0019 stub CascadeChildWindows
@@ -530,8 +530,8 @@
 0523 stdcall SetWindowWord(long long long) SetWindowWord
 0524 stdcall SetWindowsHookA(long ptr) SetWindowsHook32A
 0525 stdcall SetWindowsHookExA(long long long long) SetWindowsHookEx32A
-0526 stub SetWindowsHookExW
-0527 stub SetWindowsHookW
+0526 stdcall SetWindowsHookExW(long long long long) SetWindowsHookEx32W
+0527 stdcall SetWindowsHookW(long long long long) SetWindowsHook32W
 0528 stdcall ShowCaret(long) ShowCaret
 0529 stdcall ShowCursor(long) ShowCursor
 0530 stub ShowOwnedPopups
@@ -560,7 +560,7 @@
 0553 stub TranslateCharsetInfo
 0554 stub TranslateMDISysAccel
 0555 stdcall TranslateMessage(ptr) USER32_TranslateMessage
-0556 stub UnhookWindowsHook
+0556 stdcall UnhookWindowsHook(long ptr) UnhookWindowsHook32
 0557 stdcall UnhookWindowsHookEx(long) UnhookWindowsHookEx32
 0558 stdcall UnionRect(ptr ptr ptr) UnionRect32
 0559 stub UnloadKeyboardLayout
diff --git a/if1632/wing.spec b/if1632/wing.spec
index f22122e..9477096 100644
--- a/if1632/wing.spec
+++ b/if1632/wing.spec
@@ -1,17 +1,16 @@
 name    wing
 type    win16
 
-1001 pascal16 WinGCreateDC() WinGCreateDC16
-1002 pascal16 WinGRecommendDIBFormat(ptr) WinGRecommendDIBFormat16
-1003 pascal16 WinGCreateBitmap(word ptr ptr) WinGCreateBitmap16
-1004 stub WINGGETDIBPOINTER
-1005 stub WINGGETDIBCOLORTABLE
-1006 stub WINGSETDIBCOLORTABLE
-1007 pascal16 WinGCreateHalfTonePalette() WinGCreateHalfTonePalette16
-1008 pascal16 WinGCreateHalfToneBrush(word long word) WinGCreateHalfToneBrush16
-1009 stub WINGSTRETCHBLT
-# Probably much like BitBlt16... but, without the last field (what value?)
-1010 stub WINGBITBLT
+1001 pascal16 WINGCREATEDC() WinGCreateDC16
+1002 pascal16 WINGRECOMMENDDIBFORMAT(ptr) WinGRecommendDIBFormat16
+1003 pascal16 WINGCREATEBITMAP(word ptr ptr) WinGCreateBitmap16
+1004 pascal WINGGETDIBPOINTER(word ptr) WinGGetDIBPointer16
+1005 pascal16 WINGGETDIBCOLORTABLE(word word word ptr) WinGGetDIBColorTable16
+1006 pascal16 WINGSETDIBCOLORTABLE(word word word ptr) WinGSetDIBColorTable16
+1007 pascal16 WINGCREATEHALFTONEPALETTE() WinGCreateHalfTonePalette16
+1008 pascal16 WINGCREATEHALFTONEBRUSH(word word word) WinGCreateHalfToneBrush16
+1009 pascal16 WINGSTRETCHBLT(word word word word word word word word word word) WinGStretchBlt16
+1010 pascal16 WINGBITBLT(word word word word word word word word) WinGBitBlt16
 
 # Seem that 1299 is the limit... weird...
 #1500 stub WINGINITIALIZETHUNK16
diff --git a/include/dialog.h b/include/dialog.h
index dd01585..eb95f2f 100644
--- a/include/dialog.h
+++ b/include/dialog.h
@@ -14,20 +14,29 @@
    * This structure is stored into the window extra bytes (cbWndExtra).
    * sizeof(DIALOGINFO) must be <= DLGWINDOWEXTRA (=30).
    */
+
+#pragma pack(1)
+
 typedef struct
 {
-    INT32       msgResult;   /* Result of EndDialog() / Default button id */
-    HWINDOWPROC dlgProc;     /* Dialog procedure */
-    LONG        userInfo;    /* User information (for DWL_USER) */
+    INT32       msgResult;   /* +00 Last message result */
+    HWINDOWPROC dlgProc;     /* +04 Dialog procedure */
+    LONG        userInfo;    /* +08 User information (for DWL_USER) */
+
+    /* implementation-dependent part */
+
     HWND16      hwndFocus;   /* Current control with focus */
     HFONT16     hUserFont;   /* Dialog font */
     HMENU16     hMenu;       /* Dialog menu */
     WORD        xBaseUnit;   /* Dialog units (depends on the font) */
     WORD        yBaseUnit;
+    INT32	idResult;    /* EndDialog() result / default pushbutton ID */
     WORD        fEnd;        /* EndDialog() called for this dialog */
     HGLOBAL16   hDialogHeap;
 } DIALOGINFO;
 
+#pragma pack(4)
+
 extern BOOL32 DIALOG_Init(void);
 
 #endif  /* DIALOG_H */
diff --git a/include/hook.h b/include/hook.h
index 2a9857b..21c0196 100644
--- a/include/hook.h
+++ b/include/hook.h
@@ -9,12 +9,23 @@
 
 #include "windows.h"
 
-extern HANDLE16 HOOK_GetHook( INT16 id , HQUEUE16 hQueue );
-extern LRESULT HOOK_CallHooks( INT16 id, INT16 code,
-                               WPARAM16 wParam, LPARAM lParam );
-extern HOOKPROC16 HOOK_GetProc16( HHOOK hook );
-extern void HOOK_ResetQueueHooks( HQUEUE16 hQueue );
+#define HOOK_WIN16   0x0
+#define HOOK_WIN32   0x1
+#define HOOK_UNICODE 0x2
+
+#define HOOK_MAPTYPE (HOOK_WIN32 | HOOK_UNICODE)
+
+extern HOOKPROC16 HOOK_GetProc16( HHOOK hhook );
+extern BOOL32 HOOK_IsHooked( INT16 id );
+extern LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
+				 LPARAM lParam );
+extern LRESULT HOOK_CallHooks32A( INT32 id, INT32 code, WPARAM32 wParam,
+				  LPARAM lParam );
+extern LRESULT HOOK_CallHooks32W( INT32 id, INT32 code, WPARAM32 wParam,
+				  LPARAM lParam );
 extern void HOOK_FreeModuleHooks( HMODULE16 hModule );
 extern void HOOK_FreeQueueHooks( HQUEUE16 hQueue );
+extern void HOOK_ResetQueueHooks( HQUEUE16 hQueue );
+extern HOOKPROC32 HOOK_GetProc( HHOOK hook );
 
 #endif  /* __WINE_HOOK_H */
diff --git a/include/windows.h b/include/windows.h
index 2cf3596..6571cc0 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -583,15 +583,16 @@
 {
     BOOL16    fMouse;
     HWND16    hWndActive;
-} CBTACTIVATESTRUCT16;
+} CBTACTIVATESTRUCT16, *LPCBTACTIVATESTRUCT16;
 
 typedef struct
 {
     BOOL32    fMouse;
     HWND32    hWndActive;
-} CBTACTIVATESTRUCT32;
+} CBTACTIVATESTRUCT32, *LPCBTACTIVATESTRUCT32;
 
 DECL_WINELIB_TYPE(CBTACTIVATESTRUCT);
+DECL_WINELIB_TYPE(LPCBTACTIVATESTRUCT);
 
   /* Shell hook values */
 #define HSHELL_WINDOWCREATED       1
@@ -977,6 +978,8 @@
 #define DEFAULT_CHARSET       1
 #define SYMBOL_CHARSET	      2
 #define SHIFTJIS_CHARSET      128
+#define HANGEUL_CHARSET       129
+#define CHINESEBIG5_CHARSET   136
 #define OEM_CHARSET	      255
 
   /* lfOutPrecision values */
@@ -4063,16 +4066,20 @@
 HRSRC32    FindResourceEx32W(HINSTANCE32,LPCWSTR,LPCWSTR,WORD);
 #define    FindResourceEx WINELIB_NAME_AW(FindResourceEx)
 BOOL32     FlushFileBuffers(HFILE);
+UINT32     GetACP(void);
 LPCSTR     GetCommandLine32A();
 LPCWSTR    GetCommandLine32W();
 #define    GetCommandLine WINELIB_NAME_AW(GetCommandLine)
 BOOL32     GetCommTimeouts(INT32,LPCOMMTIMEOUTS);
+DWORD      GetCurrentThreadId(void);
+HANDLE32   GetCurrentThread(void);
 BOOL32     GetDCOrgEx(HDC32,LPPOINT32);
 DWORD      GetFileInformationByHandle(HFILE,BY_HANDLE_FILE_INFORMATION*);
 DWORD      GetFileSize(HFILE,LPDWORD);
 DWORD      GetFileType(HFILE);
 VOID       GetLocalTime(LPSYSTEMTIME);
 DWORD      GetLogicalDrives(void);
+UINT32     GetOEMCP(void);
 HANDLE32   GetProcessHeap(void);
 DWORD      GetShortPathName32A(LPCSTR,LPSTR,DWORD);
 DWORD      GetShortPathName32W(LPCWSTR,LPWSTR,DWORD);
@@ -4228,6 +4235,9 @@
 BOOL32     BuildCommDCBAndTimeouts32A(LPCSTR,LPDCB32,LPCOMMTIMEOUTS);
 BOOL32     BuildCommDCBAndTimeouts32W(LPCWSTR,LPDCB32,LPCOMMTIMEOUTS);
 #define    BuildCommDCBAndTimeouts WINELIB_NAME_AW(BuildCommDCBAndTimeouts)
+LRESULT    CallNextHookEx16(HHOOK,INT16,WPARAM16,LPARAM);
+LRESULT    CallNextHookEx32(HHOOK,INT32,WPARAM32,LPARAM);
+#define    CallNextHookEx WINELIB_NAME(CallNextHookEx)
 LRESULT    CallWindowProc16(WNDPROC16,HWND16,UINT16,WPARAM16,LPARAM);
 LRESULT    CallWindowProc32A(WNDPROC32,HWND32,UINT32,WPARAM32,LPARAM);
 LRESULT    CallWindowProc32W(WNDPROC32,HWND32,UINT32,WPARAM32,LPARAM);
@@ -4403,6 +4413,10 @@
 LRESULT    DefFrameProc32A(HWND32,HWND32,UINT32,WPARAM32,LPARAM);
 LRESULT    DefFrameProc32W(HWND32,HWND32,UINT32,WPARAM32,LPARAM);
 #define    DefFrameProc WINELIB_NAME_AW(DefFrameProc)
+LRESULT    DefHookProc16(INT16,WPARAM16,LPARAM,HHOOK*);
+#define    DefHookProc32(code,wparam,lparam,phhook) \
+           CallNextHookEx32(*(phhook),code,wparam,lparam)
+#define    DefHookProc WINELIB_NAME(DefHookProc)
 LRESULT    DefMDIChildProc16(HWND16,UINT16,WPARAM16,LPARAM);
 LRESULT    DefMDIChildProc32A(HWND32,UINT32,WPARAM32,LPARAM);
 LRESULT    DefMDIChildProc32W(HWND32,UINT32,WPARAM32,LPARAM);
@@ -5294,6 +5308,9 @@
 BOOL32     StretchBlt32(HDC32,INT32,INT32,INT32,INT32,HDC32,INT32,INT32,
                         INT32,INT32,DWORD);
 #define    StretchBlt WINELIB_NAME(StretchBlt)
+INT16      StretchDIBits16(HDC16,INT16,INT16,INT16,INT16,INT16,INT16,INT16,INT16,const VOID*,const BITMAPINFO*,UINT16,DWORD);
+INT32      StretchDIBits32(HDC32,INT32,INT32,INT32,INT32,INT32,INT32,INT32,INT32,const VOID*,const BITMAPINFO*,UINT32,DWORD);
+#define    StretchDIBits WINELIB_NAME(StretchDIBits)
 BOOL16     SubtractRect16(LPRECT16,const RECT16*,const RECT16*);
 BOOL32     SubtractRect32(LPRECT32,const RECT32*,const RECT32*);
 #define    SubtractRect WINELIB_NAME(SubtractRect)
@@ -5468,7 +5485,6 @@
 BOOL       BringWindowToTop(HWND);
 void       CalcChildScroll(HWND,WORD);
 BOOL       CallMsgFilter(SEGPTR,INT);
-LRESULT    CallNextHookEx(HHOOK,INT,WPARAM16,LPARAM);
 BOOL       ChangeClipboardChain(HWND,HWND);
 INT        CheckMenuItem(HMENU16,UINT,UINT);
 BOOL       CloseClipboard(void);
@@ -5488,7 +5504,6 @@
 HMENU16    CreateMenu(void);
 HPALETTE16 CreatePalette(const LOGPALETTE*);
 HMENU16    CreatePopupMenu(void);
-DWORD      DefHookProc(short,WORD,DWORD,HHOOK*);
 HDWP16     DeferWindowPos(HDWP16,HWND,HWND,INT,INT,INT,INT,UINT);
 ATOM       DeleteAtom(ATOM);
 BOOL       DeleteDC(HDC16);
@@ -5716,7 +5731,6 @@
 DWORD      SizeofResource(HMODULE16,HRSRC16);
 int        StartSound(void);
 int        StopSound(void);
-int        StretchDIBits(HDC16,WORD,WORD,WORD,WORD,WORD,WORD,WORD,WORD,LPSTR,LPBITMAPINFO,WORD,DWORD);
 BOOL       SwapMouseButton(BOOL);
 void       SwapRecording(WORD);
 int        SyncAllVoices(void);
diff --git a/include/winsock.h b/include/winsock.h
index 9119c01..ca7bcaf 100644
--- a/include/winsock.h
+++ b/include/winsock.h
@@ -16,9 +16,7 @@
 #include <sys/socket.h>
 #include "windows.h"
 
-#ifndef WINELIB
-#pragma pack(1)                 /* tight alignment for the emulator */
-#endif
+#pragma pack(1)
 
 /* Win16 socket-related types */
 
@@ -135,9 +133,7 @@
         SEGPTR			lpVendorInfo;
 } WSADATA, *LPWSADATA;
 
-#ifndef WINELIB
 #pragma pack(4)
-#endif
 
 /* ----------------------------------- no Win16 structure defs beyond this line! */
 
diff --git a/library/Makefile.in b/library/Makefile.in
index 37edb7b..dce38c7 100644
--- a/library/Makefile.in
+++ b/library/Makefile.in
@@ -3,16 +3,26 @@
 TOPOBJDIR = ..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
-MODULE    = library
+MODULE    = none
+LIBMODULE = library
 
-C_SRCS = \
+LIB_SRCS = \
 	arch.c \
 	libres.c \
 	miscstubs.c \
-	sup.c \
-	winmain.c
+	sup.c
 
-all: $(MODULE).o
+STUB_SRCS = winestub.c
+
+LIB_OBJS  = $(LIB_SRCS:.c=.o)
+STUB_OBJS = $(STUB_SRCS:.c=.o)
+
+C_SRCS = $(LIB_SRCS) $(STUB_SRCS)
+
+all: $(LIBMODULE).o $(STUB_OBJS)
+
+$(LIBMODULE).o: $(LIB_OBJS)
+	$(LDCOMBINE) $(LIB_OBJS) -o $(LIBMODULE).o
 
 @MAKE_RULES@
 
diff --git a/library/winestub.c b/library/winestub.c
index b5323b8..33992cd 100644
--- a/library/winestub.c
+++ b/library/winestub.c
@@ -1,18 +1,51 @@
 /* Sample winestub.c file for compiling programs with libwine.so. */
 
+#include <string.h>
 #include "windows.h"
-#ifdef WIN_DEBUG
-#include <stdio.h>
-#endif
+#include "xmalloc.h"
 
-extern int PASCAL WinMain(HINSTANCE,HINSTANCE,LPSTR,int);
+extern int WinMain(HINSTANCE32,HINSTANCE32,LPSTR,int);
+extern int MAIN_Init(void);
+extern BOOL32 MAIN_WineInit( int *argc, char *argv[] );
+extern void TASK_Reschedule(void);
+
+int main( int argc, char *argv [] )
+{
+  HINSTANCE16 hInstance;
+  LPSTR lpszCmdParam;
+  int i, len = 0;
+
+  MAIN_WineInit( &argc, argv );
+
+  /* Alloc szCmdParam */
+  for (i = 1; i < argc; i++) len += strlen(argv[i]) + 1;
+  lpszCmdParam = (LPSTR) xmalloc(len + 1);
+  /* Concatenate arguments */
+  if (argc > 1) strcpy(lpszCmdParam, argv[1]);
+  else lpszCmdParam[0] = '\0';
+  for (i = 2; i < argc; i++) strcat(strcat(lpszCmdParam, " "), argv[i]);
+
+  if(!MAIN_Init()) return 0; /* JBP: Needed for DosDrives[] structure, etc. */
+  hInstance = WinExec( *argv, SW_SHOWNORMAL );
+  TASK_Reschedule();
+  InitApp( hInstance );
+
+  return WinMain (hInstance,    /* hInstance */
+		  0,	        /* hPrevInstance */
+		  lpszCmdParam, /* lpszCmdParam */
+		  SW_NORMAL);   /* nCmdShow */
+}
+
+#if 0
+
+extern int WinMain(HINSTANCE32,HINSTANCE32,LPSTR,int);
 /* This is the renamed main() subroutine in misc/main.c. */
 /* Note that the libdll `init()' won't work: */
-extern HINSTANCE _wine_main(int, char *[]);
+extern HINSTANCE32 _wine_main(int, char *[]);
 
 int main (int argc, char *argv [])
 {
-  HINSTANCE hInstance;
+  HINSTANCE32 hInstance;
   char szCmdParam[256] = {0};
   int index, buffer_pos;
   char *arg_holder;
@@ -22,7 +55,7 @@
   char *wine_argv[] = {argv[0], ""};
 
   /* Initialize the library dll: */
-  hInstance = (HINSTANCE)_wine_main((sizeof(wine_argv)/sizeof(char *))-1, wine_argv);
+  hInstance = (HINSTANCE32)_wine_main((sizeof(wine_argv)/sizeof(char *))-1, wine_argv);
 
 #ifdef WIN_DEBUG
   fprintf(stderr,"In winestub, reporting hInstance = %d\n", hInstance);
@@ -49,3 +82,4 @@
 		  (LPSTR)szCmdParam,	/* lpszCmdParam */
 		  SW_NORMAL);		/* nCmdShow */
 }
+#endif
diff --git a/library/winmain.c b/library/winmain.c
deleted file mode 100644
index 2ee677c..0000000
--- a/library/winmain.c
+++ /dev/null
@@ -1,41 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <malloc.h>
-#include "windows.h"
-#include "xmalloc.h"
-
-extern int MAIN_Init(void);
-extern BOOL WIDGETS_Init(void);
-extern BOOL WIN_CreateDesktopWindow(void);
-extern int WinMain(HINSTANCE16,HINSTANCE16,LPSTR,int);
-extern void TASK_Reschedule(void);
-
-
-int _WinMain (int argc, char *argv [])
-{
-  HINSTANCE16 hInstance;
-  LPSTR lpszCmdParam;
-  int i, len = 0;
-
-  /* Alloc szCmdParam */
-  for (i = 1; i < argc; i++) len += strlen(argv[i]) + 1;
-  lpszCmdParam = (LPSTR) xmalloc(len + 1);
-  /* Concatenate arguments */
-  if (argc > 1) strcpy(lpszCmdParam, argv[1]);
-  else lpszCmdParam[0] = '\0';
-  for (i = 2; i < argc; i++) strcat(strcat(lpszCmdParam, " "), argv[i]);
-
-  if(!MAIN_Init()) return 0; /* JBP: Needed for DosDrives[] structure, etc. */
-  hInstance = WinExec( *argv, SW_SHOWNORMAL );
-  TASK_Reschedule();
-  InitApp( hInstance );
-
-#ifdef WINELIBDLL
-  return (int)hInstance;
-#else
-  return WinMain (hInstance,    /* hInstance */
-		  0,	        /* hPrevInstance */
-		  lpszCmdParam, /* lpszCmdParam */
-		  SW_NORMAL);   /* nCmdShow */
-#endif
-}
diff --git a/loader/main.c b/loader/main.c
index 8cac976..3bd649e 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -163,12 +163,15 @@
 /**********************************************************************
  *					main
  */
-int _WinMain(int argc, char **argv)
+int main(int argc, char *argv[] )
 {
+    extern BOOL32 MAIN_WineInit( int *argc, char *argv[] );
+
     int i;
     HINSTANCE16 handle;
 
-    if (!MAIN_Init()) return 0;
+    if (!MAIN_WineInit( &argc, argv )) return 1;
+    if (!MAIN_Init()) return 1;
 
     for (i = 1; i < argc; i++)
     {
@@ -182,7 +185,7 @@
             case 21: fprintf( stderr, "win32 executable\n" ); break;
             default: fprintf( stderr, "error=%d\n", handle ); break;
             }
-            exit(1);
+            return 1;
         }
     }
 
diff --git a/loader/task.c b/loader/task.c
index d55e252..824e2d5 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -772,7 +772,7 @@
 
     /* extract hardware events only! */
 
-    EVENT_WaitXEvent( FALSE, TRUE );
+    if (!hTask) EVENT_WaitXEvent( FALSE, TRUE );
 
     while (!hTask)
     {
diff --git a/misc/main.c b/misc/main.c
index f8597ec..9d558f1 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -606,15 +606,12 @@
 }
 
 /***********************************************************************
- *           main
+ *           MAIN_WineInit
+ *
+ * Wine initialisation and command-line parsing
  */
-#if defined(WINELIB) && defined(WINELIBDLL)
-int _wine_main (int argc, char *argv[])
-#else
-int main( int argc, char *argv[] )
-#endif
+BOOL32 MAIN_WineInit( int *argc, char *argv[] )
 {    
-    int ret_val;
     int depth_count, i;
     int *depth_list;
     struct timeval tv;
@@ -645,7 +642,7 @@
 
     XrmInitialize();
     
-    MAIN_ParseOptions( &argc, argv );
+    MAIN_ParseOptions( argc, argv );
 
     if (Options.desktopGeometry && Options.managed)
     {
@@ -672,15 +669,12 @@
     }
     else screenDepth  = DefaultDepthOfScreen( screen );
     if (Options.synchronous) XSynchronize( display, True );
-    if (Options.desktopGeometry) MAIN_CreateDesktop( argc, argv );
+    if (Options.desktopGeometry) MAIN_CreateDesktop( *argc, argv );
     else rootWindow = DefaultRootWindow( display );
 
     MAIN_SaveSetup();
     atexit(called_at_exit);
-
-    ret_val = _WinMain( argc, argv );
-
-    return ret_val;
+    return TRUE;
 }
 
 
@@ -1063,7 +1057,8 @@
 	XKeyboardControl	keyboard_value;
 
 
-	switch (uAction) {
+	switch (uAction)
+        {
 		case SPI_GETBEEP:
 			XGetKeyboardControl(display, &keyboard_state);
 			if (keyboard_state.bell_percent == 0)
@@ -1089,20 +1084,22 @@
                                                           1 );
                     break;
 
-		case SPI_GETICONTITLEWRAP:
-			*(BOOL *) lpvParam = FALSE;
-			/* FIXME GetProfileInt32A( "desktop", "?", True ) */
-			break;
+                case SPI_GETICONTITLEWRAP:
+                    *(BOOL *) lpvParam = GetProfileInt32A( "desktop",
+                                                           "IconTitleWrap",
+                                                           TRUE );
+                    break;
 
-		case SPI_GETKEYBOARDDELAY:
-			*(INT *) lpvParam = 1;
-			/* FIXME */
-			break;
+                case SPI_GETKEYBOARDDELAY:
+                    *(INT *) lpvParam = GetProfileInt32A( "keyboard",
+                                                          "KeyboardDelay", 1 );
+                    break;
 
-		case SPI_GETKEYBOARDSPEED:
-			*(WORD *) lpvParam = 30;
-			/* FIXME */
-			break;
+                case SPI_GETKEYBOARDSPEED:
+                    *(WORD *) lpvParam = GetProfileInt32A( "keyboard",
+                                                           "KeyboardSpeed",
+                                                           30 );
+                    break;
 
 		case SPI_GETMENUDROPALIGNMENT:
 			*(BOOL *) lpvParam = GetSystemMetrics( SM_MENUDROPALIGNMENT ); /* XXX check this */
@@ -1174,19 +1171,21 @@
 
 	        case SPI_GETICONTITLELOGFONT: 
 	        {
-			  /* FIXME GetProfileString32A( "?", "?", "?" ) */
-			  LPLOGFONT16 lpLogFont = (LPLOGFONT16)lpvParam;
-			  lpLogFont->lfHeight = 10;
-			  lpLogFont->lfWidth = 0;
-			  lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
-			  lpLogFont->lfWeight = FW_NORMAL;
-			  lpLogFont->lfItalic = lpLogFont->lfStrikeOut = lpLogFont->lfUnderline = FALSE;
-			  lpLogFont->lfCharSet = ANSI_CHARSET;
-			  lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
-			  lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
-			  lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
-			  break;
-			}
+                    /* FIXME GetProfileString32A( "?", "?", "?" ) */
+                    LPLOGFONT16 lpLogFont = (LPLOGFONT16)lpvParam;
+                    lpLogFont->lfHeight = 10;
+                    lpLogFont->lfWidth = 0;
+                    lpLogFont->lfEscapement = lpLogFont->lfOrientation = 0;
+                    lpLogFont->lfWeight = FW_NORMAL;
+                    lpLogFont->lfItalic = FALSE;
+                    lpLogFont->lfStrikeOut = FALSE;
+                    lpLogFont->lfUnderline = FALSE;
+                    lpLogFont->lfCharSet = ANSI_CHARSET;
+                    lpLogFont->lfOutPrecision = OUT_DEFAULT_PRECIS;
+                    lpLogFont->lfClipPrecision = CLIP_DEFAULT_PRECIS;
+                    lpLogFont->lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
+                    break;
+                }
 
 		case SPI_LANGDRIVER:
 		case SPI_SETBORDER:
diff --git a/misc/winsock.c b/misc/winsock.c
index cb22484..1ec7004 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -174,24 +174,68 @@
   }
 }
 
-static void fd_set_update(LPWSINFO pwsi, fd_set* fds, ws_fd_set* ws)
+/*
+ * Note weirdness here: sockets with errors belong in exceptfds, but
+ * are given to us in readfds or writefds, so move them to exceptfds if
+ * there is an error. Note that this means that exceptfds may have mysterious
+ * sockets set in it that the program never asked for.
+ */
+
+static int inline sock_error_p(int s)
 {
-  if( ws )
-  {
-    int	        i, j, count = ws->fd_count;
-    ws_socket*  pws;
-    for( i = 0, j = 0; i < count; i++ )
+    unsigned int optval, optlen;
+
+    optlen = sizeof(optval);
+    getsockopt(s, SOL_SOCKET, SO_ERROR, &optval, &optlen);
+    if (optval) dprintf_winsock(stddeb, "error: %d\n", optval);
+    return optval != 0;
+}
+
+static void fd_set_update(LPWSINFO pwsi, fd_set* fds, ws_fd_set* ws,
+			  fd_set *errorfds)
+{
+    if( ws )
     {
-      pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
-      if( _check_ws(pwsi, pws) ) 
-        if( FD_ISSET(pws->fd, fds) )
-        { 
-	  ws->fd_array[j++] = ws->fd_array[i];
-          continue; 
-        }
-      ws->fd_count--;
+	int i, j, count = ws->fd_count;
+
+	for( i = 0, j = 0; i < count; i++ )
+	{
+	    ws_socket *pws = (ws_socket*)WS_HANDLE2PTR(ws->fd_array[i]);
+	    int fd = pws->fd;
+
+	    if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) ) 
+	    { 
+		/* if error, move to errorfds */
+		if (errorfds && (FD_ISSET(fd, errorfds) || sock_error_p(fd)))
+		    FD_SET(fd, errorfds);
+		else
+		    ws->fd_array[j++] = ws->fd_array[i];
+	    }
+	}
+	ws->fd_count = j;
+	dprintf_winsock(stddeb, "\n");
     }
-  }
+    return;
+}
+
+static void fd_set_update_except(LPWSINFO pwsi, fd_set *fds, ws_fd_set *ws,
+				 fd_set *errorfds)
+{
+    if (ws)
+    {
+	int i, j, count = ws->fd_count;
+
+	for (i=j=0; i < count; i++)
+	{
+	    ws_socket *pws = (ws_socket *)WS_HANDLE2PTR(ws->fd_array[i]);
+
+	    if (_check_ws(pwsi, pws) && (FD_ISSET(pws->fd, fds)
+					 || FD_ISSET(pws->fd, errorfds)))
+	      ws->fd_array[j++] = ws->fd_array[i];
+	}
+	ws->fd_count = j;
+    }
+    return;
 }
 
 /* ----------------------------------- API ----- 
@@ -512,7 +556,7 @@
   ws_socket*    pws  = (ws_socket*)WS_HANDLE2PTR(s);
   LPWSINFO      pwsi = wsi_find(GetCurrentTask());
 
-  dprintf_winsock(stddeb, "WSA_GETSOCKOPT(%08x): socket: %04x, opt %d, ptr %8x, ptr %8x\n", 
+  dprintf_winsock(stddeb, "WS_GETSOCKOPT(%08x): socket: %04x, opt %d, ptr %8x, ptr %8x\n", 
 			   (unsigned)pwsi, s, level, (int) optval, (int) *optlen);
 
   if( _check_ws(pwsi, pws) )
@@ -662,19 +706,20 @@
   if( pwsi )
   {
      int         highfd = 0;
-     fd_set      readfds, writefds, exceptfds;
+     fd_set      readfds, writefds, exceptfds, errorfds;
 
      fd_set_normalize(&readfds, pwsi, ws_readfds, &highfd);
      fd_set_normalize(&writefds, pwsi, ws_writefds, &highfd);
      fd_set_normalize(&exceptfds, pwsi, ws_exceptfds, &highfd);
+     FD_ZERO(&errorfds);
 
      if( (highfd = select(highfd + 1, &readfds, &writefds, &exceptfds, timeout)) >= 0 )
      {
 	  if( highfd )
 	  {
-	    fd_set_update(pwsi, &readfds, ws_readfds);
-	    fd_set_update(pwsi, &writefds, ws_writefds);
- 	    fd_set_update(pwsi, &exceptfds, ws_exceptfds);
+	    fd_set_update(pwsi, &readfds, ws_readfds, &errorfds);
+	    fd_set_update(pwsi, &writefds, ws_writefds, &errorfds);
+ 	    fd_set_update_except(pwsi, &exceptfds, ws_exceptfds, &errorfds);
 	  }
 	  return highfd; 
      }
@@ -820,14 +865,19 @@
 /*	printf("created %04x (%i)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
  */
         if( pnew ) return (SOCKET16)WS_PTR2HANDLE(pnew);
-        else pwsi->errno = WSAENOBUFS;
+        else
+	{
+	    close(sock);
+	    pwsi->errno = WSAENOBUFS;
+	    return INVALID_SOCKET;
+	}
     }
 
     if (errno == EPERM) /* raw socket denied */
     {
         fprintf(stderr, "WS_SOCKET: not enough privileges\n");
         pwsi->errno = WSAESOCKTNOSUPPORT;
-    } pwsi->errno = wsaErrno();
+    } else pwsi->errno = wsaErrno();
   }
  
   dprintf_winsock(stddeb, "\t\tfailed!\n");
diff --git a/objects/dib.c b/objects/dib.c
index 7a4fcf0..9ca8edf 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -619,26 +619,40 @@
 
 
 /***********************************************************************
- *           StretchDIBits    	(GDI.439)
+ *           StretchDIBits16   (GDI.439)
  */
-int StretchDIBits( HDC16 hdc, 
-                   WORD xDest, WORD yDest, WORD wDestWidth, WORD wDestHeight,
-                   WORD xSrc, WORD ySrc, WORD wSrcWidth, WORD wSrcHeight,
-                   LPSTR bits, LPBITMAPINFO info, WORD wUsage, DWORD dwRop )
+INT16 StretchDIBits16( HDC16 hdc, INT16 xDst, INT16 yDst, INT16 widthDst,
+                       INT16 heightDst, INT16 xSrc, INT16 ySrc, INT16 widthSrc,
+                       INT16 heightSrc, const VOID *bits,
+                       const BITMAPINFO *info, UINT16 wUsage, DWORD dwRop )
 {
-    HBITMAP16 hBitmap, hOldBitmap;
-    HDC16 hdcMem;
+    return (INT16)StretchDIBits32( hdc, xDst, yDst, widthDst, heightDst,
+                                   xSrc, ySrc, widthSrc, heightSrc, bits,
+                                   info, wUsage, dwRop );
+}
+
+
+/***********************************************************************
+ *           StretchDIBits32   (GDI32.351)
+ */
+INT32 StretchDIBits32( HDC32 hdc, INT32 xDst, INT32 yDst, INT32 widthDst,
+                       INT32 heightDst, INT32 xSrc, INT32 ySrc, INT32 widthSrc,
+                       INT32 heightSrc, const void *bits,
+                       const BITMAPINFO *info, UINT32 wUsage, DWORD dwRop )
+{
+    HBITMAP32 hBitmap, hOldBitmap;
+    HDC32 hdcMem;
 
     hBitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
                               bits, info, wUsage );
     hdcMem = CreateCompatibleDC( hdc );
     hOldBitmap = SelectObject32( hdcMem, hBitmap );
-    StretchBlt32( hdc, xDest, yDest, wDestWidth, wDestHeight,
-                  hdcMem, xSrc, ySrc, wSrcWidth, wSrcHeight, dwRop );
+    StretchBlt32( hdc, xDst, yDst, widthDst, heightDst,
+                  hdcMem, xSrc, ySrc, widthSrc, heightSrc, dwRop );
     SelectObject32( hdcMem, hOldBitmap );
     DeleteDC( hdcMem );
     DeleteObject32( hBitmap );
-    return wSrcHeight;
+    return heightSrc;
 }
 
 
diff --git a/objects/font.c b/objects/font.c
index 061e5cc..784cb2f 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -320,7 +320,9 @@
     metrics->tmDigitizedAspectX = 1;
     metrics->tmDigitizedAspectY = 1;
     metrics->tmPitchAndFamily   = (logfont->lfPitchAndFamily&0xf0)|TMPF_DEVICE;
-    if (logfont->lfPitchAndFamily & FIXED_PITCH) 
+
+    /* TMPF_FIXED_PITCH bit means variable pitch...Don't you love Microsoft? */
+    if (xfont->min_bounds.width != xfont->max_bounds.width)
         metrics->tmPitchAndFamily |= TMPF_FIXED_PITCH;
 
     if (!xfont->per_char) average = metrics->tmMaxCharWidth;
@@ -827,6 +829,10 @@
 
 /***********************************************************************
  *           GetTextExtentPoint16    (GDI.471)
+ *
+ * FIXME: Should this have a bug for compatibility?
+ * Original Windows versions of GetTextExtentPoint{A,W} have documented
+ * bugs.
  */
 BOOL16 GetTextExtentPoint16( HDC16 hdc, LPCSTR str, INT16 count, LPSIZE16 size)
 {
@@ -838,7 +844,7 @@
 
 
 /***********************************************************************
- *           GetTextExtentPoint32A    (GDI32.232)
+ *           GetTextExtentPoint32A    (GDI32.230)
  */
 BOOL32 GetTextExtentPoint32A( HDC32 hdc, LPCSTR str, INT32 count,
                               LPSIZE32 size )
@@ -861,7 +867,7 @@
 
 
 /***********************************************************************
- *           GetTextExtentPoint32W    (GDI32.233)
+ *           GetTextExtentPoint32W    (GDI32.231)
  */
 BOOL32 GetTextExtentPoint32W( HDC32 hdc, LPCWSTR str, INT32 count,
                               LPSIZE32 size )
@@ -872,6 +878,26 @@
     return ret;
 }
 
+/***********************************************************************
+ *           GetTextExtentPoint32ABuggy    (GDI32.232)
+ */
+BOOL32 GetTextExtentPoint32ABuggy( HDC32 hdc, LPCSTR str, INT32 count,
+				   LPSIZE32 size )
+{
+    fprintf( stderr, "GetTextExtentPoint32ABuggy: not bug compatible.\n" );
+    return GetTextExtentPoint32A( hdc, str, count, size );
+}
+
+/***********************************************************************
+ *           GetTextExtentPoint32WBuggy    (GDI32.233)
+ */
+BOOL32 GetTextExtentPoint32WBuggy( HDC32 hdc, LPCWSTR str, INT32 count,
+				   LPSIZE32 size )
+{
+    fprintf( stderr, "GetTextExtentPoint32WBuggy: not bug compatible.\n" );
+    return GetTextExtentPoint32W( hdc, str, count, size );
+}
+
 
 /***********************************************************************
  *           GetTextMetrics16    (GDI.93)
diff --git a/objects/metafile.c b/objects/metafile.c
index 65e5484..d1891bb 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -677,10 +677,10 @@
        LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[11]);
        LPSTR bits = MF_GetDIBitsPointer(info);
        if (bits)
-        StretchDIBits(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
-		    mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
-		    mr->rdParam[4],mr->rdParam[3],bits,info,
-		    mr->rdParam[2],MAKELONG(mr->rdParam[0],mr->rdParam[1]));
+        StretchDIBits16(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
+                       mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
+                       mr->rdParam[4],mr->rdParam[3],bits,info,
+                       mr->rdParam[2],MAKELONG(mr->rdParam[0],mr->rdParam[1]));
       }
       break;
 
@@ -689,10 +689,10 @@
        LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[10]); 
        LPSTR bits = MF_GetDIBitsPointer(info);
        if (bits)
-         StretchDIBits(hdc,mr->rdParam[9],mr->rdParam[8],mr->rdParam[7],
-		    mr->rdParam[6],mr->rdParam[5],mr->rdParam[4],
-		    mr->rdParam[3],mr->rdParam[2],bits,info,
-		    DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
+         StretchDIBits16(hdc,mr->rdParam[9],mr->rdParam[8],mr->rdParam[7],
+                       mr->rdParam[6],mr->rdParam[5],mr->rdParam[4],
+                       mr->rdParam[3],mr->rdParam[2],bits,info,
+                       DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
       }
       break;		  
 
@@ -705,7 +705,7 @@
                                       mr->rdParam[14], /*BitsPixel*/
                                       (LPSTR)&mr->rdParam[15]);  /*bits*/
        SelectObject32(hdcSrc,hbitmap);
-       StretchBlt32(hdc,mr->rdParam[9],mr->rdParam[8],
+       StretchBlt16(hdc,mr->rdParam[9],mr->rdParam[8],
                     mr->rdParam[7],mr->rdParam[6],
 		    hdcSrc,mr->rdParam[5],mr->rdParam[4],
 		    mr->rdParam[3],mr->rdParam[2],
diff --git a/objects/text.c b/objects/text.c
index fd2450f..13659b2 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -86,19 +86,20 @@
 	case PREFIX:
 	    if (!(format & DT_NOPREFIX))
 	    {
-		prefix_offset = j;
-		i++;
+                if (str[++i] != PREFIX)
+                {
+                    prefix_offset = j;
+                    break;
+                }
 	    }
-	    else
-	    {
-		dest[j++] = str[i++];
-		if (!(format & DT_NOCLIP) || (format & DT_WORDBREAK))
-		{
-		    if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
-			return NULL;
-		    plen += size.cx;
-		}
-	    }
+            dest[j++] = str[i++];
+            if (!(format & DT_NOCLIP) || !(format & DT_NOPREFIX) ||
+                (format & DT_WORDBREAK))
+            {
+                if (!GetTextExtentPoint16(hdc, &dest[j-1], 1, &size))
+                    return NULL;
+                plen += size.cx;
+            }
 	    break;
 	    
 	case TAB:
diff --git a/rc/winerc.c b/rc/winerc.c
index 63a9f4e..3f9edbe 100644
--- a/rc/winerc.c
+++ b/rc/winerc.c
@@ -53,7 +53,6 @@
 {  
 	extern int yydebug;
 	extern char* optarg;
-	char* tmpc;
 	int optc,lose,ret,binary;
 	lose=binary=0;
 	while((optc=getopt(argc,argv,"bcdp:vo:w:"))!=EOF)
@@ -66,12 +65,7 @@
 					 setbuf(stdout,0);
 					 setbuf(stderr,0);
 					break;
-			case 'p':prefix=strdup(optarg);
-					 if(!isalpha(*prefix))*prefix='_';
-					 for(tmpc=prefix;*tmpc;tmpc++)
-					  if( !isalnum(*tmpc) && *tmpc!='_')
-					   *tmpc='_';
-					break;
+			case 'p':prefix=strdup(optarg); break;
 			case 'c':constant=1;break;
 			case 'v':verbose=1;
 					 setbuf(stderr,0);
diff --git a/tools/Makefile.in b/tools/Makefile.in
index fb8436a..c1d3f14 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -4,10 +4,10 @@
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 
-PROGRAMS = build makedep
+PROGRAMS = build makedep fnt2bdf
 MODULE   = none
 
-C_SRCS = build.c makedep.c
+C_SRCS = build.c makedep.c fnt2bdf.c
 
 all: $(PROGRAMS)
 
@@ -19,4 +19,7 @@
 makedep: makedep.o
 	$(CC) $(CFLAGS) -o makedep makedep.o
 
+fnt2bdf: fnt2bdf.o
+	$(CC) $(CFLAGS) -o fnt2bdf fnt2bdf.o
+
 ### Dependencies:
diff --git a/tools/build.c b/tools/build.c
index 76de29e..2381002 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <unistd.h>
 #include "wintypes.h"
 #include "registers.h"
 #include "winerror.h"  /* for ERROR_CALL_NOT_IMPLEMENTED */
@@ -253,6 +254,12 @@
     return token;
 }
 
+
+/*******************************************************************
+ *         ParseVariable
+ *
+ * Parse a variable definition.
+ */
 static int ParseVariable( ORDDEF *odp )
 {
     char *endptr;
@@ -264,7 +271,7 @@
     if (*token != '(')
     {
 	fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
-	exit(1);
+	return -1;
     }
 
     n_values = 0;
@@ -288,14 +295,14 @@
 	{
 	    fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
 		    token);
-	    exit(1);
+	    return -1;
 	}
     }
     
     if (token == NULL)
     {
 	fprintf(stderr, "%d: End of file in variable declaration\n", Line);
-	exit(1);
+	return -1;
     }
 
     odp->u.var.n_values = n_values;
@@ -304,6 +311,12 @@
     return 0;
 }
 
+
+/*******************************************************************
+ *         ParseExportFunction
+ *
+ * Parse a function definition.
+ */
 static int ParseExportFunction( ORDDEF *odp )
 {
     char *token;
@@ -315,19 +328,19 @@
         if (odp->type == TYPE_STDCALL)
         {
             fprintf( stderr, "%d: 'stdcall' not supported for Win16\n", Line );
-            exit(1);
+            return -1;
         }
         if (odp->type == TYPE_CDECL)
         {
             fprintf( stderr, "%d: 'cdecl' not supported for Win16\n", Line );
-            exit(1);
+            return -1;
         }
         break;
     case SPEC_WIN32:
         if ((odp->type == TYPE_PASCAL) || (odp->type == TYPE_PASCAL_16))
         {
             fprintf( stderr, "%d: 'pascal' not supported for Win32\n", Line );
-            exit(1);
+            return -1;
         }
         break;
     default:
@@ -338,7 +351,7 @@
     if (*token != '(')
     {
 	fprintf(stderr, "%d: Expected '(' got '%s'\n", Line, token);
-	exit(1);
+	return -1;
     }
 
     for (i = 0; i < sizeof(odp->u.func.arg_types)-1; i++)
@@ -358,7 +371,7 @@
         else
         {
             fprintf(stderr, "%d: Unknown variable type '%s'\n", Line, token);
-            exit(1);
+            return -1;
         }
         if (SpecType == SPEC_WIN32)
         {
@@ -366,14 +379,14 @@
             {
                 fprintf( stderr, "%d: Type '%s' not supported for Win32\n",
                          Line, token );
-                exit(1);
+                return -1;
             }
         }
     }
     if (*token != ')')
     {
         fprintf( stderr, "%d: Too many arguments\n", Line );
-        exit(1);
+        return -1;
     }
     odp->u.func.arg_types[i] = '\0';
     if ((odp->type == TYPE_STDCALL) && !i)
@@ -398,7 +411,7 @@
     {
 	fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
 		token);
-	exit(1);
+	return -1;
     }
 
     odp->u.abs.value = value;
@@ -422,7 +435,7 @@
     {
 	fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
 		token);
-	exit(1);
+	return -1;
     }
 
     token = GetToken();
@@ -431,7 +444,7 @@
     {
 	fprintf(stderr, "%d: Expected number value, got '%s'\n", Line,
 		token);
-	exit(1);
+	return -1;
     }
 
     return 0;
@@ -461,7 +474,7 @@
     if (SpecType == SPEC_WIN16)
     {
         fprintf( stderr, "%d: 'extern' not supported for Win16\n", Line );
-        exit(1);
+        return -1;
     }
     strcpy( odp->u.ext.link_name, GetToken() );
     return 0;
@@ -481,7 +494,7 @@
     if (ordinal >= MAX_ORDINALS)
     {
 	fprintf(stderr, "%d: Ordinal number too large\n", Line);
-	exit(1);
+	return -1;
     }
     if (ordinal > Limit) Limit = ordinal;
 
@@ -489,7 +502,7 @@
     if (!(token = GetToken()))
     {
 	fprintf(stderr, "%d: Expected type after ordinal\n", Line);
-	exit(1);
+	return -1;
     }
 
     for (odp->type = 0; odp->type < TYPE_NBTYPES; odp->type++)
@@ -501,13 +514,13 @@
         fprintf( stderr,
                  "%d: Expected type after ordinal, found '%s' instead\n",
                  Line, token );
-        exit(1);
+        return -1;
     }
 
     if (!(token = GetToken()))
     {
         fprintf( stderr, "%d: Expected name after type\n", Line );
-        exit(1);
+        return -1;
     }
     strcpy( odp->name, token );
 
@@ -533,10 +546,16 @@
 	return ParseExtern( odp );
     default:
         fprintf( stderr, "Should not happen\n" );
-        exit(1);
+        return -1;
     }
 }
 
+
+/*******************************************************************
+ *         ParseTopLevel
+ *
+ * Parse a spec file.
+ */
 static int ParseTopLevel(void)
 {
     char *token;
@@ -556,7 +575,7 @@
             else
             {
                 fprintf(stderr, "%d: Type must be 'win16' or 'win32'\n", Line);
-                exit(1);
+                return -1;
             }
         }
 	else if (strcmp(token, "base") == 0)
@@ -565,7 +584,7 @@
             if (!IsNumberString(token))
             {
 		fprintf(stderr, "%d: Expected number after base\n", Line);
-		exit(1);
+		return -1;
             }
             Base = atoi(token);
 	}
@@ -575,7 +594,7 @@
             if (!IsNumberString(token))
             {
 		fprintf(stderr, "%d: Expected number after heap\n", Line);
-		exit(1);
+		return -1;
             }
             DLLHeapSize = atoi(token);
 	}
@@ -592,7 +611,7 @@
 	{
 	    fprintf(stderr, 
 		    "%d: Expected name, id, length or ordinal\n", Line);
-	    exit(1);
+	    return -1;
 	}
     }
 
@@ -633,19 +652,20 @@
  *
  * Dump a byte stream into the assembly code.
  */
-static void DumpBytes( const unsigned char *data, int len,
+static void DumpBytes( FILE *outfile, const unsigned char *data, int len,
                        const char *section, const char *label_start )
 {
     int i;
-    if (section) printf( "\t%s\n", section );
-    if (label_start) printf( "%s:\n", label_start );
+    if (section) fprintf( outfile, "\t%s\n", section );
+    if (label_start) fprintf( outfile, "%s:\n", label_start );
     for (i = 0; i < len; i++)
     {
-        if (!(i & 0x0f)) printf( "\t.byte " );
-        printf( "%d", *data++ );
-        if (i < len - 1) printf( "%c", ((i & 0x0f) != 0x0f) ? ',' : '\n' );
+        if (!(i & 0x0f)) fprintf( outfile, "\t.byte " );
+        fprintf( outfile, "%d", *data++ );
+        if (i < len - 1)
+            fprintf( outfile, "%c", ((i & 0x0f) != 0x0f) ? ',' : '\n' );
     }
-    printf( "\n" );
+    fprintf( outfile, "\n" );
 }
 
 
@@ -655,7 +675,8 @@
  * Build the in-memory representation of a 16-bit NE module, and dump it
  * as a byte stream into the assembly code.
  */
-static int BuildModule16( int max_code_offset, int max_data_offset )
+static int BuildModule16( FILE *outfile, int max_code_offset,
+                          int max_data_offset )
 {
     ORDDEF *odp;
     int i;
@@ -830,7 +851,7 @@
 
       /* Dump the module content */
 
-    DumpBytes( (char *)pModule, (int)pstr - (int)pModule,
+    DumpBytes( outfile, (char *)pModule, (int)pstr - (int)pModule,
                ".data", "Module_Start" );
     return (int)pstr - (int)pModule;
 }
@@ -842,7 +863,7 @@
  * Build the in-memory representation of a 32-bit pseudo-NE module, and dump it
  * as a byte stream into the assembly code.
  */
-static int BuildModule32(void)
+static int BuildModule32( FILE *outfile )
 {
     char *buffer;
     NE_MODULE *pModule;
@@ -940,27 +961,27 @@
 
       /* Dump the module content */
 
-    DumpBytes( (char *)pModule, (int)pstr - (int)pModule,
+    DumpBytes( outfile, (char *)pModule, (int)pstr - (int)pModule,
                ".data", "Module_Start" );
     return (int)pstr - (int)pModule;
 }
 
 
 /*******************************************************************
- *         BuildSpec32Files
+ *         BuildSpec32File
  *
  * Build a Win32 assembly file from a spec file.
  */
-static void BuildSpec32Files(void)
+static int BuildSpec32File( FILE *outfile )
 {
     ORDDEF *odp;
     int i, module_size, len;
     char buffer[1024];
 
-    printf( "/* File generated automatically; do not edit! */\n" );
-    printf( "\t.text\n" );
-    printf( "\t.align 4\n" );
-    printf( "Code_Start:\n\n" );
+    fprintf( outfile, "/* File generated automatically; do not edit! */\n" );
+    fprintf( outfile, "\t.text\n" );
+    fprintf( outfile, "\t.align 4\n" );
+    fprintf( outfile, "Code_Start:\n\n" );
 
     odp = OrdinalDefinitions;
     for (i = 0; i <= Limit; i++, odp++)
@@ -974,62 +995,59 @@
         case TYPE_CDECL:
         case TYPE_STUB:
         case TYPE_REGISTER:
-            printf( "/* %s.%d (%s) */\n",
-                     DLLName, i, odp->name);
-            printf( "%s_%d:\n", DLLName, i );
-            printf( "\tpushl %%ebp\n" );
-            printf( "\tpushl $" PREFIX "%s\n", odp->u.func.link_name );
-            printf( "\tcall " PREFIX "CallFrom32_%s_%d\n",
-                    (odp->type == TYPE_REGISTER) ? "regs" :
-                    ((odp->type == TYPE_STDCALL) ? "stdcall" : "cdecl"),
-                    strlen(odp->u.func.arg_types));
-            printf( "\tnop\n" );
+            fprintf( outfile, "/* %s.%d (%s) */\n", DLLName, i, odp->name);
+            fprintf( outfile, "%s_%d:\n", DLLName, i );
+            fprintf( outfile, "\tpushl %%ebp\n" );
+            fprintf( outfile, "\tpushl $" PREFIX "%s\n",odp->u.func.link_name);
+            fprintf( outfile, "\tcall " PREFIX "CallFrom32_%s_%d\n",
+                     (odp->type == TYPE_REGISTER) ? "regs" :
+                     ((odp->type == TYPE_STDCALL) ? "stdcall" : "cdecl"),
+                     strlen(odp->u.func.arg_types));
+            fprintf( outfile, "\tnop\n" );
             break;
 
         case TYPE_RETURN:
-            printf( "/* %s.%d (%s) */\n",
-                     DLLName, i, odp->name);
-            printf( "%s_%d:\n", DLLName, i );
-            printf( "\tmovl $%d,%%eax\n", ERROR_CALL_NOT_IMPLEMENTED );
-            printf( "\tmovl %%eax," PREFIX "WIN32_LastError\n" );
-            printf( "\tmovl $%d,%%eax\n", odp->u.ret.ret_value );
+            fprintf( outfile, "/* %s.%d (%s) */\n", DLLName, i, odp->name);
+            fprintf( outfile, "%s_%d:\n", DLLName, i );
+            fprintf( outfile, "\tmovl $%d,%%eax\n",ERROR_CALL_NOT_IMPLEMENTED);
+            fprintf( outfile, "\tmovl %%eax," PREFIX "WIN32_LastError\n" );
+            fprintf( outfile, "\tmovl $%d,%%eax\n", odp->u.ret.ret_value );
             if (odp->u.ret.arg_size)
             {
-                printf( "\tret $%d\n", odp->u.ret.arg_size );
-                printf( "\tnop\n" );
-                printf( "\tnop\n" );
+                fprintf( outfile, "\tret $%d\n", odp->u.ret.arg_size );
+                fprintf( outfile, "\tnop\n" );
+                fprintf( outfile, "\tnop\n" );
             }
-            else printf( "\tret\n" );
+            else fprintf( outfile, "\tret\n" );
             break;
 
         case TYPE_BYTE:
-            printf( "/* %s.%d (%s) */\n",
-                     DLLName, i, odp->name);
-            printf( "\t.data\n" );
-            printf( "%s_%d:\n", DLLName, i );
+            fprintf( outfile, "/* %s.%d (%s) */\n", DLLName, i, odp->name);
+            fprintf( outfile, "\t.data\n" );
+            fprintf( outfile, "%s_%d:\n", DLLName, i );
             len = StoreVariableCode( buffer, 1, odp );
-            DumpBytes( buffer, len, NULL, NULL );
-            printf( "\t.text\n" );
+            DumpBytes( outfile, buffer, len, NULL, NULL );
+            fprintf( outfile, "\t.text\n" );
             break;
 
         case TYPE_WORD:
-            printf( "/* %s.%d (%s) */\n",
+            fprintf( outfile, "/* %s.%d (%s) */\n",
                      DLLName, i, odp->name);
-            printf( "\t.data\n" );
-            printf( "%s_%d:\n", DLLName, i );
+            fprintf( outfile, "\t.data\n" );
+            fprintf( outfile, "%s_%d:\n", DLLName, i );
             len = StoreVariableCode( buffer, 2, odp );
-            DumpBytes( buffer, len, NULL, NULL );
-            printf( "\t.text\n" );
+            DumpBytes( outfile, buffer, len, NULL, NULL );
+            fprintf( outfile, "\t.text\n" );
             break;
 
         case TYPE_LONG:
-            printf( "/* %s.%d (%s) */\n",
+            fprintf( outfile, "/* %s.%d (%s) */\n",
                      DLLName, i, odp->name);
-            printf( "\t.data\n" );
-            printf( "%s_%d:\n", DLLName, i );
+            fprintf( outfile, "\t.data\n" );
+            fprintf( outfile, "%s_%d:\n", DLLName, i );
             len = StoreVariableCode( buffer, 4, odp );
-            DumpBytes( buffer, len, NULL, NULL );
-            printf( "\t.text\n" );
+            DumpBytes( outfile, buffer, len, NULL, NULL );
+            fprintf( outfile, "\t.text\n" );
             break;
 
         case TYPE_EXTERN:
@@ -1038,42 +1056,42 @@
         default:
             fprintf(stderr,"build: function type %d not available for Win32\n",
                     odp->type);
-            exit(1);
+            return -1;
         }
     }
 
-    module_size = BuildModule32();
+    module_size = BuildModule32( outfile );
 
     /* Output the DLL functions table */
 
-    printf( "\t.text\n" );
-    printf( "\t.align 4\n" );
-    printf( "Functions:\n" );
+    fprintf( outfile, "\t.text\n" );
+    fprintf( outfile, "\t.align 4\n" );
+    fprintf( outfile, "Functions:\n" );
     odp = OrdinalDefinitions;
     for (i = 0; i <= Limit; i++, odp++)
     {
         switch(odp->type)
         {
         case TYPE_INVALID:
-            printf( "\t.long 0\n" );
+            fprintf( outfile, "\t.long 0\n" );
             break;
         case TYPE_EXTERN:
-            printf( "\t.long " PREFIX "%s\n", odp->u.ext.link_name );
+            fprintf( outfile, "\t.long " PREFIX "%s\n", odp->u.ext.link_name );
             break;
         default:
-            printf( "\t.long %s_%d\n", DLLName, i );
+            fprintf( outfile, "\t.long %s_%d\n", DLLName, i );
             break;
         }
     }
 
     /* Output the DLL names table */
 
-    printf( "FuncNames:\n" );
+    fprintf( outfile, "FuncNames:\n" );
     odp = OrdinalDefinitions;
     for (i = 0; i <= Limit; i++, odp++)
     {
-        if (odp->type == TYPE_INVALID) printf( "\t.long 0\n" );
-        else printf( "\t.long Name_%d\n", i );
+        if (odp->type == TYPE_INVALID) fprintf( outfile, "\t.long 0\n" );
+        else fprintf( outfile, "\t.long Name_%d\n", i );
     }
 
     /* Output the DLL names */
@@ -1081,32 +1099,33 @@
     for (i = 0, odp = OrdinalDefinitions; i <= Limit; i++, odp++)
     {
         if (odp->type != TYPE_INVALID)
-            printf( "Name_%d:\t.ascii \"%s\\0\"\n", i, odp->name );
+            fprintf( outfile, "Name_%d:\t.ascii \"%s\\0\"\n", i, odp->name );
     }
 
     /* Output the DLL descriptor */
 
-    printf( "DLLName:\t.ascii \"%s\\0\"\n", DLLName );
-    printf( "\t.align 4\n" );
-    printf( "\t.globl " PREFIX "%s_Descriptor\n", DLLName );
-    printf( PREFIX "%s_Descriptor:\n", DLLName );
-    printf( "\t.long DLLName\n" );          /* Name */
-    printf( "\t.long Module_Start\n" );     /* Module start */
-    printf( "\t.long %d\n", module_size );  /* Module size */
-    printf( "\t.long %d\n", Base );         /* Base */
-    printf( "\t.long %d\n", Limit+1 );      /* Size */
-    printf( "\t.long Code_Start\n" );       /* Code start */
-    printf( "\t.long Functions\n" );        /* Functions */
-    printf( "\t.long FuncNames\n" );        /* Function names */
+    fprintf( outfile, "DLLName:\t.ascii \"%s\\0\"\n", DLLName );
+    fprintf( outfile, "\t.align 4\n" );
+    fprintf( outfile, "\t.globl " PREFIX "%s_Descriptor\n", DLLName );
+    fprintf( outfile, PREFIX "%s_Descriptor:\n", DLLName );
+    fprintf( outfile, "\t.long DLLName\n" );          /* Name */
+    fprintf( outfile, "\t.long Module_Start\n" );     /* Module start */
+    fprintf( outfile, "\t.long %d\n", module_size );  /* Module size */
+    fprintf( outfile, "\t.long %d\n", Base );         /* Base */
+    fprintf( outfile, "\t.long %d\n", Limit+1 );      /* Size */
+    fprintf( outfile, "\t.long Code_Start\n" );       /* Code start */
+    fprintf( outfile, "\t.long Functions\n" );        /* Functions */
+    fprintf( outfile, "\t.long FuncNames\n" );        /* Function names */
+    return 0;
 }
 
 
 /*******************************************************************
- *         BuildSpec16Files
+ *         BuildSpec16File
  *
  * Build a Win16 assembly file from a spec file.
  */
-static void BuildSpec16Files(void)
+static int BuildSpec16File( FILE *outfile )
 {
     ORDDEF *odp;
     int i;
@@ -1117,9 +1136,9 @@
     memset( data, 0, 16 );
     data_offset = 16;
 
-    printf( "/* File generated automatically; do not edit! */\n" );
-    printf( "\t.text\n" );
-    printf( "Code_Start:\n" );
+    fprintf( outfile, "/* File generated automatically; do not edit! */\n" );
+    fprintf( outfile, "\t.text\n" );
+    fprintf( outfile, "Code_Start:\n" );
     code_offset = 0;
 
     odp = OrdinalDefinitions;
@@ -1151,17 +1170,17 @@
             break;
 
           case TYPE_RETURN:
-            printf( "/* %s.%d */\n", DLLName, i);
-            printf( "\tmovw $%d,%%ax\n", LOWORD(odp->u.ret.ret_value) );
-            printf( "\tmovw $%d,%%dx\n", HIWORD(odp->u.ret.ret_value) );
-            printf( "\t.byte 0x66\n");
+            fprintf( outfile,"/* %s.%d */\n", DLLName, i);
+            fprintf( outfile,"\tmovw $%d,%%ax\n",LOWORD(odp->u.ret.ret_value));
+            fprintf( outfile,"\tmovw $%d,%%dx\n",HIWORD(odp->u.ret.ret_value));
+            fprintf( outfile,"\t.byte 0x66\n");
             if (odp->u.ret.arg_size != 0)
-                printf( "\tlret $%d\n\n", odp->u.ret.arg_size);
+                fprintf( outfile, "\tlret $%d\n\n", odp->u.ret.arg_size);
             else
             {
-                printf( "\tlret\n");
-                printf( "\tnop\n");
-                printf( "\tnop\n\n");
+                fprintf( outfile, "\tlret\n");
+                fprintf( outfile, "\tnop\n");
+                fprintf( outfile, "\tnop\n\n");
             }
             odp->offset = code_offset;
             code_offset += 12;  /* Assembly code is 12 bytes long */
@@ -1171,19 +1190,19 @@
           case TYPE_PASCAL:
           case TYPE_PASCAL_16:
           case TYPE_STUB:
-            printf( "/* %s.%d */\n", DLLName, i);
-            printf( "\tpushw %%bp\n" );
-            printf( "\tpushl $" PREFIX "%s\n", odp->u.func.link_name );
+            fprintf( outfile, "/* %s.%d */\n", DLLName, i);
+            fprintf( outfile, "\tpushw %%bp\n" );
+            fprintf( outfile, "\tpushl $" PREFIX "%s\n",odp->u.func.link_name);
             /* FreeBSD does not understand lcall, so do it the hard way */
-            printf( "\t.byte 0x9a /*lcall*/\n" );
-            printf( "\t.long " PREFIX "CallFrom16_%s_%s\n",
-                    (odp->type == TYPE_REGISTER) ? "regs" :
-                    (odp->type == TYPE_PASCAL) ? "long" : "word",
-                    odp->u.func.arg_types );
-            printf( "\t.byte 0x%02x,0x%02x\n", /* Some asms don't have .word */
-                    LOBYTE(WINE_CODE_SELECTOR), HIBYTE(WINE_CODE_SELECTOR) );
-            printf( "\tnop\n" );
-            printf( "\tnop\n\n" );
+            fprintf( outfile, "\t.byte 0x9a /*lcall*/\n" );
+            fprintf( outfile, "\t.long " PREFIX "CallFrom16_%s_%s\n",
+                     (odp->type == TYPE_REGISTER) ? "regs" :
+                     (odp->type == TYPE_PASCAL) ? "long" : "word",
+                     odp->u.func.arg_types );
+            fprintf( outfile,"\t.byte 0x%02x,0x%02x\n", /* Some asms don't have .word */
+                     LOBYTE(WINE_CODE_SELECTOR), HIBYTE(WINE_CODE_SELECTOR) );
+            fprintf( outfile, "\tnop\n" );
+            fprintf( outfile, "\tnop\n\n" );
             odp->offset = code_offset;
             code_offset += 16;  /* Assembly code is 16 bytes long */
             break;
@@ -1191,65 +1210,65 @@
           default:
             fprintf(stderr,"build: function type %d not available for Win16\n",
                     odp->type);
-            exit(1);
+            return -1;
 	}
     }
 
     if (!code_offset)  /* Make sure the code segment is not empty */
     {
-        printf( "\t.byte 0\n" );
+        fprintf( outfile, "\t.byte 0\n" );
         code_offset++;
     }
 
     /* Output data segment */
 
-    DumpBytes( data, data_offset, NULL, "Data_Start" );
+    DumpBytes( outfile, data, data_offset, NULL, "Data_Start" );
 
     /* Build the module */
 
-    module_size = BuildModule16( code_offset, data_offset );
+    module_size = BuildModule16( outfile, code_offset, data_offset );
 
     /* Output the DLL descriptor */
 
-    printf( "\t.text\n" );
-    printf( "DLLName:\t.ascii \"%s\\0\"\n", DLLName );
-    printf( "\t.align 4\n" );
-    printf( "\t.globl " PREFIX "%s_Descriptor\n", DLLName );
-    printf( PREFIX "%s_Descriptor:\n", DLLName );
-    printf( "\t.long DLLName\n" );          /* Name */
-    printf( "\t.long Module_Start\n" );     /* Module start */
-    printf( "\t.long %d\n", module_size );  /* Module size */
-    printf( "\t.long Code_Start\n" );       /* Code start */
-    printf( "\t.long Data_Start\n" );       /* Data start */
+    fprintf( outfile, "\t.text\n" );
+    fprintf( outfile, "DLLName:\t.ascii \"%s\\0\"\n", DLLName );
+    fprintf( outfile, "\t.align 4\n" );
+    fprintf( outfile, "\t.globl " PREFIX "%s_Descriptor\n", DLLName );
+    fprintf( outfile, PREFIX "%s_Descriptor:\n", DLLName );
+    fprintf( outfile, "\t.long DLLName\n" );          /* Name */
+    fprintf( outfile, "\t.long Module_Start\n" );     /* Module start */
+    fprintf( outfile, "\t.long %d\n", module_size );  /* Module size */
+    fprintf( outfile, "\t.long Code_Start\n" );       /* Code start */
+    fprintf( outfile, "\t.long Data_Start\n" );       /* Data start */
+    return 0;
 }
 
 
 /*******************************************************************
- *         BuildSpecFiles
+ *         BuildSpecFile
  *
  * Build an assembly file from a spec file.
  */
-static void BuildSpecFiles( char *specname )
+static int BuildSpecFile( FILE *outfile, char *specname )
 {
     SpecFp = fopen( specname, "r");
     if (SpecFp == NULL)
     {
 	fprintf(stderr, "Could not open specification file, '%s'\n", specname);
-	exit(1);
+        return -1;
     }
 
-    ParseTopLevel();
+    if (ParseTopLevel() < 0) return -1;
+
     switch(SpecType)
     {
-    case SPEC_INVALID:
-        fprintf( stderr, "%s: Missing 'type' declaration\n", specname );
-        exit(1);
     case SPEC_WIN16:
-        BuildSpec16Files();
-        break;
+        return BuildSpec16File( outfile );
     case SPEC_WIN32:
-        BuildSpec32Files();
-        break;
+        return BuildSpec32File( outfile );
+    default:
+        fprintf( stderr, "%s: Missing 'type' declaration\n", specname );
+        return -1;
     }
 }
 
@@ -1273,65 +1292,62 @@
  * (ebp+4)   ret addr
  * (ebp)     ebp
  */
-static void BuildCall32LargeStack(void)
+static void BuildCall32LargeStack( FILE *outfile )
 {
     /* Function header */
 
-    printf( "/**********\n" );
-    printf( " * " PREFIX "CallTo32_LargeStack\n" );
-    printf( " **********/\n" );
-    printf( "\t.align 4\n" );
-    printf( "\t.globl " PREFIX "CallTo32_LargeStack\n\n" );
-    printf( PREFIX "CallTo32_LargeStack:\n" );
+    fprintf( outfile, "\n\t.align 4\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CallTo32_LargeStack\n" );
+    fprintf( outfile, PREFIX "CallTo32_LargeStack:\n" );
     
     /* Entry code */
 
-    printf( "\tpushl %%ebp\n" );
-    printf( "\tmovl %%esp,%%ebp\n" );
+    fprintf( outfile, "\tpushl %%ebp\n" );
+    fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
 
     /* Save registers */
 
-    printf( "\tpushl %%ecx\n" );
-    printf( "\tpushl %%esi\n" );
-    printf( "\tpushl %%edi\n" );
+    fprintf( outfile, "\tpushl %%ecx\n" );
+    fprintf( outfile, "\tpushl %%esi\n" );
+    fprintf( outfile, "\tpushl %%edi\n" );
 
     /* Retrieve the original 32-bit stack pointer and switch to it if any */
 
-    printf( "\tmovl " PREFIX "IF1632_Original32_esp, %%eax\n" );
-    printf( "\torl %%eax,%%eax\n" );
-    printf( "\tje no_orig_esp\n" );
-    printf( "\tmovl %%eax,%%esp\n" );
-    printf( "no_orig_esp:\n" );
+    fprintf( outfile, "\tmovl " PREFIX "IF1632_Original32_esp, %%eax\n" );
+    fprintf( outfile, "\torl %%eax,%%eax\n" );
+    fprintf( outfile, "\tje no_orig_esp\n" );
+    fprintf( outfile, "\tmovl %%eax,%%esp\n" );
+    fprintf( outfile, "no_orig_esp:\n" );
 
     /* Transfer the arguments */
 
-    printf( "\tmovl 12(%%ebp),%%ecx\n" );
-    printf( "\torl %%ecx,%%ecx\n" );
-    printf( "\tje no_args\n" );
-    printf( "\tleal 16(%%ebp),%%esi\n" );
-    printf( "\tshll $2,%%ecx\n" );
-    printf( "\tsubl %%ecx,%%esp\n" );
-    printf( "\tmovl %%esp,%%edi\n" );
-    printf( "\tshrl $2,%%ecx\n" );
-    printf( "\tcld\n" );
-    printf( "\trep; movsl\n" );
-    printf( "no_args:\n" );
+    fprintf( outfile, "\tmovl 12(%%ebp),%%ecx\n" );
+    fprintf( outfile, "\torl %%ecx,%%ecx\n" );
+    fprintf( outfile, "\tje no_args\n" );
+    fprintf( outfile, "\tleal 16(%%ebp),%%esi\n" );
+    fprintf( outfile, "\tshll $2,%%ecx\n" );
+    fprintf( outfile, "\tsubl %%ecx,%%esp\n" );
+    fprintf( outfile, "\tmovl %%esp,%%edi\n" );
+    fprintf( outfile, "\tshrl $2,%%ecx\n" );
+    fprintf( outfile, "\tcld\n" );
+    fprintf( outfile, "\trep; movsl\n" );
+    fprintf( outfile, "no_args:\n" );
 
     /* Call the function */
 
-    printf( "\tcall 8(%%ebp)\n" );
+    fprintf( outfile, "\tcall 8(%%ebp)\n" );
 
     /* Switch back to the normal stack */
 
-    printf( "\tleal -12(%%ebp),%%esp\n" );
+    fprintf( outfile, "\tleal -12(%%ebp),%%esp\n" );
 
     /* Restore registers and return */
 
-    printf( "\tpopl %%edi\n" );
-    printf( "\tpopl %%esi\n" );
-    printf( "\tpopl %%ecx\n" );
-    printf( "\tpopl %%ebp\n" );
-    printf( "\tret\n" );
+    fprintf( outfile, "\tpopl %%edi\n" );
+    fprintf( outfile, "\tpopl %%esi\n" );
+    fprintf( outfile, "\tpopl %%ecx\n" );
+    fprintf( outfile, "\tpopl %%ebp\n" );
+    fprintf( outfile, "\tret\n" );
 }
 
 
@@ -1347,17 +1363,17 @@
  *  (bp+2)    ip
  *  (bp)      bp
  */
-static int TransferArgs16To32( char *args )
+static int TransferArgs16To32( FILE *outfile, char *args )
 {
     int i, pos16, pos32;
 
     /* Save ebx first */
 
-    printf( "\tpushl %%ebx\n" );
+    fprintf( outfile, "\tpushl %%ebx\n" );
 
     /* Get the 32-bit stack pointer */
 
-    printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" );
+    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" );
 
     /* Copy the arguments */
 
@@ -1370,33 +1386,33 @@
         switch(args[i-1])
         {
         case 'w':  /* word */
-            printf( "\tmovzwl %d(%%ebp),%%eax\n", pos16 );
-            printf( "\tmovl %%eax,%d(%%ebx)\n", pos32 );
+            fprintf( outfile, "\tmovzwl %d(%%ebp),%%eax\n", pos16 );
+            fprintf( outfile, "\tmovl %%eax,%d(%%ebx)\n", pos32 );
             pos16 += 2;
             break;
 
         case 's':  /* s_word */
-            printf( "\tmovswl %d(%%ebp),%%eax\n", pos16 );
-            printf( "\tmovl %%eax,%d(%%ebx)\n", pos32 );
+            fprintf( outfile, "\tmovswl %d(%%ebp),%%eax\n", pos16 );
+            fprintf( outfile, "\tmovl %%eax,%d(%%ebx)\n", pos32 );
             pos16 += 2;
             break;
 
         case 'l':  /* long */
-            printf( "\tmovl %d(%%ebp),%%eax\n", pos16 );
-            printf( "\tmovl %%eax,%d(%%ebx)\n", pos32 );
+            fprintf( outfile, "\tmovl %d(%%ebp),%%eax\n", pos16 );
+            fprintf( outfile, "\tmovl %%eax,%d(%%ebx)\n", pos32 );
             pos16 += 4;
             break;
 
         case 'p':  /* ptr */
             /* Get the selector */
-            printf( "\tmovw %d(%%ebp),%%ax\n", pos16 + 2 );
+            fprintf( outfile, "\tmovw %d(%%ebp),%%ax\n", pos16 + 2 );
             /* Get the selector base */
-            printf( "\tandl $0xfff8,%%eax\n" );
-            printf( "\tmovl " PREFIX "ldt_copy(%%eax),%%eax\n" );
-            printf( "\tmovl %%eax,%d(%%ebx)\n", pos32 );
+            fprintf( outfile, "\tandl $0xfff8,%%eax\n" );
+            fprintf( outfile, "\tmovl " PREFIX "ldt_copy(%%eax),%%eax\n" );
+            fprintf( outfile, "\tmovl %%eax,%d(%%ebx)\n", pos32 );
             /* Add the offset */
-            printf( "\tmovzwl %d(%%ebp),%%eax\n", pos16 );
-            printf( "\taddl %%eax,%d(%%ebx)\n", pos32 );
+            fprintf( outfile, "\tmovzwl %d(%%ebp),%%eax\n", pos16 );
+            fprintf( outfile, "\taddl %%eax,%d(%%ebx)\n", pos32 );
             pos16 += 4;
             break;
 
@@ -1407,7 +1423,7 @@
 
     /* Restore ebx */
     
-    printf( "\tpopl %%ebx\n" );
+    fprintf( outfile, "\tpopl %%ebx\n" );
 
     return pos16 - 6;  /* Return the size of the 16-bit args */
 }
@@ -1420,30 +1436,30 @@
  * The only valid registers in the context structure are:
  *   eax, ebx, ecx, edx, esi, edi, ds, es, (some of the) flags
  */
-static void BuildContext16(void)
+static void BuildContext16( FILE *outfile )
 {
     /* Save ebx first */
 
-    printf( "\tpushl %%ebx\n" );
+    fprintf( outfile, "\tpushl %%ebx\n" );
 
     /* Get the 32-bit stack pointer */
 
-    printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" );
+    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" );
 
     /* Store the registers */
 
-    printf( "\tpopl %d(%%ebx)\n", SIGCONTEXTOFFSET(EBX) ); /* Get ebx from stack*/
-    printf( "\tmovl %%eax,%d(%%ebx)\n", SIGCONTEXTOFFSET(EAX) );
-    printf( "\tmovl %%ecx,%d(%%ebx)\n", SIGCONTEXTOFFSET(ECX) );
-    printf( "\tmovl %%edx,%d(%%ebx)\n", SIGCONTEXTOFFSET(EDX) );
-    printf( "\tmovl %%esi,%d(%%ebx)\n", SIGCONTEXTOFFSET(ESI) );
-    printf( "\tmovl %%edi,%d(%%ebx)\n", SIGCONTEXTOFFSET(EDI) );
-    printf( "\tmovw -10(%%ebp),%%ax\n" );  /* Get saved ds from stack */
-    printf( "\tmovw %%ax,%d(%%ebx)\n", SIGCONTEXTOFFSET(DS) );
-    printf( "\tmovw -6(%%ebp),%%ax\n" );  /* Get saved es from stack */
-    printf( "\tmovw %%ax,%d(%%ebx)\n", SIGCONTEXTOFFSET(ES) );
-    printf( "\tpushfl\n" );
-    printf( "\tpopl %d(%%ebx)\n", SIGCONTEXTOFFSET(EFL) );
+    fprintf( outfile, "\tpopl %d(%%ebx)\n", SIGCONTEXTOFFSET(EBX) ); /* Get ebx from stack*/
+    fprintf( outfile, "\tmovl %%eax,%d(%%ebx)\n", SIGCONTEXTOFFSET(EAX) );
+    fprintf( outfile, "\tmovl %%ecx,%d(%%ebx)\n", SIGCONTEXTOFFSET(ECX) );
+    fprintf( outfile, "\tmovl %%edx,%d(%%ebx)\n", SIGCONTEXTOFFSET(EDX) );
+    fprintf( outfile, "\tmovl %%esi,%d(%%ebx)\n", SIGCONTEXTOFFSET(ESI) );
+    fprintf( outfile, "\tmovl %%edi,%d(%%ebx)\n", SIGCONTEXTOFFSET(EDI) );
+    fprintf( outfile, "\tmovw -10(%%ebp),%%ax\n" ); /*Get saved ds from stack*/
+    fprintf( outfile, "\tmovw %%ax,%d(%%ebx)\n", SIGCONTEXTOFFSET(DS) );
+    fprintf( outfile, "\tmovw -6(%%ebp),%%ax\n" ); /*Get saved es from stack*/
+    fprintf( outfile, "\tmovw %%ax,%d(%%ebx)\n", SIGCONTEXTOFFSET(ES) );
+    fprintf( outfile, "\tpushfl\n" );
+    fprintf( outfile, "\tpopl %d(%%ebx)\n", SIGCONTEXTOFFSET(EFL) );
 }
 
 
@@ -1452,26 +1468,26 @@
  *
  * Restore the registers from the context structure
  */
-static void RestoreContext16(void)
+static void RestoreContext16( FILE *outfile )
 {
     /* Get the 32-bit stack pointer */
 
-    printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" );
+    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebx\n" );
 
     /* Restore the registers */
 
-    printf( "\tmovl %d(%%ebx),%%ecx\n", SIGCONTEXTOFFSET(ECX) );
-    printf( "\tmovl %d(%%ebx),%%edx\n", SIGCONTEXTOFFSET(EDX) );
-    printf( "\tmovl %d(%%ebx),%%esi\n", SIGCONTEXTOFFSET(ESI) );
-    printf( "\tmovl %d(%%ebx),%%edi\n", SIGCONTEXTOFFSET(EDI) );
-    printf( "\tpopl %%eax\n" );  /* Remove old ds and ip from stack */
-    printf( "\tpopl %%eax\n" );  /* Remove old cs and es from stack */
-    printf( "\tpushw %d(%%ebx)\n", SIGCONTEXTOFFSET(DS) ); /* Push new ds */
-    printf( "\tpushw %d(%%ebx)\n", SIGCONTEXTOFFSET(ES) ); /* Push new es */
-    printf( "\tpushl %d(%%ebx)\n", SIGCONTEXTOFFSET(EFL) );
-    printf( "\tpopfl\n" );
-    printf( "\tmovl %d(%%ebx),%%eax\n", SIGCONTEXTOFFSET(EAX) );
-    printf( "\tmovl %d(%%ebx),%%ebx\n", SIGCONTEXTOFFSET(EBX) );
+    fprintf( outfile, "\tmovl %d(%%ebx),%%ecx\n", SIGCONTEXTOFFSET(ECX) );
+    fprintf( outfile, "\tmovl %d(%%ebx),%%edx\n", SIGCONTEXTOFFSET(EDX) );
+    fprintf( outfile, "\tmovl %d(%%ebx),%%esi\n", SIGCONTEXTOFFSET(ESI) );
+    fprintf( outfile, "\tmovl %d(%%ebx),%%edi\n", SIGCONTEXTOFFSET(EDI) );
+    fprintf( outfile, "\tpopl %%eax\n" ); /* Remove old ds and ip from stack */
+    fprintf( outfile, "\tpopl %%eax\n" ); /* Remove old cs and es from stack */
+    fprintf( outfile, "\tpushw %d(%%ebx)\n", SIGCONTEXTOFFSET(DS) ); /* Push new ds */
+    fprintf( outfile, "\tpushw %d(%%ebx)\n", SIGCONTEXTOFFSET(ES) ); /*Push new es */
+    fprintf( outfile, "\tpushl %d(%%ebx)\n", SIGCONTEXTOFFSET(EFL) );
+    fprintf( outfile, "\tpopfl\n" );
+    fprintf( outfile, "\tmovl %d(%%ebx),%%eax\n", SIGCONTEXTOFFSET(EAX) );
+    fprintf( outfile, "\tmovl %d(%%ebx),%%ebx\n", SIGCONTEXTOFFSET(EBX) );
 }
 
 
@@ -1498,7 +1514,7 @@
  * (sp)    word   low word of ip of 16-bit entry point
  *
  */
-static void BuildCallFrom16Func( char *profile )
+static void BuildCallFrom16Func( FILE *outfile, char *profile )
 {
     int argsize = 0;
     int short_ret = 0;
@@ -1517,119 +1533,117 @@
 
     /* Function header */
 
-    printf( "/**********\n" );
-    printf( " * " PREFIX "CallFrom16_%s\n", profile );
-    printf( " **********/\n" );
-    printf( "\t.align 4\n" );
-    printf( "\t.globl " PREFIX "CallFrom16_%s\n\n", profile );
-    printf( PREFIX "CallFrom16_%s:\n", profile );
+    fprintf( outfile, "\n\t.align 4\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CallFrom16_%s\n", profile );
+    fprintf( outfile, PREFIX "CallFrom16_%s:\n", profile );
 
     /* Setup bp to point to its copy on the stack */
 
-    printf( "\tmovzwl %%sp,%%ebp\n" );
-    printf( "\taddw $12,%%bp\n" );
+    fprintf( outfile, "\tmovzwl %%sp,%%ebp\n" );
+    fprintf( outfile, "\taddw $12,%%bp\n" );
 
     /* Save 16-bit ds and es */
 
     /* Stupid FreeBSD assembler doesn't know these either */
-    /* printf( "\tmovw %%ds,-10(%%ebp)\n" ); */
-    printf( "\t.byte 0x66,0x8c,0x5d,0xf6\n" );
-    /* printf( "\tmovw %%es,-6(%%ebp)\n" ); */
-    printf( "\t.byte 0x66,0x8c,0x45,0xfa\n" );
+    /* fprintf( outfile, "\tmovw %%ds,-10(%%ebp)\n" ); */
+    fprintf( outfile, "\t.byte 0x66,0x8c,0x5d,0xf6\n" );
+    /* fprintf( outfile, "\tmovw %%es,-6(%%ebp)\n" ); */
+    fprintf( outfile, "\t.byte 0x66,0x8c,0x45,0xfa\n" );
 
     /* Restore 32-bit ds and es */
 
-    printf( "\tpushl $0x%04x%04x\n", WINE_DATA_SELECTOR, WINE_DATA_SELECTOR );
-    printf( "\tpopw %%ds\n" );
-    printf( "\tpopw %%es\n" );
+    fprintf( outfile, "\tpushl $0x%04x%04x\n",
+             WINE_DATA_SELECTOR, WINE_DATA_SELECTOR );
+    fprintf( outfile, "\tpopw %%ds\n" );
+    fprintf( outfile, "\tpopw %%es\n" );
 
 
     /* Save the 16-bit stack */
 
-    printf( "\tpushw " PREFIX "IF1632_Saved16_sp\n" );
-    printf( "\tpushw " PREFIX "IF1632_Saved16_ss\n" );
+    fprintf( outfile, "\tpushw " PREFIX "IF1632_Saved16_sp\n" );
+    fprintf( outfile, "\tpushw " PREFIX "IF1632_Saved16_ss\n" );
 #ifdef __svr4__
-    printf("\tdata16\n");
+    fprintf( outfile,"\tdata16\n");
 #endif
-    printf( "\tmovw %%ss," PREFIX "IF1632_Saved16_ss\n" );
-    printf( "\tmovw %%sp," PREFIX "IF1632_Saved16_sp\n" );
+    fprintf( outfile, "\tmovw %%ss," PREFIX "IF1632_Saved16_ss\n" );
+    fprintf( outfile, "\tmovw %%sp," PREFIX "IF1632_Saved16_sp\n" );
 
     /* Transfer the arguments */
 
-    if (reg_func) BuildContext16();
-    else if (*args) argsize = TransferArgs16To32( args );
+    if (reg_func) BuildContext16( outfile );
+    else if (*args) argsize = TransferArgs16To32( outfile, args );
 
     /* Get the address of the API function */
 
-    printf( "\tmovl -4(%%ebp),%%eax\n" );
+    fprintf( outfile, "\tmovl -4(%%ebp),%%eax\n" );
 
     /* If necessary, save %edx over the API function address */
 
     if (!reg_func && short_ret)
-        printf( "\tmovl %%edx,-4(%%ebp)\n" );
+        fprintf( outfile, "\tmovl %%edx,-4(%%ebp)\n" );
 
     /* Switch to the 32-bit stack */
 
-    printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebp\n" );
-    printf( "\tpushw %%ds\n" );
-    printf( "\tpopw %%ss\n" );
-    printf( "\tleal -%d(%%ebp),%%esp\n",
-            reg_func ? sizeof(SIGCONTEXT) : 4 * strlen(args) );
+    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%ebp\n" );
+    fprintf( outfile, "\tpushw %%ds\n" );
+    fprintf( outfile, "\tpopw %%ss\n" );
+    fprintf( outfile, "\tleal -%d(%%ebp),%%esp\n",
+             reg_func ? sizeof(SIGCONTEXT) : 4 * strlen(args) );
     if (reg_func)  /* Push the address of the context struct */
-        printf( "\tpushl %%esp\n" );
+        fprintf( outfile, "\tpushl %%esp\n" );
 
     /* Setup %ebp to point to the previous stack frame (built by CallTo16) */
 
-    printf( "\taddl $24,%%ebp\n" );
+    fprintf( outfile, "\taddl $24,%%ebp\n" );
 
     /* Print the debug information before the call */
 
     if (debugging)
     {
-        printf( "\tpushl %%eax\n" );
-        printf( "\tpushl $Profile_%s\n", profile );
-        printf( "\tpushl $%d\n", reg_func ? 2 : (short_ret ? 1 : 0) );
-        printf( "\tcall " PREFIX "RELAY_DebugCallFrom16\n" );
-        printf( "\tpopl %%eax\n" );
-        printf( "\tpopl %%eax\n" );
-        printf( "\tpopl %%eax\n" );
+        fprintf( outfile, "\tpushl %%eax\n" );
+        fprintf( outfile, "\tpushl $Profile_%s\n", profile );
+        fprintf( outfile, "\tpushl $%d\n", reg_func ? 2 : (short_ret ? 1 : 0));
+        fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallFrom16\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
     }
 
     /* Call the entry point */
 
-    printf( "\tcall %%eax\n" );
+    fprintf( outfile, "\tcall %%eax\n" );
 
     /* Print the debug information after the call */
 
     if (debugging)
     {
-        printf( "\tpushl %%eax\n" );
-        printf( "\tpushl $%d\n", reg_func ? 2 : (short_ret ? 1 : 0) );
-        printf( "\tcall " PREFIX "RELAY_DebugCallFrom16Ret\n" );
-        printf( "\tpopl %%eax\n" );
-        printf( "\tpopl %%eax\n" );
+        fprintf( outfile, "\tpushl %%eax\n" );
+        fprintf( outfile, "\tpushl $%d\n", reg_func ? 2 : (short_ret ? 1 : 0));
+        fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallFrom16Ret\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
     }
 
     /* Restore the 16-bit stack */
 
 #ifdef __svr4__
-    printf( "\tdata16\n");
+    fprintf( outfile, "\tdata16\n");
 #endif
-    printf( "\tmovw " PREFIX "IF1632_Saved16_ss,%%ss\n" );
-    printf( "\tmovw " PREFIX "IF1632_Saved16_sp,%%sp\n" );
+    fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss,%%ss\n" );
+    fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_sp,%%sp\n" );
 #ifdef __svr4__
-    printf( "\tdata16\n");
+    fprintf( outfile, "\tdata16\n");
 #endif
-    printf( "\tpopw " PREFIX "IF1632_Saved16_ss\n" );
+    fprintf( outfile, "\tpopw " PREFIX "IF1632_Saved16_ss\n" );
 #ifdef __svr4__
-    printf( "\tdata16\n");
+    fprintf( outfile, "\tdata16\n");
 #endif
-    printf( "\tpopw " PREFIX "IF1632_Saved16_sp\n" );
+    fprintf( outfile, "\tpopw " PREFIX "IF1632_Saved16_sp\n" );
 
     if (reg_func)
     {
         /* Restore registers from the context structure */
-        RestoreContext16();
+        RestoreContext16( outfile );
         
         /* Calc the arguments size */
         while (*args)
@@ -1651,48 +1665,48 @@
         }
 
         /* Restore ds and es */
-        printf( "\tpopw %%es\n" );
-        printf( "\tpopw %%ds\n" );
+        fprintf( outfile, "\tpopw %%es\n" );
+        fprintf( outfile, "\tpopw %%ds\n" );
 
         /* Remove the entry point from the stack */
         /* (we don't use add to avoid modifying the carry flag) */
-        printf( "\tpopl %%ebp\n" );
+        fprintf( outfile, "\tpopl %%ebp\n" );
     }
     else
     {
         /* Restore ds and es */
-        printf( "\tpopw %%bp\n" );       /* Remove ip */
-        printf( "\tpopl %%ebp\n" );      /* Remove ds and cs */
-        printf( "\tmovw %%bp,%%ds\n" );  /* Restore ds */
-        printf( "\tpopw %%es\n" );       /* Restore es */
+        fprintf( outfile, "\tpopw %%bp\n" );       /* Remove ip */
+        fprintf( outfile, "\tpopl %%ebp\n" );      /* Remove ds and cs */
+        fprintf( outfile, "\tmovw %%bp,%%ds\n" );  /* Restore ds */
+        fprintf( outfile, "\tpopw %%es\n" );       /* Restore es */
 
-        if (short_ret) printf( "\tpopl %%edx\n" );     /* Restore edx */
+        if (short_ret) fprintf( outfile, "\tpopl %%edx\n" );  /* Restore edx */
         else
         {
             /* Get the return value into dx:ax */
-            printf( "\tpushl %%eax\n" );
-            printf( "\tpopw %%ax\n" );
-            printf( "\tpopw %%dx\n" );
+            fprintf( outfile, "\tpushl %%eax\n" );
+            fprintf( outfile, "\tpopw %%ax\n" );
+            fprintf( outfile, "\tpopw %%dx\n" );
             /* Remove API entry point */
-            printf( "\taddl $4,%%esp\n" );
+            fprintf( outfile, "\taddl $4,%%esp\n" );
         }
     }
 
     /* Restore bp */
 
-    printf( "\tpopw %%bp\n" );
+    fprintf( outfile, "\tpopw %%bp\n" );
 
     /* Remove the arguments and return */
 
     if (argsize)
     {
-        printf( "\t.byte 0x66\n" );
-        printf( "\tlret $%d\n", argsize );
+        fprintf( outfile, "\t.byte 0x66\n" );
+        fprintf( outfile, "\tlret $%d\n", argsize );
     }
     else
     {
-        printf( "\t.byte 0x66\n" );
-        printf( "\tlret\n" );
+        fprintf( outfile, "\t.byte 0x66\n" );
+        fprintf( outfile, "\tlret\n" );
     }
 }
 
@@ -1718,7 +1732,7 @@
  *                               WORD ax, WORD bx, WORD cx, WORD dx,
  *                               WORD si, WORD di );
  */
-static void BuildCallTo16Func( char *profile )
+static void BuildCallTo16Func( FILE *outfile, char *profile )
 {
     int short_ret = 0;
     int reg_func = 0;
@@ -1734,91 +1748,88 @@
 
     /* Function header */
 
-    printf( "/**********\n" );
-    printf( " * " PREFIX "CallTo16_%s\n", profile );
-    printf( " **********/\n" );
-    printf( "\t.align 4\n" );
-    printf( "\t.globl " PREFIX "CallTo16_%s\n\n", profile );
-    printf( PREFIX "CallTo16_%s:\n", profile );
+    fprintf( outfile, "\n\t.align 4\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CallTo16_%s\n", profile );
+    fprintf( outfile, PREFIX "CallTo16_%s:\n", profile );
 
     /* Push code selector before return address to simulate a lcall */
 
-    printf( "\tpopl %%eax\n" );
-    printf( "\tpushl $0x%04x\n", WINE_CODE_SELECTOR );
-    printf( "\tpushl %%eax\n" );
+    fprintf( outfile, "\tpopl %%eax\n" );
+    fprintf( outfile, "\tpushl $0x%04x\n", WINE_CODE_SELECTOR );
+    fprintf( outfile, "\tpushl %%eax\n" );
 
     /* Entry code */
 
-    printf( "\tpushl %%ebp\n" );
-    printf( "\tmovl %%esp,%%ebp\n" );
+    fprintf( outfile, "\tpushl %%ebp\n" );
+    fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
 
     /* Save the 32-bit registers */
 
-    printf( "\tpushl %%ebx\n" );
-    printf( "\tpushl %%ecx\n" );
-    printf( "\tpushl %%edx\n" );
-    printf( "\tpushl %%esi\n" );
-    printf( "\tpushl %%edi\n" );
+    fprintf( outfile, "\tpushl %%ebx\n" );
+    fprintf( outfile, "\tpushl %%ecx\n" );
+    fprintf( outfile, "\tpushl %%edx\n" );
+    fprintf( outfile, "\tpushl %%esi\n" );
+    fprintf( outfile, "\tpushl %%edi\n" );
 
     /* Save the 32-bit stack */
 
-    printf( "\tpushl " PREFIX "IF1632_Saved32_esp\n" );
-    printf( "\tmovl %%esp," PREFIX "IF1632_Saved32_esp\n" );
-    printf( "\tmovl %%ebp,%%ebx\n" );
+    fprintf( outfile, "\tpushl " PREFIX "IF1632_Saved32_esp\n" );
+    fprintf( outfile, "\tmovl %%esp," PREFIX "IF1632_Saved32_esp\n" );
+    fprintf( outfile, "\tmovl %%ebp,%%ebx\n" );
 
     /* Print debugging info */
 
     if (debugging)
     {
         /* Push the address of the first argument */
-        printf( "\tmovl %%ebx,%%eax\n" );
-        printf( "\taddl $12,%%eax\n" );
-        printf( "\tpushl $%d\n", reg_func ? 8 : strlen(args) );
-        printf( "\tpushl %%eax\n" );
-        printf( "\tcall " PREFIX "RELAY_DebugCallTo16\n" );
-        printf( "\tpopl %%eax\n" );
-        printf( "\tpopl %%eax\n" );
+        fprintf( outfile, "\tmovl %%ebx,%%eax\n" );
+        fprintf( outfile, "\taddl $12,%%eax\n" );
+        fprintf( outfile, "\tpushl $%d\n", reg_func ? 8 : strlen(args) );
+        fprintf( outfile, "\tpushl %%eax\n" );
+        fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo16\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
     }
 
     /* Switch to the 16-bit stack */
 
 #ifdef __svr4__
-    printf("\tdata16\n");
+    fprintf( outfile,"\tdata16\n");
 #endif
-    printf( "\tmovw " PREFIX "IF1632_Saved16_ss,%%ss\n" );
-    printf( "\tmovw " PREFIX "IF1632_Saved16_sp,%%sp\n" );
+    fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss,%%ss\n" );
+    fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_sp,%%sp\n" );
 
     /* Transfer the arguments */
 
     if (reg_func)
     {
         /* Get the registers. ebx is handled later on. */
-        printf( "\tpushw 20(%%ebx)\n" );
-        printf( "\tpopw %%es\n" );
-        printf( "\tmovl 24(%%ebx),%%ebp\n" );
-        printf( "\tmovl 28(%%ebx),%%eax\n" );
-        printf( "\tmovl 36(%%ebx),%%ecx\n" );
-        printf( "\tmovl 40(%%ebx),%%edx\n" );
-        printf( "\tmovl 44(%%ebx),%%esi\n" );
-        printf( "\tmovl 48(%%ebx),%%edi\n" );
+        fprintf( outfile, "\tpushw 20(%%ebx)\n" );
+        fprintf( outfile, "\tpopw %%es\n" );
+        fprintf( outfile, "\tmovl 24(%%ebx),%%ebp\n" );
+        fprintf( outfile, "\tmovl 28(%%ebx),%%eax\n" );
+        fprintf( outfile, "\tmovl 36(%%ebx),%%ecx\n" );
+        fprintf( outfile, "\tmovl 40(%%ebx),%%edx\n" );
+        fprintf( outfile, "\tmovl 44(%%ebx),%%esi\n" );
+        fprintf( outfile, "\tmovl 48(%%ebx),%%edi\n" );
     }
     else  /* not a register function */
     {
         int pos = 16;  /* first argument position */
 
         /* Make %bp point to the previous stackframe (built by CallFrom16) */
-        printf( "\tmovzwl %%sp,%%ebp\n" );
-        printf( "\taddw $16,%%bp\n" );
+        fprintf( outfile, "\tmovzwl %%sp,%%ebp\n" );
+        fprintf( outfile, "\taddw $16,%%bp\n" );
 
         while (*args)
         {
             switch(*args++)
             {
             case 'w': /* word */
-                printf( "\tpushw %d(%%ebx)\n", pos );
+                fprintf( outfile, "\tpushw %d(%%ebx)\n", pos );
                 break;
             case 'l': /* long */
-                printf( "\tpushl %d(%%ebx)\n", pos );
+                fprintf( outfile, "\tpushl %d(%%ebx)\n", pos );
                 break;
             }
             pos += 4;
@@ -1827,36 +1838,37 @@
 
     /* Push the return address */
 
-    printf( "\tpushl " PREFIX "CALLTO16_RetAddr_%s\n",
-            short_ret ? "word" : "long" );
+    fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_%s\n",
+             short_ret ? "word" : "long" );
 
     /* Push the called routine address */
 
-    printf( "\tpushl 12(%%ebx)\n" );
+    fprintf( outfile, "\tpushl 12(%%ebx)\n" );
 
     /* Get the 16-bit ds */
 
     if (reg_func)
     {
-        printf( "\tpushw 16(%%ebx)\n" );
-        printf( "\tmovl 32(%%ebx),%%ebx\n" ); /*Get ebx from the 32-bit stack*/
-        printf( "\tpopw %%ds\n" );
+        fprintf( outfile, "\tpushw 16(%%ebx)\n" );
+        /* Get ebx from the 32-bit stack */
+        fprintf( outfile, "\tmovl 32(%%ebx),%%ebx\n" );
+        fprintf( outfile, "\tpopw %%ds\n" );
     }
     else
     {
         /* Get previous ds from the 16-bit stack and */
         /* set ax equal to ds for window procedures. */
-        printf( "\tmovw -10(%%ebp),%%ax\n" );
+        fprintf( outfile, "\tmovw -10(%%ebp),%%ax\n" );
 #ifdef __svr4__
-        printf( "\tdata16\n");
+        fprintf( outfile, "\tdata16\n");
 #endif
-        printf( "\tmovw %%ax,%%ds\n" );
+        fprintf( outfile, "\tmovw %%ax,%%ds\n" );
     }
 
     /* Jump to the called routine */
 
-    printf( "\t.byte 0x66\n" );
-    printf( "\tlret\n" );
+    fprintf( outfile, "\t.byte 0x66\n" );
+    fprintf( outfile, "\tlret\n" );
 }
 
 
@@ -1865,61 +1877,61 @@
  *
  * Build the return code for 16-bit callbacks
  */
-static void BuildRet16Func()
+static void BuildRet16Func( FILE *outfile )
 {
-    printf( "\t.globl " PREFIX "CALLTO16_Ret_word\n" );
-    printf( "\t.globl " PREFIX "CALLTO16_Ret_long\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_word\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_long\n" );
 
     /* Put return value into eax */
 
-    printf( PREFIX "CALLTO16_Ret_long:\n" );
-    printf( "\tpushw %%dx\n" );
-    printf( "\tpushw %%ax\n" );
-    printf( "\tpopl %%eax\n" );
-    printf( PREFIX "CALLTO16_Ret_word:\n" );
+    fprintf( outfile, PREFIX "CALLTO16_Ret_long:\n" );
+    fprintf( outfile, "\tpushw %%dx\n" );
+    fprintf( outfile, "\tpushw %%ax\n" );
+    fprintf( outfile, "\tpopl %%eax\n" );
+    fprintf( outfile, PREFIX "CALLTO16_Ret_word:\n" );
 
     /* Restore 32-bit segment registers */
 
-    printf( "\tmovw $0x%04x,%%bx\n", WINE_DATA_SELECTOR );
+    fprintf( outfile, "\tmovw $0x%04x,%%bx\n", WINE_DATA_SELECTOR );
 #ifdef __svr4__
-    printf( "\tdata16\n");
+    fprintf( outfile, "\tdata16\n");
 #endif
-    printf( "\tmovw %%bx,%%ds\n" );
+    fprintf( outfile, "\tmovw %%bx,%%ds\n" );
 #ifdef __svr4__
-    printf( "\tdata16\n");
+    fprintf( outfile, "\tdata16\n");
 #endif
-    printf( "\tmovw %%bx,%%es\n" );
+    fprintf( outfile, "\tmovw %%bx,%%es\n" );
 #ifdef __svr4__
-    printf( "\tdata16\n");
+    fprintf( outfile, "\tdata16\n");
 #endif
-    printf( "\tmovw %%bx,%%ss\n" );
+    fprintf( outfile, "\tmovw %%bx,%%ss\n" );
 
     /* Restore the 32-bit stack */
 
-    printf( "\tmovl " PREFIX "IF1632_Saved32_esp,%%esp\n" );
-    printf( "\tpopl " PREFIX "IF1632_Saved32_esp\n" );
+    fprintf( outfile, "\tmovl " PREFIX "IF1632_Saved32_esp,%%esp\n" );
+    fprintf( outfile, "\tpopl " PREFIX "IF1632_Saved32_esp\n" );
 
     /* Restore the 32-bit registers */
 
-    printf( "\tpopl %%edi\n" );
-    printf( "\tpopl %%esi\n" );
-    printf( "\tpopl %%edx\n" );
-    printf( "\tpopl %%ecx\n" );
-    printf( "\tpopl %%ebx\n" );
+    fprintf( outfile, "\tpopl %%edi\n" );
+    fprintf( outfile, "\tpopl %%esi\n" );
+    fprintf( outfile, "\tpopl %%edx\n" );
+    fprintf( outfile, "\tpopl %%ecx\n" );
+    fprintf( outfile, "\tpopl %%ebx\n" );
 
     /* Return to caller */
 
-    printf( "\tpopl %%ebp\n" );
-    printf( "\tlret\n" );
+    fprintf( outfile, "\tpopl %%ebp\n" );
+    fprintf( outfile, "\tlret\n" );
 
     /* Declare the return address variables */
 
-    printf( "\t.data\n" );
-    printf( "\t.globl " PREFIX "CALLTO16_RetAddr_word\n" );
-    printf( "\t.globl " PREFIX "CALLTO16_RetAddr_long\n" );
-    printf( PREFIX "CALLTO16_RetAddr_word:\t.long 0\n" );
-    printf( PREFIX "CALLTO16_RetAddr_long:\t.long 0\n" );
-    printf( "\t.text\n" );
+    fprintf( outfile, "\t.data\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_word\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_long\n" );
+    fprintf( outfile, PREFIX "CALLTO16_RetAddr_word:\t.long 0\n" );
+    fprintf( outfile, PREFIX "CALLTO16_RetAddr_long:\t.long 0\n" );
+    fprintf( outfile, "\t.text\n" );
 }
 
 
@@ -1928,41 +1940,41 @@
  *
  * Build the context structure on the stack.
  */
-static void BuildContext32(void)
+static void BuildContext32( FILE *outfile )
 {
     /* Build the context structure */
 
-    printf( "\tpushfl\n" );
-    printf( "\tsubl $%d,%%esp\n", sizeof(CONTEXT) );
-    printf( "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Eax) );
-    printf( "\tmovl %%ebx,%d(%%esp)\n", CONTEXTOFFSET(Ebx) );
-    printf( "\tmovl %%ecx,%d(%%esp)\n", CONTEXTOFFSET(Ecx) );
-    printf( "\tmovl %%edx,%d(%%esp)\n", CONTEXTOFFSET(Edx) );
-    printf( "\tmovl %%esi,%d(%%esp)\n", CONTEXTOFFSET(Esi) );
-    printf( "\tmovl %%edi,%d(%%esp)\n", CONTEXTOFFSET(Edi) );
+    fprintf( outfile, "\tpushfl\n" );
+    fprintf( outfile, "\tsubl $%d,%%esp\n", sizeof(CONTEXT) );
+    fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Eax) );
+    fprintf( outfile, "\tmovl %%ebx,%d(%%esp)\n", CONTEXTOFFSET(Ebx) );
+    fprintf( outfile, "\tmovl %%ecx,%d(%%esp)\n", CONTEXTOFFSET(Ecx) );
+    fprintf( outfile, "\tmovl %%edx,%d(%%esp)\n", CONTEXTOFFSET(Edx) );
+    fprintf( outfile, "\tmovl %%esi,%d(%%esp)\n", CONTEXTOFFSET(Esi) );
+    fprintf( outfile, "\tmovl %%edi,%d(%%esp)\n", CONTEXTOFFSET(Edi) );
 
-    printf( "\tmovl %d(%%esp),%%eax\n", sizeof(CONTEXT) );
-    printf( "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(EFlags) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", sizeof(CONTEXT) );
+    fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(EFlags) );
 
-    printf( "\tmovl %%cs,%d(%%esp)\n", CONTEXTOFFSET(SegCs) );
-    printf( "\tmovl %%ds,%d(%%esp)\n", CONTEXTOFFSET(SegDs) );
-    printf( "\tmovl %%es,%d(%%esp)\n", CONTEXTOFFSET(SegEs) );
-    printf( "\tmovl %%fs,%d(%%esp)\n", CONTEXTOFFSET(SegFs) );
-    printf( "\tmovl %%gs,%d(%%esp)\n", CONTEXTOFFSET(SegGs) );
-    printf( "\tmovl %%ss,%d(%%esp)\n", CONTEXTOFFSET(SegSs) );
+    fprintf( outfile, "\tmovl %%cs,%d(%%esp)\n", CONTEXTOFFSET(SegCs) );
+    fprintf( outfile, "\tmovl %%ds,%d(%%esp)\n", CONTEXTOFFSET(SegDs) );
+    fprintf( outfile, "\tmovl %%es,%d(%%esp)\n", CONTEXTOFFSET(SegEs) );
+    fprintf( outfile, "\tmovl %%fs,%d(%%esp)\n", CONTEXTOFFSET(SegFs) );
+    fprintf( outfile, "\tmovl %%gs,%d(%%esp)\n", CONTEXTOFFSET(SegGs) );
+    fprintf( outfile, "\tmovl %%ss,%d(%%esp)\n", CONTEXTOFFSET(SegSs) );
 
-    printf( "\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
+    fprintf( outfile, "\tfsave %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
 
-    printf( "\tmovl 4(%%ebp),%%eax\n" ); /* %eip at time of call */
-    printf( "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Eip) );
-    printf( "\tmovl 0(%%ebp),%%eax\n" ); /* %ebp at time of call */
-    printf( "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Ebp) );
-    printf( "\tleal 8(%%ebp),%%eax\n" ); /* %esp at time of call */
-    printf( "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Esp) );
+    fprintf( outfile, "\tmovl 4(%%ebp),%%eax\n" ); /* %eip at time of call */
+    fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Eip) );
+    fprintf( outfile, "\tmovl 0(%%ebp),%%eax\n" ); /* %ebp at time of call */
+    fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Ebp) );
+    fprintf( outfile, "\tleal 8(%%ebp),%%eax\n" ); /* %esp at time of call */
+    fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", CONTEXTOFFSET(Esp) );
 
     /* Push pointer to context */
 
-    printf( "\tpushl %%esp\n" );
+    fprintf( outfile, "\tpushl %%esp\n" );
 }
 
 
@@ -1971,40 +1983,40 @@
  *
  * Restore the registers from the context structure
  */
-static void RestoreContext32(void)
+static void RestoreContext32( FILE *outfile )
 {
     /* Restore the context structure */
 
-    printf( "\tleal %d(%%ebp),%%esp\n", -sizeof(CONTEXT)-12 );
-    printf( "\tfrstor %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
+    fprintf( outfile, "\tleal %d(%%ebp),%%esp\n", -sizeof(CONTEXT)-12 );
+    fprintf( outfile, "\tfrstor %d(%%esp)\n", CONTEXTOFFSET(FloatSave) );
 
-    printf( "\tmovl %d(%%esp),%%ebx\n", CONTEXTOFFSET(Ebx) );
-    printf( "\tmovl %d(%%esp),%%ecx\n", CONTEXTOFFSET(Ecx) );
-    printf( "\tmovl %d(%%esp),%%edx\n", CONTEXTOFFSET(Edx) );
-    printf( "\tmovl %d(%%esp),%%esi\n", CONTEXTOFFSET(Esi) );
-    printf( "\tmovl %d(%%esp),%%edi\n", CONTEXTOFFSET(Edi) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%ebx\n", CONTEXTOFFSET(Ebx) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%ecx\n", CONTEXTOFFSET(Ecx) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%edx\n", CONTEXTOFFSET(Edx) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%esi\n", CONTEXTOFFSET(Esi) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%edi\n", CONTEXTOFFSET(Edi) );
 
-    printf( "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(EFlags) );
-    printf( "\tmovl %%eax,%d(%%esp)\n", sizeof(CONTEXT) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(EFlags) );
+    fprintf( outfile, "\tmovl %%eax,%d(%%esp)\n", sizeof(CONTEXT) );
 
-/*    printf( "\tmovl %d(%%esp),%%cs\n", CONTEXTOFFSET(SegCs) ); */
-    printf( "\tmovl %d(%%esp),%%ds\n", CONTEXTOFFSET(SegDs) );
-    printf( "\tmovl %d(%%esp),%%es\n", CONTEXTOFFSET(SegEs) );
-    printf( "\tmovl %d(%%esp),%%fs\n", CONTEXTOFFSET(SegFs) );
-    printf( "\tmovl %d(%%esp),%%gs\n", CONTEXTOFFSET(SegGs) );
+/*    fprintf( outfile, "\tmovl %d(%%esp),%%cs\n", CONTEXTOFFSET(SegCs) ); */
+    fprintf( outfile, "\tmovl %d(%%esp),%%ds\n", CONTEXTOFFSET(SegDs) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%es\n", CONTEXTOFFSET(SegEs) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%fs\n", CONTEXTOFFSET(SegFs) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%gs\n", CONTEXTOFFSET(SegGs) );
 
-    printf( "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Eip) );
-    printf( "\tmovl %%eax,4(%%ebp)\n" ); /* %eip at time of call */
-    printf( "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Ebp) );
-    printf( "\tmovl %%eax,0(%%ebp)\n" ); /* %ebp at time of call */
+    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Eip) );
+    fprintf( outfile, "\tmovl %%eax,4(%%ebp)\n" ); /* %eip at time of call */
+    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Ebp) );
+    fprintf( outfile, "\tmovl %%eax,0(%%ebp)\n" ); /* %ebp at time of call */
 
-/*    printf( "\tmovl %d(%%esp),%%ss\n", CONTEXTOFFSET(SegSs) ); */
-/*    printf( "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Esp) ); */
+/*    fprintf( outfile, "\tmovl %d(%%esp),%%ss\n", CONTEXTOFFSET(SegSs) ); */
+/*    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Esp) ); */
 
-    printf( "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Eax) );
+    fprintf( outfile, "\tmovl %d(%%esp),%%eax\n", CONTEXTOFFSET(Eax) );
 
-    printf( "\taddl $%d,%%esp\n", sizeof(CONTEXT) );
-    printf( "\tpopfl\n" );
+    fprintf( outfile, "\taddl $%d,%%esp\n", sizeof(CONTEXT) );
+    fprintf( outfile, "\tpopfl\n" );
 }
 
 
@@ -2023,7 +2035,7 @@
  * (ebp-4)   entry point
  * (ebp-8)   relay addr
  */
-static void BuildCallFrom32Func( const char *profile )
+static void BuildCallFrom32Func( FILE *outfile, const char *profile )
 {
     int args, stdcall, reg_func;
 
@@ -2045,76 +2057,74 @@
     }
     else
     {
-        fprintf( stderr, "Invalid function profile '%s'\n", profile );
+        fprintf( stderr, "Invalid function profile '%s', ignored\n", profile );
         return;
     }
 
     /* Function header */
 
-    printf( "/**********\n" );
-    printf( " * " PREFIX "CallFrom32_%s\n", profile );
-    printf( " **********/\n" );
-    printf( "\t.align 4\n" );
-    printf( "\t.globl " PREFIX "CallFrom32_%s\n\n", profile );
-    printf( PREFIX "CallFrom32_%s:\n", profile );
+    fprintf( outfile, "\n\t.align 4\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CallFrom32_%s\n", profile );
+    fprintf( outfile, PREFIX "CallFrom32_%s:\n", profile );
 
     /* Entry code */
 
-    printf( "\tleal 8(%%esp),%%ebp\n" );
+    fprintf( outfile, "\tleal 8(%%esp),%%ebp\n" );
 
     /* Transfer the arguments */
 
-    if (reg_func) BuildContext32();
+    if (reg_func) BuildContext32( outfile );
 
     if (args)
     {
         int i;
-        for (i = args; i > 0; i--) printf( "\tpushl %d(%%ebp)\n", 4 * i + 4 );
+        for (i = args; i > 0; i--)
+            fprintf( outfile, "\tpushl %d(%%ebp)\n", 4 * i + 4 );
     }
     else if (!reg_func)
     {
         /* Push the address of the arguments. The called function will */
         /* ignore this if it really takes no arguments. */
-        printf( "\tleal 8(%%ebp),%%eax\n" );
-        printf( "\tpushl %%eax\n" );
+        fprintf( outfile, "\tleal 8(%%ebp),%%eax\n" );
+        fprintf( outfile, "\tpushl %%eax\n" );
     }
 
     /* Print the debugging info */
 
     if (debugging)
     {
-        printf( "\tpushl $%d\n", reg_func ? -1 : args );  /* Nb args */
-        printf( "\tpushl %%ebp\n" );
-        printf( "\tcall " PREFIX "RELAY_DebugCallFrom32\n" );
-        printf( "\tadd $8, %%esp\n" );
+        fprintf( outfile, "\tpushl $%d\n", reg_func ? -1 : args); /* Nb args */
+        fprintf( outfile, "\tpushl %%ebp\n" );
+        fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallFrom32\n" );
+        fprintf( outfile, "\tadd $8, %%esp\n" );
     }
 
     /* Call the function */
 
-    printf( "\tcall -4(%%ebp)\n" );
+    fprintf( outfile, "\tcall -4(%%ebp)\n" );
 
     /* Print the debugging info */
 
     if (debugging)
     {
-        printf( "\tpushl %%eax\n" );
-        printf( "\tpushl $%d\n", reg_func ? -1 : args );  /* Nb args */
-        printf( "\tpushl %%ebp\n" );
-        printf( "\tcall " PREFIX "RELAY_DebugCallFrom32Ret\n" );
-        printf( "\tpopl %%eax\n" );
-        printf( "\tpopl %%eax\n" );
-        printf( "\tpopl %%eax\n" );
+        fprintf( outfile, "\tpushl %%eax\n" );
+        fprintf( outfile, "\tpushl $%d\n", reg_func ? -1 : args); /* Nb args */
+        fprintf( outfile, "\tpushl %%ebp\n" );
+        fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallFrom32Ret\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
+        fprintf( outfile, "\tpopl %%eax\n" );
     }
 
-    if (reg_func) RestoreContext32();
+    if (reg_func) RestoreContext32( outfile );
 
-    printf( "\tmovl %%ebp,%%esp\n" );
-    printf( "\tpopl %%ebp\n" );
+    fprintf( outfile, "\tmovl %%ebp,%%esp\n" );
+    fprintf( outfile, "\tpopl %%ebp\n" );
 
     /* Return, removing arguments */
 
-    if (args && stdcall) printf( "\tret $%d\n", args * 4 );
-    else printf( "\tret\n" );
+    if (args && stdcall) fprintf( outfile, "\tret $%d\n", args * 4 );
+    else fprintf( outfile, "\tret\n" );
 }
 
 
@@ -2134,144 +2144,234 @@
  * Prototype for the CallTo32 functions:
  *   extern LONG CallTo32_nn( FARPROC32 func, args... );
  */
-static void BuildCallTo32Func( int args )
+static void BuildCallTo32Func( FILE *outfile, int args )
 {
     /* Function header */
 
-    printf( "/**********\n" );
-    printf( " * " PREFIX "CallTo32_%d\n", args );
-    printf( " **********/\n" );
-    printf( "\t.align 4\n" );
-    printf( "\t.globl " PREFIX "CallTo32_%d\n\n", args );
-    printf( PREFIX "CallTo32_%d:\n", args );
+    fprintf( outfile, "\n\t.align 4\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CallTo32_%d\n", args );
+    fprintf( outfile, PREFIX "CallTo32_%d:\n", args );
 
     /* Entry code */
 
-    printf( "\tpushl %%ebp\n" );
-    printf( "\tmovl %%esp,%%ebp\n" );
+    fprintf( outfile, "\tpushl %%ebp\n" );
+    fprintf( outfile, "\tmovl %%esp,%%ebp\n" );
 
     /* Transfer arguments */
 
     if (args)
     {
         int i;
-        for (i = args; i > 0; i--) printf( "\tpushl %d(%%ebp)\n", 4 * i + 8 );
+        for (i = args; i > 0; i--)
+            fprintf( outfile, "\tpushl %d(%%ebp)\n", 4 * i + 8 );
     }
 
     /* Print the debugging output */
 
     if (debugging)
     {
-        printf( "\tpushl $%d\n", args );
-        printf( "\tpushl 8(%%ebp)\n" );
-        printf( "\tcall " PREFIX "RELAY_DebugCallTo32\n" );
-        printf( "\taddl $8,%%esp\n" );
+        fprintf( outfile, "\tpushl $%d\n", args );
+        fprintf( outfile, "\tpushl 8(%%ebp)\n" );
+        fprintf( outfile, "\tcall " PREFIX "RELAY_DebugCallTo32\n" );
+        fprintf( outfile, "\taddl $8,%%esp\n" );
     }
 
     /* Call the function */
 
-    printf( "\tcall 8(%%ebp)\n" );
+    fprintf( outfile, "\tcall 8(%%ebp)\n" );
 
     /* Return to Wine */
 
-    printf( "\tmovl %%ebp,%%esp\n" );
-    printf( "\tpopl %%ebp\n" );
-    printf( "\tret\n" );
+    fprintf( outfile, "\tmovl %%ebp,%%esp\n" );
+    fprintf( outfile, "\tpopl %%ebp\n" );
+    fprintf( outfile, "\tret\n" );
 }
 
 
+/*******************************************************************
+ *         BuildSpec
+ *
+ * Build the spec files
+ */
+static int BuildSpec( FILE *outfile, int argc, char *argv[] )
+{
+    int i;
+    for (i = 2; i < argc; i++)
+        if (BuildSpecFile( outfile, argv[i] ) < 0) return -1;
+    return 0;
+}
+
+
+/*******************************************************************
+ *         BuildCallFrom16
+ *
+ * Build the 16-bit-to-Wine callbacks
+ */
+static int BuildCallFrom16( FILE *outfile, int argc, char *argv[] )
+{
+    int i;
+
+    /* File header */
+
+    fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
+    fprintf( outfile, "\t.text\n" );
+
+    /* Build the 32-bit large stack callback */
+
+    BuildCall32LargeStack( outfile );
+
+    /* Build the callback functions */
+
+    for (i = 2; i < argc; i++) BuildCallFrom16Func( outfile, argv[i] );
+
+    /* Output the argument debugging strings */
+
+    if (debugging)
+    {
+        fprintf( outfile, "/* Argument strings */\n" );
+        for (i = 2; i < argc; i++)
+        {
+            fprintf( outfile, "Profile_%s:\n", argv[i] );
+            fprintf( outfile, "\t.ascii \"%s\\0\"\n", argv[i] + 5 );
+        }
+    }
+    return 0;
+}
+
+
+/*******************************************************************
+ *         BuildCallTo16
+ *
+ * Build the Wine-to-16-bit callbacks
+ */
+static int BuildCallTo16( FILE *outfile, int argc, char *argv[] )
+{
+    int i;
+
+    /* File header */
+
+    fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
+    fprintf( outfile, "\t.text\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Start\n" );
+    fprintf( outfile, PREFIX "CALLTO16_Start:\n" );
+
+    /* Build the callback functions */
+
+    for (i = 2; i < argc; i++) BuildCallTo16Func( outfile, argv[i] );
+
+    /* Output the 16-bit return code */
+
+    BuildRet16Func( outfile );
+
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_End\n" );
+    fprintf( outfile, PREFIX "CALLTO16_End:\n" );
+    return 0;
+}
+
+
+/*******************************************************************
+ *         BuildCallFrom32
+ *
+ * Build the 32-bit-to-Wine callbacks
+ */
+static int BuildCallFrom32( FILE *outfile, int argc, char *argv[] )
+{
+    int i;
+
+    /* File header */
+
+    fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
+    fprintf( outfile, "\t.text\n" );
+
+    /* Build the callback functions */
+
+    for (i = 2; i < argc; i++) BuildCallFrom32Func( outfile, argv[i] );
+    return 0;
+}
+
+
+/*******************************************************************
+ *         BuildCallTo32
+ *
+ * Build the Wine-to-32-bit callbacks
+ */
+static int BuildCallTo32( FILE *outfile, int argc, char *argv[] )
+{
+    int i;
+
+    /* File header */
+
+    fprintf( outfile, "/* File generated automatically. Do not edit! */\n\n" );
+    fprintf( outfile, "\t.text\n" );
+
+    /* Build the callback functions */
+
+    for (i = 2; i < argc; i++) BuildCallTo32Func( outfile, atoi(argv[i]) );
+    return 0;
+}
+
+
+/*******************************************************************
+ *         usage
+ */
 static void usage(void)
 {
-    fprintf(stderr, "usage: build -spec SPECNAMES\n"
-                    "       build -callfrom16 FUNCTION_PROFILES\n"
-                    "       build -callto16 FUNCTION_PROFILES\n"
-                    "       build -callfrom32 FUNCTION_PROFILES\n"
-                    "       build -callto32 FUNCTION_PROFILES\n" );
+    fprintf(stderr, "usage: build [-o outfile] -spec SPECNAMES\n"
+                    "       build [-o outfile] -callfrom16 FUNCTION_PROFILES\n"
+                    "       build [-o outfile] -callto16 FUNCTION_PROFILES\n"
+                    "       build [-o outfile] -callfrom32 FUNCTION_PROFILES\n"
+                    "       build [-o outfile] -callto32 FUNCTION_PROFILES\n");
     exit(1);
 }
 
 
+/*******************************************************************
+ *         main
+ */
 int main(int argc, char **argv)
 {
-    int i;
+    char *outname = NULL;
+    FILE *outfile = stdout;
+    int res = -1;
 
     if (argc <= 2) usage();
 
-    if (!strcmp( argv[1], "-spec" ))
+    if (!strcmp( argv[1], "-o" ))
     {
-        for (i = 2; i < argc; i++) BuildSpecFiles( argv[i] );
-    }
-    else if (!strcmp( argv[1], "-callfrom16" ))  /* 16-bit-to-Wine callbacks */
-    {
-        /* File header */
-
-        printf( "/* File generated automatically. Do not edit! */\n\n" );
-        printf( "\t.text\n" );
-
-        /* Build the 32-bit large stack callback */
-
-        BuildCall32LargeStack();
-
-        /* Build the callback functions */
-
-        for (i = 2; i < argc; i++) BuildCallFrom16Func( argv[i] );
-
-        /* Output the argument debugging strings */
-
-        if (debugging)
+        outname = argv[2];
+        argv += 2;
+        argc -= 2;
+        if (argc <= 2) usage();
+        if (!(outfile = fopen( outname, "w" )))
         {
-            printf( "/* Argument strings */\n" );
-            for (i = 2; i < argc; i++)
-            {
-                printf( "Profile_%s:\n", argv[i] );
-                printf( "\t.ascii \"%s\\0\"\n", argv[i] + 5 );
-            }
+            fprintf( stderr, "Unable to create output file '%s'\n", outname );
+            exit(1);
         }
     }
-    else if (!strcmp( argv[1], "-callto16" ))  /* Wine-to-16-bit callbacks */
+
+    if (!strcmp( argv[1], "-spec" ))
+        res = BuildSpec( outfile, argc, argv );
+    else if (!strcmp( argv[1], "-callfrom16" ))
+        res = BuildCallFrom16( outfile, argc, argv );
+    else if (!strcmp( argv[1], "-callto16" ))
+        res = BuildCallTo16( outfile, argc, argv );
+    else if (!strcmp( argv[1], "-callfrom32" ))
+        res = BuildCallFrom32( outfile, argc, argv );
+    else if (!strcmp( argv[1], "-callto32" ))
+        res = BuildCallTo32( outfile, argc, argv );
+    else
     {
-        /* File header */
-
-        printf( "/* File generated automatically. Do not edit! */\n\n" );
-        printf( "\t.text\n" );
-        printf( "\t.globl " PREFIX "CALLTO16_Start\n" );
-        printf( PREFIX "CALLTO16_Start:\n" );
-
-        /* Build the callback functions */
-
-        for (i = 2; i < argc; i++) BuildCallTo16Func( argv[i] );
-
-        /* Output the 16-bit return code */
-
-        BuildRet16Func();
-
-        printf( "\t.globl " PREFIX "CALLTO16_End\n" );
-        printf( PREFIX "CALLTO16_End:\n" );
+        fclose( outfile );
+        unlink( outname );
+        usage();
     }
-    else if (!strcmp( argv[1], "-callfrom32" ))  /* 32-bit-to-Wine callbacks */
+
+    fclose( outfile );
+    if (res < 0)
     {
-        /* File header */
-
-        printf( "/* File generated automatically. Do not edit! */\n\n" );
-        printf( "\t.text\n" );
-
-        /* Build the callback functions */
-
-        for (i = 2; i < argc; i++) BuildCallFrom32Func( argv[i] );
+        unlink( outname );
+        return 1;
     }
-    else if (!strcmp( argv[1], "-callto32" ))  /* Wine-to-32-bit callbacks */
-    {
-        /* File header */
-
-        printf( "/* File generated automatically. Do not edit! */\n\n" );
-        printf( "\t.text\n" );
-
-        /* Build the callback functions */
-
-        for (i = 2; i < argc; i++) BuildCallTo32Func( atoi(argv[i]) );
-    }
-    else usage();
-
     return 0;
 }
 
diff --git a/tools/fnt2bdf.c b/tools/fnt2bdf.c
new file mode 100644
index 0000000..f391b79
--- /dev/null
+++ b/tools/fnt2bdf.c
@@ -0,0 +1,584 @@
+/************************************************
+ *
+ * Extract fonts from .fnt or Windows DLL files
+ * and convert them to the .bdf format.
+ *
+ * Copyright 1994-1996 Kevin Carothers and Alex Korobka
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "windows.h"
+#include "fnt2bdf.h"
+#include "neexe.h"
+#include "module.h"
+
+#define MAP_BEG 118
+
+extern char*   g_lpstrFileName;
+extern char*   g_lpstrCharSet;
+
+#define FILE_ERROR	0
+#define FILE_DLL	1
+#define FILE_FNT	2
+
+/* global options */
+
+char*	g_lpstrFileName = NULL;
+char*	g_lpstrCharSet = NULL;
+char*   g_lpstrInputFile = NULL;
+
+static char*	errorDLLRead = "Unable to read Windows DLL.\n";
+static char*    errorFNTRead = "Unable to read .FNT file.\n";
+static char*    errorOpenFile = "Unable to open file.\n";
+static char*    errorMemory = "Memory allocation error.\n";
+static char*    errorFile = "Corrupt or invalid file.\n";
+static char*    errorFontData = "Unable to parse font data: Error ";
+static char*    errorEmpty = "No fonts found.\n";
+
+/* info */
+
+void usage()
+{
+    printf("Usage: font2bdf [-c charset] [-o basename] [input file]\n");
+    printf("  -c charset\tuse this charset name for OEM_CHARSET fonts\n");
+    printf("  -f basename\tbasic output filename\n");
+    printf("  input file\tMSWindows .fon, .fnt, .dll, or .exe file.\n");
+    printf("\nExample:\n  fnt2bdf -c winsys vgasys.fnt\n\n");
+    exit(-1);
+}
+
+/* convert big-endian value to the local format */
+
+int return_data_value(enum data_types dtype, void * pChr)
+{
+int   ret_val = 0;
+
+    switch(dtype) {
+        case (dfChar): 
+            ret_val = (int) *(unsigned char *)pChr;
+            break;
+            
+        case(dfShort): 
+            ret_val = *(unsigned char *)pChr;
+            ret_val += (*((unsigned char *)pChr + 1) << 8);
+            break;
+            
+        case(dfLong): {
+            int  i;
+
+            for(i=3; i >= 0; i--)  {
+                ret_val += *((unsigned char *)pChr + i) << (8*i);
+                }
+            break;
+            }
+	case(dfString):
+        } 
+    return ret_val;
+}
+
+int make_bdf_filename(char* name, fnt_fontS* cpe_font_struct, unsigned char* file_buffer)
+{
+int     l_nameoffset = return_data_value(dfLong, cpe_font_struct->hdr.dfFace);
+char*   lpChar;
+
+  if( !g_lpstrFileName )
+  {
+    if( !l_nameoffset || 
+         l_nameoffset > return_data_value(dfLong, cpe_font_struct->hdr.dfSize) + 1 )
+         return ERROR_DATA;
+    lpChar =  (char*)(file_buffer + l_nameoffset);
+  }
+    else lpChar = g_lpstrFileName;
+
+  strcpy( name, lpChar );
+
+  while( (lpChar = strchr( name, ' ')) ) 
+         *lpChar = '-';
+
+  /* construct a filename from the font typeface, slant, weight, and size */
+
+  if( cpe_font_struct->hdr.dfItalic[0] ) strcat(name, "_i" );
+  else strcat(name, "_r" );
+
+  lpChar = name + strlen( name );
+  sprintf(lpChar, "%d-%d.bdf", return_data_value(dfShort, cpe_font_struct->hdr.dfWeight),
+                               return_data_value(dfShort, cpe_font_struct->hdr.dfPoints) );
+  return 0;
+}
+
+/* parse FONT resource and write .bdf file */
+
+int parse_fnt_data(unsigned char* file_buffer, int length)
+{
+  fnt_fontS	cpe_font_struct; 
+  int     	ic=0, t;
+
+  bcopy(file_buffer, (char *) &cpe_font_struct.hdr, sizeof(fnt_hdrS));
+
+  /* check font header */
+
+  t = return_data_value(dfShort, cpe_font_struct.hdr.dfVersion);
+  if( t != 0x300 && t != 0x200) return ERROR_VERSION;
+
+  t = return_data_value(dfLong, cpe_font_struct.hdr.dfSize);
+  if( t > length ) return ERROR_SIZE;
+  else
+  {    	
+    /* set up the charWidth/charOffset  structure pairs (dfCharTable)... */
+
+    int l_fchar = return_data_value(dfChar, cpe_font_struct.hdr.dfFirstChar),
+        l_lchar = return_data_value(dfChar, cpe_font_struct.hdr.dfLastChar); 
+    int l_len   = l_lchar-l_fchar, l_ptr = MAP_BEG;
+
+    /* malloc size = (# chars) * sizeof(WinCharS) */
+
+    if((cpe_font_struct.dfCharTable = (WinCharS *) calloc(sizeof(WinCharS), l_len)) == NULL) 
+	return ERROR_MEMORY;
+
+    /* NOW, convert them all to UNIX (lton) notation... */
+
+    for(ic=0; ic < l_len; ic++) {
+   	cpe_font_struct.dfCharTable[ic].charWidth = return_data_value(dfShort, &file_buffer[l_ptr]);
+	l_ptr += 2;	/* bump by sizeof(short) */
+
+
+	if( return_data_value(dfShort, cpe_font_struct.hdr.dfVersion) == 0x200) {
+	    cpe_font_struct.dfCharTable[ic].charOffset = 
+			return_data_value(dfShort, &file_buffer[l_ptr]);
+	    l_ptr += 2;	/* bump by sizeof(long) */
+	    }
+	else { 	/*  Windows Version 3.0 type font */
+	    cpe_font_struct.dfCharTable[ic].charOffset = 
+			return_data_value(dfLong, &file_buffer[l_ptr]);
+	    l_ptr += 4;	/* bump by sizeof(long) */
+	    }
+	}
+    t = dump_bdf(&cpe_font_struct, file_buffer);
+    free( cpe_font_struct.dfCharTable );
+  }
+  return t;
+}
+
+int dump_bdf( fnt_fontS* cpe_font_struct, unsigned char* file_buffer)
+{
+  FILE*   fp;
+  int	  ic;
+  int     l_fchar = return_data_value(dfChar, cpe_font_struct->hdr.dfFirstChar), 
+          l_lchar = return_data_value(dfChar, cpe_font_struct->hdr.dfLastChar); 
+
+  int     l_len = l_lchar-l_fchar,
+          l_hgt = return_data_value(dfChar, cpe_font_struct->hdr.dfPixHeight); 
+  int	  l_ascent = return_data_value(dfShort, cpe_font_struct->hdr.dfAscent);
+  char    l_filename[256];
+
+    if( (ic = make_bdf_filename(l_filename, cpe_font_struct, file_buffer)) )
+	return ic;
+
+    if((fp = fopen(l_filename, "w")) == (FILE *) 0)   
+    {
+      fprintf(stderr, "Couldn't open \"%s\" for output.\n", l_filename);
+      return ERROR_FILE;
+    }
+
+    dump_bdf_hdr(fp, cpe_font_struct, file_buffer);
+
+    /* NOW, convert all chars to UNIX (lton) notation... */
+
+    for(ic=0; ic < l_len; ic++) {
+	int rowidx, l_span,		/* how many char-cols wide is char? */
+	    l_idx = cpe_font_struct->dfCharTable[ic].charOffset;
+
+	l_span = (int) (cpe_font_struct->dfCharTable[ic].charWidth-1)/8; 
+
+	fprintf(fp, "STARTCHAR %d  \n", ic);
+	fprintf(fp, "ENCODING %d\n",   l_fchar);
+	fprintf(fp, "SWIDTH    %d    %d \n", 
+		cpe_font_struct->dfCharTable[ic].charWidth*1000, 
+		0);
+
+	fprintf(fp, "DWIDTH    %d    %d \n", 
+		cpe_font_struct->dfCharTable[ic].charWidth, 0);
+
+	fprintf(fp, "BBX  %d  %d  %d   %d\n",
+		cpe_font_struct->dfCharTable[ic].charWidth, l_hgt, 0, 
+		l_ascent - l_hgt);
+
+	fprintf(fp, "BITMAP\n");
+	for(rowidx=0; rowidx < l_hgt; rowidx++) {
+	    switch(l_span) {
+		case(0):	/* 1-7 pixels wide font */
+		    {
+		    fprintf(fp, "%02X\n", (int) file_buffer[l_idx+rowidx]);
+		    break;
+		    }
+		
+		case(1):	/* 8-15 pixels wide font */
+		    {
+		    fprintf(fp, "%02X%02X", 
+			(int) file_buffer[l_idx+rowidx], file_buffer[l_idx+l_hgt+rowidx]);
+		    fprintf(fp, "\n");
+		    break;
+		    }
+
+		case(2):	/* 16-23 pixels wide font */
+		    {
+		    fprintf(fp, "%02X%02X%02X", 
+			file_buffer[l_idx+rowidx],
+		        file_buffer[l_idx+l_hgt+rowidx],
+		        file_buffer[l_idx+(2*l_hgt)+rowidx]);
+		    fprintf(fp, "\n");
+		    break;
+		    }
+
+		case(3):	/* 24-31 pixels wide font */
+		    {
+		    fprintf(fp, "%02X%02X%02X%02X", 
+			file_buffer[l_idx+rowidx],
+			file_buffer[l_idx+l_hgt+rowidx],
+			file_buffer[l_idx+(2*l_hgt)+rowidx],
+			file_buffer[l_idx+(3*l_hgt)+rowidx]);
+		    fprintf(fp, "\n");
+		    break;
+		    }
+		case(4):	/* 32-39 */
+		    {
+		    fprintf(fp, "%02X%02X%02X%02X%02X",
+			file_buffer[l_idx+rowidx],
+			file_buffer[l_idx+l_hgt+rowidx],
+                        file_buffer[l_idx+(2*l_hgt)+rowidx],
+                        file_buffer[l_idx+(3*l_hgt)+rowidx],
+			file_buffer[l_idx+(4*l_hgt)+rowidx]);
+		    fprintf(fp, "\n");
+                    break;
+                    }
+		default:
+		    fclose(fp);
+		    unlink(l_filename);
+		    return ERROR_DATA;
+		}
+	    }
+	fprintf(fp, "ENDCHAR\n");
+
+	l_fchar++;	/* Go to next one */
+	}
+fprintf(fp, "ENDFONT\n");
+fclose(fp);
+return 0;
+}
+
+
+int dump_bdf_hdr(FILE* fs, fnt_fontS* cpe_font_struct, unsigned char* file_buffer)
+{
+int     l_fchar = return_data_value(dfChar, cpe_font_struct->hdr.dfFirstChar), 
+        l_lchar = return_data_value(dfChar, cpe_font_struct->hdr.dfLastChar);
+int     l_len = l_lchar - l_fchar;
+int     l_nameoffset = return_data_value(dfLong, cpe_font_struct->hdr.dfFace);
+int 	l_cellheight = return_data_value(dfShort, cpe_font_struct->hdr.dfPixHeight);
+int     l_ascent = return_data_value(dfShort, cpe_font_struct->hdr.dfAscent);
+
+    fprintf(fs, "STARTFONT   2.1\n");
+
+    /* Compose font name */
+
+    if( l_nameoffset && 
+	l_nameoffset < return_data_value(dfLong, cpe_font_struct->hdr.dfSize) )
+    {
+      int     dpi, point_size;
+      char*   lpFace = (char*)(file_buffer + l_nameoffset), *lpChar;
+      short   tmWeight = return_data_value(dfShort, cpe_font_struct->hdr.dfWeight);
+
+      while((lpChar = strchr(lpFace, '-')) ) 
+	    *lpChar = ' ';
+
+      fprintf(fs, "FONT -windows-%s-", lpFace );
+
+      if( tmWeight == 0 )			/* weight */
+	  fputs("medium-", fs);
+      else if( tmWeight <= FW_LIGHT )
+	  fputs("light-", fs);
+      else if( tmWeight <= FW_MEDIUM )
+	  fputs("medium-", fs);
+      else if( tmWeight <= FW_DEMIBOLD )
+	  fputs("demibold-", fs);
+      else if( tmWeight <= FW_BOLD )
+	  fputs("bold-", fs);
+      else fputs("black-", fs);
+
+      if( cpe_font_struct->hdr.dfItalic[0] )	/* slant */
+	  fputs("i-", fs);
+      else fputs("r-", fs);
+
+      /* style */
+
+      if( (cpe_font_struct->hdr.dfPitchAndFamily[0] & 0xF0) == FF_SWISS )
+	  fputs("normal-sans-", fs);
+      else fputs("normal--", fs);	/* still can be -sans */
+
+      /* y extents */
+
+      point_size = 10 * return_data_value(dfShort, cpe_font_struct->hdr.dfPoints );
+      dpi = (l_cellheight * 720) / point_size;
+
+      fprintf(fs, "%d-%d-%d-%d-", l_cellheight, 10*l_cellheight, 72, 72);
+						/* point_size, dpi, dpi); */
+
+      /* spacing */
+
+      if( return_data_value(dfShort, cpe_font_struct->hdr.dfPixWidth) ) fputs("c-", fs);
+      else fputs("m-", fs);
+	
+      /* average width */
+
+      fprintf( fs, "%d-", 10 * return_data_value(dfShort, cpe_font_struct->hdr.dfAvgWidth) );
+
+      /* charset */
+
+      switch( cpe_font_struct->hdr.dfCharSet[0] )
+      {
+	case ANSI_CHARSET: fputs("ansi-0\n", fs); break;
+	default:
+	case DEFAULT_CHARSET: fputs("iso8859-1\n", fs); break;
+	case SYMBOL_CHARSET: fputs("misc-fontspecific\n", fs); break;
+	case SHIFTJIS_CHARSET: fputs("jisx0208.1983-0\n", fs); break;
+	case OEM_CHARSET: 
+		if( !g_lpstrCharSet ) 
+		{ fputs("Undefined OEM charset, use -c option.\n", stderr); 
+		  return ERROR_DATA; }
+	        fprintf(fs, "%s\n", g_lpstrCharSet);
+      }
+    }
+    else return ERROR_DATA;
+
+    fprintf(fs, "SIZE  %d  %d   %d\n",  
+	l_cellheight,
+	return_data_value(dfShort, cpe_font_struct->hdr.dfHorizRes),
+	return_data_value(dfShort, cpe_font_struct->hdr.dfVertRes));   /* dfVertRes[2] */
+
+    fprintf(fs, "FONTBOUNDINGBOX %d  %d  %d  %d\n",
+	return_data_value(dfShort, cpe_font_struct->hdr.dfMaxWidth),
+        return_data_value(dfChar, cpe_font_struct->hdr.dfPixHeight),
+   	0, l_ascent - l_cellheight );
+
+    fprintf(fs, "STARTPROPERTIES  4\n");
+
+    fprintf(fs, "FONT_ASCENT %d\n", l_ascent );                       /*  dfAscent[2] */
+    fprintf(fs, "FONT_DESCENT %d\n", l_cellheight - l_ascent );
+    fprintf(fs, "CAP_HEIGHT %d\n", l_ascent -
+                                   return_data_value(dfShort, cpe_font_struct->hdr.dfInternalLeading));
+    fprintf(fs, "DEFAULT_CHAR %d\n", return_data_value(dfShort, cpe_font_struct->hdr.dfDefaultChar));
+
+    fprintf(fs, "ENDPROPERTIES\n");
+
+    fprintf(fs, "CHARS  %d\n",  l_len);
+    return 0;
+}
+
+
+
+void parse_options(int argc, char **argv)
+{
+  int i;
+
+  switch( argc )
+  {
+    case 2:
+	 g_lpstrInputFile = argv[1];
+	 break;
+
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+	 for( i = 1; i < argc - 1; i++ )
+	 {
+	   if( argv[i][0] != '-' ||
+	       strlen(argv[i]) != 2 ) break;
+
+	   if( argv[i][1] == 'c' ) { g_lpstrCharSet = argv[i+1]; }
+	   else 
+	   if( argv[i][1] == 'f' ) { g_lpstrFileName = argv[i+1]; }
+	   else
+	   usage();
+
+	   i++;
+	 } 
+	 if( i == argc - 1 )
+	 {
+	   g_lpstrInputFile = argv[i];
+	   break;
+	 }
+    default: usage();
+  }
+    
+}
+
+/* read file data and return file type */
+
+int get_resource_table(int fd, unsigned char** lpdata, int fsize)
+{
+  struct mz_header_s mz_header;
+  struct ne_header_s ne_header;
+  short		     s, offset, size, retval;
+
+ 
+  lseek( fd, 0, SEEK_SET );
+
+  if( read(fd, &mz_header, sizeof(mz_header)) != sizeof(mz_header) ) 
+      return FILE_ERROR;
+
+  s = return_data_value(dfShort, &mz_header.mz_magic);
+
+  if( s == MZ_SIGNATURE) 		/* looks like .dll file so far... */
+  {
+    s = return_data_value(dfShort, &mz_header.ne_offset);
+    lseek( fd, s, SEEK_SET );
+
+    if( read(fd, &ne_header, sizeof(ne_header)) != sizeof(ne_header) )
+	return FILE_ERROR;
+
+    s = return_data_value(dfShort, &ne_header.ne_magic);
+
+    if( s == PE_SIGNATURE)
+    {
+       fprintf( stderr, "Do not know how to handle 32-bit Windows DLLs.\n");
+       return FILE_ERROR; 
+    }
+    else if ( s != NE_SIGNATURE) return FILE_ERROR;
+
+    s = return_data_value(dfShort, &ne_header.resource_tab_offset);
+    size = return_data_value(dfShort, &ne_header.rname_tab_offset);
+
+    if( size > fsize ) return FILE_ERROR;
+
+    size -= s;
+    offset = s + return_data_value(dfShort, &mz_header.ne_offset);
+
+    if( size <= sizeof(NE_TYPEINFO) ) return FILE_ERROR;
+    retval = FILE_DLL;
+  }
+  else if( s == 0x300 || s == 0x200 )		/* maybe .fnt ? */
+  {
+    size = return_data_value(dfLong, &mz_header.dont_care);
+
+    if( size != fsize ) return FILE_ERROR;
+    offset  = 0;
+    retval = FILE_FNT; 
+  }
+  else return FILE_ERROR;
+
+  *lpdata = (unsigned char*)malloc(size);
+
+  if( *lpdata )
+  {
+    lseek( fd, offset, SEEK_SET );
+    if( read(fd, *lpdata, size) != size )
+           { free( *lpdata ); *lpdata = NULL; }
+  }
+  return retval;
+}
+
+
+/* entry point */
+
+int main(int argc, char **argv)
+{
+  unsigned char* lpdata = NULL;
+  int 		 fd;
+
+  parse_options( argc, argv);
+
+  if( (fd = open( g_lpstrInputFile, O_RDONLY)) ) 
+  {
+    int    i;
+    struct stat file_stat;
+
+    fstat( fd, &file_stat);
+    i = get_resource_table( fd, &lpdata, file_stat.st_size );
+
+    switch(i)
+    {
+	case FILE_DLL:
+	     if( lpdata )
+	     {
+	       int	    j, count = 0;
+	       NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(lpdata + 2);
+	       NE_NAMEINFO* pFontStorage = NULL;
+
+	       while( (i = return_data_value(dfShort, &pTInfo->type_id)) ) 
+	       {
+		  j = return_data_value(dfShort, &pTInfo->count);
+		  if( i == NE_RSCTYPE_FONT )
+		  {
+		    count = j;
+		    pFontStorage = (NE_NAMEINFO*)(pTInfo + 1);
+		  }
+
+		  pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1) + j*sizeof(NE_NAMEINFO));
+	       }
+	       if( pFontStorage && count )
+	       {
+		 unsigned short		size_shift = return_data_value(dfShort, lpdata);
+		 unsigned char*		lpfont = NULL;
+		 unsigned		offset;
+		 unsigned		length;
+
+		 for( j = 0; j < count; j++, pFontStorage++ )
+		 {
+		    length = return_data_value(dfShort, &pFontStorage->length) << size_shift;
+		    offset = return_data_value(dfShort, &pFontStorage->offset) << size_shift;
+		    
+		    if( !(lpfont = (unsigned char*) realloc( lpfont, length )) )
+		    {
+			fprintf(stderr, errorMemory );
+			free(lpdata);
+			return -1;
+		    }
+
+		    lseek( fd, offset, SEEK_SET );
+		    if( read(fd, lpfont, length) != length )
+		    {
+			fprintf(stderr, errorDLLRead );
+			free(lpdata); free(lpfont);
+			return -1;
+		    }
+
+		    if( (i = parse_fnt_data( lpfont, length )) )
+			fprintf(stderr, "%s%d\n", errorFontData, i );
+		 }
+		 free(lpfont); free(lpdata);
+		 return 0;
+	       }
+	       else fprintf(stderr, errorEmpty );
+	       free( lpdata );
+	     }
+	     else fprintf(stderr, errorDLLRead);
+	     break;
+
+	case FILE_FNT:
+	     if( lpdata )
+	     {
+	       if( (i = parse_fnt_data( lpdata, file_stat.st_size )) )
+		   fprintf(stderr, "%s%d\n", errorFontData, i );
+
+	       free( lpdata );
+	     }
+	     else fprintf(stderr, errorFNTRead);
+	     break;
+
+	case FILE_ERROR:
+	     fprintf(stderr, errorFile );
+ 
+    }
+    close(fd);
+  }
+  else fprintf(stderr, errorOpenFile );
+  return -1;
+}
diff --git a/tools/fnt2bdf.h b/tools/fnt2bdf.h
new file mode 100644
index 0000000..e40dbad
--- /dev/null
+++ b/tools/fnt2bdf.h
@@ -0,0 +1,74 @@
+#include <stdio.h>
+
+enum data_types {dfChar, dfShort, dfLong, dfString};
+
+#define ERROR_DATA	1
+#define ERROR_VERSION	2
+#define ERROR_SIZE	3
+#define ERROR_MEMORY	4
+#define ERROR_FILE	5
+
+typedef struct tagFontHeader 
+{
+    unsigned char dfVersion[2]; 	/* Version (always 0x3000) */ 
+    unsigned char dfSize[4];            /* Total File Size */
+    unsigned char dfCopyright[60];      /* Copyright notice */
+    unsigned char dfType[2];            /* Vector or bitmap font */
+    unsigned char dfPoints[2];          /* Nominal point size */
+    unsigned char dfVertRes[2]; 	/* Vertical Resolution */
+    unsigned char dfHorizRes[2];        /* Horizontal Resolutionchar */  
+    unsigned char dfAscent[2];          /* Character ascent in pixels */ 
+    unsigned char dfInternalLeading[2]; /* Leading included in character defn */
+    unsigned char dfExternalLeading[2]; /* Leading to be added by Windows */
+    unsigned char dfItalic[1];             /* 1=Italic font */
+    unsigned char dfUnderline[1];          /* 1=underlined font */
+    unsigned char dfStrikeOut[1];          /* 1=strike-out font */
+    unsigned char dfWeight[2];          /* Weight: 400=normal */
+    unsigned char dfCharSet[1];            /* Character Set for this font */
+    unsigned char dfPixWidth[2];        /* Character width (0 for proportional) */
+    unsigned char dfPixHeight[2];       /* Character height */
+    unsigned char dfPitchAndFamily[1];     /* Font Pitch and family */
+    unsigned char dfAvgWidth[2];        /* Average character width */
+    unsigned char dfMaxWidth[2];        /* Maximum character width */
+    unsigned char dfFirstChar[1];          /* Firwst character of the font */
+    unsigned char dfLastChar[1];           /* Last character of the font */
+    unsigned char dfDefaultChar[1];        /* Missing character */
+    unsigned char dfBreakChar[1];          /* Character to indicate word breaks */
+    unsigned char dfWidthBytes[2];      /* Number of bytes in each row */
+    unsigned char dfDevice[4];          /* Offset to device name */
+    unsigned char dfFace[4];            /* Offset to type face name */
+    unsigned char dfBitsPointer[4];
+    unsigned char dfBitsOffset[4];      /* Offset to bitmaps */
+    unsigned char dfReserved[1];
+    unsigned char dfFlags[4];           /* Bitmapped flags */
+    unsigned char dfAspace[2];
+    unsigned char dfBspace[2];
+    unsigned char dfCspace[2];
+    unsigned char dfColorTable[2];      /* Offset to Color table */
+    unsigned char dfReserved1[4];
+} fnt_hdrS;
+
+typedef struct WinCharStruct
+{
+    unsigned int charWidth;
+    unsigned int charOffset;
+} WinCharS;
+ 
+typedef struct fntFontStruct
+{
+    fnt_hdrS 	 	hdr;
+    WinCharS 		*dfCharTable;
+    unsigned char	*dfDeviceP;
+    unsigned char 	*dfFaceP;
+    unsigned char 	*dfBitsPointerP;
+    unsigned char 	*dfBitsOffsetP;
+    short 		*dfColorTableP;
+} fnt_fontS;
+
+extern	int return_data_value(enum data_types, void *);
+ 
+extern	int dump_bdf(fnt_fontS*, unsigned char* );
+extern	int dump_bdf_hdr(FILE* fp,fnt_fontS*, unsigned char* );
+
+extern	int parse_fnt_data(unsigned char* file_buffer, int length);
+
diff --git a/win32/code_page.c b/win32/code_page.c
index 2d60fc4..f181ad3 100644
--- a/win32/code_page.c
+++ b/win32/code_page.c
@@ -17,7 +17,7 @@
 /***********************************************************************
  *           GetACP               (KERNEL32.148)
  */
-UINT GetACP(void)
+UINT32 GetACP(void)
 {
     return 1252;    /* Windows 3.1 ISO Latin */
 }
@@ -36,7 +36,7 @@
 /***********************************************************************
  *              GetOEMCP                (KERNEL32.248)
  */
-UINT GetOEMCP(void)
+UINT32 GetOEMCP(void)
 {
     return 437;    /* MS-DOS United States */
 }
diff --git a/win32/findfile.c b/win32/findfile.c
index 50bb75d..011070e 100644
--- a/win32/findfile.c
+++ b/win32/findfile.c
@@ -5,6 +5,7 @@
 #include <malloc.h>
 #include "xmalloc.h"
 #include "windows.h"
+#include "winerror.h"
 #include "dos_fs.h"
 #include "heap.h"
 #include "string32.h"
@@ -188,8 +189,12 @@
 {
     FindFileContext32 *context;
 
-	if (handle==(INVALID_HANDLE_VALUE))
-		return TRUE;
+    /* Windows95 ignores an invalid handle. */
+    if (handle == INVALID_HANDLE_VALUE)
+    {
+	SetLastError(ERROR_INVALID_HANDLE);
+        return FALSE;
+    }
     context = (FindFileContext32 *) handle;
     if (context->dir)
 	closedir(context->dir);
diff --git a/win32/newfns.c b/win32/newfns.c
index e9de49a..29f779f 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -23,32 +23,6 @@
 	return WinHelp(hWnd,lpszHelp,uCommand,dwData);
 }
 
-HHOOK SetWindowsHookEx32A(INT32 id, HOOKPROC32 hookfn, HINSTANCE32 hModule,
-				DWORD ThreadId)
-
-{
-	/* Stub for now */
-	fprintf(stdnimp, "SetWindowsHookEx32A Stub called! (hook Id %d)\n",id);
-	
-	return (HHOOK) NULL;
-}
-
-HHOOK SetWindowsHook32A(INT32 HookId, HOOKPROC32 hookfn)
-{
-	/* Stub for now */
-	fprintf(stdnimp, "SetWindowsHook32A Stub called! (hook Id %d)\n", HookId);
-	SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-	return (HHOOK) NULL;
-}
-
-BOOL32 UnhookWindowsHookEx32(HHOOK hHook)
-
-{
-	/* Stub for now */
-	fprintf(stdnimp, "UnhookWindowsHookEx32 Stub called!\n");
-	return FALSE;
-}
-
 /****************************************************************************
  *		QueryPerformanceCounter (KERNEL32.415)
  */
diff --git a/win32/thread.c b/win32/thread.c
index 37e3c54..ae020f7 100644
--- a/win32/thread.c
+++ b/win32/thread.c
@@ -15,12 +15,13 @@
 #include "xmalloc.h"
 
 /***********************************************************************
- *           GetCurrentThreadId   (KERNEL32.200)
+ *           GetCurrentThreadId   (KERNEL32.201)
  */
 
-int GetCurrentThreadId(void)
+DWORD GetCurrentThreadId(void)
 {
-        return getpid();
+        /* Windows 95 returns the address of the thread database (sorta) */
+        return MAKELONG(GetCurrentTask(), 0);
 }
 
 /***********************************************************************
@@ -35,7 +36,7 @@
  */
 HANDLE32 GetCurrentThread(void)
 {
-	return 0;
+        return 0xFFFFFFFE;	/* that's -2 */
 }
 
 /**********************************************************************
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 03a2d22..99e2a1f 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -89,18 +89,18 @@
         !(SendMessage16(hwndNew, WM_GETDLGCODE, 0, 0 ) & DLGC_UNDEFPUSHBUTTON))
         return FALSE;  /* Destination is not a push button */
     
-    if (dlgInfo->msgResult)  /* There's already a default pushbutton */
+    if (dlgInfo->idResult)  /* There's already a default pushbutton */
     {
-        HWND32 hwndOld = GetDlgItem( hwndDlg, dlgInfo->msgResult );
+        HWND32 hwndOld = GetDlgItem( hwndDlg, dlgInfo->idResult );
         if (SendMessage32A( hwndOld, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON)
             SendMessage32A( hwndOld, BM_SETSTYLE32, BS_PUSHBUTTON, TRUE );
     }
     if (hwndNew)
     {
         SendMessage32A( hwndNew, BM_SETSTYLE32, BS_DEFPUSHBUTTON, TRUE );
-        dlgInfo->msgResult = GetDlgCtrlID( hwndNew );
+        dlgInfo->idResult = GetDlgCtrlID( hwndNew );
     }
-    else dlgInfo->msgResult = 0;
+    else dlgInfo->idResult = 0;
     return TRUE;
 }
 
@@ -177,8 +177,8 @@
 
         case DM_GETDEFID:
             if (dlgInfo->fEnd) return 0;
-	    if (dlgInfo->msgResult)
-	      return MAKELONG( dlgInfo->msgResult, DC_HASDEFID );
+	    if (dlgInfo->idResult)
+	      return MAKELONG( dlgInfo->idResult, DC_HASDEFID );
 	    hwndDefId = DEFDLG_FindDefButton( hwnd );
 	    if (hwndDefId)
 	      return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
@@ -223,7 +223,9 @@
                                            hwnd, msg, wParam, lParam );
 
         /* Check if window was destroyed by dialog procedure */
-        if (result || !IsWindow( hwnd )) return result;
+
+	if (!IsWindow( hwnd )) return result;
+	else if( result ) return dlgInfo->msgResult;
     }
     
     switch(msg)
@@ -267,7 +269,9 @@
                                             hwnd, msg, wParam, lParam );
 
         /* Check if window was destroyed by dialog procedure */
-        if (result || !IsWindow( hwnd )) return result;
+
+        if (!IsWindow( hwnd )) return result;
+        else if( result ) return dlgInfo->msgResult;
     }
     
     switch(msg)
@@ -310,7 +314,9 @@
                                             hwnd, msg, wParam, lParam );
 
         /* Check if window was destroyed by dialog procedure */
-        if (result || !IsWindow( hwnd )) return result;
+
+        if (!IsWindow( hwnd )) return result;
+        else if( result ) return dlgInfo->msgResult;
     }
     
     switch(msg)
diff --git a/windows/dialog.c b/windows/dialog.c
index 7f51666..e1b0946 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -293,7 +293,7 @@
                 SendMessage32A( hwndDefButton, BM_SETSTYLE32,
                                 BS_PUSHBUTTON,FALSE );
             hwndDefButton = hwndCtrl;
-            dlgInfo->msgResult = GetWindowWord( hwndCtrl, GWW_ID );
+            dlgInfo->idResult = GetWindowWord( hwndCtrl, GWW_ID );
         }
     }    
     dprintf_dialog(stddeb, " END\n" );
@@ -583,7 +583,8 @@
     dlgInfo->hMenu     = hMenu;
     dlgInfo->xBaseUnit = xUnit;
     dlgInfo->yBaseUnit = yUnit;
-    dlgInfo->msgResult = 0;  /* This is used to store the default button id */
+    dlgInfo->msgResult = 0; 
+    dlgInfo->idResult  = 0;
     dlgInfo->hDialogHeap = 0;
 
     if (dlgInfo->hUserFont)
@@ -747,7 +748,7 @@
 	}
 	if (dlgInfo->fEnd) break;
     }
-    retval = dlgInfo->msgResult;
+    retval = dlgInfo->idResult;
     EnableWindow( owner, TRUE );
     DestroyWindow( hwnd );
     return retval;
@@ -860,7 +861,7 @@
 {
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     DIALOGINFO * dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
-    dlgInfo->msgResult = retval;
+    dlgInfo->idResult = retval;
     dlgInfo->fEnd = TRUE;
     dprintf_dialog(stddeb, "EndDialog: %04x %d\n", hwnd, retval );
     return TRUE;
diff --git a/windows/event.c b/windows/event.c
index 49d325a..1143c44 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -307,6 +307,8 @@
     if( dndSelection == None )
 	dndSelection = XInternAtom( display, "DndSelection" , False );
 
+    XSetWMProtocols( display, pWnd->window, &wmDeleteWindow, 1 );
+
     if (!winContext) winContext = XUniqueContext();
     XSaveContext( display, pWnd->window, winContext, (char *)pWnd );
 }
diff --git a/windows/focus.c b/windows/focus.c
index 99654b7..7d284d0 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -101,8 +101,8 @@
 	if( hwnd == hwndFocus ) return hwnd;
 
 	/* call hooks */
-	if( HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM16)hwnd,
-                            (LPARAM)hwndFocus) )
+	if( HOOK_CallHooks16( WH_CBT, HCBT_SETFOCUS, (WPARAM16)hwnd,
+			      (LPARAM)hwndFocus) )
 	    return 0;
 
         /* activate hwndTop if needed. */
@@ -113,7 +113,7 @@
 	    if (!IsWindow( hwnd )) return 0;  /* Abort if window destroyed */
 	}
     }
-    else if( HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)hwndFocus ) )
+    else if( HOOK_CallHooks16( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)hwndFocus ) )
              return 0;
 
       /* Change focus and send messages */
diff --git a/windows/hook.c b/windows/hook.c
index ef81d3a..a64db7c 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -2,6 +2,7 @@
  * Windows hook functions
  *
  * Copyright 1994, 1995 Alexandre Julliard
+ *                 1996 Andrew Lewycky
  *
  * Based on investigations by Alex Korobka
  */
@@ -14,9 +15,13 @@
  */
 
 #define NO_TRANSITION_TYPES  /* This file is Win32-clean */
+#include "windows.h"
 #include "hook.h"
 #include "queue.h"
 #include "user.h"
+#include "heap.h"
+#include "struct32.h"
+#include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -26,11 +31,12 @@
 typedef struct
 {
     HANDLE16   next;               /* 00 Next hook in chain */
-    HOOKPROC16 proc WINE_PACKED;   /* 02 Hook procedure */
+    HOOKPROC32 proc WINE_PACKED;   /* 02 Hook procedure */
     INT16      id;                 /* 06 Hook id (WH_xxx) */
     HQUEUE16   ownerQueue;         /* 08 Owner queue (0 for system hook) */
     HMODULE16  ownerModule;        /* 0a Owner module */
     WORD       inHookProc;         /* 0c TRUE if in this->proc */
+    INT32      flags;
 } HOOKDATA;
 
 #pragma pack(4)
@@ -40,6 +46,743 @@
   /* This should probably reside in USER heap */
 static HANDLE16 HOOK_systemHooks[WH_NB_HOOKS] = { 0, };
 
+typedef VOID (*HOOK_MapFunc)(INT32, INT32, WPARAM32 *, LPARAM *);
+typedef VOID (*HOOK_UnMapFunc)(INT32, INT32, WPARAM32, LPARAM, WPARAM32,
+			       LPARAM);
+
+
+/***********************************************************************
+ *           Hook Mapping Functions
+ */
+
+
+/***********************************************************************
+ *           HOOK_Map16To32Common
+ */
+static void HOOK_Map16To32Common(INT32 id, INT32 code, WPARAM32 *pwParam,
+				 LPARAM *plParam)
+{
+    switch (id)
+    {
+    case WH_MSGFILTER:
+    case WH_SYSMSGFILTER:
+    case WH_GETMESSAGE:
+    case WH_JOURNALRECORD:
+        {
+            LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(*plParam);
+            LPMSG32 lpmsg32 = HeapAlloc( SystemHeap, 0, sizeof(*lpmsg32) );
+	
+            STRUCT32_MSG16to32( lpmsg16, lpmsg32 );
+            *plParam = (LPARAM)lpmsg32;
+            break;
+        }
+    case WH_JOURNALPLAYBACK:
+        {
+            LPEVENTMSG16 lpem16 = PTR_SEG_TO_LIN(*plParam);
+            LPEVENTMSG32 lpem32 = HeapAlloc( SystemHeap, 0, sizeof(*lpem32) );
+
+            lpem32->message = lpem16->message;
+            lpem32->paramL = lpem16->paramL;
+            lpem32->paramH = lpem16->paramH;
+            lpem32->time = lpem16->time;
+            lpem32->hwnd = 0;	/* FIXME */
+
+            *plParam = (LPARAM)lpem32;
+            break;
+        }
+    case WH_CBT:
+	switch (code)
+	{
+        case HCBT_ACTIVATE:
+            {
+                LPCBTACTIVATESTRUCT16 lpcas16 = PTR_SEG_TO_LIN(*plParam);
+                LPCBTACTIVATESTRUCT32 lpcas32 = HeapAlloc( SystemHeap, 0,
+                                                           sizeof(*lpcas32) );
+                lpcas32->fMouse = lpcas16->fMouse;
+                lpcas32->hWndActive = lpcas16->hWndActive;
+                *plParam = (LPARAM)lpcas32;
+                break;
+            }
+        case HCBT_CLICKSKIPPED:
+            {
+                LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
+                LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
+                                                        sizeof(*lpms32) );
+
+                STRUCT32_POINT16to32( &lpms16->pt, &lpms32->pt );
+
+                /* wHitTestCode may be negative, so convince compiler to do
+                   correct sign extension. Yay. :| */
+                lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
+
+                lpms32->dwExtraInfo = lpms16->dwExtraInfo;
+                lpms32->hwnd = lpms16->hwnd;
+                *plParam = (LPARAM)lpms32;
+                break;
+            }
+        case HCBT_MOVESIZE:
+            {
+                LPRECT16 lprect16 = PTR_SEG_TO_LIN(*plParam);
+                LPRECT32 lprect32 = HeapAlloc( SystemHeap, 0,
+                                               sizeof(*lprect32) );
+
+                STRUCT32_RECT16to32( lprect16, lprect32 );
+                *plParam = (LPARAM)lprect32;
+                break;
+            }
+	}
+	break;
+    case WH_MOUSE:
+        {
+            LPMOUSEHOOKSTRUCT16 lpms16 = PTR_SEG_TO_LIN(*plParam);
+            LPMOUSEHOOKSTRUCT32 lpms32 = HeapAlloc( SystemHeap, 0,
+                                                    sizeof(*lpms32) );
+
+            STRUCT32_POINT16to32( &lpms16->pt, &lpms32->pt );
+
+            /* wHitTestCode may be negative, so convince compiler to do
+               correct sign extension. Yay. :| */
+            lpms32->wHitTestCode = (INT32)((INT16)lpms16->wHitTestCode);
+            lpms32->dwExtraInfo = lpms16->dwExtraInfo;
+            lpms32->hwnd = lpms16->hwnd;
+            *plParam = (LPARAM)lpms32;
+            break;
+        }
+    case WH_DEBUG:
+        {
+            LPDEBUGHOOKINFO16 lpdh16 = PTR_SEG_TO_LIN(*plParam);
+            LPDEBUGHOOKINFO32 lpdh32 = HeapAlloc( SystemHeap, 0,
+                                                  sizeof(*lpdh32) );
+
+            lpdh32->idThread = 0;               /* FIXME */
+            lpdh32->idThreadInstaller = 0;	/* FIXME */
+            lpdh32->lParam = lpdh16->lParam;	/* FIXME Check for sign ext */
+            lpdh32->wParam = lpdh16->wParam;
+            lpdh32->code = lpdh16->code;
+	  
+            /* do sign extension if it was WH_MSGFILTER */
+            if (*pwParam == 0xffff) *pwParam = WH_MSGFILTER;
+
+            *plParam = (LPARAM)lpdh32;
+            break;
+        }
+    case WH_SHELL:
+    case WH_KEYBOARD:
+	break;
+
+    case WH_CALLWNDPROC:
+    case WH_HARDWARE:
+	break;	/* NYI */
+
+    default:
+	fprintf(stderr, "Unknown hook id: %d\n", id);
+	return;
+    }
+}
+
+
+/***********************************************************************
+ *           HOOK_Map16To32A
+ */
+static void HOOK_Map16To32A(INT32 id, INT32 code, WPARAM32 *pwParam,
+			    LPARAM *plParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
+	LPCBT_CREATEWND32A lpcbtcw32 = HeapAlloc( SystemHeap, 0,
+						  sizeof(*lpcbtcw32) );
+	lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
+				     sizeof(*lpcbtcw32->lpcs) );
+
+	STRUCT32_CREATESTRUCT16to32A( lpcbtcw16->lpcs, lpcbtcw32->lpcs );
+
+	if (HIWORD(lpcbtcw16->lpcs->lpszName))
+            lpcbtcw32->lpcs->lpszName
+                = PTR_SEG_TO_LIN(lpcbtcw16->lpcs->lpszName);
+	else
+            lpcbtcw32->lpcs->lpszName = (LPSTR)lpcbtcw16->lpcs->lpszName;
+
+	if (HIWORD(lpcbtcw16->lpcs->lpszClass))
+            lpcbtcw32->lpcs->lpszClass
+                = PTR_SEG_TO_LIN(lpcbtcw16->lpcs->lpszClass);
+	else
+            lpcbtcw32->lpcs->lpszClass = (LPSTR)lpcbtcw16->lpcs->lpszClass;
+
+	lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
+
+	*plParam = (LPARAM)lpcbtcw32;
+    }
+    else
+        HOOK_Map16To32Common( id, code, pwParam, plParam );
+}
+
+
+/***********************************************************************
+ *           HOOK_Map16To32W
+ */
+static void HOOK_Map16To32W(INT32 id, INT32 code, WPARAM32 *pwParam,
+			    LPARAM *plParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(*plParam);
+	LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
+	LPCBT_CREATEWND32W lpcbtcw32 = HeapAlloc( SystemHeap, 0,
+						  sizeof(*lpcbtcw32) );
+	lpcbtcw32->lpcs = HeapAlloc( SystemHeap, 0,
+				     sizeof(*lpcbtcw32->lpcs) );
+
+	STRUCT32_CREATESTRUCT16to32A( lpcs16,
+				      (LPCREATESTRUCT32A)lpcbtcw32->lpcs );
+
+	if (HIWORD(lpcs16->lpszName))
+            lpcbtcw32->lpcs->lpszName = 
+                STRING32_DupAnsiToUni( PTR_SEG_TO_LIN(lpcs16->lpszName) );
+	else
+            lpcbtcw32->lpcs->lpszName = (LPWSTR)lpcs16->lpszName;
+
+	if (HIWORD(lpcs16->lpszClass))
+            lpcbtcw32->lpcs->lpszClass =
+                STRING32_DupAnsiToUni( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
+	else
+            lpcbtcw32->lpcs->lpszClass = (LPWSTR)lpcs16->lpszClass;
+
+	lpcbtcw32->hwndInsertAfter = lpcbtcw16->hwndInsertAfter;
+
+	*plParam = (LPARAM)lpcbtcw32;
+    }
+    else HOOK_Map16To32Common( id, code, pwParam, plParam );
+}
+
+
+/***********************************************************************
+ *           HOOK_UnMap16To32Common
+ */
+static void HOOK_UnMap16To32Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
+				   LPARAM lParamOrig, WPARAM32 wParam,
+				   LPARAM lParam)
+{
+    switch (id)
+    {
+      case WH_MSGFILTER:
+      case WH_SYSMSGFILTER:
+      case WH_JOURNALRECORD:
+      case WH_JOURNALPLAYBACK:
+      {
+	  HeapFree( SystemHeap, 0, (LPVOID)lParam );
+	  break;
+      }
+
+      case WH_GETMESSAGE:
+      {
+	  LPMSG16 lpmsg16 = PTR_SEG_TO_LIN(lParamOrig);
+	  STRUCT32_MSG32to16( (LPMSG32)lParam, lpmsg16 );
+	  HeapFree( SystemHeap, 0, (LPVOID)lParam );
+	  break;
+      }
+
+      case WH_MOUSE:
+      case WH_DEBUG:
+	HeapFree( SystemHeap, 0, (LPVOID)lParam );
+	break;
+
+	/* I don't think any of these need to be copied */
+      case WH_CBT:
+	switch (code)
+	{
+	  case HCBT_ACTIVATE:
+	  case HCBT_CLICKSKIPPED:
+	  case HCBT_MOVESIZE:
+	    HeapFree( SystemHeap, 0, (LPVOID)lParam);
+	    break;
+	}
+	break;
+
+      case WH_SHELL:
+      case WH_KEYBOARD:
+	break;
+
+      case WH_CALLWNDPROC:
+      case WH_HARDWARE:
+	fprintf(stderr, "Can't map hook id: %d\n", id);
+	break;
+
+      default:
+	fprintf(stderr, "Unknown hook id: %d\n", id);
+	return;
+    }
+}
+
+
+/***********************************************************************
+ *           HOOK_UnMap16To32A
+ */
+static void HOOK_UnMap16To32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
+			      LPARAM lParamOrig, WPARAM32 wParam,
+			      LPARAM lParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)lParam;
+	HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
+	HeapFree( SystemHeap, 0, lpcbtcw32 );
+    }
+    else
+      HOOK_UnMap16To32Common( id, code, wParamOrig, lParamOrig, wParam,
+			      lParam);
+    return;
+}
+
+
+/***********************************************************************
+ *           HOOK_UnMap16To32W
+ */
+static void HOOK_UnMap16To32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
+			      LPARAM lParamOrig, WPARAM32 wParam,
+			      LPARAM lParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)lParam;
+	if (HIWORD(lpcbtcw32->lpcs->lpszName))
+	  free( (LPWSTR)lpcbtcw32->lpcs->lpszName );
+	if (HIWORD(lpcbtcw32->lpcs->lpszClass))
+	  free( (LPWSTR)lpcbtcw32->lpcs->lpszClass );
+	HeapFree( SystemHeap, 0, lpcbtcw32->lpcs );
+	HeapFree( SystemHeap, 0, lpcbtcw32 );
+    }
+    else
+      HOOK_UnMap16To32Common(id, code, wParamOrig, lParamOrig, wParam, lParam);
+}
+
+
+/***********************************************************************
+ *           HOOK_Map32To16Common
+ */
+static void HOOK_Map32To16Common(INT32 id, INT32 code, WPARAM32 *pwParam,
+				 LPARAM *plParam)
+{
+    switch (id)
+    {
+      case WH_MSGFILTER:
+      case WH_SYSMSGFILTER:
+      case WH_GETMESSAGE:
+      case WH_JOURNALRECORD:
+      {
+	  LPMSG32 lpmsg32 = (LPMSG32)*plParam;
+	  LPMSG16 lpmsg16 = SEGPTR_NEW( MSG16 );
+
+	  STRUCT32_MSG32to16( lpmsg32, lpmsg16 );
+
+	  *plParam = (LPARAM)SEGPTR_GET( lpmsg16 );
+	  break;
+      }
+
+      case WH_JOURNALPLAYBACK:
+      {
+	  LPEVENTMSG32 lpem32 = (LPEVENTMSG32)*plParam;
+	  LPEVENTMSG16 lpem16 = SEGPTR_NEW( EVENTMSG16 );
+
+	  lpem16->message = lpem32->message;
+	  lpem16->paramL  = lpem32->paramL;
+	  lpem16->paramH  = lpem32->paramH;
+	  lpem16->time    = lpem32->time;
+
+	  *plParam = (LPARAM)SEGPTR_GET( lpem16 );
+	  break;
+      }
+
+      case WH_CBT:
+	switch (code)
+	{
+	  case HCBT_ACTIVATE:
+	  {
+	      LPCBTACTIVATESTRUCT32 lpcas32 = (LPCBTACTIVATESTRUCT32)*plParam;
+	      LPCBTACTIVATESTRUCT16 lpcas16 =SEGPTR_NEW( CBTACTIVATESTRUCT16 );
+
+	      lpcas16->fMouse     = lpcas32->fMouse;
+	      lpcas16->hWndActive = lpcas32->hWndActive
+;
+	      *plParam = (LPARAM)SEGPTR_GET( lpcas16 );
+	      break;
+	  }
+	      
+	  case HCBT_CLICKSKIPPED:
+	  {
+	      LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
+	      LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
+
+	      STRUCT32_POINT32to16( &lpms32->pt, &lpms16->pt );
+
+	      lpms16->hwnd         = lpms32->hwnd;
+	      lpms16->wHitTestCode = lpms32->wHitTestCode;
+	      lpms16->dwExtraInfo  = lpms32->dwExtraInfo;
+
+	      *plParam = (LPARAM)SEGPTR_GET( lpms16 );
+	      break;
+	  }
+
+	  case HCBT_MOVESIZE:
+	  {
+	      LPRECT32 lprect32 = (LPRECT32)*plParam;
+	      LPRECT16 lprect16 = SEGPTR_NEW( RECT16 );
+
+	      STRUCT32_RECT32to16( lprect32, lprect16 );
+
+	      *plParam = (LPARAM)SEGPTR_GET( lprect16 );
+	      break;
+	  }
+	}
+	break;
+
+      case WH_MOUSE:
+      {
+	  LPMOUSEHOOKSTRUCT32 lpms32 = (LPMOUSEHOOKSTRUCT32)*plParam;
+	  LPMOUSEHOOKSTRUCT16 lpms16 = SEGPTR_NEW( MOUSEHOOKSTRUCT16 );
+
+	  STRUCT32_POINT32to16( &lpms32->pt, &lpms16->pt );
+
+	  lpms16->hwnd = lpms32->hwnd;
+	  lpms16->wHitTestCode = lpms32->wHitTestCode;
+	  lpms16->dwExtraInfo = lpms32->dwExtraInfo;
+
+	  *plParam = (LPARAM)SEGPTR_GET( lpms16 );
+	  break;
+      }
+
+      case WH_DEBUG:
+      {
+	  LPDEBUGHOOKINFO32 lpdh32 = (LPDEBUGHOOKINFO32)*plParam;
+	  LPDEBUGHOOKINFO16 lpdh16 = SEGPTR_NEW( DEBUGHOOKINFO16 );
+
+	  lpdh16->hModuleHook = 0;	/* FIXME */
+	  lpdh16->reserved    = 0;
+	  lpdh16->lParam      = lpdh32->lParam;
+	  lpdh16->wParam      = lpdh32->wParam;
+	  lpdh16->code        = lpdh32->code;
+	  
+	  *plParam = (LPARAM)SEGPTR_GET( lpdh16 );
+	  break;
+      }
+
+      case WH_SHELL:
+      case WH_KEYBOARD:
+	break;
+
+      case WH_CALLWNDPROC:
+      case WH_HARDWARE:
+	fprintf(stderr, "Can't map hook id: %d\n", id);
+	break;
+
+      default:
+	fprintf(stderr, "Unknown hook id: %d\n", id);
+	return;
+    }
+}
+
+
+/***********************************************************************
+ *           HOOK_Map32ATo16
+ */
+static void HOOK_Map32ATo16(INT32 id, INT32 code, WPARAM32 *pwParam,
+			    LPARAM *plParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND32A lpcbtcw32 = (LPCBT_CREATEWND32A)*plParam;
+	LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
+	LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
+
+	lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
+	STRUCT32_CREATESTRUCT32Ato16( lpcbtcw32->lpcs, lpcs16 );
+
+	if (HIWORD(lpcbtcw32->lpcs->lpszName))
+	  lpcs16->lpszName =
+	    SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszName ) );
+	else
+	  lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
+
+	if (HIWORD(lpcbtcw32->lpcs->lpszClass))
+	  lpcs16->lpszClass =
+	    SEGPTR_GET( SEGPTR_STRDUP( lpcbtcw32->lpcs->lpszClass ) );
+	else
+	  lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
+
+	lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
+
+	*plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
+    }
+    else HOOK_Map32To16Common(id, code, pwParam, plParam);
+}
+
+
+/***********************************************************************
+ *           HOOK_Map32WTo16
+ */
+static void HOOK_Map32WTo16(INT32 id, INT32 code, WPARAM32 *pwParam,
+			    LPARAM *plParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND32W lpcbtcw32 = (LPCBT_CREATEWND32W)*plParam;
+	LPCBT_CREATEWND16 lpcbtcw16 = SEGPTR_NEW( CBT_CREATEWND16 );
+	LPCREATESTRUCT16 lpcs16 = SEGPTR_NEW( CREATESTRUCT16 );
+
+	lpcbtcw16->lpcs = (LPCREATESTRUCT16)SEGPTR_GET( lpcs16 );
+	STRUCT32_CREATESTRUCT32Ato16( (LPCREATESTRUCT32A)lpcbtcw32->lpcs,
+				      lpcs16 );
+
+	if (HIWORD(lpcbtcw32->lpcs->lpszName))
+	{
+	    LPSTR str = SEGPTR_ALLOC( lstrlen32W(lpcbtcw32->lpcs->lpszName) );
+	    STRING32_UniToAnsi( str, lpcbtcw32->lpcs->lpszName );
+	    lpcs16->lpszName = SEGPTR_GET( str );
+	}
+	else
+	  lpcs16->lpszName = (SEGPTR)lpcbtcw32->lpcs->lpszName;
+
+	if (HIWORD(lpcbtcw32->lpcs->lpszClass))
+	{
+	    LPSTR str = SEGPTR_ALLOC( lstrlen32W(lpcbtcw32->lpcs->lpszClass) );
+	    STRING32_UniToAnsi( str, lpcbtcw32->lpcs->lpszClass );
+	    lpcs16->lpszClass = SEGPTR_GET( str );
+	}
+	else
+	  lpcs16->lpszClass = (SEGPTR)lpcbtcw32->lpcs->lpszClass;
+
+	lpcbtcw16->hwndInsertAfter = lpcbtcw32->hwndInsertAfter;
+
+	*plParam = (LPARAM)SEGPTR_GET( lpcbtcw16 );
+    }
+    else HOOK_Map32To16Common(id, code, pwParam, plParam);
+}
+
+
+/***********************************************************************
+ *           HOOK_UnMap32To16Common
+ */
+static void HOOK_UnMap32To16Common(INT32 id, INT32 code, WPARAM32 wParamOrig,
+				   LPARAM lParamOrig, WPARAM32 wParam,
+				   LPARAM lParam)
+{
+    switch (id)
+    {
+      case WH_MSGFILTER:
+      case WH_SYSMSGFILTER:
+      case WH_JOURNALRECORD:
+      case WH_JOURNALPLAYBACK:
+      case WH_MOUSE:
+      case WH_DEBUG:
+	SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
+	break;
+
+      case WH_GETMESSAGE:
+      {
+	  LPMSG32 lpmsg32 = (LPMSG32)lParamOrig;
+
+	  STRUCT32_MSG16to32( (LPMSG16)PTR_SEG_TO_LIN(lParam), lpmsg32 );
+	  SEGPTR_FREE( PTR_SEG_TO_LIN(lParam) );
+	  break;
+      }
+
+      case WH_CBT:
+	switch (code)
+	{
+	  case HCBT_ACTIVATE:
+	  case HCBT_CLICKSKIPPED:
+	  case HCBT_MOVESIZE:
+	    SEGPTR_FREE( (LPVOID)lParam );
+	    break;
+	}
+	break;
+
+      case WH_SHELL:
+      case WH_KEYBOARD:
+	break;
+
+      case WH_CALLWNDPROC:
+      case WH_HARDWARE:
+	fprintf(stderr, "Can't map hook id: %d\n", id);
+	break;
+
+      default:
+	fprintf(stderr, "Unknown hook id: %d\n", id);
+	return;
+    }
+}
+
+
+/***********************************************************************
+ *           HOOK_UnMap32ATo16
+ */
+static void HOOK_UnMap32ATo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
+			      LPARAM lParamOrig, WPARAM32 wParam,
+			      LPARAM lParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND16 lpcbtcw16 = PTR_SEG_TO_LIN(lParam);
+	LPCREATESTRUCT16 lpcs16 = PTR_SEG_TO_LIN(lpcbtcw16->lpcs);
+
+	if (HIWORD(lpcs16->lpszName))
+	  SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszName) );
+
+	if (HIWORD(lpcs16->lpszClass))
+	  SEGPTR_FREE( PTR_SEG_TO_LIN(lpcs16->lpszClass) );
+
+	SEGPTR_FREE( lpcs16 );
+	SEGPTR_FREE( lpcbtcw16 );
+    }
+    else
+      return HOOK_UnMap32To16Common( id, code, wParamOrig, lParamOrig, wParam,
+				     lParam );
+    return;
+}
+
+
+/***********************************************************************
+ *           HOOK_UnMap32WTo16
+ */
+static void HOOK_UnMap32WTo16(INT32 id, INT32 code, WPARAM32 wParamOrig,
+			      LPARAM lParamOrig, WPARAM32 wParam,
+			      LPARAM lParam)
+{
+    HOOK_UnMap32ATo16( id, code, wParamOrig, lParamOrig, wParam, lParam );
+}
+
+
+/***********************************************************************
+ *           HOOK_Map32ATo32W
+ */
+static void HOOK_Map32ATo32W(INT32 id, INT32 code, WPARAM32 *pwParam,
+			     LPARAM *plParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)*plParam;
+	LPCBT_CREATEWND32W lpcbtcwW = HeapAlloc( SystemHeap, 0,
+						 sizeof(*lpcbtcwW) );
+	lpcbtcwW->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwW->lpcs) );
+
+	lpcbtcwW->hwndInsertAfter = lpcbtcwA->hwndInsertAfter;
+	*lpcbtcwW->lpcs = *(LPCREATESTRUCT32W)lpcbtcwA->lpcs;
+
+	if (HIWORD(lpcbtcwA->lpcs->lpszName))
+	{
+	    lpcbtcwW->lpcs->lpszName =
+	      STRING32_DupAnsiToUni( lpcbtcwA->lpcs->lpszName );
+	}
+	else
+	  lpcbtcwW->lpcs->lpszName = (LPWSTR)lpcbtcwA->lpcs->lpszName;
+
+	if (HIWORD(lpcbtcwA->lpcs->lpszClass))
+	{
+	    lpcbtcwW->lpcs->lpszClass =
+	      STRING32_DupAnsiToUni( lpcbtcwA->lpcs->lpszClass);
+	}
+	else
+	  lpcbtcwW->lpcs->lpszClass = (LPCWSTR)lpcbtcwA->lpcs->lpszClass;
+    }
+    return;
+}
+
+
+/***********************************************************************
+ *           HOOK_UnMap32ATo32W
+ */
+static void HOOK_UnMap32ATo32W(INT32 id, INT32 code, WPARAM32 wParamOrig,
+			       LPARAM lParamOrig, WPARAM32 wParam,
+			       LPARAM lParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)lParam;
+	if (HIWORD(lpcbtcwW->lpcs->lpszName))
+            free( (LPWSTR)lpcbtcwW->lpcs->lpszName );
+	if (HIWORD(lpcbtcwW->lpcs->lpszClass))
+            free( (LPWSTR)lpcbtcwW->lpcs->lpszClass );
+	HeapFree( SystemHeap, 0, lpcbtcwW->lpcs );
+	HeapFree( SystemHeap, 0, lpcbtcwW );
+    }
+    return;
+}
+
+
+/***********************************************************************
+ *           HOOK_Map32WTo32A
+ */
+static void HOOK_Map32WTo32A(INT32 id, INT32 code, WPARAM32 *pwParam,
+			     LPARAM *plParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND32W lpcbtcwW = (LPCBT_CREATEWND32W)*plParam;
+	LPCBT_CREATEWND32A lpcbtcwA = HeapAlloc( SystemHeap, 0,
+						 sizeof(*lpcbtcwA) );
+	lpcbtcwA->lpcs = HeapAlloc( SystemHeap, 0, sizeof(*lpcbtcwA->lpcs) );
+
+	lpcbtcwA->hwndInsertAfter = lpcbtcwW->hwndInsertAfter;
+	*lpcbtcwA->lpcs = *(LPCREATESTRUCT32A)lpcbtcwW->lpcs;
+
+	if (HIWORD(lpcbtcwW->lpcs->lpszName))
+	  lpcbtcwA->lpcs->lpszName =
+	    STRING32_DupUniToAnsi( lpcbtcwW->lpcs->lpszName );
+	else
+	  lpcbtcwA->lpcs->lpszName = (LPSTR)lpcbtcwW->lpcs->lpszName;
+
+	if (HIWORD(lpcbtcwW->lpcs->lpszClass))
+	  lpcbtcwA->lpcs->lpszClass =
+	    STRING32_DupUniToAnsi( lpcbtcwW->lpcs->lpszClass);
+	else
+	  lpcbtcwA->lpcs->lpszClass = (LPSTR)lpcbtcwW->lpcs->lpszClass;
+    }
+    return;
+}
+
+
+/***********************************************************************
+ *           HOOK_UnMap32WTo32A
+ */
+static void HOOK_UnMap32WTo32A(INT32 id, INT32 code, WPARAM32 wParamOrig,
+			       LPARAM lParamOrig, WPARAM32 wParam,
+			       LPARAM lParam)
+{
+    if (id == WH_CBT && code == HCBT_CREATEWND)
+    {
+	LPCBT_CREATEWND32A lpcbtcwA = (LPCBT_CREATEWND32A)lParam;
+	if (HIWORD(lpcbtcwA->lpcs->lpszName))
+	  free( (LPSTR)lpcbtcwA->lpcs->lpszName );
+	if (HIWORD(lpcbtcwA->lpcs->lpszClass))
+	  free( (LPSTR)lpcbtcwA->lpcs->lpszClass );
+	HeapFree( SystemHeap, 0, lpcbtcwA->lpcs );
+	HeapFree( SystemHeap, 0, lpcbtcwA );
+    }
+    return;
+}
+
+
+/***********************************************************************
+ *           Map Function Tables
+ */
+static const HOOK_MapFunc HOOK_MapFuncs[3][3] = 
+{
+    { NULL,            HOOK_Map16To32A,  HOOK_Map16To32W },
+    { HOOK_Map32ATo16, NULL,             HOOK_Map32ATo32W },
+    { HOOK_Map32WTo16, HOOK_Map32WTo32A, NULL }
+};
+
+static const HOOK_UnMapFunc HOOK_UnMapFuncs[3][3] = 
+{
+    { NULL,              HOOK_UnMap16To32A,  HOOK_UnMap16To32W },
+    { HOOK_UnMap32ATo16, NULL,               HOOK_UnMap32ATo32W },
+    { HOOK_UnMap32WTo16, HOOK_UnMap32WTo32A, NULL }
+};
+
+
+/***********************************************************************
+ *           Internal Functions
+ */
 
 /***********************************************************************
  *           HOOK_GetNextHook
@@ -49,9 +792,11 @@
 static HANDLE16 HOOK_GetNextHook( HANDLE16 hook )
 {
     HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR( hook );
+
     if (!data || !hook) return 0;
     if (data->next) return data->next;
     if (!data->ownerQueue) return 0;  /* Already system hook */
+
     /* Now start enumerating the system hooks */
     return HOOK_systemHooks[data->id - WH_MINHOOK];
 }
@@ -62,7 +807,7 @@
  *
  * Get the first hook for a given type.
  */
-HANDLE16 HOOK_GetHook( INT16 id , HQUEUE16 hQueue )
+static HANDLE16 HOOK_GetHook( INT16 id, HQUEUE16 hQueue )
 {
     MESSAGEQUEUE *queue;
     HANDLE16 hook = 0;
@@ -75,24 +820,12 @@
 
 
 /***********************************************************************
- *           HOOK_GetProc16
- */
-HOOKPROC16 HOOK_GetProc16( HHOOK hhook )
-{
-    HOOKDATA *data;
-    if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
-    if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
-    return data->proc;
-}
-
-
-/***********************************************************************
  *           HOOK_SetHook
  *
  * Install a given hook.
  */
-static HANDLE16 HOOK_SetHook( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
-                              HTASK16 hTask )
+static HANDLE16 HOOK_SetHook( INT16 id, LPVOID proc, INT32 type,
+			      HINSTANCE16 hInst, HTASK16 hTask )
 {
     HOOKDATA *data;
     HANDLE16 handle;
@@ -104,6 +837,8 @@
     dprintf_hook( stddeb, "Setting hook %d: %08x %04x %04x\n",
                   id, (UINT32)proc, hInst, hTask );
 
+    if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
+
     if (hTask)  /* Task-specific hook */
     {
 	if ((id == WH_JOURNALRECORD) || (id == WH_JOURNALPLAYBACK) ||
@@ -111,19 +846,6 @@
         if (!(hQueue = GetTaskQueue( hTask ))) return 0;
     }
 
-    if (id == WH_DEBUG)
-    {
-        fprintf( stdnimp,"WH_DEBUG is broken in 16-bit Windows.\n");
-        return 0;
-    }
-    else if (id == WH_CBT || id == WH_SHELL)
-    {
-	fprintf( stdnimp, "Half-implemented hook set: (%s,%08lx,%04x,%04x)!\n",
-                 (id==WH_CBT)?"WH_CBT":"WH_SHELL", (DWORD)proc, hInst, hTask );
-    }
-
-    if (id == WH_JOURNALPLAYBACK) EnableHardwareInput(FALSE);
-     
     /* Create the hook structure */
 
     if (!(handle = USER_HEAP_ALLOC( sizeof(HOOKDATA) ))) return 0;
@@ -133,6 +855,7 @@
     data->ownerQueue  = hQueue;
     data->ownerModule = hInst;
     data->inHookProc  = 0;
+    data->flags       = type;
 
     /* Insert it in the correct linked list */
 
@@ -170,7 +893,7 @@
     {
         /* Mark it for deletion later on */
         dprintf_hook( stddeb, "Hook still running, deletion delayed\n" );
-        data->proc = (HOOKPROC16)0;
+        data->proc = (HOOKPROC32)0;
         return TRUE;
     }
 
@@ -197,57 +920,144 @@
 
 
 /***********************************************************************
+ *           HOOK_FindValidHook
+ */
+static HANDLE16 HOOK_FindValidHook( HANDLE16 hook )
+{
+    HOOKDATA *data;
+
+    for (;;)
+    {
+	if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
+	if (data->proc) return hook;
+	hook = data->next;
+    }
+}
+
+
+/***********************************************************************
  *           HOOK_CallHook
  *
  * Call a hook procedure.
  */
-static LRESULT HOOK_CallHook( HANDLE16 hook, INT16 code,
-                              WPARAM16 wParam, LPARAM lParam )
+static LRESULT HOOK_CallHook( HANDLE16 hook, INT32 fromtype, INT32 code,
+                              WPARAM32 wParam, LPARAM lParam )
 {
-    HOOKDATA *data;
     MESSAGEQUEUE *queue;
     HANDLE16 prevHook;
+    HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
     LRESULT ret;
 
-    /* Find the first hook with a valid proc */
+    WPARAM32 wParamOrig = wParam;
+    LPARAM lParamOrig = lParam;
+    HOOK_MapFunc MapFunc;
+    HOOK_UnMapFunc UnMapFunc;
 
-    for (;;)
-    {
-        if (!hook) return 0;
-        if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook))) return 0;
-        if (data->proc) break;
-        hook = data->next;
-    }
+    MapFunc = HOOK_MapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
+    UnMapFunc = HOOK_UnMapFuncs[fromtype][data->flags & HOOK_MAPTYPE];
+
+    if (MapFunc)
+      MapFunc( data->id, code, &wParam, &lParam );
 
     /* Now call it */
 
     if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
     prevHook = queue->hCurHook;
     queue->hCurHook = hook;
-    data->inHookProc = 1;
+    data->inHookProc = TRUE;
 
-    dprintf_hook( stddeb, "Calling hook %04x: proc=%p %d %04lx %08lx\n",
-                  hook, data->proc, code, (DWORD)wParam, lParam );
-    ret = data->proc( code, wParam, lParam );
+    dprintf_hook( stddeb, "Calling hook %04x: %d %08x %08lx\n",
+                  hook, code, wParam, lParam );
+
+    ret = data->proc(code, wParam, lParam);
+
     dprintf_hook( stddeb, "Ret hook %04x = %08lx\n", hook, ret );
 
-    data->inHookProc = 0;
+    data->inHookProc = FALSE;
     queue->hCurHook = prevHook;
+
+    if (UnMapFunc)
+      UnMapFunc( data->id, code, wParamOrig, lParamOrig, wParam, lParam );
+
     if (!data->proc) HOOK_RemoveHook( hook );
+
     return ret;
 }
 
+/***********************************************************************
+ *           Exported Functions & APIs
+ */
+
+/***********************************************************************
+ *           HOOK_GetProc16
+ *
+ * Don't call this unless you are the if1632/thunk.c.
+ */
+HOOKPROC16 HOOK_GetProc16( HHOOK hhook )
+{
+    HOOKDATA *data;
+    if (HIWORD(hhook) != HOOK_MAGIC) return NULL;
+    if (!(data = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) ))) return NULL;
+    if (data->flags & HOOK_WIN32) return NULL;
+    return (HOOKPROC16)data->proc;
+}
+
 
 /***********************************************************************
- *           HOOK_CallHooks
+ *           HOOK_IsHooked
+ *
+ * Replacement for calling HOOK_GetHook from other modules.
+ */
+BOOL32 HOOK_IsHooked( INT16 id )
+{
+    return HOOK_GetHook( id, GetTaskQueue(0) ) != 0;
+}
+
+
+/***********************************************************************
+ *           HOOK_CallHooks16
  *
  * Call a hook chain.
  */
-LRESULT HOOK_CallHooks( INT16 id, INT16 code, WPARAM16 wParam, LPARAM lParam )
+LRESULT HOOK_CallHooks16( INT16 id, INT16 code, WPARAM16 wParam,
+                          LPARAM lParam )
 {
-    HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
-    if (!hook) return 0;
-    return HOOK_CallHook( hook, code, wParam, lParam );
+    HANDLE16 hook; 
+
+    if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
+    if (!(hook = HOOK_FindValidHook(hook))) return 0;
+    return HOOK_CallHook( hook, HOOK_WIN16, code, wParam, lParam );
+}
+
+/***********************************************************************
+ *           HOOK_CallHooks32A
+ *
+ * Call a hook chain.
+ */
+LRESULT HOOK_CallHooks32A( INT32 id, INT32 code, WPARAM32 wParam,
+                           LPARAM lParam )
+{
+    HANDLE16 hook; 
+
+    if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
+    if (!(hook = HOOK_FindValidHook(hook))) return 0;
+    return HOOK_CallHook( hook, HOOK_WIN32, code, wParam, lParam );
+}
+
+/***********************************************************************
+ *           HOOK_CallHooks32W
+ *
+ * Call a hook chain.
+ */
+LRESULT HOOK_CallHooks32W( INT32 id, INT32 code, WPARAM32 wParam,
+                           LPARAM lParam )
+{
+    HANDLE16 hook; 
+
+    if (!(hook = HOOK_GetHook( id , GetTaskQueue(0) ))) return 0;
+    if (!(hook = HOOK_FindValidHook(hook))) return 0;
+    return HOOK_CallHook( hook, HOOK_WIN32 | HOOK_UNICODE, code, wParam,
+			  lParam );
 }
 
 
@@ -342,19 +1152,133 @@
  */
 FARPROC16 SetWindowsHook16( INT16 id, HOOKPROC16 proc )
 {
-    HTASK16 	hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
-    HANDLE16 	handle = HOOK_SetHook( id, proc, 0, hTask );
+    HANDLE16 handle;
+    HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
 
+    /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
+    HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
+
+    if (id == WH_DEBUG)
+    {
+	fprintf( stdnimp, "WH_DEBUG is broken in 16-bit Windows.\n");
+	return 0;
+    }
+
+    handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
     return (handle) ? (FARPROC16)MAKELONG( handle, HOOK_MAGIC ) : NULL;
 }
 
 
 /***********************************************************************
+ *           SetWindowsHook32A   (USER32.524)
+ *
+ * FIXME: I don't know if this is correct
+ */
+HHOOK SetWindowsHook32A( INT32 id, HOOKPROC32 proc )
+{
+    HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
+
+    /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
+    HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
+
+    HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32, hInst, hTask );
+    return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
+}
+
+
+/***********************************************************************
+ *           SetWindowsHook32W   (USER32.527)
+ *
+ * FIXME: I don't know if this is correct
+ */
+HHOOK SetWindowsHook32W( INT32 id, HOOKPROC32 proc )
+{
+    HINSTANCE16 hInst = __winelib ? 0 : FarGetOwner( HIWORD(proc) );
+
+    /* WH_MSGFILTER is the only task-specific hook for SetWindowsHook() */
+    HTASK16 hTask = (id == WH_MSGFILTER) ? GetCurrentTask() : 0;
+
+    HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN32 | HOOK_UNICODE,
+				    hInst, hTask );
+    return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : 0;
+}
+
+
+/***********************************************************************
+ *           SetWindowsHookEx16   (USER.291)
+ */
+HHOOK SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
+			  HTASK16 hTask )
+{
+    HANDLE16 handle = HOOK_SetHook( id, proc, HOOK_WIN16, hInst, hTask );
+    return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
+}
+
+
+/***********************************************************************
+ *           SetWindowsHookEx32A   (USER32.525)
+ */
+HHOOK SetWindowsHookEx32A( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
+			   DWORD dwThreadID )
+{
+    HANDLE16 handle;
+    HTASK16 hTask;
+
+    if (dwThreadID == GetCurrentThreadId())
+      hTask = GetCurrentTask();
+    else
+      hTask = LOWORD(dwThreadID);
+
+    handle = HOOK_SetHook( id, proc, HOOK_WIN32, hInst, hTask );
+    return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
+}
+
+
+/***********************************************************************
+ *           SetWindowsHookEx32W   (USER32.526)
+ */
+HHOOK SetWindowsHookEx32W( INT32 id, HOOKPROC32 proc, HINSTANCE32 hInst,
+			   DWORD dwThreadID )
+{
+    HANDLE16 handle;
+    HTASK16 hTask;
+
+    if (dwThreadID == GetCurrentThreadId())
+      hTask = GetCurrentTask();
+    else
+      hTask = LOWORD(dwThreadID);
+
+    handle = HOOK_SetHook( id, proc, HOOK_WIN32 | HOOK_UNICODE, hInst, hTask );
+    return (handle) ? (HHOOK)MAKELONG( handle, HOOK_MAGIC ) : (HHOOK)NULL;
+}
+
+
+/***********************************************************************
  *           UnhookWindowsHook16   (USER.234)
  */
 BOOL16 UnhookWindowsHook16( INT16 id, HOOKPROC16 proc )
 {
-    HANDLE16 hook = HOOK_GetHook( id, GetTaskQueue(0) );
+    HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
+
+    dprintf_hook( stddeb, "UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc );
+
+    while (hook)
+    {
+        HOOKDATA *data = (HOOKDATA *)USER_HEAP_LIN_ADDR(hook);
+        if (data->proc == (HOOKPROC32)proc) break;
+        hook = HOOK_GetNextHook( hook );
+    }
+    if (!hook) return FALSE;
+    return HOOK_RemoveHook( hook );
+}
+
+
+/***********************************************************************
+ *           UnhookWindowsHook32   (USER32.556)
+ */
+BOOL32 UnhookWindowsHook32( INT32 id, HOOKPROC32 proc )
+{
+    HANDLE16 hook = HOOK_GetHook( id , GetTaskQueue(0) );
 
     dprintf_hook( stddeb, "UnhookWindowsHook: %d %08lx\n", id, (DWORD)proc );
 
@@ -370,45 +1294,7 @@
 
 
 /***********************************************************************
- *           DefHookProc   (USER.235)
- */
-LRESULT DefHookProc( INT16 code, WPARAM16 wParam, LPARAM lParam, HHOOK *hhook )
-{
-    /* Note: the *hhook parameter is never used, since we rely on the
-     * current hook value from the task queue to find the next hook. */
-    MESSAGEQUEUE *queue;
-    HANDLE16 next;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
-    if (!(next = HOOK_GetNextHook( queue->hCurHook ))) return 0;
-    return HOOK_CallHook( next, code, wParam, lParam );
-}
-
-
-/***********************************************************************
- *           CallMsgFilter   (USER.123)
- */
-BOOL16 CallMsgFilter( SEGPTR msg, INT16 code )
-{
-    if (GetSysModalWindow16()) return FALSE;
-    if (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
-    return HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg );
-}
-
-
-/***********************************************************************
- *           SetWindowsHookEx16   (USER.291)
- */
-HHOOK SetWindowsHookEx16( INT16 id, HOOKPROC16 proc, HINSTANCE16 hInst,
-                          HTASK16 hTask )
-{
-    HANDLE16 handle = HOOK_SetHook( id, proc, hInst, hTask );
-    return (handle) ? MAKELONG( handle, HOOK_MAGIC ) : NULL;
-}
-
-
-/***********************************************************************
- *           UnhookWindowsHookEx16   (USER.292)
+ *           UnhookWindowHookEx16   (USER.292)
  */
 BOOL16 UnhookWindowsHookEx16( HHOOK hhook )
 {
@@ -418,12 +1304,106 @@
 
 
 /***********************************************************************
- *           CallNextHookEx   (USER.293)
+ *           UnhookWindowHookEx32   (USER32.557)
  */
-LRESULT CallNextHookEx(HHOOK hhook, INT16 code, WPARAM16 wParam, LPARAM lParam)
+BOOL32 UnhookWindowsHookEx32( HHOOK hhook )
+{
+    return UnhookWindowsHookEx16( hhook );
+}
+
+
+/***********************************************************************
+ *           CallNextHookEx16     (USER.293)
+ *
+ * I wouldn't have separated this into 16 and 32 bit versions, but I
+ * need a way to figure out if I need to do a mapping or not.
+ */
+LRESULT CallNextHookEx16( HHOOK hhook, INT16 code, WPARAM16 wParam,
+			  LPARAM lParam )
 {
     HANDLE16 next;
+
     if (HIWORD(hhook) != HOOK_MAGIC) return 0;  /* Not a new format hook */
     if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
-    return HOOK_CallHook( next, code, wParam, lParam );
+
+    return HOOK_CallHook( next, HOOK_WIN16, code, wParam, lParam );
+}
+
+
+/***********************************************************************
+ *           CallNextHookEx32    (USER32.16)
+ *
+ * There aren't ANSI and UNICODE versions of this.
+ */
+LRESULT CallNextHookEx32( HHOOK hhook, INT32 code, WPARAM32 wParam,
+			  LPARAM lParam )
+{
+    HANDLE16 next;
+    INT32 fromtype;	/* figure out Ansi/Unicode */
+    HOOKDATA *oldhook;
+
+    if (HIWORD(hhook) != HOOK_MAGIC) return 0;  /* Not a new format hook */
+    if (!(next = HOOK_GetNextHook( LOWORD(hhook) ))) return 0;
+
+    oldhook = (HOOKDATA *)USER_HEAP_LIN_ADDR( LOWORD(hhook) );
+    fromtype = oldhook->flags & HOOK_MAPTYPE;
+
+    if (!(fromtype & HOOK_WIN32))
+      fprintf(stderr, "CallNextHookEx32: called from 16bit hook!\n");
+
+    return HOOK_CallHook( next, fromtype, code, wParam, lParam );
+}
+
+
+/***********************************************************************
+ *           DefHookProc16   (USER.235)
+ */
+LRESULT DefHookProc16( INT16 code, WPARAM16 wParam, LPARAM lParam,
+		       HHOOK *hhook )
+{
+    /* Note: the *hhook parameter is never used, since we rely on the
+     * current hook value from the task queue to find the next hook. */
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock16( GetTaskQueue(0) ))) return 0;
+    return CallNextHookEx16( queue->hCurHook, code, wParam, lParam );
+}
+
+
+/***********************************************************************
+ *           CallMsgFilter16   (USER.123)
+ */
+BOOL16 CallMsgFilter16( SEGPTR msg, INT16 code )
+{
+    if (GetSysModalWindow16()) return FALSE;
+    if (HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0, (LPARAM)msg )) return TRUE;
+    return HOOK_CallHooks16( WH_MSGFILTER, code, 0, (LPARAM)msg );
+}
+
+
+/***********************************************************************
+ *           CallMsgFilter32A   (USER32.14)
+ */
+/*
+ * FIXME: There are ANSI and UNICODE versions of this, plus an unspecified
+ * version, plus USER (the 16bit one) has a CallMsgFilter32 function.
+ */
+BOOL32 CallMsgFilter32A( LPMSG32 msg, INT32 code )
+{
+    if (GetSysModalWindow16()) return FALSE;	/* ??? */
+    if (HOOK_CallHooks32A( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
+      return TRUE;
+    return HOOK_CallHooks32A( WH_MSGFILTER, code, 0, (LPARAM)msg );
+}
+
+
+/***********************************************************************
+ *           CallMsgFilter32W   (USER32.15)
+ */
+BOOL32 CallMsgFilter32W( LPMSG32 msg, INT32 code )
+{
+    if (GetSysModalWindow16()) return FALSE;	/* ??? */
+    if (HOOK_CallHooks32W( WH_SYSMSGFILTER, code, 0, (LPARAM)msg ))
+      return TRUE;
+    return HOOK_CallHooks32W( WH_MSGFILTER, code, 0, (LPARAM)msg );
 }
diff --git a/windows/message.c b/windows/message.c
index 77ee2f9..05f8ad5 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -91,15 +91,15 @@
 	msg->lParam = MAKELONG( pt.x, pt.y );
         /* No need to further process the message */
 
-        if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
+        if (!HOOK_IsHooked( WH_MOUSE ) ||
             !(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
             return SYSQ_MSG_ACCEPT;
         hook->pt           = msg->pt;
         hook->hwnd         = msg->hwnd;
         hook->wHitTestCode = HTCLIENT;
         hook->dwExtraInfo  = 0;
-        ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
-                               msg->message, (LPARAM)SEGPTR_GET(hook));
+        ret = !HOOK_CallHooks16( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
+                                 msg->message, (LPARAM)SEGPTR_GET(hook));
         SEGPTR_FREE(hook);
         return ret ? SYSQ_MSG_ACCEPT : SYSQ_MSG_SKIP ;
     }
@@ -195,7 +195,7 @@
 
     /* Call the WH_MOUSE hook */
 
-    if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
+    if (!HOOK_IsHooked( WH_MOUSE ) ||
         !(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
         return SYSQ_MSG_ACCEPT;
 
@@ -203,8 +203,8 @@
     hook->hwnd         = msg->hwnd;
     hook->wHitTestCode = hittest;
     hook->dwExtraInfo  = 0;
-    ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
-                           msg->message, (LPARAM)SEGPTR_GET(hook) );
+    ret = !HOOK_CallHooks16( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
+                             msg->message, (LPARAM)SEGPTR_GET(hook) );
     SEGPTR_FREE(hook);
     return ret ? SYSQ_MSG_ACCEPT : SYSQ_MSG_SKIP;
 }
@@ -245,9 +245,9 @@
         if (queue) QUEUE_SetWakeBit( queue, QS_KEY );
         return SYSQ_MSG_ABANDON;
     }
-    return (HOOK_CallHooks( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
-                            msg->wParam, msg->lParam ))
-            ? SYSQ_MSG_SKIP : SYSQ_MSG_ACCEPT;
+    return (HOOK_CallHooks16( WH_KEYBOARD, remove ? HC_ACTION : HC_NOREMOVE,
+			      msg->wParam, msg->lParam )
+            ? SYSQ_MSG_SKIP : SYSQ_MSG_ACCEPT);
 }
 
 
@@ -268,16 +268,16 @@
         event->paramH = msg->lParam & 0x7FFF;  
         if (HIWORD(msg->lParam) & 0x0100)
             event->paramH |= 0x8000;               /* special_key - bit */
-        HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0,
-                        (LPARAM)SEGPTR_GET(event) );
+        HOOK_CallHooks16( WH_JOURNALRECORD, HC_ACTION, 0,
+                          (LPARAM)SEGPTR_GET(event) );
     }
     else if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
     {
         event->paramL = LOWORD(msg->lParam);       /* X pos */
         event->paramH = HIWORD(msg->lParam);       /* Y pos */ 
         ClientToScreen16( msg->hwnd, (LPPOINT16)&event->paramL );
-        HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0,
-                        (LPARAM)SEGPTR_GET(event) );
+        HOOK_CallHooks16( WH_JOURNALRECORD, HC_ACTION, 0,
+                          (LPARAM)SEGPTR_GET(event) );
     }
     else if ((msg->message >= WM_NCMOUSEFIRST) &&
              (msg->message <= WM_NCMOUSELAST))
@@ -285,8 +285,8 @@
         event->paramL = LOWORD(msg->lParam);       /* X pos */
         event->paramH = HIWORD(msg->lParam);       /* Y pos */ 
         event->message += WM_MOUSEMOVE-WM_NCMOUSEMOVE;/* give no info about NC area */
-        HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0,
-                        (LPARAM)SEGPTR_GET(event) );
+        HOOK_CallHooks16( WH_JOURNALRECORD, HC_ACTION, 0,
+                          (LPARAM)SEGPTR_GET(event) );
     }
     SEGPTR_FREE(event);
 }
@@ -302,10 +302,11 @@
  long wtime,lParam;
  WORD keyDown,i,wParam,result=0;
 
- if ( HOOK_GetHook(WH_JOURNALPLAYBACK, 0) )
+ if ( HOOK_IsHooked( WH_JOURNALPLAYBACK ) )
  {
   tmpMsg = SEGPTR_NEW(EVENTMSG16);
-  wtime=HOOK_CallHooks( WH_JOURNALPLAYBACK, HC_GETNEXT, 0, (LPARAM)SEGPTR_GET(tmpMsg));
+  wtime=HOOK_CallHooks16( WH_JOURNALPLAYBACK, HC_GETNEXT, 0,
+			  (LPARAM)SEGPTR_GET(tmpMsg));
   /*  dprintf_msg(stddeb,"Playback wait time =%ld\n",wtime); */
   if (wtime<=0)
   {
@@ -360,7 +361,8 @@
                      tmpMsg->paramL, tmpMsg->paramH, tmpMsg->time, 0 );
     }
    }
-   HOOK_CallHooks( WH_JOURNALPLAYBACK, HC_SKIP, 0, (LPARAM)SEGPTR_GET(tmpMsg));
+   HOOK_CallHooks16( WH_JOURNALPLAYBACK, HC_SKIP, 0,
+		     (LPARAM)SEGPTR_GET(tmpMsg));
   }
   else
     result= QS_MOUSE | QS_KEY;
@@ -412,9 +414,9 @@
                 hook->wMessage = msg->message;
                 hook->wParam   = msg->wParam;
                 hook->lParam   = msg->lParam;
-                ret = HOOK_CallHooks( WH_HARDWARE,
-                                      remove ? HC_ACTION : HC_NOREMOVE,
-                                      0, (LPARAM)SEGPTR_GET(hook) );
+                ret = HOOK_CallHooks16( WH_HARDWARE,
+                                        remove ? HC_ACTION : HC_NOREMOVE,
+                                        0, (LPARAM)SEGPTR_GET(hook) );
                 SEGPTR_FREE(hook);
                 status = ret ? SYSQ_MSG_SKIP : SYSQ_MSG_ACCEPT;
             }
@@ -434,7 +436,7 @@
             ((msg->message < first) || (msg->message > last))) continue;
         if (remove)
         {
-            if (HOOK_GetHook( WH_JOURNALRECORD, GetTaskQueue(0) ))
+            if (HOOK_IsHooked( WH_JOURNALRECORD ))
                 MSG_JournalRecordMsg( msg );
             QUEUE_RemoveMsg( sysMsgQueue, pos );
         }
@@ -776,18 +778,17 @@
 
         /* Call message filters */
 
-        if (HOOK_GetHook( WH_SYSMSGFILTER, GetTaskQueue(0) ) ||
-            HOOK_GetHook( WH_MSGFILTER, GetTaskQueue(0) ))
+        if (HOOK_IsHooked( WH_SYSMSGFILTER ) || HOOK_IsHooked( WH_MSGFILTER ))
         {
             MSG16 *pmsg = SEGPTR_NEW(MSG16);
             if (pmsg)
             {
                 BOOL32 ret;
                 *pmsg = *msg;
-                ret = ((BOOL16)HOOK_CallHooks( WH_SYSMSGFILTER, code, 0,
-                                               (LPARAM)SEGPTR_GET(pmsg) ) ||
-                       (BOOL16)HOOK_CallHooks( WH_MSGFILTER, code, 0,
-                                               (LPARAM)SEGPTR_GET(pmsg) ));
+                ret = ((BOOL16)HOOK_CallHooks16( WH_SYSMSGFILTER, code, 0,
+                                                 (LPARAM)SEGPTR_GET(pmsg) ) ||
+                       (BOOL16)HOOK_CallHooks16( WH_MSGFILTER, code, 0,
+                                                 (LPARAM)SEGPTR_GET(pmsg) ));
                 SEGPTR_FREE(pmsg);
                 if (ret)
                 {
@@ -826,7 +827,7 @@
 
     dprintf_msg(stddeb,"message %04x, hwnd %04x, filter(%04x - %04x)\n", lpmsg->message,
 		     				                 hwnd, first, last );
-    HOOK_CallHooks( WH_GETMESSAGE, HC_ACTION, 0, (LPARAM)msg );
+    HOOK_CallHooks16( WH_GETMESSAGE, HC_ACTION, 0, (LPARAM)msg );
     return (lpmsg->message != WM_QUIT);
 }
 
@@ -924,30 +925,30 @@
         return TRUE;
     }
 
-    if (HOOK_GetHook( WH_CALLWNDPROC, GetTaskQueue(0) ))
-    { 
-        struct msgstruct
-        {
-            LPARAM   lParam;
-            WPARAM16 wParam;
-            UINT16   wMsg;
-            HWND16   hWnd;
-        } *pmsg;
-        
-        if ((pmsg = SEGPTR_NEW(struct msgstruct)))
-        {
-            pmsg->hWnd   = hwnd;
-            pmsg->wMsg   = msg;
-            pmsg->wParam = wParam;
-            pmsg->lParam = lParam;
-            HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1,
-                            (LPARAM)SEGPTR_GET(pmsg) );
-            hwnd   = pmsg->hWnd;
-            msg    = pmsg->wMsg;
-            wParam = pmsg->wParam;
-            lParam = pmsg->lParam;
-            SEGPTR_FREE( pmsg );
-        }
+    if (HOOK_IsHooked( WH_CALLWNDPROC ))
+    {
+	struct msgstruct
+	{
+	    LPARAM   lParam;
+	    WPARAM16 wParam;
+	    UINT16   wMsg;
+	    HWND16   hWnd;
+	} *pmsg;
+
+	if ((pmsg = SEGPTR_NEW(struct msgstruct)))
+	{
+	    pmsg->hWnd   = hwnd;
+	    pmsg->wMsg   = msg;
+	    pmsg->wParam = wParam;
+	    pmsg->lParam = lParam;
+	    HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 1,
+			      (LPARAM)SEGPTR_GET(pmsg) );
+	    hwnd   = pmsg->hWnd;
+	    msg    = pmsg->wMsg;
+	    wParam = pmsg->wParam;
+	    lParam = pmsg->lParam;
+	    SEGPTR_FREE( pmsg );
+	}
     }
 
     if (!(wndPtr = WIN_FindWndPtr( hwnd )))
@@ -1134,7 +1135,7 @@
     {
 	if (msg->lParam)
         {
-/*            HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
+/*            HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
 	    return CallWindowProc16( (WNDPROC16)msg->lParam, msg->hwnd,
                                    msg->message, msg->wParam, GetTickCount() );
         }
@@ -1145,7 +1146,7 @@
     if (!wndPtr->winproc) return 0;
     painting = (msg->message == WM_PAINT);
     if (painting) wndPtr->flags |= WIN_NEEDS_BEGINPAINT;
-/*    HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
+/*    HOOK_CallHooks16( WH_CALLWNDPROC, HC_ACTION, 0, FIXME ); */
 
     SPY_EnterMessage( SPY_DISPATCHMESSAGE16, msg->hwnd, msg->message,
                       msg->wParam, msg->lParam );
diff --git a/windows/nonclient.c b/windows/nonclient.c
index d7f70cb..423cb4f 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -1149,14 +1149,14 @@
 	if (rootWindow == DefaultRootWindow(display)) XUngrabServer( display );
     }
 
-    if (HOOK_GetHook( WH_CBT, GetTaskQueue(0) ))
+    if (HOOK_IsHooked( WH_CBT ))
     {
        RECT16* pr = SEGPTR_NEW(RECT16);
        if( pr )
        {
 	 *pr = sizingRect;
-	  if( HOOK_CallHooks( WH_CBT, HCBT_MOVESIZE, hwnd,
-			             (LPARAM)SEGPTR_GET(pr)) )
+	  if( HOOK_CallHooks16( WH_CBT, HCBT_MOVESIZE, hwnd,
+			        (LPARAM)SEGPTR_GET(pr)) )
 	      sizingRect = wndPtr->rectWindow;
 	  else
 	      sizingRect = *pr;
diff --git a/windows/win.c b/windows/win.c
index 2b48de3..56cfa04 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -579,36 +579,20 @@
 
     hwndLinkAfter = (cs->style & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
 
-    if (HOOK_GetHook( WH_CBT, GetTaskQueue(0) ))
+    if (HOOK_IsHooked( WH_CBT ))
     {
-        CBT_CREATEWND16* cbtc;
+	CBT_CREATEWND32A cbtc;
 
-        if ((cbtc = SEGPTR_NEW(CBT_CREATEWND16)))
-        {
-            /* Dummy message params to use WINPROC_MapMsg functions */
-            UINT16 msg;
-            WPARAM16 wparam;
-            LPARAM lparam;
-
-            /* Map the CREATESTRUCT to 16-bit format */
-            lparam = (LPARAM)cs;
-            if (unicode)
-                WINPROC_MapMsg32WTo16( WM_CREATE, 0, &msg, &wparam, &lparam );
-            else
-                WINPROC_MapMsg32ATo16( WM_CREATE, 0, &msg, &wparam, &lparam );
-            cbtc->lpcs = (CREATESTRUCT16 *)lparam;
-            cbtc->hwndInsertAfter = hwndLinkAfter;
-            wmcreate = !HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, hwnd,
-                                        (LPARAM)SEGPTR_GET(cbtc) );
-            WINPROC_UnmapMsg32ATo16( WM_CREATE, 0, lparam );
-            SEGPTR_FREE(cbtc);
-            if (!wmcreate)
-            {
-                dprintf_win(stddeb,"CreateWindowEx: CBT-hook returned 0\n" );
-                USER_HEAP_FREE( hwnd );
-                return 0;
-            }
-        }
+	cbtc.lpcs = cs;
+	cbtc.hwndInsertAfter = hwndLinkAfter;
+	wmcreate = !HOOK_CallHooks32A( WH_CBT, HCBT_CREATEWND, hwnd,
+				       (LPARAM)&cbtc );
+	if (!wmcreate)
+	{
+	    dprintf_win(stddeb, "CreateWindowEx: CBT-hook returned 0\n");
+	    USER_HEAP_FREE( hwnd );
+	    return 0;
+	}
     }
 
     /* Set the window procedure */
@@ -817,7 +801,7 @@
     /* Call WH_SHELL hook */
 
     if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
-        HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
+        HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWCREATED, hwnd, 0 );
 
     dprintf_win(stddeb, "CreateWindowEx: returning %04x\n", hwnd);
     return hwnd;
@@ -1019,12 +1003,12 @@
 
       /* Call hooks */
 
-    if( HOOK_CallHooks( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
+    if( HOOK_CallHooks16( WH_CBT, HCBT_DESTROYWND, hwnd, 0L) )
         return FALSE;
 
     if (!(wndPtr->dwStyle & WS_CHILD) && !wndPtr->owner)
     {
-        HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
+        HOOK_CallHooks16( WH_SHELL, HSHELL_WINDOWDESTROYED, hwnd, 0L );
         /* FIXME: clean up palette - see "Internals" p.352 */
     }
 
@@ -1406,6 +1390,7 @@
     {
 	case GWW_ID:        ptr = (WORD *)&wndPtr->wIDmenu; break;
 	case GWW_HINSTANCE: ptr = (WORD *)&wndPtr->hInstance; break;
+	case GWW_HWNDPARENT: return SetParent( hwnd, newval );
 	default:
             fprintf( stderr, "SetWindowWord: invalid offset %d\n", offset );
             return 0;
diff --git a/windows/winpos.c b/windows/winpos.c
index 81a727e..3142e14 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -595,7 +595,7 @@
             swpflags |= SWP_FRAMECHANGED;
             if (!(wndPtr->dwStyle & WS_MINIMIZE))
             {
-		if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+		if( HOOK_CallHooks16( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
 		    return 0;
 
                 if (wndPtr->dwStyle & WS_MAXIMIZE)
@@ -623,7 +623,7 @@
             swpflags |= SWP_SHOWWINDOW | SWP_FRAMECHANGED;
             if (!(wndPtr->dwStyle & WS_MAXIMIZE))
             {
-		if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+		if( HOOK_CallHooks16( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
 		    return 0;
 
                   /* Store the current position and find the maximized size */
@@ -669,7 +669,7 @@
 
             if (wndPtr->dwStyle & WS_MINIMIZE)
             {
-		if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+		if( HOOK_CallHooks16( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
 		    return 0;
 
                 if( !SendMessage16( hwnd, WM_QUERYOPEN, 0, 0L) )
@@ -702,7 +702,7 @@
             }
             else if (wndPtr->dwStyle & WS_MAXIMIZE)
             {
-		if( HOOK_CallHooks( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
+		if( HOOK_CallHooks16( WH_CBT, HCBT_MINMAX, hwnd, cmd) )
 		    return 0;
 
                 wndPtr->ptMaxPos.x = wndPtr->rectWindow.left;
@@ -962,8 +962,8 @@
         LRESULT wRet;
         cbtStruct->fMouse     = fMouse;
         cbtStruct->hWndActive = hwndActive;
-        wRet = HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
-                               (LPARAM)SEGPTR_GET(cbtStruct) );
+        wRet = HOOK_CallHooks16( WH_CBT, HCBT_ACTIVATE, (WPARAM16)hWnd,
+                                 (LPARAM)SEGPTR_GET(cbtStruct) );
         SEGPTR_FREE(cbtStruct);
         if (wRet) return wRet;
     }