Release 960314

Wed Mar 13 19:46:50 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [controls/edit.c]
	Removed calls to memmove (not portable).

	* [debugger/dbg.y] [debugger/debug.l]
	Prefixed all token with 't' to avoid conflicts with type
	definitions.
	Added 'walk queue', 'walk class' and 'info class' commands.

	* [debugger/info.c]
	Moved queue and window information functions to windows/queue.c
	and windows/win.c respectively.

	* [loader/signal.c]
	Added SIGHUP handling to force entry into built-in debugger.
	Cleaned up a bit.

	* [misc/spy.c]
	General cleanup and performance improvements.

	* [windows/class.c]
	Added CLASS_DumpClass() and CLASS_WalkClasses() functions for
	debugger.

	* [windows/event.c]
	Pressing Ctrl-Alt-Return forces an entry into the debugger. Not
	sure if this key combination is a good choice...

	* [windows/message.c] [windows/queue.c] (New file)
	Moved message queue handling functions to windows/queue.c.

Tue Mar 12 14:55:16 1996  Onno Hovers  <onno@stack.urc.tue.nl>

	* [if1632/except.S] [include/except.h] [win32/except.c] (New files)
	Implemented Win32 exception functions: RaiseException(),
 	RtlUnwind(), SetUnhandledExceptionFilter() and
	UnhandledExceptionFilter().

Mon Mar 11 19:23:29 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [controls/listbox.c] [include/listbox.h]
	Special handling for COMBOLBOX styles introduced via extension of
 	HEADLIST structure: lphl->dwStyle.

Mon Mar 11 13:31:06 1996  Greg Kreider <kreider@natlab.research.philips.com>

	* [controls/combo.c]
	Any mouse movement within a small distance (defined by CBLMM_EDGE)
	of the top or bottom edge causes the window to scroll.  Also moved 
	some assignments so the routine works correctly.

	* [controls/listbox.c]
	Changing selection in ListBoxSetCurSel now updates PrevFocused.
	Added to LBSetFont and CreateListBoxStruct a fake hdc that tests 
	and sets the standard text height.

Sun Mar 10 08:39:23 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/dce.c]
	Fixed memory leak in DCE_ClipWindows().
diff --git a/ANNOUNCE b/ANNOUNCE
index db46d6a..e9201d2 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,13 @@
-This is release 960309 of Wine the MS Windows emulator.  This is still a
+This is release 960314 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.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-960309: (see ChangeLog for details)
-	- More edit control improvements.
-	- Help begins to work.
-	- Internal LZEXPAND.DLL.
+WHAT'S NEW with Wine-960314: (see ChangeLog for details)
+	- Many combo and listbox fixes.
+	- Win32 exception handling.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -17,10 +16,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960309.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960309.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960309.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960309.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960314.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960314.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960314.tar.gz
+    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960314.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 3191e3e..9374983 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,67 @@
 ----------------------------------------------------------------------
+Wed Mar 13 19:46:50 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [controls/edit.c]
+	Removed calls to memmove (not portable).
+
+	* [debugger/dbg.y] [debugger/debug.l]
+	Prefixed all token with 't' to avoid conflicts with type
+	definitions.
+	Added 'walk queue', 'walk class' and 'info class' commands.
+
+	* [debugger/info.c]
+	Moved queue and window information functions to windows/queue.c
+	and windows/win.c respectively.
+
+	* [loader/signal.c]
+	Added SIGHUP handling to force entry into built-in debugger.
+	Cleaned up a bit.
+
+	* [misc/spy.c]
+	General cleanup and performance improvements.
+
+	* [windows/class.c]
+	Added CLASS_DumpClass() and CLASS_WalkClasses() functions for
+	debugger.
+
+	* [windows/event.c]
+	Pressing Ctrl-Alt-Return forces an entry into the debugger. Not
+	sure if this key combination is a good choice...
+
+	* [windows/message.c] [windows/queue.c] (New file)
+	Moved message queue handling functions to windows/queue.c.
+
+Tue Mar 12 14:55:16 1996  Onno Hovers  <onno@stack.urc.tue.nl>
+
+	* [if1632/except.S] [include/except.h] [win32/except.c] (New files)
+	Implemented Win32 exception functions: RaiseException(),
+ 	RtlUnwind(), SetUnhandledExceptionFilter() and
+	UnhandledExceptionFilter().
+
+Mon Mar 11 19:23:29 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [controls/listbox.c] [include/listbox.h]
+	Special handling for COMBOLBOX styles introduced via extension of
+ 	HEADLIST structure: lphl->dwStyle.
+
+Mon Mar 11 13:31:06 1996  Greg Kreider <kreider@natlab.research.philips.com>
+
+	* [controls/combo.c]
+	Any mouse movement within a small distance (defined by CBLMM_EDGE)
+	of the top or bottom edge causes the window to scroll.  Also moved 
+	some assignments so the routine works correctly.
+
+	* [controls/listbox.c]
+	Changing selection in ListBoxSetCurSel now updates PrevFocused.
+	Added to LBSetFont and CreateListBoxStruct a fake hdc that tests 
+	and sets the standard text height.
+
+Sun Mar 10 08:39:23 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>
+
+	* [windows/dce.c]
+	Fixed memory leak in DCE_ClipWindows().
+
+----------------------------------------------------------------------
 Fri Mar  8 19:07:18 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [configure.in]
@@ -69,6 +132,11 @@
 	* [include/wintypes.h]
 	Added "#define __export".
 
+	* [objects/bitblt.c]
+	Put in a few hacks to make bitblt-ing work when upside-down and/or
+	mirrored.  BITBLT_StretchImage should really be checked over
+	thoroughly.
+
 	* [programs/progman/main.c]
 	Added "#include <resource.h>" for definition of HAVE_WINE_CONSTRUCTOR.
 
diff --git a/configure b/configure
index 2ad3415..4e497a1 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.7 
+# Generated automatically using autoconf version 2.8 
 # Copyright (C) 1992, 1993, 1994 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.7"
+    echo "configure generated by autoconf version 2.8"
     exit 0 ;;
 
   -with-* | --with-*)
@@ -506,12 +506,9 @@
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='echo $CPP $CPPFLAGS 1>&5;
-$CPP $CPPFLAGS'
-ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5;
-${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
-ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5;
-${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
+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'
 
 if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
   # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
@@ -644,7 +641,6 @@
     fi
   done
   IFS="$ac_save_ifs"
-  test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc"
 fi
 fi
 CC="$ac_cv_prog_CC"
@@ -654,6 +650,55 @@
   echo "$ac_t""no" 1>&6
 fi
 
+if test -z "$CC"; then
+  # 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
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  ac_prog_rejected=no
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
@@ -664,7 +709,7 @@
   yes;
 #endif
 EOF
-if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:713: \"$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
@@ -716,12 +761,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 720 "configure"
+#line 765 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:771: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -730,12 +776,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 734 "configure"
+#line 780 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:786: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   :
@@ -787,17 +834,20 @@
   :
 fi
 
+# $have_x is `yes', `no', `disabled', or empty when we do not yet know.
 if test "x$with_x" = xno; then
-  no_x=yes
+  # The user explicitly disabled X.
+  have_x=disabled
 else
   if test "x$x_includes" != xNONE && test "x$x_libraries" != xNONE; then
-    no_x=
+    # Both variables are already set.
+    have_x=yes
   else
-if eval "test \"`echo '$''{'ac_cv_path_x'+set}'`\" = set"; then
+if eval "test \"`echo '$''{'ac_cv_have_x'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   # One or both of the vars are not set, and there is no cached value.
-no_x=yes
+ac_x_includes=NO ac_x_libraries=NO
 rm -fr conftestdir
 if mkdir conftestdir; then
   cd conftestdir
@@ -807,7 +857,6 @@
 	@echo 'ac_im_incroot="${INCROOT}"; ac_im_usrlibdir="${USRLIBDIR}"; ac_im_libdir="${LIBDIR}"'
 EOF
   if (xmkmf) >/dev/null 2>/dev/null && test -f Makefile; then
-    no_x=
     # GNU make sometimes prints "make[1]: Entering...", which would confuse us.
     eval `${MAKE-make} acfindx 2>/dev/null | grep -v make`
     # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR.
@@ -831,24 +880,28 @@
   rm -fr conftestdir
 fi
 
-if test "$no_x" = yes; then
-test -z "$x_direct_test_library" && x_direct_test_library=Xt
-test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
-test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+if test "$ac_x_includes" = NO; then
+  # Guess where to find include files, by looking for this one X11 .h file.
+  test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
+
+  # First, try using that file with no special directory specified.
 cat > conftest.$ac_ext <<EOF
-#line 840 "configure"
+#line 890 "configure"
 #include "confdefs.h"
 #include <$x_direct_test_include>
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:895: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
-  no_x= ac_x_includes=
+  # We can compile using X headers with no special include directory.
+ac_x_includes=
 else
   echo "$ac_err" >&5
   rm -rf conftest*
-    for ac_dir in               \
+  # Look for the header file in a standard set of common directories.
+  for ac_dir in               \
     /usr/X11R6/include        \
     /usr/X11R5/include        \
     /usr/X11R4/include        \
@@ -886,20 +939,26 @@
     ; \
   do
     if test -r "$ac_dir/$x_direct_test_include"; then
-      no_x= ac_x_includes=$ac_dir
+      ac_x_includes=$ac_dir
       break
     fi
   done
 fi
 rm -f conftest*
+fi # $ac_x_includes = NO
 
-# Check for the libraries.
-# See if we find them without any special options.
-# Don't add to $LIBS permanently.
-ac_save_LIBS="$LIBS"
-LIBS="-l$x_direct_test_library $LIBS"
+if test "$ac_x_libraries" = NO; then
+  # Check for the libraries.
+
+  test -z "$x_direct_test_library" && x_direct_test_library=Xt
+  test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
+
+  # See if we find them without any special options.
+  # Don't add to $LIBS permanently.
+  ac_save_LIBS="$LIBS"
+  LIBS="-l$x_direct_test_library $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 903 "configure"
+#line 962 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -907,9 +966,11 @@
 ${x_direct_test_function}()
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:970: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
-  LIBS="$ac_save_LIBS" no_x= ac_x_libraries=
+  LIBS="$ac_save_LIBS"
+# We can link X programs with no special library path.
+ac_x_libraries=
 else
   rm -rf conftest*
   LIBS="$ac_save_LIBS"
@@ -953,7 +1014,7 @@
 do
   for ac_extension in a so sl; do
     if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then
-      no_x= ac_x_libraries=$ac_dir
+      ac_x_libraries=$ac_dir
       break 2
     fi
   done
@@ -961,27 +1022,35 @@
 fi
 rm -f conftest*
 
-fi
-if test "$no_x" = yes; then
-  ac_cv_path_x="no_x=yes"
+fi # $ac_x_libraries = NO
+
+if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then
+  # Didn't find X anywhere.  Cache the known absence of X.
+  ac_cv_have_x="have_x=no"
 else
-  ac_cv_path_x="no_x= ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
+  # Record where we found X for the cache.
+  ac_cv_have_x="have_x=yes \
+	        ac_x_includes=$ac_x_includes ac_x_libraries=$ac_x_libraries"
 fi
 fi
   fi
-  eval "$ac_cv_path_x"
+  eval "$ac_cv_have_x"
 fi # $with_x != no
 
-if test "$no_x" = yes; then
-  echo "$ac_t""no" 1>&6
+if test "$have_x" != yes; then
+  echo "$ac_t""$have_x" 1>&6
+  no_x=yes
 else
+  # If each of the values was on the command line, it overrides each guess.
   test "x$x_includes" = xNONE && x_includes=$ac_x_includes
   test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries
-  ac_cv_path_x="no_x= ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
+  # Update the cache value to reflect the command line values.
+  ac_cv_have_x="have_x=yes \
+		ac_x_includes=$x_includes ac_x_libraries=$x_libraries"
   echo "$ac_t""libraries $x_libraries, headers $x_includes" 1>&6
 fi
 
-if test "$no_x" = yes; then 
+if test "$no_x" = yes; then
   # Not all programs may use this symbol, but it does not hurt to define it.
   X_CFLAGS="$X_CFLAGS -DX_DISPLAY_MISSING"
 else
@@ -1011,14 +1080,14 @@
   # libraries we check for below, so use a different variable.
   #  --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
   echo $ac_n "checking for -lICE""... $ac_c" 1>&6
-ac_lib_var=`echo ICE | tr '.-/+' '___p'`
+ac_lib_var=`echo ICE_IceConnectionNumber | tr '.-/+' '___p'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lICE  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1022 "configure"
+#line 1091 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1026,7 +1095,7 @@
 IceConnectionNumber()
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1099: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1055,14 +1124,14 @@
     # 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 -ldnet""... $ac_c" 1>&6
-ac_lib_var=`echo dnet | tr '.-/+' '___p'`
+ac_lib_var=`echo dnet_dnet_ntoa | tr '.-/+' '___p'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1066 "configure"
+#line 1135 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1070,7 +1139,7 @@
 dnet_ntoa()
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1143: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1090,14 +1159,14 @@
 
     if test $ac_cv_lib_dnet = no; then
       echo $ac_n "checking for -ldnet_stub""... $ac_c" 1>&6
-ac_lib_var=`echo dnet_stub | tr '.-/+' '___p'`
+ac_lib_var=`echo dnet_stub_dnet_ntoa | tr '.-/+' '___p'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet_stub  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1101 "configure"
+#line 1170 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1105,7 +1174,7 @@
 dnet_ntoa()
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1178: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1130,14 +1199,14 @@
     # Not sure which flavor of 386 UNIX this is, but it seems harmless to
     # check for it.
     echo $ac_n "checking for -lnsl""... $ac_c" 1>&6
-ac_lib_var=`echo nsl | tr '.-/+' '___p'`
+ac_lib_var=`echo nsl_t_accept | tr '.-/+' '___p'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1141 "configure"
+#line 1210 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1145,7 +1214,7 @@
 t_accept()
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1169,14 +1238,14 @@
     # But -lsocket is broken on IRIX, according to simon@lia.di.epfl.ch.
     if test "`(uname) 2>/dev/null`" != IRIX; then
       echo $ac_n "checking for -lsocket""... $ac_c" 1>&6
-ac_lib_var=`echo socket | tr '.-/+' '___p'`
+ac_lib_var=`echo socket_socket | tr '.-/+' '___p'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1180 "configure"
+#line 1249 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1184,7 +1253,7 @@
 socket()
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1257: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1274,14 +1343,14 @@
   *) ac_lib=l ;;
   esac
   echo $ac_n "checking for -l$ac_lib""... $ac_c" 1>&6
-ac_lib_var=`echo $ac_lib | tr '.-/+' '___p'`
+ac_lib_var=`echo $ac_lib_yywrap | tr '.-/+' '___p'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-l$ac_lib  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1285 "configure"
+#line 1354 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1289,7 +1358,7 @@
 yywrap()
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1397,14 +1466,14 @@
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking for -li386""... $ac_c" 1>&6
-ac_lib_var=`echo i386 | tr '.-/+' '___p'`
+ac_lib_var=`echo i386_i386_set_ldt | tr '.-/+' '___p'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-li386  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1408 "configure"
+#line 1477 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1412,7 +1481,7 @@
 i386_set_ldt()
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1444,11 +1513,11 @@
   ac_cv_c_cross=yes
 else
 cat > conftest.$ac_ext <<EOF
-#line 1448 "configure"
+#line 1517 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
-eval $ac_link
+{ (eval echo configure:1521: \"$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
@@ -1469,7 +1538,7 @@
   ac_cv_c_gcc_strength_bug="yes"
 else
 cat > conftest.$ac_ext <<EOF
-#line 1473 "configure"
+#line 1542 "configure"
 #include "confdefs.h"
 
 int main(void) {
@@ -1480,7 +1549,7 @@
   exit( Array[1] != -2 );
 }
 EOF
-eval $ac_link
+{ (eval echo configure:1553: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
   ac_cv_c_gcc_strength_bug="no"
 else
@@ -1505,7 +1574,7 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1509 "configure"
+#line 1578 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -1527,7 +1596,7 @@
 
 ; return 0; }
 EOF
-if eval $ac_link; then
+if { (eval echo configure:1600: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -1557,11 +1626,12 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1561 "configure"
+#line 1630 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1635: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1590,7 +1660,7 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1594 "configure"
+#line 1664 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1645,7 +1715,7 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1649 "configure"
+#line 1719 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1695,7 +1765,7 @@
 
 ; return 0; }
 EOF
-if eval $ac_compile; then
+if { (eval echo configure:1769: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1719,14 +1789,15 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1723 "configure"
+#line 1793 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
 #include <string.h>
 #include <float.h>
 EOF
-eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1801: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1741,7 +1812,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 1745 "configure"
+#line 1816 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1759,7 +1830,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 1763 "configure"
+#line 1834 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1780,7 +1851,7 @@
   :
 else
 cat > conftest.$ac_ext <<EOF
-#line 1784 "configure"
+#line 1855 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1791,7 +1862,7 @@
 exit (0); }
 
 EOF
-eval $ac_link
+{ (eval echo configure:1866: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }
 if test -s conftest && (./conftest; exit) 2>/dev/null; then
   :
 else
@@ -1815,7 +1886,7 @@
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1819 "configure"
+#line 1890 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1899,7 +1970,7 @@
 # Protect against shell expansion while executing Makefile rules.
 # Protect against Makefile macro expansion.
 cat > conftest.defs <<\EOF
-s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%-D\1=\2%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
 s%[ 	`~#$^&*(){}\\|;'"<>?]%\\&%g
 s%\[%\\&%g
 s%\]%\\&%g
@@ -1934,7 +2005,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.7"
+    echo "$CONFIG_STATUS generated by autoconf version 2.8"
     exit 0 ;;
   -help | --help | --hel | --he | --h)
     echo "\$ac_cs_usage"; exit 0 ;;
diff --git a/controls/combo.c b/controls/combo.c
index 6cc8eae..338c0c8 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -32,6 +32,9 @@
   * I hope no programs rely on the implementation of combos.
   */
 
+#define CBLMM_EDGE   4    /* distance inside box which is same as moving mouse
+			     outside box, to trigger scrolling of CBL */
+
 static HBITMAP hComboBit = 0;
 static WORD CBitHeight, CBitWidth;
 
@@ -470,6 +473,8 @@
 
   wRet = ListBoxSetCurSel(lphl, wParam);
 
+  dprintf_combo(stddeb,"CBSetCurSel: hwnd "NPFMT" wp %x lp %lx wRet %d\n",
+		hwnd,wParam,lParam,wRet);
 /*  SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);*/
   InvalidateRect(hwnd, NULL, TRUE);
 
@@ -877,37 +882,41 @@
 static LRESULT CBLMouseMove( HWND hwnd, WPARAM wParam, LPARAM lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
-  int  y;
+  short y;
   WORD wRet;
-  RECT rect, rectsel;   /* XXX Broken */
+  RECT rect, rectsel;
 
+  y = SHIWORD(lParam);
+  wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
+  ListBoxGetItemRect(lphl, wRet, &rectsel);
+  GetClientRect(hwnd, &rect);
+
+  dprintf_combo(stddeb,"CBLMouseMove: hwnd "NPFMT" wp %x lp %lx  y %d  if %d wret %d %d,%d-%d,%d\n",
+hwnd,wParam,lParam,y,lphl->ItemFocused,wRet,rectsel.left,rectsel.top,rectsel.right,rectsel.bottom);
+  
   if ((wParam & MK_LBUTTON) != 0) {
-    y = SHIWORD(lParam);
-    if (y < 0) {
+    if (y < CBLMM_EDGE) {
       if (lphl->FirstVisible > 0) {
 	lphl->FirstVisible--;
 	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+	ListBoxSetCurSel(lphl, wRet);
 	InvalidateRect(hwnd, NULL, TRUE);
 	return 0;
       }
     }
-    GetClientRect(hwnd, &rect);
-    if (y >= rect.bottom) {
+    else if (y >= (rect.bottom-CBLMM_EDGE)) {
       if (lphl->FirstVisible < ListMaxFirstVisible(lphl)) {
 	lphl->FirstVisible++;
 	SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
+	ListBoxSetCurSel(lphl, wRet);
 	InvalidateRect(hwnd, NULL, TRUE);
 	return 0;
       }
     }
-    if ((y > 0) && (y < (rect.bottom - 4))) {
-      if ((y < rectsel.top) || (y > rectsel.bottom)) {
-	wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
-	if (wRet == lphl->ItemFocused) return 0;
-	ListBoxSetCurSel(lphl, wRet);
-	ListBoxGetItemRect(lphl, wRet, &rectsel);
-	InvalidateRect(hwnd, NULL, TRUE);
-      }
+    else {
+      if ((short) wRet == lphl->ItemFocused) return 0;
+      ListBoxSetCurSel(lphl, wRet);
+      InvalidateRect(hwnd, NULL, TRUE);
     }
   }
 
diff --git a/controls/edit.c b/controls/edit.c
index 04db65b..9eeb811 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -1757,7 +1757,7 @@
 {
     int plen;
     EDITSTATE *es = EDIT_GetEditState(hwnd);
-    char *text = EDIT_HeapLock(hwnd, es->hText);
+    char *p, *text = EDIT_HeapLock(hwnd, es->hText);
     
     plen = strlen(text) + len;
     if (plen + 1 > es->textlen)
@@ -1767,7 +1767,7 @@
       text = EDIT_HeapLock(hwnd, es->hText);
       es->textlen = plen + 1;
     }
-    memmove(CurrChar + len, CurrChar, strlen(CurrChar) + 1);
+    for (p = CurrChar + strlen(CurrChar); p >= CurrChar; p--) p[len] = *p;
     memcpy(CurrChar, str, len);
 
     EDIT_BuildTextPointers(hwnd);
@@ -1834,7 +1834,7 @@
 {
     EDITSTATE *es = EDIT_GetEditState(hwnd);
     char *text = EDIT_HeapLock(hwnd, es->hText);
-    char *currchar;
+    char *currchar, *p;
     RECT rc;
     BOOL FullPaint = FALSE;
 
@@ -1890,14 +1890,14 @@
     /* make space for new character and put char in buffer */
     if (ch == '\n')
     {
-	memmove(currchar + 2, currchar, strlen(currchar) + 1);
+        for (p = currchar + strlen(currchar); p >= currchar; p--) p[2] = p[0];
 	*currchar = '\r';
 	*(currchar + 1) = '\n';
 	EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 2);
     }
     else
     {
-	memmove(currchar + 1, currchar, strlen(currchar) + 1);
+        for (p = currchar + strlen(currchar); p >= currchar; p--) p[1] = p[0];
 	*currchar = ch;
 	EDIT_ModTextPointers(hwnd, es->CurrLine + 1, 1);
     }
diff --git a/controls/listbox.c b/controls/listbox.c
index 3365cde..e255cbd 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -78,6 +78,7 @@
 void CreateListBoxStruct(HWND hwnd, WORD CtlType, LONG styles, HWND parent)
 {
   LPHEADLIST lphl;
+  HDC         hdc;
 
   lphl = (LPHEADLIST)xmalloc(sizeof(HEADLIST));
   SetWindowLong(hwnd, 0, (LONG)lphl);
@@ -89,11 +90,27 @@
   lphl->TabStops       = NULL;
   lphl->hFont          = GetStockObject(SYSTEM_FONT);
   lphl->hSelf          = hwnd;  
+  if (CtlType==ODT_COMBOBOX)              /* use the "faked" style for COMBOLBOX */
+                                          /* LBS_SORT instead CBS_SORT e.g.      */
+    lphl->dwStyle   = MAKELONG(LOWORD(styles),HIWORD(GetWindowLong(hwnd,GWL_STYLE)));
+  else
+    lphl->dwStyle   = GetWindowLong(hwnd,GWL_STYLE); /* use original style dword */
   lphl->hParent        = parent;
   lphl->StdItemHeight  = 15; /* FIXME: should get the font height */
   lphl->OwnerDrawn     = styles & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE);
   lphl->HasStrings     = (styles & LBS_HASSTRINGS) || !lphl->OwnerDrawn;
 
+  /* create dummy hdc to set text height */
+  if ((hdc = GetDC(0)))
+  {
+      TEXTMETRIC tm;
+      GetTextMetrics( hdc, &tm );
+      lphl->StdItemHeight = tm.tmHeight;
+      dprintf_listbox(stddeb,"CreateListBoxStruct:  font height %d\n",
+                      lphl->StdItemHeight);
+      ReleaseDC( 0, hdc );
+  }
+
   if (lphl->OwnerDrawn) {
     LISTSTRUCT dummyls;
     
@@ -143,9 +160,7 @@
    has the LBS_NOTIFY style */
 void ListBoxSendNotification(LPHEADLIST lphl, WORD code)
 {
-  DWORD dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
-
-  if (dwStyle & LBS_NOTIFY)
+  if (lphl->dwStyle & LBS_NOTIFY)
 #ifdef WINELIB32
     SendMessage(lphl->hParent, WM_COMMAND,
 		MAKEWPARAM(lphl->CtlID,code), (LPARAM)lphl->hSelf);
@@ -223,8 +238,6 @@
 void ListBoxDrawItem (HWND hwnd, LPHEADLIST lphl, HDC hdc, LPLISTSTRUCT lpls, 
 		      RECT *rect, WORD itemAction, WORD itemState)
 {
-  LONG dwStyle = GetWindowLong(hwnd,GWL_STYLE);
-
   if (lphl->OwnerDrawn) {
     DRAWITEMSTRUCT   *dis = USER_HEAP_LIN_ADDR(lphl->hDrawItemStruct);
 
@@ -251,7 +264,7 @@
 	FillRect(hdc, rect, GetStockObject(BLACK_BRUSH));
       }
 
-      if (dwStyle & LBS_USETABSTOPS) {
+      if (lphl->dwStyle & LBS_USETABSTOPS) {
 	TabbedTextOut(hdc, rect->left + 5, rect->top + 2, 
 		      (char *)lpls->itemText, strlen((char *)lpls->itemText), 
 		      lphl->iNumStops, lphl->TabStops, 0);
@@ -311,7 +324,7 @@
   lpmeasure->itemHeight = lphl->StdItemHeight;
   SendMessage(lphl->hParent, WM_MEASUREITEM, 0, (LPARAM)USER_HEAP_SEG_ADDR(hTemp));
 
-  if (GetWindowLong(lphl->hSelf,GWL_STYLE) & LBS_OWNERDRAWFIXED) {
+  if (lphl->dwStyle & LBS_OWNERDRAWFIXED) {
     lphl->StdItemHeight = lpmeasure->itemHeight;
     lphl->needMeasure = FALSE;
   }
@@ -405,10 +418,9 @@
 
 int ListBoxAddString(LPHEADLIST lphl, LPCSTR newstr)
 {
-    LONG dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
     UINT pos = (UINT) -1;
     
-    if (lphl->HasStrings && (dwStyle & LBS_SORT)) {
+    if (lphl->HasStrings && (lphl->dwStyle & LBS_SORT)) {
 	LPLISTSTRUCT lpls = lphl->lpFirst;
 	for (pos = 0; lpls != NULL; lpls = lpls->lpNext, pos++)
 	    if (strcmp(lpls->itemText, newstr) >= 0)
@@ -503,7 +515,6 @@
   UINT	       Count;
   UINT         First = nFirst + 1;
   LPSTR        lpMatchStr = (LPSTR)MatchStr;
-  LONG	       dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
 
   if (First > lphl->ItemsCount) return LB_ERR;
 
@@ -514,7 +525,7 @@
   while(lpls != NULL) {
     if (lphl->HasStrings) {
       if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
-    } else if (dwStyle & LBS_SORT) {
+    } else if (lphl->dwStyle & LBS_SORT) {
       /* XXX Do a compare item */
     }
     else
@@ -531,7 +542,7 @@
   while (Count < First) {
     if (lphl->HasStrings) {
       if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
-    } else if (dwStyle & LBS_SORT) {
+    } else if (lphl->dwStyle & LBS_SORT) {
       /* XXX Do a compare item */
     } else {
       if (lpls->mis.itemData == (DWORD)lpMatchStr) return Count;
@@ -572,13 +583,13 @@
 int ListBoxSetCurSel(LPHEADLIST lphl, WORD wIndex)
 {
   LPLISTSTRUCT lpls;
-  DWORD	       dwStyle = GetWindowWord(lphl->hSelf,GWL_STYLE);
 
   /* use ListBoxSetSel instead */
-  if (dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) return 0;
+  if (lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) return 0;
 
   /* unselect previous item */
   if (lphl->ItemFocused != -1) {
+    lphl->PrevFocused = lphl->ItemFocused;
     lpls = ListBoxGetItem(lphl, lphl->ItemFocused);
     if (lpls == 0) return LB_ERR;
     lpls->itemState = 0;
@@ -602,8 +613,7 @@
   LPLISTSTRUCT  lpls;
   int           n = 0;
 
-  if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & 
-       (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
+  if (!(lphl->dwStyle &  (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
         return LB_ERR;
 
   if (wIndex == (UINT)-1) {
@@ -715,7 +725,7 @@
 {
   LPLISTSTRUCT lpls;
 
-  if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & LBS_OWNERDRAWVARIABLE)) {
+  if (!(lphl->dwStyle & LBS_OWNERDRAWVARIABLE)) {
     lphl->StdItemHeight = (short)height;
     return 0;
   }
@@ -747,7 +757,7 @@
   for(; lpls != NULL; lpls = lpls->lpNext, count++) {
     if (*lpls->itemText != (char)wChar) 
       break;
-    if (count > lphl->ItemFocused)
+    if ((short) count > lphl->ItemFocused)
       return count;
   }
   return first;
@@ -776,6 +786,7 @@
   return 0;
 }
 
+
 /***********************************************************************
  *           LBDestroy
  */
@@ -905,7 +916,6 @@
   WORD       wRet;
   int        y,n;
   RECT       rectsel;
-  LONG	     dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
   POINT      tmpPOINT;
   tmpPOINT.x = LOWORD(lParam); tmpPOINT.y = HIWORD(lParam);
 
@@ -918,12 +928,12 @@
 
   if (y == -1) return 0;
 
-  if (dwStyle & LBS_NOTIFY && y!= LB_ERR )
+  if (lphl->dwStyle & LBS_NOTIFY && y!= LB_ERR )
      if( SendMessage(lphl->hParent, WM_LBTRACKPOINT, y, lParam) )
          return 0;
 
 
-  switch( dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )
+  switch( lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )
    {
         case LBS_MULTIPLESEL:
                 lphl->ItemFocused = y;
@@ -960,7 +970,7 @@
    }
 
  /* invalidate changed items */
- if( dwStyle & LBS_MULTIPLESEL || y!=lphl->PrevFocused )
+ if( lphl->dwStyle & LBS_MULTIPLESEL || y!=lphl->PrevFocused )
    {
      ListBoxGetItemRect(lphl, y, &rectsel);
      InvalidateRect(hwnd, &rectsel, TRUE);
@@ -1021,7 +1031,6 @@
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   int  y,redraw_prev = 0;
   int  iRet;
-  LONG  dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
   RECT rect, rectsel;   /* XXX Broken */
 
   dprintf_listbox(stddeb,"LBMouseMove %d %d\n",SLOWORD(lParam),SHIWORD(lParam));
@@ -1050,10 +1059,10 @@
         if (iRet == lphl->ItemFocused || iRet == -1)  {
 	  return 0;
 	}
-	if (dwStyle & LBS_MULTIPLESEL) {
+	if (lphl->dwStyle & LBS_MULTIPLESEL) {
           lphl->ItemFocused = iRet;
 	  ListBoxSendNotification(lphl, LBN_SELCHANGE);
-        } else if ( dwStyle & LBS_EXTENDEDSEL )
+        } else if ( lphl->dwStyle & LBS_EXTENDEDSEL )
                   {
                      /* Fixme: extended selection mode */
                      ListBoxSetSel( lphl, lphl->ItemFocused, 0);
@@ -1089,7 +1098,6 @@
 static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  LONG       dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
   WORD       newFocused = 0xFFFF;
   RECT	     rect;
 
@@ -1104,7 +1112,7 @@
 	case VK_DOWN:
 	case VK_PRIOR:
 	case VK_NEXT:
-	     if ( dwStyle & LBS_WANTKEYBOARDINPUT )
+	     if ( lphl->dwStyle & LBS_WANTKEYBOARDINPUT )
 	        {
 		  newFocused = (WORD)(INT)SendMessage(lphl->hParent,WM_VKEYTOITEM,
 					              wParam,MAKELPARAM(lphl->ItemFocused,hwnd));
@@ -1124,7 +1132,7 @@
                           newFocused = lphl->ItemsCount - 1;
                           break;
                         case VK_LEFT:
-  			  if (dwStyle & LBS_MULTICOLUMN) {
+  			  if (lphl->dwStyle & LBS_MULTICOLUMN) {
                             if (newFocused >= lphl->ItemsPerColumn) {
                                 newFocused -= lphl->ItemsPerColumn;
                             } else {
@@ -1136,7 +1144,7 @@
                           if (newFocused > 0) newFocused--;
                           break;
                         case VK_RIGHT:
-                          if (dwStyle & LBS_MULTICOLUMN) 
+                          if (lphl->dwStyle & LBS_MULTICOLUMN) 
                              newFocused += lphl->ItemsPerColumn;
                           break;
                         case VK_DOWN:
@@ -1157,7 +1165,7 @@
 		}
 	     break;   
 	case VK_SPACE:
-             if (dwStyle & LBS_MULTIPLESEL)
+             if (lphl->dwStyle & LBS_MULTIPLESEL)
                 {
                  WORD wRet = ListBoxGetSel(lphl, lphl->ItemFocused);
                  ListBoxSetSel(lphl, lphl->ItemFocused, !wRet);
@@ -1174,7 +1182,7 @@
   if (newFocused >= lphl->ItemsCount)
     newFocused = lphl->ItemsCount - 1;
   
-  if (!(dwStyle & LBS_MULTIPLESEL)) 
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) 
      {
         ListBoxSetCurSel(lphl, newFocused);
 	ListBoxSendNotification(lphl, LBN_SELCHANGE);
@@ -1182,7 +1190,7 @@
 
   lphl->ItemFocused = newFocused;
 
-  if( ListBoxScrollToFocus(lphl) || (dwStyle & 
+  if( ListBoxScrollToFocus(lphl) || (lphl->dwStyle & 
                           (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)) )
   InvalidateRect(hwnd, NULL, TRUE);
   else
@@ -1206,10 +1214,9 @@
 static LONG LBChar(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  LONG	     dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
   WORD       newFocused = 0xFFFF;
 
-  if ( (dwStyle & LBS_WANTKEYBOARDINPUT) && !(lphl->HasStrings))
+  if ( (lphl->dwStyle & LBS_WANTKEYBOARDINPUT) && !(lphl->HasStrings))
        {
         newFocused = (WORD)(INT)SendMessage(lphl->hParent,WM_CHARTOITEM,
                                             wParam,MAKELPARAM(lphl->ItemFocused,hwnd));
@@ -1224,7 +1231,7 @@
   if (newFocused >= lphl->ItemsCount)
     newFocused = lphl->ItemsCount - 1;
 
-  if (!(dwStyle & LBS_MULTIPLESEL)) 
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL)) 
      {
     ListBoxSetCurSel(lphl, newFocused);
 	ListBoxSendNotification(lphl, LBN_SELCHANGE);
@@ -1259,12 +1266,26 @@
 static LONG LBSetFont(HWND hwnd, WPARAM wParam, LPARAM lParam)
 {
   LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
+  HDC hdc;
 
   if (wParam == 0)
     lphl->hFont = GetStockObject(SYSTEM_FONT);
   else
     lphl->hFont = (HFONT) wParam;
 
+  /* a new font means possible new text height */
+  /* does this mean the height of each entry must be separately changed? */
+  /* or are we guaranteed to get a LBSetFont before the first insert/add? */
+  if ((hdc = GetDC(0)))
+  {
+      TEXTMETRIC tm;
+      GetTextMetrics( hdc, &tm );
+      lphl->StdItemHeight = tm.tmHeight;
+      dprintf_listbox(stddeb,"LBSetFont:  new font %d with height %d",
+                      lphl->hFont, lphl->StdItemHeight);
+      ReleaseDC( 0, hdc );
+  }
+
   return 0;
 }
 
@@ -1274,7 +1295,6 @@
 static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
-  LONG	       dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
   LPLISTSTRUCT lpls;
   PAINTSTRUCT  ps;
   HBRUSH       hBrush;
@@ -1311,7 +1331,7 @@
   FillRect(hdc, &rect, hBrush);
 
   maxwidth = rect.right;
-  if (dwStyle & LBS_MULTICOLUMN) {
+  if (lphl->dwStyle & LBS_MULTICOLUMN) {
     rect.right = lphl->ColumnsWidth;
   }
   lpls = lphl->lpFirst;
@@ -1326,7 +1346,7 @@
       height = lpls->mis.itemHeight;
 
       if (top > rect.bottom) {
-	if (dwStyle & LBS_MULTICOLUMN) {
+	if (lphl->dwStyle & LBS_MULTICOLUMN) {
 	  lphl->ItemsPerColumn = MAX(lphl->ItemsPerColumn, ipc);
 	  ipc = 0;
 	  top = 0;
@@ -1345,7 +1365,7 @@
 
       if( IntersectRect(&scratchRect,&paintRect,&lpls->itemRect) )
        {
-        dprintf_listbox(stddeb,"drawing item: %ld %d %ld %d %d\n",(LONG)rect.left,top,
+        dprintf_listbox(stddeb,"LBPaint: drawing item: %ld %d %ld %d %d\n",(LONG)rect.left,top,
                             (LONG)rect.right,top+height,lpls->itemState);
 
         if (lphl->OwnerDrawn && (lphl->ItemFocused == i) && GetFocus() == hwnd)
@@ -1380,13 +1400,9 @@
 static LONG LBSetFocus(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  LONG       dwStyle;
 
   dprintf_listbox(stddeb,"ListBox WM_SETFOCUS for "NPFMT"\n",hwnd);
-
-  dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
-
-  if(!(dwStyle & LBS_MULTIPLESEL) )
+  if(!(lphl->dwStyle & LBS_MULTIPLESEL) )
        if( lphl->ItemsCount && lphl->ItemFocused != -1)
          {
            HDC          hDC = GetDC(hwnd);
@@ -1412,13 +1428,9 @@
 static LONG LBKillFocus(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  LONG       dwStyle;
 
   dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS for "NPFMT"\n",hwnd);
-
-  dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
-
-  if (!(dwStyle & LBS_MULTIPLESEL))
+  if (!(lphl->dwStyle & LBS_MULTIPLESEL))
      {
        if( lphl->ItemsCount )
            if( lphl->ItemFocused != -1 )
@@ -1626,8 +1638,7 @@
   int          cnt = 0;
   int          items = 0;
 
-  if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & 
-       (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
+  if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
 	 return LB_ERR;
 
   for( lpls = lphl->lpFirst;
@@ -1652,8 +1663,7 @@
   int cnt, idx;
   int *lpItems = PTR_SEG_TO_LIN(lParam);
 
-  if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & 
-       (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
+  if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
         return LB_ERR;
 
   if (wParam == 0) return 0;
@@ -1715,8 +1725,7 @@
 
   if( iRet != LB_ERR)
     {
-      if( GetWindowLong(hwnd, GWL_STYLE) &
-         (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )
+      if( lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )
          ListBoxSetSel(lphl,iRet,TRUE);
       else
          ListBoxSetCurSel(lphl,iRet);
@@ -1739,8 +1748,7 @@
   WORD         last = HIWORD(lParam);
   BOOL         select = wParam;
 
-  if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & 
-       (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
+  if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
         return LB_ERR;
 
   if (first >= lphl->ItemsCount ||
@@ -1770,8 +1778,7 @@
   LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
   int          i;
 
-  if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & 
-       (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return 0;
+  if (!(lphl->dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return 0;
 
   dprintf_listbox(stddeb,"LBSetCaretIndex: hwnd "NPFMT" n=%i\n",hwnd,wParam);  
 
@@ -1886,7 +1893,7 @@
       InvalidateRect(hwnd, NULL, TRUE);
   else if( iRet != LB_ERR )
       {
-        if( GetWindowLong(hwnd,GWL_STYLE) & LBS_EXTENDEDSEL &&
+        if( lphl->dwStyle & LBS_EXTENDEDSEL &&
             lphl->ItemFocused != LOWORD(lParam) )
           {
             ListBoxGetItemRect(lphl, lphl->ItemFocused , &rect);
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 1105e0a..206247b 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -9,7 +9,10 @@
 #include <stdio.h>
 #include <signal.h>
 #include <unistd.h>
-#include "windows.h"
+#include "class.h"
+#include "options.h"
+#include "queue.h"
+#include "win.h"
 #include "debugger.h"
 
 extern FILE * yyin;
@@ -33,15 +36,15 @@
     int              integer;
 }
 
-%token CONT STEP LIST NEXT QUIT HELP BACKTRACE INFO STACK SEGMENTS REGS
-%token ENABLE DISABLE BREAK DELETE SET MODE PRINT EXAM DEFINE ABORT WALK
-%token WND QUEUE 
-%token NO_SYMBOL EOL
-%token SYMBOLFILE
+%token tCONT tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK
+%token tENABLE tDISABLE tBREAK tDELETE tSET tMODE tPRINT tEXAM tDEFINE tABORT
+%token tCLASS tSTACK tSEGMENTS tREGS tWND tQUEUE 
+%token tNO_SYMBOL tEOL
+%token tSYMBOLFILE
 
-%token <string> IDENTIFIER
-%token <integer> NUM FORMAT
-%token <reg> REG
+%token <string> tIDENTIFIER
+%token <integer> tNUM tFORMAT
+%token <reg> tREG
 
 /* %left ',' */
 /* %left '=' OP_OR_EQUAL OP_XOR_EQUAL OP_AND_EQUAL OP_SHL_EQUAL \
@@ -66,127 +69,135 @@
 
 %%
 
- input:   line			{ issue_prompt(); }
-	| input line		{ issue_prompt(); }
+input: line                    { issue_prompt(); }
+    | input line               { issue_prompt(); }
 
- line:  command 
-	| EOL
-	| error	EOL	       { yyerrok; }
+line: command 
+    | tEOL
+    | error tEOL               { yyerrok; }
 
- command: QUIT EOL             { exit(0); }
-	| HELP EOL             { DEBUG_Help(); }
-	| CONT EOL             { dbg_exec_mode = EXEC_CONT; return 0; }
-	| STEP EOL             { dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
-	| NEXT EOL             { dbg_exec_mode = EXEC_STEP_OVER; return 0; }
-	| LIST EOL	       { DEBUG_List( NULL, 15 ); }
-	| LIST addr EOL	       { DEBUG_List( &$2, 15 ); }
-	| ABORT	EOL            { kill(getpid(), SIGABRT); }
-	| SYMBOLFILE IDENTIFIER EOL  { DEBUG_ReadSymbolTable( $2 ); }
-	| DEFINE IDENTIFIER addr EOL { DEBUG_AddSymbol( $2, &$3 ); }
-	| MODE NUM EOL	       { mode_command($2); }
-	| ENABLE NUM EOL       { DEBUG_EnableBreakpoint( $2, TRUE ); }
-	| DISABLE NUM EOL      { DEBUG_EnableBreakpoint( $2, FALSE ); }
-	| BREAK '*' addr EOL   { DEBUG_AddBreakpoint( &$3 ); }
-	| BREAK symbol EOL     { DEBUG_AddBreakpoint( &$2 ); }
-	| BREAK EOL	       { DBG_ADDR addr = { CS_reg(DEBUG_context),
-						     EIP_reg(DEBUG_context) };
-				 DEBUG_AddBreakpoint( &addr );
-			       }
-	| DELETE BREAK NUM EOL { DEBUG_DelBreakpoint( $3 ); }
-	| BACKTRACE EOL	       { DEBUG_BackTrace(); }
-	| WALK WND EOL	       { DEBUG_InitWalk(); DEBUG_WndWalk( NULL ); }
-	| WALK WND NUM EOL     { DEBUG_InitWalk(); DEBUG_WndWalk( $3 ); }
-	| infocmd
-	| x_command
-	| print_command
-	| deposit_command
+command:
+      tQUIT tEOL               { exit(0); }
+    | tHELP tEOL               { DEBUG_Help(); }
+    | tCONT tEOL               { dbg_exec_mode = EXEC_CONT; return 0; }
+    | tSTEP tEOL               { dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
+    | tNEXT tEOL               { dbg_exec_mode = EXEC_STEP_OVER; return 0; }
+    | tLIST tEOL               { DEBUG_List( NULL, 15 ); }
+    | tLIST addr tEOL          { DEBUG_List( &$2, 15 ); }
+    | tABORT tEOL              { kill(getpid(), SIGABRT); }
+    | tSYMBOLFILE tIDENTIFIER tEOL  { DEBUG_ReadSymbolTable( $2 ); }
+    | tDEFINE tIDENTIFIER addr tEOL { DEBUG_AddSymbol( $2, &$3 ); }
+    | tMODE tNUM tEOL          { mode_command($2); }
+    | tENABLE tNUM tEOL        { DEBUG_EnableBreakpoint( $2, TRUE ); }
+    | tDISABLE tNUM tEOL       { DEBUG_EnableBreakpoint( $2, FALSE ); }
+    | tDELETE tBREAK tNUM tEOL { DEBUG_DelBreakpoint( $3 ); }
+    | tBACKTRACE tEOL	       { DEBUG_BackTrace(); }
+    | set_command
+    | x_command
+    | print_command
+    | break_command
+    | info_command
+    | walk_command
 
-deposit_command:
-	SET REG '=' expr EOL	      { DEBUG_SetRegister( $2, $4 ); }
-	| SET '*' addr '=' expr	EOL   { DEBUG_WriteMemory( &$3, $5 ); }
-	| SET IDENTIFIER '=' addr EOL { if (!DEBUG_SetSymbolValue( $2, &$4 ))
-				         {
-					   fprintf( stderr,
-						 "Symbol %s not found\n", $2 );
-					   YYERROR;
-				         }
-				       }
-
+set_command:
+      tSET tREG '=' expr tEOL	     { DEBUG_SetRegister( $2, $4 ); }
+    | tSET '*' addr '=' expr tEOL    { DEBUG_WriteMemory( &$3, $5 ); }
+    | tSET tIDENTIFIER '=' addr tEOL { if (!DEBUG_SetSymbolValue( $2, &$4 ))
+                                       {
+                                           fprintf( stderr,
+                                                 "Symbol %s not found\n", $2 );
+                                           YYERROR;
+                                       }
+                                     }
 
 x_command:
-	  EXAM addr EOL         { DEBUG_ExamineMemory( &$2, 1, 'x'); }
-	| EXAM FORMAT addr EOL  { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); }
+      tEXAM addr tEOL          { DEBUG_ExamineMemory( &$2, 1, 'x'); }
+    | tEXAM tFORMAT addr tEOL  { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); }
 
- print_command:
-	  PRINT addr EOL        { DEBUG_Print( &$2, 1, 'x' ); }
-	| PRINT FORMAT addr EOL { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff ); }
+print_command:
+      tPRINT addr tEOL         { DEBUG_Print( &$2, 1, 'x' ); }
+    | tPRINT tFORMAT addr tEOL { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff ); }
 
- symbol: IDENTIFIER   { if (!DEBUG_GetSymbolValue( $1, &$$ ))
+break_command:
+      tBREAK '*' addr tEOL     { DEBUG_AddBreakpoint( &$3 ); }
+    | tBREAK symbol tEOL       { DEBUG_AddBreakpoint( &$2 ); }
+    | tBREAK tEOL              { DBG_ADDR addr = { CS_reg(DEBUG_context),
+                                                   EIP_reg(DEBUG_context) };
+                                 DEBUG_AddBreakpoint( &addr );
+                               }
+
+info_command:
+      tINFO tBREAK tEOL         { DEBUG_InfoBreakpoints(); }
+    | tINFO tCLASS expr tEOL    { CLASS_DumpClass( $3 ); }
+    | tINFO tQUEUE expr tEOL    { QUEUE_DumpQueue( $3 ); }
+    | tINFO tREGS tEOL          { DEBUG_InfoRegisters(); }
+    | tINFO tSEGMENTS expr tEOL { LDT_Print( SELECTOR_TO_ENTRY($3), 1 ); }
+    | tINFO tSEGMENTS tEOL      { LDT_Print( 0, -1 ); }
+    | tINFO tSTACK tEOL         { DEBUG_InfoStack(); }
+    | tINFO tWND expr tEOL      { WIN_DumpWindow( $3 ); } 
+
+walk_command:
+      tWALK tCLASS tEOL         { CLASS_WalkClasses(); }
+    | tWALK tQUEUE tEOL         { QUEUE_WalkQueues(); }
+    | tWALK tWND tEOL           { WIN_WalkWindows( 0, 0 ); }
+    | tWALK tWND tNUM tEOL      { WIN_WalkWindows( $3, 0 ); }
+
+symbol: tIDENTIFIER   { if (!DEBUG_GetSymbolValue( $1, &$$ ))
 			{
 			   fprintf( stderr, "Symbol %s not found\n", $1 );
 			   YYERROR;
 			}
 		      } 
 
- addr: expr				{ $$.seg = 0xffffffff; $$.off = $1; }
-       | segaddr			{ $$ = $1; }
+addr:
+      expr                       { $$.seg = 0xffffffff; $$.off = $1; }
+    | segaddr                    { $$ = $1; }
 
- segaddr: expr ':' expr			{ $$.seg = $1; $$.off = $3; }
-       | symbol				{ $$ = $1; }
+segaddr:
+      expr ':' expr              { $$.seg = $1; $$.off = $3; }
+    | symbol                     { $$ = $1; }
 
- expr:	NUM				{ $$ = $1;	}
-	| REG				{ $$ = DEBUG_GetRegister($1); }
-	| expr OP_LOR expr		{ $$ = $1 || $3; }
-	| expr OP_LAND expr		{ $$ = $1 && $3; }
-	| expr '|' expr			{ $$ = $1 | $3; }
-	| expr '&' expr			{ $$ = $1 & $3; }
-	| expr '^' expr			{ $$ = $1 ^ $3; }
-	| expr OP_EQ expr		{ $$ = $1 == $3; }
-	| expr '>' expr			{ $$ = $1 > $3; }
-	| expr '<' expr			{ $$ = $1 < $3; }
-	| expr OP_GE expr		{ $$ = $1 >= $3; }
-	| expr OP_LE expr		{ $$ = $1 <= $3; }
-	| expr OP_NE expr		{ $$ = $1 != $3; }
-	| expr OP_SHL expr		{ $$ = (unsigned)$1 << $3; }
-	| expr OP_SHR expr		{ $$ = (unsigned)$1 >> $3; }
-	| expr '+' expr			{ $$ = $1 + $3; }
-	| expr '-' expr			{ $$ = $1 - $3; }
-	| expr '*' expr			{ $$ = $1 * $3; }
-	| expr '/' expr
-	  { if ($3) 
-	      if ($3 == -1 && $1 == 0x80000000l)
-		yyerror ("Division overflow");
-	      else
-		$$ = $1 / $3;
-	    else
-	      yyerror ("Division by zero"); }
-	| expr '%' expr
-	  { if ($3) 
-	      if ($3 == -1 && $1 == 0x80000000l)
-		$$ = 0; /* A sensible result in this case.  */
-	      else
-		$$ = $1 % $3;
-	    else
-	      yyerror ("Division by zero"); }
-	| '-' expr %prec OP_SIGN	{ $$ = -$2; }
-	| '+' expr %prec OP_SIGN	{ $$ = $2; }
-	| '!' expr			{ $$ = !$2; }
-	| '~' expr			{ $$ = ~$2; }
-	| '(' expr ')'			{ $$ = $2; }
+expr:
+      tNUM                       { $$ = $1; }
+    | tREG                       { $$ = DEBUG_GetRegister($1); }
+    | expr OP_LOR expr           { $$ = $1 || $3; }
+    | expr OP_LAND expr          { $$ = $1 && $3; }
+    | expr '|' expr              { $$ = $1 | $3; }
+    | expr '&' expr              { $$ = $1 & $3; }
+    | expr '^' expr              { $$ = $1 ^ $3; }
+    | expr OP_EQ expr            { $$ = $1 == $3; }
+    | expr '>' expr              { $$ = $1 > $3; }
+    | expr '<' expr              { $$ = $1 < $3; }
+    | expr OP_GE expr            { $$ = $1 >= $3; }
+    | expr OP_LE expr            { $$ = $1 <= $3; }
+    | expr OP_NE expr            { $$ = $1 != $3; }
+    | expr OP_SHL expr           { $$ = (unsigned)$1 << $3; }
+    | expr OP_SHR expr           { $$ = (unsigned)$1 >> $3; }
+    | expr '+' expr              { $$ = $1 + $3; }
+    | expr '-' expr              { $$ = $1 - $3; }
+    | expr '*' expr              { $$ = $1 * $3; }
+    | expr '/' expr              { if ($3) 
+                                       if ($3 == -1 && $1 == 0x80000000l)
+                                           yyerror ("Division overflow");
+                                       else $$ = $1 / $3;
+                                   else yyerror ("Division by zero");
+                                 }
+    | expr '%' expr              { if ($3) 
+                                       if ($3 == -1 && $1 == 0x80000000l)
+                                           $$ = 0; /* A sensible result in this case.  */
+                                       else $$ = $1 % $3;
+                                   else yyerror ("Division by zero");
+                                 }
+    | '-' expr %prec OP_SIGN     { $$ = -$2; }
+    | '+' expr %prec OP_SIGN     { $$ = $2; }
+    | '!' expr                   { $$ = !$2; }
+    | '~' expr                   { $$ = ~$2; }
+    | '(' expr ')'               { $$ = $2; }
 /* For parser technical reasons we can't use "addr" here.  */
-	| '*' expr %prec OP_DEREF	{ DBG_ADDR addr = { 0xffffffff, $2 };
-					  $$ = DEBUG_ReadMemory( &addr ); }
-	| '*' segaddr %prec OP_DEREF	{ $$ = DEBUG_ReadMemory( &$2 ); }
+    | '*' expr %prec OP_DEREF    { DBG_ADDR addr = { 0xffffffff, $2 };
+                                   $$ = DEBUG_ReadMemory( &addr ); }
+    | '*' segaddr %prec OP_DEREF { $$ = DEBUG_ReadMemory( &$2 ); }
 	
- infocmd: INFO REGS EOL	          { DEBUG_InfoRegisters(); }
-	| INFO STACK EOL          { DEBUG_InfoStack(); }
-	| INFO BREAK EOL          { DEBUG_InfoBreakpoints(); }
-	| INFO SEGMENTS EOL	  { LDT_Print( 0, -1 ); }
-	| INFO SEGMENTS expr EOL  { LDT_Print( SELECTOR_TO_ENTRY($3), 1 ); }
-	| INFO WND expr EOL       { DEBUG_WndDump( $3 ); } 
-	| INFO QUEUE expr EOL     { DEBUG_QueueDump( $3 ); }
-
-
 %%
 
 void 
diff --git a/debugger/debug.l b/debugger/debug.l
index cc46238..abacf8e 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -35,7 +35,7 @@
 
 %%
 
-\n		{ syntax_error = 0; return EOL; } /*Indicates end of command*/
+\n		{ syntax_error = 0; return tEOL; } /*Indicates end of command*/
 
 "||"		{ return OP_LOR; }
 "&&"		{ return OP_LAND; }
@@ -47,77 +47,76 @@
 ">>"		{ return OP_SHR; }
 [-+<=>|&^()*/%:!~]	{ return *yytext; }
 
-"0x"{HEXDIGIT}+      { sscanf(yytext, "%x", &yylval.integer); return NUM; }
-{DIGIT}+             { sscanf(yytext, "%d", &yylval.integer); return NUM; }
+"0x"{HEXDIGIT}+      { sscanf(yytext, "%x", &yylval.integer); return tNUM; }
+{DIGIT}+             { sscanf(yytext, "%d", &yylval.integer); return tNUM; }
 
 "/"{DIGIT}+{FORMAT}  { char * last;
                        yylval.integer = strtol( yytext+1, &last, NULL );
                        yylval.integer = (yylval.integer << 8) | *last;
-                       return FORMAT; }
-"/"{FORMAT}          { yylval.integer = (1 << 8) | yytext[1]; return FORMAT; }
+                       return tFORMAT; }
+"/"{FORMAT}          { yylval.integer = (1 << 8) | yytext[1]; return tFORMAT; }
 
-$pc     { yylval.reg = REG_EIP; return REG; }
-$flags  { yylval.reg = REG_EFL; return REG; }
-$eip    { yylval.reg = REG_EIP; return REG; }
-$ip     { yylval.reg = REG_IP;  return REG; }
-$esp    { yylval.reg = REG_ESP; return REG; }
-$sp     { yylval.reg = REG_SP;  return REG; }
-$eax    { yylval.reg = REG_EAX; return REG; }
-$ebx    { yylval.reg = REG_EBX; return REG; }
-$ecx    { yylval.reg = REG_ECX; return REG; }
-$edx    { yylval.reg = REG_EDX; return REG; }
-$esi    { yylval.reg = REG_ESI; return REG; }
-$edi    { yylval.reg = REG_EDI; return REG; }
-$ebp    { yylval.reg = REG_EBP; return REG; }
-$ax     { yylval.reg = REG_AX;  return REG; }
-$bx     { yylval.reg = REG_BX;  return REG; }
-$cx     { yylval.reg = REG_CX;  return REG; }
-$dx     { yylval.reg = REG_DX;  return REG; }
-$si     { yylval.reg = REG_SI;  return REG; }
-$di     { yylval.reg = REG_DI;  return REG; }
-$bp     { yylval.reg = REG_BP;  return REG; }
-$es     { yylval.reg = REG_ES;  return REG; }
-$ds     { yylval.reg = REG_DS;  return REG; }
-$cs     { yylval.reg = REG_CS;  return REG; }
-$ss     { yylval.reg = REG_SS;  return REG; }
+$pc     { yylval.reg = REG_EIP; return tREG; }
+$flags  { yylval.reg = REG_EFL; return tREG; }
+$eip    { yylval.reg = REG_EIP; return tREG; }
+$ip     { yylval.reg = REG_IP;  return tREG; }
+$esp    { yylval.reg = REG_ESP; return tREG; }
+$sp     { yylval.reg = REG_SP;  return tREG; }
+$eax    { yylval.reg = REG_EAX; return tREG; }
+$ebx    { yylval.reg = REG_EBX; return tREG; }
+$ecx    { yylval.reg = REG_ECX; return tREG; }
+$edx    { yylval.reg = REG_EDX; return tREG; }
+$esi    { yylval.reg = REG_ESI; return tREG; }
+$edi    { yylval.reg = REG_EDI; return tREG; }
+$ebp    { yylval.reg = REG_EBP; return tREG; }
+$ax     { yylval.reg = REG_AX;  return tREG; }
+$bx     { yylval.reg = REG_BX;  return tREG; }
+$cx     { yylval.reg = REG_CX;  return tREG; }
+$dx     { yylval.reg = REG_DX;  return tREG; }
+$si     { yylval.reg = REG_SI;  return tREG; }
+$di     { yylval.reg = REG_DI;  return tREG; }
+$bp     { yylval.reg = REG_BP;  return tREG; }
+$es     { yylval.reg = REG_ES;  return tREG; }
+$ds     { yylval.reg = REG_DS;  return tREG; }
+$cs     { yylval.reg = REG_CS;  return tREG; }
+$ss     { yylval.reg = REG_SS;  return tREG; }
 
-info|inf|in			{ return INFO; }
-show|sho|sh			{ return INFO; }
-list|lis|li|l			{ return LIST; }
-segments|segment|segm|seg|se	{ return SEGMENTS; }
-break|brea|bre|br|b		{ return BREAK; }
-enable|enabl|enab|ena		{ return ENABLE;}
-disable|disabl|disab|disa|dis	{ return DISABLE; }
-delete|delet|dele|del		{ return DELETE; }
-quit|qui|qu|q			{ return QUIT; }
-walk|w				{ return WALK; }
-queue|queu|que			{ return QUEUE; }
-window|windo|wind|win|wnd	{ return WND; }
-x				{ return EXAM; }
+info|inf|in			{ return tINFO; }
+show|sho|sh			{ return tINFO; }
+list|lis|li|l			{ return tLIST; }
+break|brea|bre|br|b		{ return tBREAK; }
+enable|enabl|enab|ena		{ return tENABLE;}
+disable|disabl|disab|disa|dis	{ return tDISABLE; }
+delete|delet|dele|del		{ return tDELETE; }
+quit|qui|qu|q			{ return tQUIT; }
+set|se				{ return tSET; }
+walk|w				{ return tWALK; }
+x				{ return tEXAM; }
 
-help|hel|he|"?"			{ return HELP; }
+class|clas|cla                  { return tCLASS; }
+queue|queu|que			{ return tQUEUE; }
+registers|regs|reg|re		{ return tREGS; }
+segments|segment|segm|seg|se	{ return tSEGMENTS; }
+stack|stac|sta|st     		{ return tSTACK; }
+window|windo|wind|win|wnd	{ return tWND; }
 
-set|se				{ return SET; }
+help|hel|he|"?"			{ return tHELP; }
 
-bt				{ return BACKTRACE; }
+backtrace|bt			{ return tBACKTRACE; }
 
-cont|con|co|c   		{ return CONT; }
-step|ste|st|s   		{ return STEP; }
-next|nex|ne|n   		{ return NEXT; }
+cont|con|co|c   		{ return tCONT; }
+step|ste|st|s   		{ return tSTEP; }
+next|nex|ne|n   		{ return tNEXT; }
 
-symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return SYMBOLFILE; }
+symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return tSYMBOLFILE; }
 
-define|defin|defi|def|de        { return DEFINE; }
-abort|abor|abo         	        { return ABORT; }
-print|prin|pri|pr|p		{ return PRINT; }
+define|defin|defi|def|de        { return tDEFINE; }
+abort|abor|abo         	        { return tABORT; }
+print|prin|pri|pr|p		{ return tPRINT; }
 
-mode				{ return MODE; }
+mode				{ return tMODE; }
 
-registers|regs|reg|re		{ return REGS; }
-
-stack|stac|sta|st     		{ return STACK; }
-
-{IDENTIFIER}	{ yylval.string = make_symbol(yytext); return IDENTIFIER; }
+{IDENTIFIER}	{ yylval.string = make_symbol(yytext); return tIDENTIFIER; }
 
 [ \t]+        /* Eat up whitespace */
 
diff --git a/debugger/hash.c b/debugger/hash.c
index 60be910..c21c0d0 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -215,7 +215,6 @@
     unsigned int address;
     BOOL ok;
 
-    fprintf( stderr, "Adding symbols from loaded modules\n" );
     for (ok = ModuleFirst(&entry); ok; ok = ModuleNext(&entry))
     {
         if (!(pModule = (NE_MODULE *)GlobalLock( entry.hModule ))) continue;
diff --git a/debugger/info.c b/debugger/info.c
index c17efaa..b656879 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -7,191 +7,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "global.h"
-#include "user.h"
-#include "class.h"
-#include "win.h"
-#include "message.h"
-#include "spy.h"
 #include "debugger.h"
 
-int	  	iWndIndent = 0;
-
-extern 	char	lpstrSpyMessageIndent[]; /* from misc/spy.c */
-
-/***********************************************************************
- *	    DEBUG_InitWalk
- */
-void DEBUG_InitWalk(void)
-{
-  fprintf(stderr,"%-24.24s %-6.6s %-17.17s %-8.8s %s\n",
-                 "HWND / WNDPTR","hQueue","Class Name", "Style", "WndProc");
-  lpstrSpyMessageIndent[0]='\0';
-}
-
-/***********************************************************************
- *           DEBUG_WndWalk
- *
- */
-void DEBUG_WndWalk(HWND hStart)
-{
-  WND*  	wndPtr;
-  CLASS*	classPtr;
-  char	 	className[0x10];
-  int		i;
-
-  if( !hStart )
-       hStart = GetDesktopHwnd();
-
-  wndPtr = WIN_FindWndPtr(hStart);
-
-  if( !wndPtr )
-    { fprintf(stderr, "Invalid window handle: %04x\n", hStart);
-      return; }
-
-  i = strlen(lpstrSpyMessageIndent);
- 
-  /* 0x10 bytes are always reserved at the end of lpstrSpyMessageIndent */
-  sprintf(lpstrSpyMessageIndent + i,"%04x %08x",hStart, (unsigned) wndPtr);
-
-  classPtr = CLASS_FindClassPtr(wndPtr->hClass);
-  if(classPtr)
-     GlobalGetAtomName(classPtr->atomName ,className, 0x10);
-  else
-     strcpy(className,"<BAD>");
-
-  fprintf(stderr,"%-24.24s %-6.4x %-17.17s %08x %04x:%04x\n",
-		 lpstrSpyMessageIndent,
-		 wndPtr->hmemTaskQ, 
-		 className,
-		 (unsigned) wndPtr->dwStyle,
-		 HIWORD(wndPtr->lpfnWndProc),
-		 LOWORD(wndPtr->lpfnWndProc));
-
-  lpstrSpyMessageIndent[i] = '\0';
-
-  if( wndPtr->hwndChild )  
-    {
-      /* walk children */
-
-      hStart = wndPtr->hwndChild;
-      wndPtr = WIN_FindWndPtr(hStart);
-
-      iWndIndent ++;
-      if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 )
-        { 
-          lpstrSpyMessageIndent[iWndIndent - 1] = ' ';
-	  lpstrSpyMessageIndent[iWndIndent] = '\0';
-        }
- 
-      while( wndPtr )
-  	  { 
-             DEBUG_WndWalk(hStart);
-	     hStart = wndPtr->hwndNext; 
-	     wndPtr = WIN_FindWndPtr(hStart);
-  	  }
-
-      if( hStart )
-          fprintf(stderr, "%s%s"NPFMT"\n", lpstrSpyMessageIndent,
-					  "<BAD>", hStart);
-
-      if( iWndIndent )
-        {
-          iWndIndent--;
-          if( iWndIndent < SPY_MAX_INDENTLEVEL - 0x10 )
-              lpstrSpyMessageIndent[iWndIndent] = '\0';
-        }
-
-    }
-}
-
-/***********************************************************************
- *	     DEBUG_WndDump
- *
- */ 
-void DEBUG_WndDump(HWND hWnd)
-{
-  WND*		wnd;
-  char*		lpWndText = NULL;
-
-  wnd = WIN_FindWndPtr(hWnd);
-
-  if( !wnd )
-    { fprintf(stderr, "Invalid window handle: %04x\n", hWnd);
-      return; }
- 
-  if( wnd->hText ) 
-      lpWndText = (LPSTR) USER_HEAP_LIN_ADDR( wnd->hText );
-
-  fprintf( stderr, "next: %12.4x\n"
-                   "child:  %10.4x\n"
-                   "parent: %10.4x\n"
-                   "owner:  %10.4x\n"
-                   "hClass: %10.4x\n"
-                   "hInst:  %10.4x\n"
-                   "clientRect: %i,%i - %i,%i\n"
-                   "windowRect: %i,%i - %i,%i\n"
-                   "hRgnUpdate: %6.4x\n"
-                   "hLastPopup: %6.4x\n"
-                   "Style:  %10.8x\n"
-                   "StyleEx: %9.8x\n"
-                   "hDCE:   %10.4x\n"
-                   "hVscroll: %8.4x\n"
-                   "hHscroll: %8.4x\n"
-                   "menuID: %10.4x\n"
-                   "hText:  %10.4x (\"%s\")\n"
-                   "flags:  %10.4x\n",
-                   wnd->hwndNext, wnd->hwndChild,wnd->hwndParent,
-                   wnd->hwndOwner,wnd->hClass,wnd->hInstance,
-                   wnd->rectClient.left, wnd->rectClient.top, 
-                   wnd->rectClient.right, wnd->rectClient.bottom,
-                   wnd->rectWindow.left, wnd->rectWindow.top,
-                   wnd->rectWindow.right, wnd->rectWindow.bottom,
-                   wnd->hrgnUpdate, wnd->hwndLastActive,
-                   (unsigned) wnd->dwStyle, (unsigned) wnd->dwExStyle,
-                   wnd->hdce, wnd->hVScroll, wnd->hHScroll,
-                   wnd->wIDmenu, wnd->hText, (lpWndText)?lpWndText:"NULL",
-                   wnd->flags);
-}
-
-/***********************************************************************
- *	     DEBUG_QueueDump
- *
- */
-void DEBUG_QueueDump(HQUEUE hQ)
-{
- MESSAGEQUEUE*	pq; 
-
- if( !hQ || IsBadReadPtr((SEGPTR)MAKELONG( 0, GlobalHandleToSel(hQ)),
-		    				sizeof(MESSAGEQUEUE)) )
-   {
-     fprintf(stderr, "Invalid queue handle: "NPFMT"\n", hQ);
-     return;
-   }
-
- pq = (MESSAGEQUEUE*) GlobalLock( hQ );
-
- fprintf(stderr,"next: %12.4x  Intertask SendMessage:\n"
-                "hTask: %11.4x  ----------------------\n"
-                "msgSize: %9.4x  hWnd: %10.4x\n"
-                "msgCount: %8.4x  msg: %11.4x\n"
-                "msgNext: %9.4x  wParam: %8.4x\n"
-                "msgFree: %9.4x  lParam: %8.8x\n"
-                "qSize: %11.4x  lRet: %10.8x\n"
-                "wWinVer: %9.4x  ISMH: %10.4x\n"
-                "paints: %10.4x  hSendTask: %5.4x\n"
-                "timers: %10.4x  hPrevSend: %5.4x\n"
-                "wakeBits: %8.4x\n"
-                "wakeMask: %8.4x\n"
-                "hCurHook: %8.4x\n",
-                pq->next, pq->hTask, pq->msgSize, pq->hWnd, 
-		pq->msgCount, pq->msg, pq->nextMessage, pq->wParam,
-		pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize,
-		(unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
-		pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
-		pq->hPrevSendingTask, pq->status, pq->wakeMask, pq->hCurHook);
-}
-
 /***********************************************************************
  *           DEBUG_Print
  *
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index 7e94b98..f896da8 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -46,7 +46,8 @@
 ASM_SRCS = \
 	$(SPEC16_FILES) \
 	call16.S \
-	call32.S
+	call32.S \
+	except.S
 
 .SUFFIXES: .spec
 
diff --git a/if1632/except.S b/if1632/except.S
new file mode 100644
index 0000000..60cd710
--- /dev/null
+++ b/if1632/except.S
@@ -0,0 +1,192 @@
+/*
+ * Win32 exception assembly functions
+ *
+ * Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl)
+ *
+ */
+
+#ifndef __ELF__
+     .globl _EXC_CallUnhandledExceptionFilter
+     .extern _pTopExcHandler
+
+ _EXC_CallUnhandledExceptionFilter:
+#else  /* __ELF__ */
+     .globl EXC_CallUnhandledExceptionFilter
+     .extern pTopExcHandler
+
+ EXC_CallUnhandledExceptionFilter:
+#endif  /* __ELF__ */
+     leal   4(%esp),%eax
+     pushl  %eax
+#ifndef __ELF__
+     call   *_pTopExcHandler
+#else  /* __ELF__ */
+     call   *pTopExcHandler
+#endif  /* __ELF__ */
+     movl   %ebp,%esp
+     ret
+
+
+
+/*******************************************************************
+ *
+ *        RaiseException           (KERNEL32. 418 )
+ *        RtlUnwind                (KERNEL32. 443 )
+ *
+ * we need to save our context before a call to
+ *
+ * -RaiseException
+ * -RtlUnwind
+ *
+ * after these functions we need to restore that context structure as
+ * the actual context so changes made to the context structure in an
+ * exception-handler will be reflected in the context after these
+ * functions return. Fortunately both functions have 4 DWORD params.
+ * we pass the function to be called as a fifth parameter to ContextCall
+ *
+ */
+       .equ CONTEXT_SegSs,        -4
+       .equ CONTEXT_Esp,          -8
+       .equ CONTEXT_EFlags,       -12
+       .equ CONTEXT_SegCs,        -16
+       .equ CONTEXT_Eip,          -20
+       .equ CONTEXT_Ebp,          -24
+       .equ CONTEXT_Eax,          -28
+       .equ CONTEXT_Ecx,          -32
+       .equ CONTEXT_Edx,          -36
+       .equ CONTEXT_Ebx,          -40
+       .equ CONTEXT_Esi,          -44
+       .equ CONTEXT_Edi,          -48
+       .equ CONTEXT_SegDs,        -52
+       .equ CONTEXT_SegEs,        -56
+       .equ CONTEXT_SegFs,        -60
+       .equ CONTEXT_SegGs,        -64
+       .equ FLOAT_Cr0NpxState,    -68
+       .equ FLOAT_RegisterArea,   -148
+       .equ FLOAT_DataSelector,   -152
+       .equ FLOAT_DataOffset,     -156
+       .equ FLOAT_ErrorSelector,  -160
+       .equ FLOAT_ErrorOffset,    -164
+       .equ FLOAT_TagWord,        -168
+       .equ FLOAT_StatusWord,     -172
+       .equ FLOAT_ControlWord,    -176
+       .equ CONTEXT_FloatSave,    -176
+       .equ CONTEXT_Dr7,          -180
+       .equ CONTEXT_Dr6,          -184
+       .equ CONTEXT_Dr3,          -188
+       .equ CONTEXT_Dr2,          -192
+       .equ CONTEXT_Dr1,          -196
+       .equ CONTEXT_Dr0,          -200
+       .equ CONTEXT_ContextFlags, -204
+       .equ CONTEXT,              -204
+       .equ CONTEXTSIZE,           204
+       .equ CONTEXTFLAGS,          0x10007
+
+       .equ ORIG_ESP,              16         /** cdecl !!! **/
+       .equ PARM_ARG4,             28
+       .equ PARM_ARG3,             24
+       .equ PARM_ARG2,             20
+       .equ PARM_ARG1,             16
+       .equ PARM_RETURN,           12
+       .equ PARM_CALLFUNC,         8
+       .equ PARM_EBP,              4
+       .equ PARM_EFLAGS,           0
+
+#ifndef __ELF__
+	.globl _RaiseException
+        .extern _EXC_RaiseException
+
+ _RaiseException:
+       push   $_EXC_RaiseException
+       jmp    ContextCall
+
+       .globl _RtlUnwind
+
+ _RtlUnwind:
+       push   $_EXC_RtlUnwind
+
+#else  /* __ELF__ */
+       .globl RaiseException
+       .extern EXC_RaiseException
+
+ RaiseException:
+       push   $EXC_RaiseException
+       jmp    ContextCall
+
+       .globl RtlUnwind
+
+ RtlUnwind:
+       push   $EXC_RtlUnwind
+#endif  /* __ELF__ */
+
+ ContextCall:
+       pushl  %ebp
+       pushfl
+       movl   %esp, %ebp
+       subl   $CONTEXTSIZE,      %esp
+       movl   %eax, CONTEXT_Eax(%ebp)
+       leal   ORIG_ESP(%ebp), %eax
+       movl   %eax, CONTEXT_Esp(%ebp)
+       movl   PARM_EFLAGS(%ebp), %eax
+       movl   %eax, CONTEXT_EFlags(%ebp)
+       movl   PARM_EBP(%ebp), %eax
+       movl   %eax, CONTEXT_Ebp(%ebp)
+       movl   PARM_RETURN(%ebp), %eax
+       movl   %eax, CONTEXT_Eip(%ebp)
+       movl   %edi, CONTEXT_Edi(%ebp)
+       movl   %esi, CONTEXT_Esi(%ebp)
+       movl   %ebx, CONTEXT_Ebx(%ebp)
+       movl   %edx, CONTEXT_Edx(%ebp)
+       movl   %ecx, CONTEXT_Ecx(%ebp)
+       xorl   %eax, %eax
+       movw   %ss, %ax
+       movl   %eax, CONTEXT_SegSs(%ebp)
+       movw   %cs, %ax
+       movl   %eax, CONTEXT_SegCs(%ebp)
+       movw   %gs, %ax
+       movl   %eax, CONTEXT_SegGs(%ebp)
+       movw   %fs, %ax
+       movl   %eax, CONTEXT_SegFs(%ebp)
+       movw   %es, %ax
+       movl   %eax, CONTEXT_SegEs(%ebp)
+       movw   %ds, %ax
+       movl   %eax, CONTEXT_SegDs(%ebp)
+       fsave  CONTEXT_FloatSave(%ebp)
+       movl   $CONTEXTFLAGS, %eax
+       movl   %eax, CONTEXT_ContextFlags(%ebp)
+       pushl  %ebp
+       leal   CONTEXT(%ebp), %eax
+       pushl  %eax
+       pushl  PARM_ARG4(%ebp)
+       pushl  PARM_ARG3(%ebp)
+       pushl  PARM_ARG2(%ebp)
+       pushl  PARM_ARG1(%ebp)
+       call   *PARM_CALLFUNC(%ebp)
+       addl   $20,%esp
+       popl   %ebp
+       lds    CONTEXT_Esp(%ebp),%edi
+       movl   CONTEXT_Eip(%ebp),%eax
+       movl   %eax,-4(%edi)
+       movl   CONTEXT_EFlags(%ebp),%eax
+       movl   %eax,-8(%edi)
+       movl   CONTEXT_Edi(%ebp),%eax
+       movl   %eax,-12(%edi)
+       movl   CONTEXT_SegDs(%ebp),%eax
+       movw   %ax,%ds
+       movl   CONTEXT_SegEs(%ebp),%eax
+       movw   %ax,%es
+       movl   CONTEXT_SegFs(%ebp),%eax
+       movw   %ax,%fs
+       movl   CONTEXT_SegGs(%ebp),%eax
+       movw   %ax,%gs
+       frstor CONTEXT_FloatSave(%ebp)
+       movl   CONTEXT_Ecx(%ebp),%ecx
+       movl   CONTEXT_Edx(%ebp),%edx
+       movl   CONTEXT_Ebx(%ebp),%ebx
+       movl   CONTEXT_Esi(%ebp),%esi
+       movl   CONTEXT_Eax(%ebp),%eax
+       movl   CONTEXT_Ebp(%ebp),%ebp
+       lea    -12(%edi),%esp
+       popl   %edi
+       popfl
+       ret
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index b54f516..20f485a 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -445,7 +445,7 @@
 0440 stub ResumeThread
 0441 stub RtlFillMemory
 0442 stub RtlMoveMemory
-0443 stub RtlUnwind
+0443    stdcall RtlUnwind(ptr long ptr long) RtlUnwind
 0444 stub RtlZeroMemory
 0445 stub ScrollConsoleScreenBufferA
 0446 stub ScrollConsoleScreenBufferW
@@ -518,7 +518,7 @@
 0513 stub SetThreadLocale
 0514 stub SetThreadPriority
 0515 stub SetTimeZoneInformation
-0516 stub SetUnhandledExceptionFilter
+0516    stdcall SetUnhandledExceptionFilter(ptr) SetUnhandledExceptionFilter
 0517 stub SetVDMCurrentDirectories
 0518 stub SetVolumeLabelA
 0519 stub SetVolumeLabelW
@@ -539,7 +539,7 @@
 0534 stub TransactNamedPipe
 0535 stub TransmitCommChar
 0536 stub TrimVirtualBuffer
-0537 stub UnhandledExceptionFilter
+0537    stdcall UnhandledExceptionFilter(ptr) UnhandledExceptionFilter
 0538 stub UnlockFile
 0539 stub UnlockFileEx
 0540 stub UnmapViewOfFile
diff --git a/if1632/keyboard.spec b/if1632/keyboard.spec
index af38f70..714bd3c 100644
--- a/if1632/keyboard.spec
+++ b/if1632/keyboard.spec
@@ -7,7 +7,7 @@
 4   pascal16 ToAscii(word word ptr ptr word) ToAscii
 5   pascal16 AnsiToOem(ptr ptr) AnsiToOem
 6   pascal16 OemToAnsi(ptr ptr) OemToAnsi
-#7	pascal	SetSpeed
+7   return   SetSpeed 2 65535
 #100	pascal	ScreenSwitchEnable
 #126	pascal	GetTableSeg
 #127	pascal	NewTable
diff --git a/if1632/user.spec b/if1632/user.spec
index 4df1c0f..fcc0b1b 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -13,7 +13,7 @@
 12  pascal16 KillTimer(word word) KillTimer
 13  pascal   GetTickCount() GetTickCount
 14  pascal   GetTimerResolution() GetTimerResolution
-15  pascal   GetCurrentTime() GetTickCount
+15  pascal   GetCurrentTime() GetCurrentTime
 16  pascal16 ClipCursor(ptr) ClipCursor
 17  pascal16 GetCursorPos(ptr) GetCursorPos
 18  pascal16 SetCapture(word) SetCapture
diff --git a/include/class.h b/include/class.h
index 90c3a3c..073745f 100644
--- a/include/class.h
+++ b/include/class.h
@@ -31,9 +31,10 @@
 #pragma pack(4)
 #endif
 
-
-HCLASS CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance, CLASS **ptr );
-CLASS * CLASS_FindClassPtr( HCLASS hclass );
-
+extern void CLASS_DumpClass( HCLASS hClass );
+extern void CLASS_WalkClasses(void);
+extern HCLASS CLASS_FindClassByName( SEGPTR name, HINSTANCE hinstance,
+                                     CLASS **ptr );
+extern CLASS * CLASS_FindClassPtr( HCLASS hclass );
 
 #endif  /* CLASS_H */
diff --git a/include/debugger.h b/include/debugger.h
index 8cc7c48..42b4206 100644
--- a/include/debugger.h
+++ b/include/debugger.h
@@ -89,10 +89,6 @@
 extern void DEBUG_PrintAddress( const DBG_ADDR *addr, int addrlen );
 extern void DEBUG_Help(void);
 extern void DEBUG_List( DBG_ADDR *addr, int count );
-extern void DEBUG_InitWalk(void);
-extern void DEBUG_WndWalk( HWND );
-extern void DEBUG_WndDump( HWND );
-extern void DEBUG_QueueDump( HQUEUE );
 
   /* debugger/memory.c */
 extern BOOL DEBUG_IsBadReadPtr( const DBG_ADDR *address, int size );
diff --git a/include/except.h b/include/except.h
new file mode 100644
index 0000000..c3654fb
--- /dev/null
+++ b/include/except.h
@@ -0,0 +1,283 @@
+/*
+ * except.h
+ * Copyright (c) 1996, Onno Hovers (onno@stack.urc.tue.nl)
+ */
+
+#ifndef __WINE_EXCEPT_H
+#define __WINE_EXCEPT_H
+
+#include"windows.h"
+
+/* 
+ * general definitions
+ */
+ 
+#ifndef PVOID
+#define PVOID void *
+#endif
+
+/*
+ * exception codes
+ */
+ 
+#define STATUS_WAIT_0                    0x00000000
+#define STATUS_ABANDONED_WAIT_0          0x00000080
+#define STATUS_USER_APC                  0x000000C0
+#define STATUS_TIMEOUT                   0x00000102
+#define STATUS_PENDING                   0x00000103
+#define STATUS_DATATYPE_MISALIGNMENT     0x80000002
+#define STATUS_BREAKPOINT                0x80000003
+#define STATUS_SINGLE_STEP               0x80000004
+#define STATUS_ACCESS_VIOLATION          0xC0000005
+#define STATUS_IN_PAGE_ERROR             0xC0000006
+#define STATUS_NO_MEMORY                 0xC0000017
+#define STATUS_ILLEGAL_INSTRUCTION       0xC000001D
+#define STATUS_NONCONTINUABLE_EXCEPTION  0xC0000025
+#define STATUS_INVALID_DISPOSITION       0xC0000026
+#define STATUS_ARRAY_BOUNDS_EXCEEDED     0xC000008C
+#define STATUS_FLOAT_DENORMAL_OPERAND    0xC000008D
+#define STATUS_FLOAT_DIVIDE_BY_ZERO      0xC000008E
+#define STATUS_FLOAT_INEXACT_RESULT      0xC000008F
+#define STATUS_FLOAT_INVALID_OPERATION   0xC0000090
+#define STATUS_FLOAT_OVERFLOW            0xC0000091
+#define STATUS_FLOAT_STACK_CHECK         0xC0000092
+#define STATUS_FLOAT_UNDERFLOW           0xC0000093
+#define STATUS_INTEGER_DIVIDE_BY_ZERO    0xC0000094
+#define STATUS_INTEGER_OVERFLOW          0xC0000095
+#define STATUS_PRIVILEGED_INSTRUCTION    0xC0000096
+#define STATUS_STACK_OVERFLOW            0xC00000FD
+#define STATUS_CONTROL_C_EXIT            0xC000013A
+
+#define EXCEPTION_ACCESS_VIOLATION      STATUS_ACCESS_VIOLATION
+#define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT
+#define EXCEPTION_BREAKPOINT            STATUS_BREAKPOINT
+#define EXCEPTION_SINGLE_STEP           STATUS_SINGLE_STEP
+#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED
+#define EXCEPTION_FLT_DENORMAL_OPERAND  STATUS_FLOAT_DENORMAL_OPERAND
+#define EXCEPTION_FLT_DIVIDE_BY_ZERO    STATUS_FLOAT_DIVIDE_BY_ZERO
+#define EXCEPTION_FLT_INEXACT_RESULT    STATUS_FLOAT_INEXACT_RESULT
+#define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION
+#define EXCEPTION_FLT_OVERFLOW          STATUS_FLOAT_OVERFLOW
+#define EXCEPTION_FLT_STACK_CHECK       STATUS_FLOAT_STACK_CHECK
+#define EXCEPTION_FLT_UNDERFLOW         STATUS_FLOAT_UNDERFLOW
+#define EXCEPTION_INT_DIVIDE_BY_ZERO    STATUS_INTEGER_DIVIDE_BY_ZERO
+#define EXCEPTION_INT_OVERFLOW          STATUS_INTEGER_OVERFLOW
+#define EXCEPTION_PRIV_INSTRUCTION      STATUS_PRIVILEGED_INSTRUCTION
+#define EXCEPTION_IN_PAGE_ERROR         STATUS_IN_PAGE_ERROR
+
+/*
+ * return values from the actual exception handlers
+ */
+
+#define ExceptionContinueExecution 0
+#define ExceptionContinueSearch    1
+#define ExceptionNestedException   2
+#define ExceptionCollidedUnwind    3
+ 
+/*
+ * return values from filters in except() and from UnhandledExceptionFilter
+ */
+ 
+#define EXCEPTION_EXECUTE_HANDLER        1
+#define EXCEPTION_CONTINUE_SEARCH        0
+#define EXCEPTION_CONTINUE_EXECUTION    -1
+
+/*
+ * from OS/2 2.0 exception handling
+ * Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD
+ */
+
+#define EH_NONCONTINUABLE   0x01
+#define EH_UNWINDING        0x02
+#define EH_EXIT_UNWIND      0x04
+#define EH_STACK_INVALID    0x08
+#define EH_NESTED_CALL      0x10
+
+#define EXCEPTION_CONTINUABLE        0
+#define EXCEPTION_NONCONTINUABLE     EH_NONCONTINUABLE
+ 
+/* 
+ * data types
+ */
+
+/*
+ * The i386 context used by Win32 for almost everything. 
+ */
+  
+#define SIZE_OF_80387_REGISTERS      80
+
+typedef struct _FLOATING_SAVE_AREA
+{
+    DWORD   ControlWord;
+    DWORD   StatusWord;
+    DWORD   TagWord;    
+    DWORD   ErrorOffset;
+    DWORD   ErrorSelector;
+    DWORD   DataOffset;
+    DWORD   DataSelector;    
+    BYTE    RegisterArea[SIZE_OF_80387_REGISTERS];
+    DWORD   Cr0NpxState;
+} FLOATING_SAVE_AREA;
+
+typedef struct __CONTEXT
+{
+    DWORD   ContextFlags;
+    DWORD   Dr0;
+    DWORD   Dr1;    
+    DWORD   Dr2;    
+    DWORD   Dr3;
+    DWORD   Dr6;
+    DWORD   Dr7;    
+    FLOATING_SAVE_AREA FloatSave;
+    DWORD   SegGs;
+    DWORD   SegFs;
+    DWORD   SegEs;
+    DWORD   SegDs;    
+    DWORD   Edi;
+    DWORD   Esi;
+    DWORD   Ebx;
+    DWORD   Edx;    
+    DWORD   Ecx;
+    DWORD   Eax;
+    DWORD   Ebp;    
+    DWORD   Eip;
+    DWORD   SegCs;
+    DWORD   EFlags;
+    DWORD   Esp;
+    DWORD   SegSs;
+} CONTEXT;
+
+typedef struct __CONTEXT *PCONTEXT;
+
+/*
+ * The exception record used by Win32 to give additional information 
+ * about exception to exception handlers.
+ */
+
+#define EXCEPTION_MAXIMUM_PARAMETERS 15
+
+typedef struct __EXCEPTION_RECORD
+{
+    DWORD    ExceptionCode;
+    DWORD    ExceptionFlags;
+    struct __EXCEPTION_RECORD *ExceptionRecord;
+
+    PVOID    ExceptionAddress;
+    DWORD    NumberParameters;
+    DWORD    ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+} EXCEPTION_RECORD;
+
+typedef struct __EXCEPTION_RECORD_MIN
+{
+    DWORD    ExceptionCode;
+    DWORD    ExceptionFlags;
+    struct __EXCEPTION_RECORD *ExceptionRecord;
+
+    PVOID    ExceptionAddress;
+    DWORD    NumberParameters;
+    DWORD    ExceptionInformation[0];
+} EXCEPTION_RECORD_MIN;
+
+typedef struct __EXCEPTION_RECORD *PEXCEPTION_RECORD;
+
+/*
+ * The exception pointers structure passed to exception filters
+ * in except() and the UnhandledExceptionFilter().
+ */
+ 
+typedef struct __EXCEPTION_POINTERS 
+{
+  PEXCEPTION_RECORD  ExceptionRecord;
+  PCONTEXT           ContextRecord;
+} EXCEPTION_POINTERS;
+
+typedef struct __EXCEPTION_POINTERS *PEXCEPTION_POINTERS;
+
+/*
+ * the function pointer to a exception handler
+ */
+
+/* forward definition */
+struct __EXCEPTION_FRAME;
+
+typedef DWORD ( *PEXCEPTION_HANDLER)( PEXCEPTION_RECORD          pexcrec,
+                                      struct __EXCEPTION_FRAME  *pestframe,
+                                      PCONTEXT                   pcontext,
+                                      PVOID                      pdispatcher);
+
+/*
+ * function pointer to a UnhandledExceptionFilter();
+ */
+
+typedef long (WINAPI *__PTOP_EXCFILTER)
+                   (PEXCEPTION_POINTERS ExceptionInfo);
+
+typedef __PTOP_EXCFILTER PTOP_LEVER_EXCEPTION_FILTER;
+typedef __PTOP_EXCFILTER LPTOP_LEVEL_EXCEPTION_FILTER;
+                                 
+/*
+ * The exception frame, used for registering exception handlers 
+ * Win32 cares only about this, but compilers generally emit 
+ * larger exception frames for their own use.
+ */
+
+typedef struct __EXCEPTION_FRAME
+{
+  struct __EXCEPTION_FRAME *Prev;
+  PEXCEPTION_HANDLER       Handler;
+} EXCEPTION_FRAME;
+
+typedef struct __EXCEPTION_FRAME *PEXCEPTION_FRAME;
+
+extern PEXCEPTION_FRAME  TebExceptionFrame asm("%fs:0");
+
+#define EXC_GetFrame()   TebExceptionFrame
+#define EXC_SetFrame(a) (TebExceptionFrame=(a))
+
+/*
+ * Function definitions  
+ */
+ 
+void EXC_RaiseException(DWORD exccode, DWORD excflags, 
+                        DWORD nargs, const LPDWORD pargs,
+                        PCONTEXT pcontext); 
+                        
+void EXC_RtlUnwind( PEXCEPTION_FRAME pestframe,
+                    LPVOID unusedEIP,
+                    PEXCEPTION_RECORD pexcrec,
+                    DWORD contextEAX,
+                    PCONTEXT pcontext );
+                    
+DWORD EXC_CallUnhandledExceptionFilter( PEXCEPTION_RECORD precord,
+                                        PCONTEXT          pcontext);
+
+void EXC_Init(void);
+
+BOOL WINAPI RaiseException(DWORD exccode, DWORD excflags,
+                           DWORD nargs, const LPDWORD pargs);
+
+/*
+ *  this undocumented function is called when an exception
+ *  handler wants all the frames to be unwound. RtlUnwind
+ *  calls all exception handlers with the EH_UNWIND or
+ *  EH_EXIT_UNWIND flags set in the exception record
+ *
+ *  This prototype assumes RtlUnwind takes the same
+ *  parameters as OS/2 2.0 DosUnwindException
+ *  Disassembling RtlUnwind shows this is true, except for
+ *  the TargetEIP parameter, which is unused. There is 
+ *  a fourth parameter, that is used as the eax in the 
+ *  context.   
+ */
+
+BOOL  WINAPI RtlUnwind( PEXCEPTION_FRAME pestframe,
+                        LPVOID unusedEIP,
+                        PEXCEPTION_RECORD pexcrec,
+                        DWORD contextEAX );
+
+DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers);
+
+__PTOP_EXCFILTER WINAPI SetUnhandledExceptionFilter(
+      LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter);
+  
+#endif  /* __WINE_EXCEPT_H */
diff --git a/include/kernel32.h b/include/kernel32.h
index 12e5761..53e28b6 100644
--- a/include/kernel32.h
+++ b/include/kernel32.h
@@ -10,6 +10,7 @@
 int KERN32_Init(void);
 void SetLastError(DWORD error);
 DWORD ErrnoToLastError(int errno_num);
+void ExitProcess(DWORD exitcode);
 
 /* Code page information.
  */
diff --git a/include/listbox.h b/include/listbox.h
index 5430172..60bed75 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -25,6 +25,7 @@
         WORD    CtlID;
 	LPLISTSTRUCT lpFirst;
 	HWND	hSelf;
+	DWORD   dwStyle;      /* added for COMBOLBOX style faking */
 	HWND    hParent;
 	HFONT   hFont;
 	BOOL    bRedrawFlag;
diff --git a/include/message.h b/include/message.h
index bf242b7..870695c 100644
--- a/include/message.h
+++ b/include/message.h
@@ -1,83 +1,20 @@
 /*
- * Message queues definitions
+ * Message definitions
  *
  * Copyright 1993 Alexandre Julliard
  */
 
-#ifndef MESSAGE_H
-#define MESSAGE_H
+#ifndef __WINE_MESSAGE_H
+#define __WINE_MESSAGE_H
 
 #include "windows.h"
 
-#ifndef WINELIB
-#pragma pack(1)
-#endif
-
-  /* Message as stored in the queue (contains the extraInfo field) */
-typedef struct tagQMSG
-{
-    DWORD   extraInfo;  /* Only in 3.1 */
-    MSG     msg;
-} QMSG;
-
-
-typedef struct tagMESSAGEQUEUE
-{
-  HANDLE    next;                   /* 00 Next queue */
-  HTASK     hTask;                  /* 02 hTask owning the queue */
-  WORD      msgSize;                /* 04 Size of messages in the queue */
-  WORD      msgCount;               /* 06 Number of waiting messages */
-  WORD      nextMessage;            /* 08 Next message to be retrieved */
-  WORD      nextFreeMessage;        /* 0a Next available slot in the queue */
-  WORD      queueSize;              /* 0c Size of the queue */
-  DWORD     GetMessageTimeVal WINE_PACKED;  /* 0e Value for GetMessageTime */
-  DWORD     GetMessagePosVal WINE_PACKED;   /* 12 Value for GetMessagePos */
-  WORD      reserved1;              /* 16 Unknown */
-  DWORD     GetMessageExtraInfoVal; /* 18 Value for GetMessageExtraInfo */
-  WORD      reserved2;              /* 1c Unknown */
-  LPARAM    lParam WINE_PACKED;     /* 1e Next 4 values set by SendMessage */
-  WPARAM    wParam;                 /* 22 */
-  UINT      msg;                    /* 24 */
-  HWND      hWnd;                   /* 26 */
-  DWORD     SendMessageReturn;      /* 28 Return value for SendMessage */
-  WORD      wPostQMsg;              /* 2c PostQuitMessage flag */
-  WORD      wExitCode;              /* 2e PostQuitMessage exit code */
-  WORD      reserved3[3];           /* 30 Unknown */
-  WORD      wWinVersion;            /* 36 Expected Windows version */
-  HQUEUE    InSendMessageHandle;    /* 38 Queue of task that sent a message */
-  HTASK     hSendingTask;           /* 3a Handle of task that sent a message */
-  HTASK     hPrevSendingTask;       /* 3c Handle of previous sender */
-  WORD      wPaintCount;            /* 3e Number of WM_PAINT needed */
-  WORD      wTimerCount;            /* 40 Number of timers for this task */
-  WORD      tempStatus;             /* 42 State reset by GetQueueStatus */
-  WORD      status;                 /* 44 Queue state */
-  WORD      wakeMask;               /* 46 Task wake-up mask */
-  WORD      SendMsgReturnPtrs[3];   /* 48 Near ptr to return values (?) */
-  HANDLE    hCurHook;               /* 4e Current hook */
-  HANDLE    hooks[WH_NB_HOOKS];     /* 50 Task hooks list */
-  WORD      reserved4[3];           /* 68 Unknown */
-  QMSG      messages[1];            /* 6e Queue messages */
-} MESSAGEQUEUE;
-
-#ifndef WINELIB
-#pragma pack(4)
-#endif
-
 extern DWORD MSG_WineStartTicks;  /* Ticks at Wine startup */
 
-extern void MSG_IncPaintCount( HANDLE hQueue );
-extern void MSG_DecPaintCount( HANDLE hQueue );
-extern void MSG_IncTimerCount( HANDLE hQueue );
-extern void MSG_DecTimerCount( HANDLE hQueue );
 extern void MSG_Synchronize();
 extern BOOL MSG_WaitXEvent( LONG maxWait );
-extern BOOL MSG_CreateSysMsgQueue( int size );
-extern BOOL MSG_DeleteMsgQueue( HANDLE hQueue );
-extern HTASK MSG_GetQueueTask( HANDLE hQueue );
-extern void hardware_event( WORD message, WORD wParam, LONG lParam,
-			    int xPos, int yPos, DWORD time, DWORD extraInfo );
 extern BOOL MSG_GetHardwareMessage( LPMSG msg );
 extern BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner,
 				    short code, WORD flags, BOOL sendIdle );
 
-#endif  /* MESSAGE_H */
+#endif  /* __WINE_MESSAGE_H */
diff --git a/include/queue.h b/include/queue.h
new file mode 100644
index 0000000..fba9398
--- /dev/null
+++ b/include/queue.h
@@ -0,0 +1,83 @@
+/*
+ * Message queues definitions
+ *
+ * Copyright 1993 Alexandre Julliard
+ */
+
+#ifndef __WINE_QUEUE_H
+#define __WINE_QUEUE_H
+
+#include "windows.h"
+
+#ifndef WINELIB
+#pragma pack(1)
+#endif
+
+  /* Message as stored in the queue (contains the extraInfo field) */
+typedef struct tagQMSG
+{
+    DWORD   extraInfo;  /* Only in 3.1 */
+    MSG     msg;
+} QMSG;
+
+
+typedef struct tagMESSAGEQUEUE
+{
+  HQUEUE    next;                   /* 00 Next queue */
+  HTASK     hTask;                  /* 02 hTask owning the queue */
+  WORD      msgSize;                /* 04 Size of messages in the queue */
+  WORD      msgCount;               /* 06 Number of waiting messages */
+  WORD      nextMessage;            /* 08 Next message to be retrieved */
+  WORD      nextFreeMessage;        /* 0a Next available slot in the queue */
+  WORD      queueSize;              /* 0c Size of the queue */
+  DWORD     GetMessageTimeVal WINE_PACKED;  /* 0e Value for GetMessageTime */
+  DWORD     GetMessagePosVal WINE_PACKED;   /* 12 Value for GetMessagePos */
+  WORD      reserved1;              /* 16 Unknown */
+  DWORD     GetMessageExtraInfoVal; /* 18 Value for GetMessageExtraInfo */
+  WORD      reserved2;              /* 1c Unknown */
+  LPARAM    lParam WINE_PACKED;     /* 1e Next 4 values set by SendMessage */
+  WPARAM    wParam;                 /* 22 */
+  UINT      msg;                    /* 24 */
+  HWND      hWnd;                   /* 26 */
+  DWORD     SendMessageReturn;      /* 28 Return value for SendMessage */
+  WORD      wPostQMsg;              /* 2c PostQuitMessage flag */
+  WORD      wExitCode;              /* 2e PostQuitMessage exit code */
+  WORD      reserved3[3];           /* 30 Unknown */
+  WORD      wWinVersion;            /* 36 Expected Windows version */
+  HQUEUE    InSendMessageHandle;    /* 38 Queue of task that sent a message */
+  HTASK     hSendingTask;           /* 3a Handle of task that sent a message */
+  HTASK     hPrevSendingTask;       /* 3c Handle of previous sender */
+  WORD      wPaintCount;            /* 3e Number of WM_PAINT needed */
+  WORD      wTimerCount;            /* 40 Number of timers for this task */
+  WORD      tempStatus;             /* 42 State reset by GetQueueStatus */
+  WORD      status;                 /* 44 Queue state */
+  WORD      wakeMask;               /* 46 Task wake-up mask */
+  WORD      SendMsgReturnPtrs[3];   /* 48 Near ptr to return values (?) */
+  HANDLE    hCurHook;               /* 4e Current hook */
+  HANDLE    hooks[WH_NB_HOOKS];     /* 50 Task hooks list */
+  WORD      reserved4[3];           /* 68 Unknown */
+  QMSG      messages[1];            /* 6e Queue messages */
+} MESSAGEQUEUE;
+
+#ifndef WINELIB
+#pragma pack(4)
+#endif
+
+extern void QUEUE_DumpQueue( HQUEUE hQueue );
+extern void QUEUE_WalkQueues(void);
+extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
+extern void QUEUE_IncPaintCount( HQUEUE hQueue );
+extern void QUEUE_DecPaintCount( HQUEUE hQueue );
+extern void QUEUE_IncTimerCount( HQUEUE hQueue );
+extern void QUEUE_DecTimerCount( HQUEUE hQueue );
+extern BOOL QUEUE_CreateSysMsgQueue( int size );
+extern BOOL QUEUE_DeleteMsgQueue( HQUEUE hQueue );
+extern HTASK QUEUE_GetQueueTask( HQUEUE hQueue );
+extern BOOL QUEUE_AddMsg( HQUEUE hQueue, MSG * msg, DWORD extraInfo );
+extern int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND hwnd,
+                          int first, int last );
+extern void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos );
+extern void hardware_event( WORD message, WORD wParam, LONG lParam,
+			    int xPos, int yPos, DWORD time, DWORD extraInfo );
+
+#endif  /* __WINE_QUEUE_H */
diff --git a/include/spy.h b/include/spy.h
index d4d9c65..c039241 100644
--- a/include/spy.h
+++ b/include/spy.h
@@ -5,18 +5,16 @@
 #ifndef __WINE_SPY_H
 #define __WINE_SPY_H
 
-#define SPY_DISPATCHMESSAGE     0x0099
-#define SPY_SENDMESSAGE         0x0100
-#define SPY_DEFWNDPROC          0x0101
+#define SPY_DISPATCHMESSAGE     0x0100
+#define SPY_SENDMESSAGE         0x0101
+#define SPY_DEFWNDPROC          0x0102
 
 #define SPY_RESULT_OK           0x0000
 #define SPY_RESULT_INVALIDHWND  0x0001
 
-#define SPY_MAX_MSGNUM          WM_USER
-#define SPY_MAX_INDENTLEVEL     64
-
-extern void EnterSpyMessage( int, HWND, WORD, WORD, LONG);
-extern void  ExitSpyMessage( int, HWND, WORD, LONG);
-extern void         SpyInit( void);
+extern void SPY_EnterMessage( int iFlag, HWND hwnd, UINT msg,
+                              WPARAM wParam, LPARAM lParam );
+extern void SPY_ExitMessage( int iFlag, HWND hwnd, UINT msg, LRESULT lReturn );
+extern int SPY_Init(void);
 
 #endif /* __WINE_SPY_H */
diff --git a/include/task.h b/include/task.h
index d2a2b30..82bc80e 100644
--- a/include/task.h
+++ b/include/task.h
@@ -73,7 +73,7 @@
     WORD    version;                    /* Expected Windows version */
     HANDLE  hInstance;                  /* Instance handle for this task */
     HMODULE hModule;                    /* Module handle */
-    HANDLE  hQueue;                     /* Selector of task message queue */
+    HQUEUE  hQueue;                     /* Selector of task message queue */
     HTASK   hParent;                    /* Selector of TDB of parent task */
     WORD    signal_flags;               /* Flags related to signal handler */
     DWORD   sighandler WINE_PACKED;     /* Signal handler */
diff --git a/include/win.h b/include/win.h
index 37184a7..f3b49b1 100644
--- a/include/win.h
+++ b/include/win.h
@@ -75,6 +75,8 @@
 
   /* Window functions */
 extern WND *WIN_FindWndPtr( HWND hwnd );
+extern void WIN_DumpWindow( HWND hwnd );
+extern void WIN_WalkWindows( HWND hwnd, int indent );
 extern Window WIN_GetXWindow( HWND hwnd );
 extern BOOL WIN_UnlinkWindow( HWND hwnd );
 extern BOOL WIN_LinkWindow( HWND hwnd, HWND hwndInsertAfter );
diff --git a/include/windows.h b/include/windows.h
index 3fd0086..53be8c8 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -2222,6 +2222,14 @@
 typedef COMPAREITEMSTRUCT NEAR* PCOMPAREITEMSTRUCT;
 typedef COMPAREITEMSTRUCT FAR* LPCOMPAREITEMSTRUCT;
 
+/* WM_KEYUP/DOWN/CHAR HIWORD(lParam) flags */
+#define KF_EXTENDED         0x0100
+#define KF_DLGMODE          0x0800
+#define KF_MENUMODE         0x1000
+#define KF_ALTDOWN          0x2000
+#define KF_REPEAT           0x4000
+#define KF_UP               0x8000
+
 /* Virtual key codes */
 #define VK_LBUTTON          0x01
 #define VK_RBUTTON          0x02
@@ -2947,7 +2955,7 @@
 VOID       GetSystemTime(LPSYSTEMTIME); /* Win32 */
 DWORD      GetTabbedTextExtent(HDC,LPSTR,int,int,LPINT);
 HINSTANCE  GetTaskDS(void);
-HGLOBAL    GetTaskQueue(HTASK);
+HQUEUE     GetTaskQueue(HTASK);
 BYTE       GetTempDrive(BYTE);
 INT        GetTempFileName(BYTE,LPCSTR,UINT,LPSTR);
 WORD       GetTextAlign(HDC);
@@ -3122,7 +3130,7 @@
 BOOL       Polyline(HDC,LPPOINT,int);
 BOOL       PostAppMessage(HANDLE,WORD,WORD,LONG);
 BOOL       PostMessage(HWND,WORD,WORD,LONG);
-void       PostQuitMessage(int);
+void       PostQuitMessage(INT);
 WORD       PrestoChangoSelector(WORD,WORD);
 void       ProfClear(void);
 void       ProfFinish(void);
@@ -3244,7 +3252,7 @@
 HWND       SetSysModalWindow(HWND);
 WORD       SetSystemPaletteUse(HDC,WORD);
 WORD       SetSystemTimer(HWND,WORD,WORD,FARPROC);
-HGLOBAL    SetTaskQueue(HTASK,HGLOBAL);
+HQUEUE     SetTaskQueue(HTASK,HQUEUE);
 WORD       SetTextAlign(HDC,WORD);
 short      SetTextCharacterExtra(HDC,short);
 DWORD      SetTextColor(HDC,DWORD);
diff --git a/loader/main.c b/loader/main.c
index 25c0990..0aca285 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -22,7 +22,7 @@
 #include "dialog.h"
 #include "directory.h"
 #include "drive.h"
-#include "message.h"
+#include "queue.h"
 #include "syscolor.h"
 #include "sysmetrics.h"
 #include "gdi.h"
@@ -54,7 +54,8 @@
     /* Load the configuration file */
     if (!PROFILE_LoadWineIni()) return 0;
 
-    SpyInit();
+    /* Initialize message spying */
+    if (!SPY_Init()) return 0;
 
 #ifndef WINELIB
       /* Initialize relay code */
@@ -120,7 +121,10 @@
 
       /* Create system message queue */
     queueSize = GetProfileInt( "windows", "TypeAhead", 120 );
-    if (!MSG_CreateSysMsgQueue( queueSize )) return 0;
+    if (!QUEUE_CreateSysMsgQueue( queueSize )) return 0;
+
+    /* Set double click time */
+    SetDoubleClickTime( GetProfileInt( "windows", "DoubleClickSpeed", 452 ) );
 
     return 1;
 }
diff --git a/loader/signal.c b/loader/signal.c
index adc2c64..3bd175f7 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -22,8 +22,6 @@
 #if !defined(BSD4_4) || defined(linux) || defined(__FreeBSD__)
 char * cstack[4096];
 #endif
-struct sigaction segv_act;
-struct sigaction usr2_act;
 
 #ifdef linux
 extern void ___sig_restore();
@@ -56,27 +54,32 @@
 static void win_fault(int signal, int code, struct sigcontext *context)
 {
 #endif
-    if (signal != SIGTRAP)
+    if (signal == SIGTRAP)
+    {
+        /* If SIGTRAP not caused by breakpoint or single step 
+           don't jump into the debugger */
+        if (!(EFL_reg(context) & STEP_FLAG))
+        {
+            DBG_ADDR addr;
+            addr.seg = CS_reg(context);
+            addr.off = EIP_reg(context) - 1;
+            if (DEBUG_FindBreakpoint(&addr) == -1) return;
+        }
+    }
+    else if (signal != SIGHUP)
     {
         if (CS_reg(context) == WINE_CODE_SELECTOR)
         {
             fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)."
-                            "  Please debug\n",
+                            "  Please debug.\n",
                             CS_reg(context), EIP_reg(context) );
         }
-        else if (INSTR_EmulateInstruction( context )) return;
-        fprintf( stderr,"In win_fault %x:%lx\n",
-                 CS_reg(context), EIP_reg(context) );
-    }
-
-      /* If SIGTRAP not caused by breakpoint or single step 
-         don't jump into the debugger */
-    if ((signal == SIGTRAP) && !(EFL_reg(context) & STEP_FLAG))
-    {
-        DBG_ADDR addr;
-        addr.seg = CS_reg(context);
-        addr.off = EIP_reg(context) - 1;
-        if (DEBUG_FindBreakpoint(&addr) == -1) return;
+        else
+        {
+            if (INSTR_EmulateInstruction( context )) return;
+            fprintf( stderr, "Segmentation fault in Windows program %x:%lx.\n",
+                     CS_reg(context), EIP_reg(context) );
+        }
     }
 
     XUngrabPointer(display, CurrentTime);
@@ -85,131 +88,104 @@
     wine_debug( signal, context );  /* Enter our debugger */
 }
 
+
+/**********************************************************************
+ *		SIGNAL_SetHandler
+ */
+static void SIGNAL_SetHandler( int sig, void (*func)() )
+{
+    int ret;
+    struct sigaction sig_act;
+
+#ifdef linux
+    sig_act.sa_handler = func;
+    /* Point to the top of the stack, minus 4 just in case, and make
+       it aligned  */
+    sig_act.sa_restorer = 
+        (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
+    ret = wine_sigaction( sig, &sig_act, NULL );
+#endif  /* linux */
+
+#if defined(__NetBSD__) || defined(__FreeBSD__)
+    sig_act.sa_handler = func;
+    sig_act.sa_flags = SA_ONSTACK;
+    sig_act.sa_mask = sig_mask;
+    ret = sigaction( sig, &sig_act, NULL );
+#endif  /* __FreeBSD__ || __NetBSD__ */
+
+#if defined (__svr4__)
+    sig_act.sa_handler = func;
+    sig_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
+    sig_act.sa_mask = sig_mask;
+    ret = sigaction( sig, &sig_act, NULL );
+#endif  /* __svr4__ */
+
+    if (ret < 0)
+    {
+        perror( "sigaction" );
+        exit(1);
+    }
+}
+
+
+/**********************************************************************
+ *		init_wine_signals
+ */
 void init_wine_signals(void)
 {
-        extern void stop_wait(int a);
-#ifdef linux
-	segv_act.sa_handler = (__sighandler_t) win_fault;
-	/* Point to the top of the stack, minus 4 just in case, and make
-	   it aligned  */
-	segv_act.sa_restorer = 
-	    (void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
-	/* Point to the top of the stack, minus 4 just in case, and make
-	   it aligned  */
-	wine_sigaction(SIGSEGV, &segv_act, NULL);
-	wine_sigaction(SIGILL, &segv_act, NULL);
-	wine_sigaction(SIGFPE, &segv_act, NULL);
-#ifdef SIGBUS
-	wine_sigaction(SIGBUS, &segv_act, NULL);
-#endif
-	wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
-#ifdef CONFIG_IPC
-	usr2_act.sa_restorer= segv_act.sa_restorer;
-	usr2_act.sa_handler = (__sighandler_t) stop_wait;
-	wine_sigaction(SIGUSR2, &usr2_act, NULL);
-#endif  /* CONFIG_IPC */
-#endif  /* linux */
+    extern void stop_wait(int a);
+
 #if defined(__NetBSD__) || defined(__FreeBSD__)
-        sigset_t sig_mask;
-        struct sigaltstack ss;
+    sigset_t sig_mask;
+    struct sigaltstack ss;
         
 #if !defined (__FreeBSD__) 
-        if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
+    if ((ss.ss_base = malloc(MINSIGSTKSZ)) == NULL) {
 #else
-        if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
+    if ((ss.ss_sp = malloc(MINSIGSTKSZ)) == NULL) {
 #endif
-	        fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
-		        MINSIGSTKSZ);
-		exit(1);
-	}
-	ss.ss_size = MINSIGSTKSZ;
-        ss.ss_flags = 0;
-        if (sigaltstack(&ss, NULL) < 0) {
-                perror("sigstack");
-                exit(1);
-        }
-        sigemptyset(&sig_mask);
-        segv_act.sa_handler = (void (*)) win_fault;
-	segv_act.sa_flags = SA_ONSTACK;
-        segv_act.sa_mask = sig_mask;
-	if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
-                perror("sigaction: SIGBUS");
-                exit(1);
-        }
-        segv_act.sa_handler = (void (*)) win_fault;
-	segv_act.sa_flags = SA_ONSTACK;
-        segv_act.sa_mask = sig_mask;
-	if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
-                perror("sigaction: SIGSEGV");
-                exit(1);
-        }
-        segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
-	segv_act.sa_flags = SA_ONSTACK;
-        segv_act.sa_mask = sig_mask;
-	if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
-                perror("sigaction: SIGTRAP");
-                exit(1);
-        }
-#ifdef CONFIG_IPC
-        usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */
-	usr2_act.sa_flags = SA_ONSTACK;
-        usr2_act.sa_mask = sig_mask;
-	if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) {
-                perror("sigaction: SIGUSR2");
-                exit(1);
-        }
-#endif  /* CONFIG_IPC */
+        fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
+                MINSIGSTKSZ);
+        exit(1);
+    }
+    ss.ss_size = MINSIGSTKSZ;
+    ss.ss_flags = 0;
+    if (sigaltstack(&ss, NULL) < 0) {
+        perror("sigstack");
+        exit(1);
+    }
+    sigemptyset(&sig_mask);
 #endif  /* __FreeBSD__ || __NetBSD__ */
-#if defined (__svr4__)
-        sigset_t sig_mask;
-        struct sigaltstack ss;
-        
-        if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
-            fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
-                    SIGSTKSZ);
-            exit(1);
-	}
-        ss.ss_size = SIGSTKSZ;
-        ss.ss_flags = 0;
-        if (sigaltstack(&ss, NULL) < 0) {
-            perror("sigstack");
-            exit(1);
-        }
-        sigemptyset(&sig_mask);
-        segv_act.sa_handler = (void (*)) win_fault;
-	segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
-        segv_act.sa_mask = sig_mask;
-	if (sigaction(SIGBUS, &segv_act, NULL) < 0) {
-            perror("sigaction: SIGBUS");
-            exit(1);
-        }
-        segv_act.sa_handler = (void (*)) win_fault;
-	segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
-        segv_act.sa_mask = sig_mask;
-	if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
-            perror("sigaction: SIGSEGV");
-            exit(1);
-        }
-        
 
-        segv_act.sa_handler = (void (*)) win_fault; /* For breakpoints */
-	segv_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
-        segv_act.sa_mask = sig_mask;
-	if (sigaction(SIGTRAP, &segv_act, NULL) < 0) {
-            perror("sigaction: SIGTRAP");
-            exit(1);
-        }
-#ifdef CONFIG_IPC
-        usr2_act.sa_handler = (void (*)) stop_wait; /* For breakpoints */
-	usr2_act.sa_flags = SA_ONSTACK | SA_SIGINFO;
-        usr2_act.sa_mask = sig_mask;
-	if (sigaction(SIGUSR2, &usr2_act, NULL) < 0) {
-            perror("sigaction: SIGUSR2");
-            exit(1);
-        }
-#endif  /* CONFIG_IPC */
+#if defined (__svr4__)
+    sigset_t sig_mask;
+    struct sigaltstack ss;
         
+    if ((ss.ss_sp = malloc(SIGSTKSZ) ) == NULL) {
+        fprintf(stderr, "Unable to allocate signal stack (%d bytes)\n",
+                SIGSTKSZ);
+        exit(1);
+    }
+    ss.ss_size = SIGSTKSZ;
+    ss.ss_flags = 0;
+    if (sigaltstack(&ss, NULL) < 0) {
+        perror("sigstack");
+        exit(1);
+    }
+    sigemptyset(&sig_mask);
 #endif  /* __svr4__ */
+
+    SIGNAL_SetHandler( SIGSEGV, (void (*)())win_fault );
+    SIGNAL_SetHandler( SIGILL,  (void (*)())win_fault );
+    SIGNAL_SetHandler( SIGFPE,  (void (*)())win_fault );
+    SIGNAL_SetHandler( SIGTRAP, (void (*)())win_fault ); /* For debugger */
+    SIGNAL_SetHandler( SIGHUP,  (void (*)())win_fault ); /* For forced break */
+#ifdef SIGBUS
+    SIGNAL_SetHandler( SIGBUS,  (void (*)())win_fault );
+#endif
+#ifdef CONFIG_IPC
+    SIGNAL_SetHandler( SIGUSR2, (void (*)())stop_wait ); /* For IPC */
+#endif
 }
 
 #endif /* ifndef WINELIB */
diff --git a/loader/task.c b/loader/task.c
index e721cf1..d8a0830 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -16,11 +16,11 @@
 #include "debugger.h"
 #include "global.h"
 #include "instance.h"
-#include "message.h"
 #include "miscemu.h"
 #include "module.h"
 #include "neexe.h"
 #include "options.h"
+#include "queue.h"
 #include "selectors.h"
 #include "toolhelp.h"
 #include "stddebug.h"
@@ -583,7 +583,7 @@
 
     /* Free the message queue */
 
-    MSG_DeleteMsgQueue( pTask->hQueue );
+    QUEUE_DeleteMsgQueue( pTask->hQueue );
 
     /* Free the selector aliases */
 
@@ -988,9 +988,9 @@
 /***********************************************************************
  *           SetTaskQueue  (KERNEL.34)
  */
-HGLOBAL SetTaskQueue( HANDLE hTask, HGLOBAL hQueue )
+HQUEUE SetTaskQueue( HANDLE hTask, HQUEUE hQueue )
 {
-    HGLOBAL hPrev;
+    HQUEUE hPrev;
     TDB *pTask;
 
     if (!hTask) hTask = hCurrentTask;
@@ -1004,7 +1004,7 @@
 /***********************************************************************
  *           GetTaskQueue  (KERNEL.35)
  */
-HGLOBAL GetTaskQueue( HANDLE hTask )
+HQUEUE GetTaskQueue( HANDLE hTask )
 {
     TDB *pTask;
 
diff --git a/misc/shell.c b/misc/shell.c
index 8e4b9f7..2c46817 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -194,8 +194,8 @@
 
 	f=fopen(from,"r");
 	if (f==NULL) {
-		perror("fopen-registry-read");
-		return;
+            dprintf_reg(stddeb,"fopen-registry-read");
+            return;
 	}
 	switch ((DWORD)hKey) {
 	case HKEY_CLASSES_ROOT:
diff --git a/misc/spy.c b/misc/spy.c
index 326e0f6..065387c 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -1,4 +1,5 @@
-/* SPY.C
+/*
+ * Message spying routines
  *
  * Copyright 1994, Bob Amstadt
  *           1995, Alex Korobka  
@@ -6,16 +7,18 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>
 #include <string.h>
 #include "windows.h"
+#include "module.h"
 #include "options.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "spy.h"
 
-const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] =
+#define SPY_MAX_MSGNUM   WM_USER
+#define SPY_INDENT_UNIT  4  /* 4 spaces */
+
+static const char *MessageTypeNames[SPY_MAX_MSGNUM + 1] =
 {
     "WM_NULL",			/* 0x00 */
     "WM_CREATE",	
@@ -75,10 +78,12 @@
     "WM_QUERYDRAGICON",
     "WM_QUERYSAVESTATE",
     "WM_COMPAREITEM", 
-    "WM_TESTING", NULL, 
+    "WM_TESTING",
+    NULL, 
     "WM_OTHERWINDOWCREATED", 
     "WM_OTHERWINDOWDESTROYED", 
-    "WM_ACTIVATESHELLWINDOW", NULL,
+    "WM_ACTIVATESHELLWINDOW",
+    NULL,
 
     NULL, 		        /* 0x40 */
     "WM_COMPACTING", NULL, NULL, 
@@ -391,164 +396,121 @@
     "WM_USER"
 };
 
-static BOOL  	SpyFilters [SPY_MAX_MSGNUM+1];
-static BOOL 	SpyIncludes[SPY_MAX_MSGNUM+1];
 
-static int      iSpyMessageIndentLevel  = 0;
-       char     lpstrSpyMessageIndent[SPY_MAX_INDENTLEVEL]; /* referenced in debugger/info.c */
-static char    *lpstrSpyMessageFromWine = "Wine";
-static char     lpstrSpyMessageFromTask[10]; 
-static char    *lpstrSpyMessageFromSelf = "self";
-static char    *lpstrSpyMessageFrom     =  NULL;
+static BOOL SPY_Exclude[SPY_MAX_MSGNUM+1] = { FALSE, };
+static int SPY_IndentLevel  = 0;
 
+#define SPY_EXCLUDE(msg) \
+    (SPY_Exclude[(msg) > SPY_MAX_MSGNUM ? SPY_MAX_MSGNUM : (msg)])
 
-/**********************************************************************
- *			      EnterSpyMessage
+/***********************************************************************
+ *           SPY_GetMsgName
  */
-void EnterSpyMessage(int iFlag, HWND hWnd, WORD msg, WORD wParam, LONG lParam)
+static const char *SPY_GetMsgName( UINT msg )
 {
-  HTASK	hTask     = GetWindowTask(hWnd);
-  WORD 	wCheckMsg = (msg > WM_USER)? WM_USER: msg;
+    static char buffer[20];
 
-  if( !SpyIncludes[wCheckMsg] || SpyFilters[wCheckMsg]) return;
-
-  /* each SPY_SENDMESSAGE must be complemented by call to ExitSpyMessage */
-  switch(iFlag)
-   {
-	case SPY_DISPATCHMESSAGE:
-		    if(msg <= WM_USER)
-		      {
-		       if(MessageTypeNames[msg])
-		          dprintf_message(stddeb,"("NPFMT") message [%04x] %s dispatched  wp=%04x lp=%08lx\n",
-		                          hWnd, msg, MessageTypeNames[msg], wParam, lParam);
-		       else
-		          dprintf_message(stddeb,"("NPFMT") message [%04x] dispatched  wp=%04x lp=%08lx\n",
-		                          hWnd, msg, wParam, lParam);
-		      }
-		    else
-		          dprintf_message(stddeb,"("NPFMT") message [%04x] WM_USER+%04d dispatched  wp=%04x lp=%08lx\n",
-		                          hWnd, msg, msg-WM_USER ,wParam ,lParam);
-		    break;
-	case SPY_SENDMESSAGE:
-		    if(hTask == GetCurrentTask())
- 		      lpstrSpyMessageFrom = lpstrSpyMessageFromSelf;
-		    else if(hTask == NULL)
-  		      	   lpstrSpyMessageFrom = lpstrSpyMessageFromWine;
-  		    	 else
-  				{
-  				   sprintf(lpstrSpyMessageFromTask, "task "NPFMT, hTask);	
-  				   lpstrSpyMessageFrom = lpstrSpyMessageFromTask;
-  				}
-		     
-	            if(msg <= WM_USER)
-	                {
-	                  if(MessageTypeNames[msg])
-			      dprintf_message(stddeb,"%s("NPFMT") message [%04x] %s sent from %s wp=%04x lp=%08lx\n",
-                                   	      lpstrSpyMessageIndent,
-                                   	      hWnd, msg, MessageTypeNames[msg],
-                                   	      lpstrSpyMessageFrom,
-                                   	      wParam, lParam);
-	                  else
-	                      dprintf_message(stddeb,"%s("NPFMT") message [%04x] sent from %s wp=%04x lp=%08lx\n",
-                                   	      lpstrSpyMessageIndent,
-                                   	      hWnd, msg,
-                                   	      lpstrSpyMessageFrom,
-                                   	      wParam, lParam);
-          		}
-        	    else
-             		  dprintf_message(stddeb,"%s("NPFMT") message [%04x] WM_USER+%04x sent from %s wp=%04x lp=%08lx\n",
-                               		  lpstrSpyMessageIndent,
-                               		  hWnd, msg, msg-WM_USER,
-                               		  lpstrSpyMessageFrom,
-                             		  wParam, lParam);
-
-	            if(SPY_MAX_INDENTLEVEL > iSpyMessageIndentLevel ) 
-		    	{
-			  iSpyMessageIndentLevel++;
-			  lpstrSpyMessageIndent[iSpyMessageIndentLevel]='\0';
-			  lpstrSpyMessageIndent[iSpyMessageIndentLevel-1]  ='\t';
-		      	}
-		    break;   
-	case SPY_DEFWNDPROC:
-		    if(msg <= WM_USER)
-		        if(MessageTypeNames[msg])
-		           dprintf_message(stddeb, "%s("NPFMT") DefWindowProc: %s [%04x]  wp=%04x lp=%08lx\n",
-		                           lpstrSpyMessageIndent,
-		                           hWnd, MessageTypeNames[msg], msg, wParam, lParam );
-		        else
-		           dprintf_message(stddeb, "%s("NPFMT") DefWindowProc: [%04x]  wp=%04x lp=%08lx\n",
-		                           lpstrSpyMessageIndent,
-		                           hWnd, msg, wParam, lParam );
-		    else
-		        dprintf_message(stddeb, "%s("NPFMT") DefWindowProc: WM_USER+%d [%04x] wp=%04x lp=%08lx\n",
-		                        lpstrSpyMessageIndent,
-		                        hWnd, msg - WM_USER, msg, wParam, lParam );
-		    break;
-	default:		    
-   }  
-
+    if (msg <= SPY_MAX_MSGNUM)
+    {
+        if (!MessageTypeNames[msg]) return "???";
+        return MessageTypeNames[msg];
+    }
+    sprintf( buffer, "WM_USER+%04x\n", msg - WM_USER );
+    return buffer;
 }
 
-/**********************************************************************
- *			      ExitSpyMessage
+
+/***********************************************************************
+ *           SPY_EnterMessage
  */
-void ExitSpyMessage(int iFlag, HWND hWnd, WORD msg, LONG lReturn)
+void SPY_EnterMessage( int iFlag, HWND hWnd, UINT msg,
+                       WPARAM wParam, LPARAM lParam )
 {
-  WORD wCheckMsg = (msg > WM_USER)? WM_USER: msg;
+    if (!debugging_message || SPY_EXCLUDE(msg)) return;
 
-  if( !SpyIncludes[wCheckMsg] || SpyFilters[wCheckMsg]) return;
-
-  if( iSpyMessageIndentLevel )
+    /* each SPY_SENDMESSAGE must be complemented by call to ExitSpyMessage */
+    switch(iFlag)
     {
-      iSpyMessageIndentLevel--;
-      lpstrSpyMessageIndent[iSpyMessageIndentLevel]='\0';
-    }
+    case SPY_DISPATCHMESSAGE:
+        dprintf_message(stddeb,"("NPFMT") message [%04x] %s dispatched  wp=%04x lp=%08lx\n",
+                        hWnd, msg, SPY_GetMsgName( msg ),
+                        wParam, lParam);
+        break;
 
-  switch(iFlag)
+    case SPY_SENDMESSAGE:
+        {
+            char taskName[30];
+            HTASK hTask = GetWindowTask(hWnd);
+            if (hTask == GetCurrentTask()) strcpy( taskName, "self" );
+            else if (!hTask) strcpy( taskName, "Wine" );
+            else sprintf( taskName, "task "NPFMT" %s",
+                          hTask, MODULE_GetModuleName( GetExePtr(hTask) ) );
+
+            dprintf_message(stddeb,"%*s("NPFMT") message [%04x] %s sent from %s wp=%04x lp=%08lx\n",
+                            SPY_IndentLevel, "", hWnd, msg,
+                            SPY_GetMsgName( msg ), taskName, wParam, lParam );
+            SPY_IndentLevel += SPY_INDENT_UNIT;
+        }
+        break;   
+
+    case SPY_DEFWNDPROC:
+        dprintf_message(stddeb, "%*s("NPFMT") DefWindowProc: %s [%04x]  wp=%04x lp=%08lx\n",
+                        SPY_IndentLevel, "", hWnd, SPY_GetMsgName( msg ),
+                        msg, wParam, lParam );
+        break;
+    }  
+}
+
+
+/***********************************************************************
+ *           SPY_ExitMessage
+ */
+void SPY_ExitMessage( int iFlag, HWND hWnd, UINT msg, LRESULT lReturn )
+{
+    if (!debugging_message || SPY_EXCLUDE(msg)) return;
+    if (SPY_IndentLevel) SPY_IndentLevel -= SPY_INDENT_UNIT;
+
+    switch(iFlag)
     {
-	case SPY_RESULT_INVALIDHWND: 
-		dprintf_message(stddeb,"%s("NPFMT") message [%04x] HAS INVALID HWND\n",
-                                lpstrSpyMessageIndent, hWnd, msg);
-	        break;
-	case SPY_RESULT_OK:
-		dprintf_message(stddeb,"%s("NPFMT") message [%04x] returned %08lx\n",
-	                        lpstrSpyMessageIndent, hWnd, msg, lReturn);
-		break;
-	default:
+    case SPY_RESULT_INVALIDHWND: 
+        dprintf_message(stddeb,"%*s("NPFMT") message [%04x] %s HAS INVALID HWND\n",
+                        SPY_IndentLevel, "", hWnd, msg,
+                        SPY_GetMsgName( msg ) );
+        break;
+    case SPY_RESULT_OK:
+        dprintf_message(stddeb,"%*s("NPFMT") message [%04x] %s returned %08lx\n",
+                        SPY_IndentLevel, "", hWnd, msg,
+                        SPY_GetMsgName( msg ), lReturn );
+        break;
     }
 }
 
-/**********************************************************************
- *					SpyInit
+
+/***********************************************************************
+ *           SPY_Init
  */
-void SpyInit(void)
+int SPY_Init(void)
 {
-    int      i;
-    char     lpstrBuffer[512];
+    int i;
+    char buffer[512];
 
-    for(i=0; i <= SPY_MAX_MSGNUM; i++) SpyFilters[i] = SpyIncludes[i] = FALSE;
+    PROFILE_GetWineIniString( "Spy", "Include", "", buffer, sizeof(buffer) );
+    if (buffer[0] && strcmp( buffer, "INCLUDEALL" ))
+    {
+        dprintf_message( stddeb, "SpyInit: Include=%s\n", buffer );
+        for (i = 0; i <= SPY_MAX_MSGNUM; i++)
+            SPY_Exclude[i] = (MessageTypeNames[i] && !strstr(buffer,MessageTypeNames[i]));
+    }
 
-    PROFILE_GetWineIniString( "spy", "Exclude", "",
-                              lpstrBuffer, sizeof(lpstrBuffer) );
-    dprintf_message(stddeb,"SpyInit: Exclude=%s\n",lpstrBuffer);
-    if( *lpstrBuffer != 0 )
-      if(strstr(lpstrBuffer,"EXCLUDEALL"))
-	for(i=0; i <= SPY_MAX_MSGNUM; i++) SpyFilters[i] = TRUE;
-      else
-        for(i=0; i <= SPY_MAX_MSGNUM; i++)
-	    if(MessageTypeNames[i])
-	       if(strstr(lpstrBuffer,MessageTypeNames[i])) SpyFilters[i] = TRUE; 
-
-    PROFILE_GetWineIniString( "spy", "Include", "INCLUDEALL",
-                              lpstrBuffer, sizeof(lpstrBuffer) );
-    dprintf_message(stddeb,"SpyInit: Include=%s\n",lpstrBuffer);
-    if( *lpstrBuffer != 0 )
-      if(strstr(lpstrBuffer,"INCLUDEALL"))
-        for(i=0; i <= SPY_MAX_MSGNUM; i++) SpyIncludes[i] = TRUE;
-      else 
-        for(i=0; i <= SPY_MAX_MSGNUM; i++)
-            if(MessageTypeNames[i])
-               if(strstr(lpstrBuffer,MessageTypeNames[i])) SpyIncludes[i] = TRUE;
-
+    PROFILE_GetWineIniString( "Spy", "Exclude", "", buffer, sizeof(buffer) );
+    if (buffer[0])
+    {
+        dprintf_message( stddeb, "SpyInit: Exclude=%s\n", buffer );
+        if (!strcmp( buffer, "EXCLUDEALL" ))
+            for (i = 0; i <= SPY_MAX_MSGNUM; i++) SPY_Exclude[i] = TRUE;
+        else
+            for (i = 0; i <= SPY_MAX_MSGNUM; i++)
+                SPY_Exclude[i] = (MessageTypeNames[i] && strstr(buffer,MessageTypeNames[i]));
+    }
+    return 1;
 }
-
diff --git a/misc/user.c b/misc/user.c
index 4fe51e8..0a3cd4f 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -1,14 +1,15 @@
 /*
-static char RCSId[] = "$Id: user.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
-static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
-*/
+ * Misc. USER functions
+ *
+ * Copyright 1993 Robert J. Amstadt
+ */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include "windows.h"
 #include "gdi.h"
 #include "user.h"
 #include "win.h"
-#include "message.h"
 #include "toolhelp.h"
 
 #define USER_HEAP_SIZE          0x10000
@@ -64,26 +65,6 @@
 
 
 /***********************************************************************
- *           TimerCount   (TOOLHELP.80)
- */
-BOOL TimerCount( TIMERINFO *pTimerInfo )
-{
-        /* FIXME
-         * In standard mode, dwmsSinceStart = dwmsThisVM 
-         *
-         * I tested this, under Windows in enhanced mode, and
-         * if you never switch VM (ie start/stop DOS) these
-         * values should be the same as well. 
-         *
-         * Also, Wine should adjust for the hardware timer
-         * to reduce the amount of error to ~1ms. 
-         * I can't be bothered, can you?
-         */
-        pTimerInfo->dwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount();
-        return TRUE;
-}
-
-/***********************************************************************
  *           USER_HeapInit
  */
 BOOL USER_HeapInit(void)
@@ -96,6 +77,27 @@
 #endif
 
 
+/***********************************************************************
+ *           TimerCount   (TOOLHELP.80)
+ */
+BOOL TimerCount( TIMERINFO *pTimerInfo )
+{
+    /* FIXME
+     * In standard mode, dwmsSinceStart = dwmsThisVM 
+     *
+     * I tested this, under Windows in enhanced mode, and
+     * if you never switch VM (ie start/stop DOS) these
+     * values should be the same as well. 
+     *
+     * Also, Wine should adjust for the hardware timer
+     * to reduce the amount of error to ~1ms. 
+     * I can't be bothered, can you?
+     */
+    pTimerInfo->dwmsSinceStart = pTimerInfo->dwmsThisVM = GetTickCount();
+    return TRUE;
+}
+
+
 /**********************************************************************
  *					USER_InitApp
  */
diff --git a/win32/Makefile.in b/win32/Makefile.in
index a5e8e38..1c2a1a9 100644
--- a/win32/Makefile.in
+++ b/win32/Makefile.in
@@ -7,6 +7,7 @@
 	console.c \
 	environment.c \
 	error.c \
+	except.c \
 	file.c \
 	gdi32.c \
 	heap.c \
diff --git a/win32/except.c b/win32/except.c
new file mode 100644
index 0000000..45188ce
--- /dev/null
+++ b/win32/except.c
@@ -0,0 +1,212 @@
+/*
+ * Win32 exception functions
+ *
+ * Copyright (c) 1996 Onno Hovers, (onno@stack.urc.tue.nl)
+ *
+ * Notes:
+ *  What really happens behind the scenes of those new
+ *  __try{...}__except(..){....}  and
+ *  __try{...}__finally{...}
+ *  statements is simply not documented by Microsoft. There could be different
+ *  reasons for this: 
+ *  One reason could be that they try to hide the fact that exception 
+ *  handling in Win32 looks almost the same as in OS/2 2.x.  
+ *  Another reason could be that Microsoft does not want others to write
+ *  binary compatible implementations of the Win32 API (like us).  
+ *
+ *  Whatever the reason, THIS SUCKS!! Ensuring portabilty or future 
+ *  compatability may be valid reasons to keep some things undocumented. 
+ *  But exception handling is so basic to Win32 that it should be 
+ *  documented!
+ *
+ * Fixmes:
+ *  -Most functions need better parameter checking.
+ *  -I do not know how to handle exceptions within an exception handler.
+ *   or what is done when ExceptionNestedException is returned from an 
+ *   exception handler
+ *  -Real exceptions are not yet implemented. only the exception functions
+ *   are implemented. A real implementation needs some new code in
+ *   loader/signal.c. There would also be a need for showing debugging
+ *   information in UnhandledExceptionFilter.
+ *
+ */
+#ifndef WINELIB
+
+#include <stdio.h>
+#include "windows.h"
+#include "winerror.h"
+#include "kernel32.h"
+#include "stddebug.h"
+#include "debug.h"
+#include "except.h"
+
+WINAPI DWORD KERNEL32_537(PEXCEPTION_POINTERS ptrs);
+
+LPTOP_LEVEL_EXCEPTION_FILTER       pTopExcHandler=
+           (LPTOP_LEVEL_EXCEPTION_FILTER) KERNEL32_537;
+
+/*
+ *       EXC_RtlUnwind
+ *
+ *  This function is undocumented. This is the general idea of 
+ *  RtlUnwind, though. Note that error handling is not yet implemented
+ *  
+ */
+
+void EXC_RtlUnwind(PEXCEPTION_FRAME pEndFrame,PVOID unusedEip, 
+                   PEXCEPTION_RECORD pRecord, DWORD returnEax,
+                   PCONTEXT pcontext)
+{   
+   EXCEPTION_RECORD record;
+   DWORD            dispatch;
+   int              retval;
+  
+   pcontext->Eax=returnEax;
+   
+   /* build an exception record, if we do not have one */
+   if(!pRecord)
+   {
+     record.ExceptionCode=   0xC0000026;  /* invalid disposition */ 
+     record.ExceptionFlags=  0;
+     record.ExceptionRecord= NULL;
+     record.ExceptionAddress=(PVOID) pcontext->Eip; 
+     record.NumberParameters= 0;
+     pRecord=&record;     
+   }
+
+   if(pEndFrame)
+     pRecord->ExceptionFlags|=EH_UNWINDING;
+   else
+     pRecord->ExceptionFlags|=EH_UNWINDING | EH_EXIT_UNWIND;
+  
+   /* get chain of exception frames */      
+   while((TebExceptionFrame!=NULL)&&
+         (TebExceptionFrame!=((void *)-1)) &&
+         (TebExceptionFrame!=pEndFrame))
+   {
+       dprintf_win32(stddeb,"calling exception handler at 0x%x\n",
+                                           (int) TebExceptionFrame->Handler);
+
+       dispatch=0;       
+       retval=TebExceptionFrame->Handler(pRecord, TebExceptionFrame,
+                                         pcontext, &dispatch);
+                                         
+       dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n",
+                              retval, (int) dispatch);
+  
+       if(retval==ExceptionCollidedUnwind)
+          TebExceptionFrame=(PVOID) dispatch;
+       else if(TebExceptionFrame!=pEndFrame)
+          TebExceptionFrame=TebExceptionFrame->Prev;
+       else
+          break;  
+   }
+}
+
+/*
+ *    EXC_RaiseException
+ *
+ */
+ 
+VOID EXC_RaiseException(DWORD dwExceptionCode,
+		    DWORD dwExceptionFlags,
+		    DWORD cArguments,
+		    const LPDWORD lpArguments,
+		    PCONTEXT pcontext)
+{
+    PEXCEPTION_FRAME    pframe; 
+    EXCEPTION_RECORD    record;
+    DWORD               dispatch; /* is this used in raising exceptions ?? */
+    int                 retval;
+    int                 i;
+    
+    /* compose an exception record */ 
+    
+    record.ExceptionCode       = dwExceptionCode;   
+    record.ExceptionFlags      = dwExceptionFlags;
+    record.ExceptionRecord     = NULL;
+    record.NumberParameters    = cArguments;
+    record.ExceptionAddress    = (PVOID) pcontext->Eip;
+    
+    for(i=0;i<cArguments;i++)
+       record.ExceptionInformation[i]=lpArguments[i];
+    
+    /* get chain of exception frames */    
+    
+    retval=ExceptionContinueSearch;    
+    pframe=TebExceptionFrame;
+    
+    while((pframe!=NULL)&&(pframe!=((void *)0xFFFFFFFF)))
+    {
+       dprintf_win32(stddeb,"calling exception handler at 0x%x\n",
+                                                (int) pframe->Handler);
+       dispatch=0;  
+       retval=pframe->Handler(&record,pframe,pcontext,&dispatch);
+ 
+       dprintf_win32(stddeb,"exception handler returns 0x%x, dispatch=0x%x\n",
+                              retval, (int) dispatch);
+                              
+       if(retval==ExceptionContinueExecution)
+          break;
+       pframe=pframe->Prev;
+   }
+
+   if(retval!=ExceptionContinueExecution)
+   {    
+      retval=EXC_CallUnhandledExceptionFilter(&record,pcontext);
+      if(retval!=EXCEPTION_CONTINUE_EXECUTION)
+      {
+         dprintf_win32(stddeb,"no handler wanted to handle "
+                              "the exception, exiting\n"     );
+         ExitProcess(dwExceptionCode); /* what status should be used here ? */         
+      }                   
+   } 
+}
+
+/*******************************************************************
+ *         UnhandledExceptionFilter (KERNEL32.537)
+ * 
+ *  This is the unhandled exception code. 
+ *  Actually, this should show up a dialog box, with all kinds of
+ *  fancy debugging information. It does nothing now!
+ */
+ 
+DWORD WINAPI UnhandledExceptionFilter(PEXCEPTION_POINTERS epointers)
+{
+   PEXCEPTION_RECORD pRecord;
+   PCONTEXT          pContext;
+   
+   pRecord=epointers->ExceptionRecord;
+   pContext=epointers->ContextRecord;
+   
+   if(pRecord->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND) )
+   {
+      dprintf_win32(stddeb,"UnhandledExceptionFilter: exiting\n");
+      ExitProcess(pRecord->ExceptionCode);            
+   }
+   else
+   {
+      RtlUnwind(0,pRecord,0,-1 );
+   }
+   
+   /* 
+    * This is just to avoid a warning, code should not get here 
+    * if it does, EXC_RaiseException will terminate it. 
+    */
+   return EXCEPTION_CONTINUE_SEARCH;
+}
+
+/*************************************************************
+ *    SetUnhandledExceptionFilter    (KERNEL32.516)
+ *  
+ *
+ */
+  
+WINAPI LPTOP_LEVEL_EXCEPTION_FILTER 
+        SetUnhandledExceptionFilter(LPTOP_LEVEL_EXCEPTION_FILTER efilter)
+{  
+   pTopExcHandler=efilter;
+   return efilter;
+}
+
+#endif  /* WINELIB */
diff --git a/win32/newfns.c b/win32/newfns.c
index 0192cb0..c4a99f1 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -16,19 +16,6 @@
 #include "debug.h"
 
 /***********************************************************************
- *           RaiseException		(KERNEL32.??)
- *
- * Stub function - does not allow exceptions to be caught yet
- */
-WINAPI VOID RaiseException(DWORD dwExceptionCode,
-		    DWORD dwExceptionFlags,
-		    DWORD cArguments,
-		    const DWORD * lpArguments)
-{
-    ExitProcess(dwExceptionCode); /* what status should be used here ? */
-}
-
-/***********************************************************************
  *           GetProcAddress		(KERNEL32.257)
  *
  */
diff --git a/windows/Makefile.in b/windows/Makefile.in
index d04102b..0bb6799 100644
--- a/windows/Makefile.in
+++ b/windows/Makefile.in
@@ -21,6 +21,7 @@
 	nonclient.c \
 	painting.c \
 	property.c \
+	queue.c \
 	scroll.c \
 	syscolor.c \
 	sysmetrics.c \
diff --git a/windows/class.c b/windows/class.c
index f148b38..527127e 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -23,6 +23,72 @@
 
 
 /***********************************************************************
+ *           CLASS_DumpClass
+ *
+ * Dump the content of a class structure to stderr.
+ */
+void CLASS_DumpClass( HCLASS hClass )
+{
+    CLASS *ptr;
+    char className[80];
+    int i;
+
+    if (!(ptr = CLASS_FindClassPtr( hClass )))
+    {
+        fprintf( stderr, "%04x is not a class handle\n", hClass );
+        return;
+    }
+    GlobalGetAtomName( ptr->atomName, className, sizeof(className) );
+
+    fprintf( stderr, "Class %04x:\n", hClass );
+    fprintf( stderr,
+             "next=%04x  name=%04x '%s'  style=%04x  wndProc=%08lx\n"
+             "inst=%04x  hdce=%04x  icon=%04x  cursor=%04x  bkgnd=%04x\n"
+             "clsExtra=%d  winExtra=%d  #windows=%d\n",
+             ptr->hNext, ptr->atomName, className, ptr->wc.style,
+             (DWORD)ptr->wc.lpfnWndProc, ptr->wc.hInstance, ptr->hdce,
+             ptr->wc.hIcon, ptr->wc.hCursor, ptr->wc.hbrBackground,
+             ptr->wc.cbClsExtra, ptr->wc.cbWndExtra, ptr->cWindows );
+    if (ptr->wc.cbClsExtra)
+    {
+        fprintf( stderr, "extra bytes:" );
+        for (i = 0; i < ptr->wc.cbClsExtra; i++)
+            fprintf( stderr, " %02x", *((BYTE *)ptr->wExtra+i) );
+        fprintf( stderr, "\n" );
+    }
+    fprintf( stderr, "\n" );
+}
+
+
+/***********************************************************************
+ *           CLASS_WalkClasses
+ *
+ * Walk the class list and print each class on stderr.
+ */
+void CLASS_WalkClasses(void)
+{
+    HCLASS hClass = firstClass;
+    CLASS *ptr;
+    char className[80];
+
+    fprintf( stderr, "Class  Name                Style WndProc\n" );
+    while (hClass)
+    {
+        if (!(ptr = CLASS_FindClassPtr( hClass )))
+        {
+            fprintf( stderr, "*** Bad class %04x in list\n", hClass );
+            return;
+        }
+        GlobalGetAtomName( ptr->atomName, className, sizeof(className) );
+        fprintf( stderr, "%04x  %-20.20s %04x %08lx\n",
+                 hClass, className, ptr->wc.style, (DWORD)ptr->wc.lpfnWndProc);
+        hClass = ptr->hNext;
+    }
+    fprintf( stderr, "\n" );
+}
+
+
+/***********************************************************************
  *           CLASS_FindClassByName
  *
  * Return a handle and a pointer to the class.
diff --git a/windows/dce.c b/windows/dce.c
index ed9c8b2..4974a2e 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -152,7 +152,7 @@
     if (!hwndStart) return hrgn;
     if (!(hrgnNew = CreateRectRgn( 0, 0, 0, 0 )))
     {
-        if (hrgn) DeleteObject( hrgn );
+        DeleteObject( hrgn );
         return 0;
     }
     for (; hwndStart != hwndEnd; hwndStart = wndPtr->hwndNext)
@@ -165,10 +165,10 @@
                     wndPtr->rectWindow.bottom + yoffset );
         if (!CombineRgn( hrgn, hrgn, hrgnNew, RGN_DIFF )) break;
     }
+    DeleteObject( hrgnNew );
     if (hwndStart != hwndEnd)  /* something went wrong */
     {
-        DeleteObject( hrgnNew );
-        if (hrgn) DeleteObject( hrgn );
+        DeleteObject( hrgn );
         return 0;
     }
     return hrgn;
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 21acb8d..4e1d060 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -54,7 +54,7 @@
     int len;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
 
-    EnterSpyMessage(SPY_DEFWNDPROC,hwnd,msg,wParam,lParam);
+    SPY_EnterMessage( SPY_DEFWNDPROC, hwnd, msg, wParam, lParam );
 
     switch(msg)
     {
diff --git a/windows/event.c b/windows/event.c
index 7ab8e42..203f75b 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -6,8 +6,11 @@
  */
 
 #include <ctype.h>
+#include <signal.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <unistd.h>
+#include <X11/keysym.h>
 #include <X11/Xlib.h>
 #include <X11/Xresource.h>
 #include <X11/Xutil.h>
@@ -16,9 +19,9 @@
 #include "windows.h"
 #include "win.h"
 #include "class.h"
-#include "message.h"
 #include "clipboard.h"
 #include "options.h"
+#include "queue.h"
 #include "winpos.h"
 #include "registers.h"
 #include "stackframe.h"
@@ -305,6 +308,11 @@
     dprintf_key(stddeb,"WM_KEY??? : keysym=%lX, count=%u / %X / '%s'\n", 
 	   keysym, count, Str[0], Str);
 
+    /* Ctrl-Alt-Return enters the debugger */
+    if ((keysym == XK_Return) && (event->type == KeyPress) &&
+        (event->state & ControlMask) && (event->state & Mod1Mask))
+        kill( getpid(), SIGHUP );
+
     xkey = LOWORD(keysym);
     key_type = HIBYTE(xkey);
     key = LOBYTE(xkey);
@@ -348,7 +356,7 @@
 	    KeyStateTable[vkey] ^= 0x80;
 	KeyStateTable[vkey] |= 0x01;
 	keylp.lp1.count = 1;
-	keylp.lp1.code = LOBYTE(event->keycode);
+	keylp.lp1.code = LOBYTE(event->keycode) - 8;
 	keylp.lp1.extended = (extended ? 1 : 0);
 	keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
 	keylp.lp1.previous = (KeyDown ? 0 : 1);
@@ -379,7 +387,7 @@
 	if (vkey == VK_MENU) ALTKeyState = FALSE;
 	KeyStateTable[vkey] &= 0xf0;
 	keylp.lp1.count = 1;
-	keylp.lp1.code = LOBYTE(event->keycode);
+	keylp.lp1.code = LOBYTE(event->keycode) - 8;
 	keylp.lp1.extended = (extended ? 1 : 0);
 	keylp.lp1.context = (event->state & Mod1Mask ? 1 : 0);
 	keylp.lp1.previous = 1;
diff --git a/windows/hook.c b/windows/hook.c
index ad3d0f4..1151e14 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -15,7 +15,7 @@
  */
 
 #include "hook.h"
-#include "message.h"
+#include "queue.h"
 #include "user.h"
 #include "stddebug.h"
 #include "debug.h"
diff --git a/windows/message.c b/windows/message.c
index cd733d3..8f00ed8 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -19,195 +19,19 @@
 #include "winpos.h"
 #include "atom.h"
 #include "dde.h"
+#include "queue.h"
 #include "stddebug.h"
 /* #define DEBUG_MSG */
 #include "debug.h"
 
 #define HWND_BROADCAST  ((HWND)0xffff)
-#define MAX_QUEUE_SIZE   120  /* Max. size of a message queue */
-
 
 extern BOOL TIMER_CheckTimer( LONG *next, MSG *msg,
 			      HWND hwnd, BOOL remove );  /* timer.c */
 
 DWORD MSG_WineStartTicks;  /* Ticks at Wine startup */
 
-/* ------- Internal Queues ------ */
-
-static HANDLE hmemSysMsgQueue = 0;
-static MESSAGEQUEUE *sysMsgQueue = NULL;
-static HANDLE hFirstQueue = 0;
-
-/* ------- Miscellaneous ------ */
-static int doubleClickSpeed = 452;
-
-
-/***********************************************************************
- *           MSG_CreateMsgQueue
- *
- * Creates a message queue. Doesn't link it into queue list!
- */
-static HANDLE MSG_CreateMsgQueue( int size )
-{
-    HANDLE hQueue;
-    MESSAGEQUEUE * msgQueue;
-    int queueSize;
-
-    queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG);
-    if (!(hQueue = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, queueSize )))
-        return 0;
-    msgQueue = (MESSAGEQUEUE *) GlobalLock( hQueue );
-    msgQueue->msgSize = sizeof(QMSG);
-    msgQueue->queueSize = size;
-    msgQueue->wWinVersion = 0;  /* FIXME? */
-    GlobalUnlock( hQueue );
-    return hQueue;
-}
-
-
-/***********************************************************************
- *	     MSG_DeleteMsgQueue
- *
- * Unlinks and deletes a message queue.
- */
-BOOL MSG_DeleteMsgQueue( HANDLE hQueue )
-{
-    MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock(hQueue);
-    HANDLE *pPrev;
-
-    if (!hQueue || !msgQueue)
-    {
-	dprintf_msg(stddeb,"DeleteMsgQueue: invalid argument.\n");
-	return 0;
-    }
-
-    pPrev = &hFirstQueue;
-    while (*pPrev && (*pPrev != hQueue))
-    {
-        MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock(*pPrev);
-        pPrev = &msgQ->next;
-    }
-    if (*pPrev) *pPrev = msgQueue->next;
-    GlobalFree( hQueue );
-    return 1;
-}
-
-
-/***********************************************************************
- *           MSG_CreateSysMsgQueue
- *
- * Create the system message queue, and set the double-click speed.
- * Must be called only once.
- */
-BOOL MSG_CreateSysMsgQueue( int size )
-{
-    if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE;
-    else if (size <= 0) size = 1;
-    if (!(hmemSysMsgQueue = MSG_CreateMsgQueue( size ))) return FALSE;
-    sysMsgQueue = (MESSAGEQUEUE *) GlobalLock( hmemSysMsgQueue );
-    doubleClickSpeed = GetProfileInt( "windows", "DoubleClickSpeed", 452 );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           MSG_AddMsg
- *
- * Add a message to the queue. Return FALSE if queue is full.
- */
-static int MSG_AddMsg( HANDLE hQueue, MSG * msg, DWORD extraInfo )
-{
-    int pos;
-    MESSAGEQUEUE *msgQueue;
-
-    if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return FALSE;
-    pos = msgQueue->nextFreeMessage;
-
-      /* Check if queue is full */
-    if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0)) {
-		fprintf(stderr,"MSG_AddMsg // queue is full !\n");
-		return FALSE;
-		}
-
-      /* Store message */
-    msgQueue->messages[pos].msg = *msg;
-    msgQueue->messages[pos].extraInfo = extraInfo;
-    if (pos < msgQueue->queueSize-1) pos++;
-    else pos = 0;
-    msgQueue->nextFreeMessage = pos;
-    msgQueue->msgCount++;
-    msgQueue->status |= QS_POSTMESSAGE;
-    msgQueue->tempStatus |= QS_POSTMESSAGE;
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           MSG_FindMsg
- *
- * Find a message matching the given parameters. Return -1 if none available.
- */
-static int MSG_FindMsg(MESSAGEQUEUE * msgQueue, HWND hwnd, int first, int last)
-{
-    int i, pos = msgQueue->nextMessage;
-
-    dprintf_msg(stddeb,"MSG_FindMsg: hwnd=0x"NPFMT"\n\n", hwnd );
-
-    if (!msgQueue->msgCount) return -1;
-    if (!hwnd && !first && !last) return pos;
-        
-    for (i = 0; i < msgQueue->msgCount; i++)
-    {
-	MSG * msg = &msgQueue->messages[pos].msg;
-
-	if (!hwnd || (msg->hwnd == hwnd))
-	{
-	    if (!first && !last) return pos;
-	    if ((msg->message >= first) && (msg->message <= last)) return pos;
-	}
-	if (pos < msgQueue->queueSize-1) pos++;
-	else pos = 0;
-    }
-    return -1;
-}
-
-
-/***********************************************************************
- *           MSG_RemoveMsg
- *
- * Remove a message from the queue (pos must be a valid position).
- */
-static void MSG_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
-{
-    if (pos >= msgQueue->nextMessage)
-    {
-	for ( ; pos > msgQueue->nextMessage; pos--)
-	    msgQueue->messages[pos] = msgQueue->messages[pos-1];
-	msgQueue->nextMessage++;
-	if (msgQueue->nextMessage >= msgQueue->queueSize)
-	    msgQueue->nextMessage = 0;
-    }
-    else
-    {
-	for ( ; pos < msgQueue->nextFreeMessage; pos++)
-	    msgQueue->messages[pos] = msgQueue->messages[pos+1];
-	if (msgQueue->nextFreeMessage) msgQueue->nextFreeMessage--;
-	else msgQueue->nextFreeMessage = msgQueue->queueSize-1;
-    }
-    msgQueue->msgCount--;
-    if (!msgQueue->msgCount) msgQueue->status &= ~QS_POSTMESSAGE;
-    msgQueue->tempStatus = 0;
-}
-
-/***********************************************************************
- *	     MSG_GetQueueTask
- */
-HTASK MSG_GetQueueTask( HANDLE hQueue )
-{
-    MESSAGEQUEUE *msgQ = GlobalLock( hQueue );
-
-    return (msgQ) ? msgQ->hTask : 0 ;
-}
+static WORD doubleClickSpeed = 452;
 
 /***********************************************************************
  *           MSG_TranslateMouseMsg
@@ -372,6 +196,7 @@
 static BOOL MSG_PeekHardwareMsg( MSG *msg, HWND hwnd, WORD first, WORD last,
                                  BOOL remove )
 {
+    MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
     int i, pos = sysMsgQueue->nextMessage;
 
     for (i = 0; i < sysMsgQueue->msgCount; i++, pos++)
@@ -410,7 +235,7 @@
             MSG tmpMsg = *msg; /* FIXME */
             HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION,
                             0, (LPARAM)MAKE_SEGPTR(&tmpMsg) );
-            MSG_RemoveMsg( sysMsgQueue, pos );
+            QUEUE_RemoveMsg( sysMsgQueue, pos );
         }
         return TRUE;
     }
@@ -419,136 +244,24 @@
 
 
 /**********************************************************************
- *		SetDoubleClickTime  (USER.20)
+ *           SetDoubleClickTime   (USER.20)
  */
 void SetDoubleClickTime( WORD interval )
 {
-    if (interval == 0)
-	doubleClickSpeed = 500;
-    else
-	doubleClickSpeed = interval;
+    doubleClickSpeed = interval ? interval : 500;
 }		
 
 
 /**********************************************************************
- *		GetDoubleClickTime  (USER.21)
+ *           GetDoubleClickTime   (USER.21)
  */
 WORD GetDoubleClickTime()
 {
-	return (WORD)doubleClickSpeed;
+    return doubleClickSpeed;
 }		
 
 
 /***********************************************************************
- *           MSG_IncPaintCount
- */
-void MSG_IncPaintCount( HANDLE hQueue )
-{
-    MESSAGEQUEUE *queue;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return;
-    queue->wPaintCount++;
-    queue->status |= QS_PAINT;
-    queue->tempStatus |= QS_PAINT;    
-}
-
-
-/***********************************************************************
- *           MSG_DecPaintCount
- */
-void MSG_DecPaintCount( HANDLE hQueue )
-{
-    MESSAGEQUEUE *queue;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return;
-    queue->wPaintCount--;
-    if (!queue->wPaintCount) queue->status &= ~QS_PAINT;
-}
-
-
-/***********************************************************************
- *           MSG_IncTimerCount
- */
-void MSG_IncTimerCount( HANDLE hQueue )
-{
-    MESSAGEQUEUE *queue;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return;
-    queue->wTimerCount++;
-    queue->status |= QS_TIMER;
-    queue->tempStatus |= QS_TIMER;
-}
-
-
-/***********************************************************************
- *           MSG_DecTimerCount
- */
-void MSG_DecTimerCount( HANDLE hQueue )
-{
-    MESSAGEQUEUE *queue;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return;
-    queue->wTimerCount--;
-    if (!queue->wTimerCount) queue->status &= ~QS_TIMER;
-}
-
-
-/***********************************************************************
- *           hardware_event
- *
- * Add an event to the system message queue.
- * Note: the position is relative to the desktop window.
- */
-void hardware_event( WORD message, WORD wParam, LONG lParam,
-		     int xPos, int yPos, DWORD time, DWORD extraInfo )
-{
-    MSG *msg;
-    int pos;
-  
-    if (!sysMsgQueue) return;
-    pos = sysMsgQueue->nextFreeMessage;
-
-      /* Merge with previous event if possible */
-
-    if ((message == WM_MOUSEMOVE) && sysMsgQueue->msgCount)
-    {
-        if (pos > 0) pos--;
-        else pos = sysMsgQueue->queueSize - 1;
-	msg = &sysMsgQueue->messages[pos].msg;
-	if ((msg->message == message) && (msg->wParam == wParam))
-            sysMsgQueue->msgCount--;  /* Merge events */
-        else
-            pos = sysMsgQueue->nextFreeMessage;  /* Don't merge */
-    }
-
-      /* Check if queue is full */
-
-    if ((pos == sysMsgQueue->nextMessage) && sysMsgQueue->msgCount)
-    {
-        /* Queue is full, beep (but not on every mouse motion...) */
-        if (message != WM_MOUSEMOVE) MessageBeep(0);
-        return;
-    }
-
-      /* Store message */
-
-    msg = &sysMsgQueue->messages[pos].msg;
-    msg->hwnd    = 0;
-    msg->message = message;
-    msg->wParam  = wParam;
-    msg->lParam  = lParam;
-    msg->time    = time;
-    msg->pt.x    = xPos & 0xffff;
-    msg->pt.y    = yPos & 0xffff;
-    sysMsgQueue->messages[pos].extraInfo = extraInfo;
-    if (pos < sysMsgQueue->queueSize - 1) pos++;
-    else pos = 0;
-    sysMsgQueue->nextFreeMessage = pos;
-    sysMsgQueue->msgCount++;
-}
-
-		    
-/***********************************************************************
  *           MSG_GetHardwareMessage
  *
  * Like GetMessage(), but only return mouse and keyboard events.
@@ -560,13 +273,14 @@
 {
     int pos;
     XEvent event;
+    MESSAGEQUEUE *sysMsgQueue = QUEUE_GetSysQueue();
 
     while(1)
     {    
-	if ((pos = MSG_FindMsg( sysMsgQueue, 0, 0, 0 )) != -1)
+	if ((pos = QUEUE_FindMsg( sysMsgQueue, 0, 0, 0 )) != -1)
 	{
 	    *msg = sysMsgQueue->messages[pos].msg;
-	    MSG_RemoveMsg( sysMsgQueue, pos );
+	    QUEUE_RemoveMsg( sysMsgQueue, pos );
 	    break;
 	}
 	XNextEvent( display, &event );
@@ -577,91 +291,6 @@
 
 
 /***********************************************************************
- *           SetMessageQueue  (USER.266)
- */
-BOOL SetMessageQueue( int size )
-{
-    HANDLE hQueue, hNewQueue;
-    MESSAGEQUEUE *queuePtr;
-
-    if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE;
-
-    if( !(hNewQueue = MSG_CreateMsgQueue( size ))) 
-    {
-	dprintf_msg(stddeb,"SetMessageQueue: failed!\n");
-	return FALSE;
-    }
-
-    /* Free the old message queue */
-    if ((hQueue = GetTaskQueue(0)) != 0) MSG_DeleteMsgQueue( hQueue );
-
-    /* Link new queue into list */
-    queuePtr = (MESSAGEQUEUE *)GlobalLock( hNewQueue );
-    queuePtr->hTask = GetCurrentTask();
-    queuePtr->next  = hFirstQueue;
-    hFirstQueue = hNewQueue;
-
-    SetTaskQueue( 0, hNewQueue );
-    return TRUE;
-}
-
-
-/***********************************************************************
- *           GetWindowTask  (USER.224)
- */
-HTASK GetWindowTask( HWND hwnd )
-{
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    MESSAGEQUEUE *queuePtr;
-
-    if (!wndPtr) return 0;
-    queuePtr = (MESSAGEQUEUE *)GlobalLock( wndPtr->hmemTaskQ );
-    if (!queuePtr) return 0;
-    return queuePtr->hTask;
-}
-
-
-/***********************************************************************
- *           PostQuitMessage   (USER.6)
- */
-void PostQuitMessage( int exitCode )
-{
-    MESSAGEQUEUE *queue;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return;
-    queue->wPostQMsg = TRUE;
-    queue->wExitCode = exitCode;
-}
-
-
-/***********************************************************************
- *           GetQueueStatus   (USER.334)
- */
-DWORD GetQueueStatus( UINT flags )
-{
-    MESSAGEQUEUE *queue;
-    DWORD ret;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0;
-    ret = MAKELONG( queue->tempStatus, queue->status );
-    queue->tempStatus = 0;
-    return ret & MAKELONG( flags, flags );
-}
-
-
-/***********************************************************************
- *           GetInputState   (USER.335)
- */
-BOOL GetInputState()
-{
-    MESSAGEQUEUE *queue;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return FALSE;
-    return queue->status & (QS_KEY | QS_MOUSEBUTTON);
-}
-
-
-/***********************************************************************
  *           MSG_Synchronize
  *
  * Synchronize with the X server. Should not be used too often.
@@ -796,7 +425,7 @@
 	}
     
 	  /* Now find a normal message */
-	pos = MSG_FindMsg( msgQueue, hwnd, first, last );
+	pos = QUEUE_FindMsg( msgQueue, hwnd, first, last );
 	if (pos != -1)
 	{
 	    QMSG *qmsg = &msgQueue->messages[pos];
@@ -805,7 +434,7 @@
 	    msgQueue->GetMessagePosVal       = *(DWORD *)&msg->pt;
 	    msgQueue->GetMessageExtraInfoVal = qmsg->extraInfo;
 
-	    if (flags & PM_REMOVE) MSG_RemoveMsg( msgQueue, pos );
+	    if (flags & PM_REMOVE) QUEUE_RemoveMsg( msgQueue, pos );
 	    break;
 	}
 
@@ -966,7 +595,7 @@
     wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr || !wndPtr->hmemTaskQ) return FALSE;
 
-    return MSG_AddMsg( wndPtr->hmemTaskQ, &msg, 0 );
+    return QUEUE_AddMsg( wndPtr->hmemTaskQ, &msg, 0 );
 }
 
 /***********************************************************************
@@ -985,7 +614,7 @@
     msg.pt.x    = 0;
     msg.pt.y    = 0;
 
-    return MSG_AddMsg( GetTaskQueue(hTask), &msg, 0 );
+    return QUEUE_AddMsg( GetTaskQueue(hTask), &msg, 0 );
 }
 
 
@@ -1028,17 +657,17 @@
         return TRUE;
     }
 
-    EnterSpyMessage(SPY_SENDMESSAGE, hwnd, msg, wParam, lParam);
+    SPY_EnterMessage( SPY_SENDMESSAGE, hwnd, msg, wParam, lParam );
 
     HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1, (LPARAM)MAKE_SEGPTR(&msgstruct) );
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) 
     {
-        ExitSpyMessage(SPY_RESULT_INVALIDHWND,hwnd,msg,0);
+        SPY_ExitMessage( SPY_RESULT_INVALIDHWND, hwnd, msg, 0 );
         return 0;
     }
     ret = CallWindowProc( wndPtr->lpfnWndProc, msgstruct.hWnd, msgstruct.wMsg,
                           msgstruct.wParam, msgstruct.lParam );
-    ExitSpyMessage(SPY_RESULT_OK,hwnd,msg,ret);
+    SPY_ExitMessage( SPY_RESULT_OK, hwnd, msg, ret );
     return ret;
 }
 
@@ -1059,7 +688,7 @@
     if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return;
     if ((queue->wPostQMsg) || 
         (queue->status & (QS_SENDMESSAGE | QS_PAINT)) ||
-        (queue->msgCount) || (sysMsgQueue->msgCount) )
+        (queue->msgCount) || (QUEUE_GetSysQueue()->msgCount) )
         return;
     if ((queue->status & QS_TIMER) && 
         TIMER_CheckTimer( &nextExp, &msg, 0, FALSE))
@@ -1095,8 +724,8 @@
     LONG retval;
     int painting;
     
-    EnterSpyMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message,
-                     msg->wParam, msg->lParam );
+    SPY_EnterMessage( SPY_DISPATCHMESSAGE, msg->hwnd, msg->message,
+                      msg->wParam, msg->lParam );
 
       /* Process timer messages */
     if ((msg->message == WM_TIMER) || (msg->message == WM_SYSTIMER))
@@ -1135,42 +764,6 @@
 
 
 /***********************************************************************
- *           GetMessagePos   (USER.119)
- */
-DWORD GetMessagePos(void)
-{
-    MESSAGEQUEUE *queue;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0;
-    return queue->GetMessagePosVal;
-}
-
-
-/***********************************************************************
- *           GetMessageTime   (USER.120)
- */
-LONG GetMessageTime(void)
-{
-    MESSAGEQUEUE *queue;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0;
-    return queue->GetMessageTimeVal;
-}
-
-
-/***********************************************************************
- *           GetMessageExtraInfo   (USER.288)
- */
-LONG GetMessageExtraInfo(void)
-{
-    MESSAGEQUEUE *queue;
-
-    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0;
-    return queue->GetMessageExtraInfoVal;
-}
-
-
-/***********************************************************************
  *           RegisterWindowMessage   (USER.118)
  */
 WORD RegisterWindowMessage( SEGPTR str )
@@ -1190,14 +783,18 @@
     return ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - MSG_WineStartTicks;
 }
 
+
 /***********************************************************************
- *           GetCurrentTime  (effectively identical to GetTickCount)
+ *           GetCurrentTime    (USER.15)
+ *
+ * (effectively identical to GetTickCount)
  */
 DWORD GetCurrentTime(void)
 {
-  return GetTickCount();
+    return GetTickCount();
 }
 
+
 /***********************************************************************
  *			InSendMessage	(USER.192
  *
diff --git a/windows/painting.c b/windows/painting.c
index 1c2b06a..d1438d5 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -8,7 +8,7 @@
 #include <X11/Xlib.h>
 
 #include "win.h"
-#include "message.h"
+#include "queue.h"
 #include "gdi.h"
 #include "stddebug.h"
 /* #define DEBUG_WIN */
@@ -32,7 +32,7 @@
 	if (!(hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ))) return 0;
 
     if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT))
-	MSG_DecPaintCount( wndPtr->hmemTaskQ );
+	QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
 
     wndPtr->hrgnUpdate = 0;
     wndPtr->flags &= ~(WIN_NEEDS_BEGINPAINT | WIN_INTERNAL_PAINT);
@@ -168,7 +168,7 @@
         else  /* No update region yet */
         {
             if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
-                MSG_IncPaintCount( wndPtr->hmemTaskQ );
+                QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
             if (hrgnUpdate)
             {
                 wndPtr->hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
@@ -206,7 +206,7 @@
             }
             if (!wndPtr->hrgnUpdate)  /* No more update region */
 		if (!(wndPtr->flags & WIN_INTERNAL_PAINT))
-		    MSG_DecPaintCount( wndPtr->hmemTaskQ );
+		    QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
         }
         if (flags & RDW_NOFRAME) wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
 	if (flags & RDW_NOERASE) wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
@@ -217,13 +217,13 @@
     if (flags & RDW_INTERNALPAINT)
     {
 	if (!wndPtr->hrgnUpdate && !(wndPtr->flags & WIN_INTERNAL_PAINT))
-	    MSG_IncPaintCount( wndPtr->hmemTaskQ );
+	    QUEUE_IncPaintCount( wndPtr->hmemTaskQ );
 	wndPtr->flags |= WIN_INTERNAL_PAINT;	    
     }
     else if (flags & RDW_NOINTERNALPAINT)
     {
 	if (!wndPtr->hrgnUpdate && (wndPtr->flags & WIN_INTERNAL_PAINT))
-	    MSG_DecPaintCount( wndPtr->hmemTaskQ );
+	    QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
 	wndPtr->flags &= ~WIN_INTERNAL_PAINT;
     }
 
diff --git a/windows/queue.c b/windows/queue.c
new file mode 100644
index 0000000..1d0028a
--- /dev/null
+++ b/windows/queue.c
@@ -0,0 +1,484 @@
+/*
+ * Message queues related functions
+ *
+ * Copyright 1993, 1994 Alexandre Julliard
+ */
+
+#include <stdlib.h>
+#include "module.h"
+#include "queue.h"
+#include "win.h"
+#include "stddebug.h"
+#include "debug.h"
+
+#define MAX_QUEUE_SIZE   120  /* Max. size of a message queue */
+
+static HQUEUE hFirstQueue = 0;
+static HQUEUE hmemSysMsgQueue = 0;
+static MESSAGEQUEUE *sysMsgQueue = NULL;
+
+
+/***********************************************************************
+ *	     QUEUE_DumpQueue
+ */
+void QUEUE_DumpQueue( HQUEUE hQueue )
+{
+    MESSAGEQUEUE *pq; 
+
+    if (!(pq = (MESSAGEQUEUE*) GlobalLock( hQueue )) ||
+        GlobalSize(hQueue) < sizeof(MESSAGEQUEUE) + pq->queueSize*sizeof(QMSG))
+    {
+        fprintf( stderr, NPFMT " is not a queue handle\n", hQueue );
+        return;
+    }
+
+    fprintf( stderr,
+             "next: %12.4x  Intertask SendMessage:\n"
+             "hTask: %11.4x  ----------------------\n"
+             "msgSize: %9.4x  hWnd: %10.4x\n"
+             "msgCount: %8.4x  msg: %11.4x\n"
+             "msgNext: %9.4x  wParam: %8.4x\n"
+             "msgFree: %9.4x  lParam: %8.8x\n"
+             "qSize: %11.4x  lRet: %10.8x\n"
+             "wWinVer: %9.4x  ISMH: %10.4x\n"
+             "paints: %10.4x  hSendTask: %5.4x\n"
+             "timers: %10.4x  hPrevSend: %5.4x\n"
+             "wakeBits: %8.4x\n"
+             "wakeMask: %8.4x\n"
+             "hCurHook: %8.4x\n",
+             pq->next, pq->hTask, pq->msgSize, pq->hWnd, 
+             pq->msgCount, pq->msg, pq->nextMessage, pq->wParam,
+             pq->nextFreeMessage, (unsigned)pq->lParam, pq->queueSize,
+             (unsigned)pq->SendMessageReturn, pq->wWinVersion, pq->InSendMessageHandle,
+             pq->wPaintCount, pq->hSendingTask, pq->wTimerCount,
+             pq->hPrevSendingTask, pq->status, pq->wakeMask, pq->hCurHook);
+}
+
+
+/***********************************************************************
+ *	     QUEUE_WalkQueues
+ */
+void QUEUE_WalkQueues(void)
+{
+    HQUEUE hQueue = hFirstQueue;
+
+    fprintf( stderr, "Queue Size Msgs Task\n" );
+    while (hQueue)
+    {
+        MESSAGEQUEUE *queue = (MESSAGEQUEUE *)GlobalLock( hQueue );
+        if (!queue)
+        {
+            fprintf( stderr, "*** Bad queue handle "NPFMT"\n", hQueue );
+            return;
+        }
+        fprintf( stderr, "%04x %5d %4d %04x %s\n",
+                 hQueue, queue->msgSize, queue->msgCount, queue->hTask,
+                 MODULE_GetModuleName( GetExePtr(queue->hTask) ) );
+        hQueue = queue->next;
+    }
+    fprintf( stderr, "\n" );
+}
+
+
+/***********************************************************************
+ *           QUEUE_CreateMsgQueue
+ *
+ * Creates a message queue. Doesn't link it into queue list!
+ */
+static HQUEUE QUEUE_CreateMsgQueue( int size )
+{
+    HQUEUE hQueue;
+    MESSAGEQUEUE * msgQueue;
+    int queueSize;
+
+    queueSize = sizeof(MESSAGEQUEUE) + size * sizeof(QMSG);
+    if (!(hQueue = GlobalAlloc( GMEM_FIXED | GMEM_ZEROINIT, queueSize )))
+        return 0;
+    msgQueue = (MESSAGEQUEUE *) GlobalLock( hQueue );
+    msgQueue->msgSize = sizeof(QMSG);
+    msgQueue->queueSize = size;
+    msgQueue->wWinVersion = 0;  /* FIXME? */
+    GlobalUnlock( hQueue );
+    return hQueue;
+}
+
+
+/***********************************************************************
+ *	     QUEUE_DeleteMsgQueue
+ *
+ * Unlinks and deletes a message queue.
+ */
+BOOL QUEUE_DeleteMsgQueue( HQUEUE hQueue )
+{
+    MESSAGEQUEUE * msgQueue = (MESSAGEQUEUE*)GlobalLock(hQueue);
+    HQUEUE *pPrev;
+
+    if (!hQueue || !msgQueue)
+    {
+	dprintf_msg(stddeb,"DeleteMsgQueue: invalid argument.\n");
+	return 0;
+    }
+
+    pPrev = &hFirstQueue;
+    while (*pPrev && (*pPrev != hQueue))
+    {
+        MESSAGEQUEUE *msgQ = (MESSAGEQUEUE*)GlobalLock(*pPrev);
+        pPrev = &msgQ->next;
+    }
+    if (*pPrev) *pPrev = msgQueue->next;
+    GlobalFree( hQueue );
+    return 1;
+}
+
+
+/***********************************************************************
+ *           QUEUE_CreateSysMsgQueue
+ *
+ * Create the system message queue, and set the double-click speed.
+ * Must be called only once.
+ */
+BOOL QUEUE_CreateSysMsgQueue( int size )
+{
+    if (size > MAX_QUEUE_SIZE) size = MAX_QUEUE_SIZE;
+    else if (size <= 0) size = 1;
+    if (!(hmemSysMsgQueue = QUEUE_CreateMsgQueue( size ))) return FALSE;
+    sysMsgQueue = (MESSAGEQUEUE *) GlobalLock( hmemSysMsgQueue );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           QUEUE_GetSysQueue
+ */
+MESSAGEQUEUE *QUEUE_GetSysQueue(void)
+{
+    return sysMsgQueue;
+}
+
+
+/***********************************************************************
+ *           QUEUE_AddMsg
+ *
+ * Add a message to the queue. Return FALSE if queue is full.
+ */
+BOOL QUEUE_AddMsg( HQUEUE hQueue, MSG * msg, DWORD extraInfo )
+{
+    int pos;
+    MESSAGEQUEUE *msgQueue;
+
+    if (!(msgQueue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return FALSE;
+    pos = msgQueue->nextFreeMessage;
+
+      /* Check if queue is full */
+    if ((pos == msgQueue->nextMessage) && (msgQueue->msgCount > 0))
+    {
+        fprintf(stderr,"MSG_AddMsg // queue is full !\n");
+        return FALSE;
+    }
+
+      /* Store message */
+    msgQueue->messages[pos].msg = *msg;
+    msgQueue->messages[pos].extraInfo = extraInfo;
+    if (pos < msgQueue->queueSize-1) pos++;
+    else pos = 0;
+    msgQueue->nextFreeMessage = pos;
+    msgQueue->msgCount++;
+    msgQueue->status |= QS_POSTMESSAGE;
+    msgQueue->tempStatus |= QS_POSTMESSAGE;
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           QUEUE_FindMsg
+ *
+ * Find a message matching the given parameters. Return -1 if none available.
+ */
+int QUEUE_FindMsg( MESSAGEQUEUE * msgQueue, HWND hwnd, int first, int last )
+{
+    int i, pos = msgQueue->nextMessage;
+
+    dprintf_msg(stddeb,"MSG_FindMsg: hwnd=0x"NPFMT"\n\n", hwnd );
+
+    if (!msgQueue->msgCount) return -1;
+    if (!hwnd && !first && !last) return pos;
+        
+    for (i = 0; i < msgQueue->msgCount; i++)
+    {
+	MSG * msg = &msgQueue->messages[pos].msg;
+
+	if (!hwnd || (msg->hwnd == hwnd))
+	{
+	    if (!first && !last) return pos;
+	    if ((msg->message >= first) && (msg->message <= last)) return pos;
+	}
+	if (pos < msgQueue->queueSize-1) pos++;
+	else pos = 0;
+    }
+    return -1;
+}
+
+
+/***********************************************************************
+ *           QUEUE_RemoveMsg
+ *
+ * Remove a message from the queue (pos must be a valid position).
+ */
+void QUEUE_RemoveMsg( MESSAGEQUEUE * msgQueue, int pos )
+{
+    if (pos >= msgQueue->nextMessage)
+    {
+	for ( ; pos > msgQueue->nextMessage; pos--)
+	    msgQueue->messages[pos] = msgQueue->messages[pos-1];
+	msgQueue->nextMessage++;
+	if (msgQueue->nextMessage >= msgQueue->queueSize)
+	    msgQueue->nextMessage = 0;
+    }
+    else
+    {
+	for ( ; pos < msgQueue->nextFreeMessage; pos++)
+	    msgQueue->messages[pos] = msgQueue->messages[pos+1];
+	if (msgQueue->nextFreeMessage) msgQueue->nextFreeMessage--;
+	else msgQueue->nextFreeMessage = msgQueue->queueSize-1;
+    }
+    msgQueue->msgCount--;
+    if (!msgQueue->msgCount) msgQueue->status &= ~QS_POSTMESSAGE;
+    msgQueue->tempStatus = 0;
+}
+
+
+/***********************************************************************
+ *           hardware_event
+ *
+ * Add an event to the system message queue.
+ * Note: the position is relative to the desktop window.
+ */
+void hardware_event( WORD message, WORD wParam, LONG lParam,
+		     int xPos, int yPos, DWORD time, DWORD extraInfo )
+{
+    MSG *msg;
+    int pos;
+  
+    if (!sysMsgQueue) return;
+    pos = sysMsgQueue->nextFreeMessage;
+
+      /* Merge with previous event if possible */
+
+    if ((message == WM_MOUSEMOVE) && sysMsgQueue->msgCount)
+    {
+        if (pos > 0) pos--;
+        else pos = sysMsgQueue->queueSize - 1;
+	msg = &sysMsgQueue->messages[pos].msg;
+	if ((msg->message == message) && (msg->wParam == wParam))
+            sysMsgQueue->msgCount--;  /* Merge events */
+        else
+            pos = sysMsgQueue->nextFreeMessage;  /* Don't merge */
+    }
+
+      /* Check if queue is full */
+
+    if ((pos == sysMsgQueue->nextMessage) && sysMsgQueue->msgCount)
+    {
+        /* Queue is full, beep (but not on every mouse motion...) */
+        if (message != WM_MOUSEMOVE) MessageBeep(0);
+        return;
+    }
+
+      /* Store message */
+
+    msg = &sysMsgQueue->messages[pos].msg;
+    msg->hwnd    = 0;
+    msg->message = message;
+    msg->wParam  = wParam;
+    msg->lParam  = lParam;
+    msg->time    = time;
+    msg->pt.x    = xPos & 0xffff;
+    msg->pt.y    = yPos & 0xffff;
+    sysMsgQueue->messages[pos].extraInfo = extraInfo;
+    if (pos < sysMsgQueue->queueSize - 1) pos++;
+    else pos = 0;
+    sysMsgQueue->nextFreeMessage = pos;
+    sysMsgQueue->msgCount++;
+}
+
+		    
+/***********************************************************************
+ *	     QUEUE_GetQueueTask
+ */
+HTASK QUEUE_GetQueueTask( HQUEUE hQueue )
+{
+    MESSAGEQUEUE *queue = GlobalLock( hQueue );
+    return (queue) ? queue->hTask : 0 ;
+}
+
+
+/***********************************************************************
+ *           QUEUE_IncPaintCount
+ */
+void QUEUE_IncPaintCount( HQUEUE hQueue )
+{
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return;
+    queue->wPaintCount++;
+    queue->status |= QS_PAINT;
+    queue->tempStatus |= QS_PAINT;    
+}
+
+
+/***********************************************************************
+ *           QUEUE_DecPaintCount
+ */
+void QUEUE_DecPaintCount( HQUEUE hQueue )
+{
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return;
+    queue->wPaintCount--;
+    if (!queue->wPaintCount) queue->status &= ~QS_PAINT;
+}
+
+
+/***********************************************************************
+ *           QUEUE_IncTimerCount
+ */
+void QUEUE_IncTimerCount( HQUEUE hQueue )
+{
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return;
+    queue->wTimerCount++;
+    queue->status |= QS_TIMER;
+    queue->tempStatus |= QS_TIMER;
+}
+
+
+/***********************************************************************
+ *           QUEUE_DecTimerCount
+ */
+void QUEUE_DecTimerCount( HQUEUE hQueue )
+{
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( hQueue ))) return;
+    queue->wTimerCount--;
+    if (!queue->wTimerCount) queue->status &= ~QS_TIMER;
+}
+
+
+/***********************************************************************
+ *           PostQuitMessage   (USER.6)
+ */
+void PostQuitMessage( INT exitCode )
+{
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return;
+    queue->wPostQMsg = TRUE;
+    queue->wExitCode = (WORD)exitCode;
+}
+
+
+/***********************************************************************
+ *           GetWindowTask   (USER.224)
+ */
+HTASK GetWindowTask( HWND hwnd )
+{
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+
+    if (!wndPtr) return 0;
+    return QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
+}
+
+
+/***********************************************************************
+ *           SetMessageQueue   (USER.266)
+ */
+BOOL SetMessageQueue( int size )
+{
+    HQUEUE hQueue, hNewQueue;
+    MESSAGEQUEUE *queuePtr;
+
+    if ((size > MAX_QUEUE_SIZE) || (size <= 0)) return TRUE;
+
+    if( !(hNewQueue = QUEUE_CreateMsgQueue( size ))) 
+    {
+	dprintf_msg(stddeb,"SetMessageQueue: failed!\n");
+	return FALSE;
+    }
+
+    /* Free the old message queue */
+    if ((hQueue = GetTaskQueue(0)) != 0) QUEUE_DeleteMsgQueue( hQueue );
+
+    /* Link new queue into list */
+    queuePtr = (MESSAGEQUEUE *)GlobalLock( hNewQueue );
+    queuePtr->hTask = GetCurrentTask();
+    queuePtr->next  = hFirstQueue;
+    hFirstQueue = hNewQueue;
+
+    SetTaskQueue( 0, hNewQueue );
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           GetQueueStatus   (USER.334)
+ */
+DWORD GetQueueStatus( UINT flags )
+{
+    MESSAGEQUEUE *queue;
+    DWORD ret;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0;
+    ret = MAKELONG( queue->tempStatus, queue->status );
+    queue->tempStatus = 0;
+    return ret & MAKELONG( flags, flags );
+}
+
+
+/***********************************************************************
+ *           GetInputState   (USER.335)
+ */
+BOOL GetInputState()
+{
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return FALSE;
+    return queue->status & (QS_KEY | QS_MOUSEBUTTON);
+}
+
+
+/***********************************************************************
+ *           GetMessagePos   (USER.119)
+ */
+DWORD GetMessagePos(void)
+{
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0;
+    return queue->GetMessagePosVal;
+}
+
+
+/***********************************************************************
+ *           GetMessageTime   (USER.120)
+ */
+LONG GetMessageTime(void)
+{
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0;
+    return queue->GetMessageTimeVal;
+}
+
+
+/***********************************************************************
+ *           GetMessageExtraInfo   (USER.288)
+ */
+LONG GetMessageExtraInfo(void)
+{
+    MESSAGEQUEUE *queue;
+
+    if (!(queue = (MESSAGEQUEUE *)GlobalLock( GetTaskQueue(0) ))) return 0;
+    return queue->GetMessageExtraInfoVal;
+}
diff --git a/windows/timer.c b/windows/timer.c
index 797f66e..1be4855 100644
--- a/windows/timer.c
+++ b/windows/timer.c
@@ -5,7 +5,7 @@
  */
 
 #include "windows.h"
-#include "message.h"
+#include "queue.h"
 #include "stddebug.h"
 /* #define DEBUG_TIMER */
 #include "debug.h"
@@ -173,7 +173,7 @@
     dprintf_timer(stddeb, "Timer added: %p, "NPFMT", %04x, %04x, %08lx\n", 
 		  pTimer, pTimer->hwnd, pTimer->msg, pTimer->id, (DWORD)pTimer->proc);
     TIMER_InsertTimer( pTimer );
-    MSG_IncTimerCount( GetTaskQueue(0) );
+    QUEUE_IncTimerCount( GetTaskQueue(0) );
     if (!id)
 	return TRUE;
     else
@@ -207,7 +207,7 @@
     pTimer->timeout = 0;
     pTimer->proc    = 0;
     TIMER_RemoveTimer( pTimer );
-    MSG_DecTimerCount( GetTaskQueue(0) );
+    QUEUE_DecTimerCount( GetTaskQueue(0) );
     return TRUE;
 }
 
diff --git a/windows/win.c b/windows/win.c
index a6609a8..eb7f3d1 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -15,8 +15,8 @@
 #include "sysmetrics.h"
 #include "cursoricon.h"
 #include "event.h"
-#include "message.h"
 #include "nonclient.h"
+#include "queue.h"
 #include "winpos.h"
 #include "color.h"
 #include "shm_main_blk.h"
@@ -52,6 +52,97 @@
 
 
 /***********************************************************************
+ *           WIN_DumpWindow
+ *
+ * Dump the content of a window structure to stderr.
+ */
+void WIN_DumpWindow( HWND hwnd )
+{
+    CLASS *classPtr;
+    WND *ptr;
+    char className[80];
+    int i;
+
+    if (!(ptr = WIN_FindWndPtr( hwnd )))
+    {
+        fprintf( stderr, "%04x is not a window handle\n", hwnd );
+        return;
+    }
+
+    if (!GetClassName( hwnd, className, sizeof(className ) ))
+        strcpy( className, "#NULL#" );
+
+    fprintf( stderr, "Window %04x:\n", hwnd );
+    fprintf( stderr,
+             "next=%04x  child=%04x  parent=%04x  owner=%04x  class=%04x '%s'\n"
+             "inst=%04x  taskQ=%04x  updRgn=%04x  active=%04x hdce=%04x  idmenu=%04x\n"
+             "style=%08lx  exstyle=%08lx  wndproc=%08lx  text=%04x '%s'\n"
+             "client=%d,%d-%d,%d  window=%d,%d-%d,%d  iconpos=%d,%d  maxpos=%d,%d\n"
+             "sysmenu=%04x  flags=%04x  props=%04x  vscroll=%04x  hscroll=%04x\n",
+             ptr->hwndNext, ptr->hwndChild, ptr->hwndParent, ptr->hwndOwner,
+             ptr->hClass, className, ptr->hInstance, ptr->hmemTaskQ,
+             ptr->hrgnUpdate, ptr->hwndLastActive, ptr->hdce, ptr->wIDmenu,
+             ptr->dwStyle, ptr->dwExStyle, (DWORD)ptr->lpfnWndProc, ptr->hText,
+             ptr->hText ? (char*)USER_HEAP_LIN_ADDR(ptr->hText) : "",
+             ptr->rectClient.left, ptr->rectClient.top, ptr->rectClient.right,
+             ptr->rectClient.bottom, ptr->rectWindow.left, ptr->rectWindow.top,
+             ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->ptIconPos.x,
+             ptr->ptIconPos.y, ptr->ptMaxPos.x, ptr->ptMaxPos.y, ptr->hSysMenu,
+             ptr->flags, ptr->hProp, ptr->hVScroll, ptr->hHScroll );
+
+    if ((classPtr = CLASS_FindClassPtr( ptr->hClass )) &&
+        classPtr->wc.cbWndExtra)
+    {
+        fprintf( stderr, "extra bytes:" );
+        for (i = 0; i < classPtr->wc.cbWndExtra; i++)
+            fprintf( stderr, " %02x", *((BYTE*)ptr->wExtra+i) );
+        fprintf( stderr, "\n" );
+    }
+    fprintf( stderr, "\n" );
+}
+
+
+/***********************************************************************
+ *           WIN_WalkWindows
+ *
+ * Walk the windows tree and print each window on stderr.
+ */
+void WIN_WalkWindows( HWND hwnd, int indent )
+{
+    WND *ptr;
+    CLASS *classPtr;
+    char className[80];
+
+    if (!hwnd) hwnd = hwndDesktop;
+    if (!indent)  /* first time around */
+        fprintf( stderr, "%-16.16s %-8.8s %-6.6s %-17.17s %-8.8s %s\n",
+                 "hwnd", " wndPtr", "queue", "Class Name", " Style", " WndProc");
+
+    while (hwnd)
+    {
+        fprintf( stderr, "%*s%04x%*s", indent, "", hwnd, 13-indent, "" );
+        if (!(ptr = WIN_FindWndPtr( hwnd )))
+        {
+            fprintf( stderr, "*** Invalid window handle\n" );
+            return;
+        }
+        
+        if (!(classPtr = CLASS_FindClassPtr( ptr->hClass ))) strcpy( className, "#NULL#" );
+        else GlobalGetAtomName( classPtr->atomName, className, sizeof(className) );
+        
+        fprintf( stderr, "%08lx %-6.4x %-17.17s %08x %04x:%04x\n",
+                 (DWORD)ptr, ptr->hmemTaskQ, className,
+                 (unsigned) ptr->dwStyle,
+                 HIWORD(ptr->lpfnWndProc),
+                 LOWORD(ptr->lpfnWndProc));
+        
+        if (ptr->hwndChild) WIN_WalkWindows( ptr->hwndChild, indent+1 );
+        hwnd = ptr->hwndNext;
+    }
+}
+
+
+/***********************************************************************
  *           WIN_GetXWindow
  *
  * Return the X window associated to a window.
@@ -209,7 +300,7 @@
     if ((wndPtr->hrgnUpdate) || (wndPtr->flags & WIN_INTERNAL_PAINT))
     {
         if (wndPtr->hrgnUpdate) DeleteObject( wndPtr->hrgnUpdate );
-        MSG_DecPaintCount( wndPtr->hmemTaskQ );
+        QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
     }
     if (!(wndPtr->dwStyle & WS_CHILD))
     {
diff --git a/windows/winpos.c b/windows/winpos.c
index 40929f4..139a6ce 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -12,6 +12,7 @@
 #include "event.h"
 #include "hook.h"
 #include "message.h"
+#include "queue.h"
 #include "stackframe.h"
 #include "winpos.h"
 #include "nonclient.h"
@@ -632,12 +633,8 @@
 BOOL ACTIVATEAPP_callback(HWND hWnd, LPARAM lParam)
 {
     ACTIVATESTRUCT  *lpActStruct = (ACTIVATESTRUCT*)lParam;
-    WND             *wndPtr = WIN_FindWndPtr( hWnd );
-
-    if( !wndPtr || hWnd == GetDesktopWindow()) return 1;
  
-    if( MSG_GetQueueTask(wndPtr->hmemTaskQ) != lpActStruct->hTaskSendTo ) 
-	return 1;
+    if (GetWindowTask(hWnd) != lpActStruct->hTaskSendTo) return 1;
 
     SendMessage( hWnd, WM_ACTIVATEAPP, lpActStruct->wFlag,
 		(LPARAM)((lpActStruct->hWindowTask)?lpActStruct->hWindowTask:0));
@@ -742,10 +739,10 @@
     /* send WM_ACTIVATEAPP if necessary */
     if (hActiveQ != wndPtr->hmemTaskQ)
     {
-	HTASK hT = MSG_GetQueueTask( hActiveQ );
+	HTASK hT = QUEUE_GetQueueTask( hActiveQ );
 
 	actStruct.wFlag = 0;                  /* deactivate */
-	actStruct.hWindowTask = MSG_GetQueueTask(wndPtr->hmemTaskQ);
+	actStruct.hWindowTask = QUEUE_GetQueueTask(wndPtr->hmemTaskQ);
 	actStruct.hTaskSendTo = hT;
 
 	/* send WM_ACTIVATEAPP to top-level windows
@@ -755,7 +752,7 @@
 
 	actStruct.wFlag = 1;                  /* activate */
 	actStruct.hWindowTask = hT;
-	actStruct.hTaskSendTo = MSG_GetQueueTask( wndPtr->hmemTaskQ );
+	actStruct.hTaskSendTo = QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
 
 	EnumWindows( enumCallback , (LPARAM)&actStruct );