Release 980201

Sun Feb  1 13:24:54 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [files/drive.c]
	Added Device= parameter to drive configuration.

	* [if1632/relay.c]
	Throw() and Catch() now use the correct CATCHBUF layout (untested).

	* [tools/build.c] [include/stackframe.h] [loader/task.c]
	Moved 16-bit stack pointer into thread database.
	Save current %fs while running 16-bit code.

Fri Jan 30 09:25:49 1998  Martin Boehme  <boehme@informatik.mu-luebeck.de>

	* [graphics/mapping.c]
	Made DPtoLP32 and LPtoDP32 respect world transforms.

	* [graphics/path.c] [graphics/painting.c] [if1632/gdi.spec]
	  [include/path.h]
	More path support.

	* [include/gdi.h] [include/windows.h] [objects/dc.c]
	  [relay/gdi32.spec]
	Support for Get/SetArcDirection and Get/SetWorldTransform

	* [windows/hook.c]
	Fixed a bug in HOOK_Map16To32Common.

Thu Jan 29 23:43:18 1998  Douglas Ridgway <ridgway@taiga.gmcl.com>

	* [graphics/metafiledrv/init.c] [objects/metafile.c]
	Documentation for metafile related API calls. Fixed a bug to avoid
	documenting it.

	* [include/windows.h]
	Declaration for LoadImage.

Thu Jan 29 21:44:45 1998  Huw D M Davies <h.davies1@physics.oxford.ac.uk>

	* [graphics/win16drv/*]
	Changes to printing code to enable use of printer fonts with the
	win3.1 postscript driver. Remember to add printer=on to [wine]
	section of wine.conf . You will also need to disable truetype
	fonts from control panel. Winword 6.0 and Write seem to be happy
	with this...

	* [include/bitmap.h]
	Fix Widthbytes for 15bpp displays.

Tue Jan 27 20:54:08 1998  Kristian Nielsen <kristian.nielsen@risoe.dk>

	* [tsx11/*] [include/ts*] [tools/make_X11wrappers]
	Implemented thread-safe X11 wrappers.

Tue Jan 27 13:54:09 1998  Constantine Sapuntzakis  <csapuntz@tma-1.lcs.mit.edu>

	* [windows/queue.c]
	Forgot to convert thdb to thread_id.

	* [misc/registry.c]
	Sped up Windows 95 registry reading. Changed code to traverse
	registry as a tree rather than read in all possible keys
	(including dead ones). 

Tue Jan 27 12:46:09 1998  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [loader/pe_image.c][Makefile.in][scheduler/thread.c]
	  [libtest/hello5.c]
	Don't exit() on failed to load referenced dlls.
	Fixed static tls allocation for multiple threads.
	WINELIB should now be able to load PE dlls. A sample
	winelib program, that dynamically loads a internal dll
	is included.

	* [graphics/ddraw.c][include/ddraw.h][include/d3d.h]
	Cleaned up and enhanced further. Added several DirectX5
	interface definitions and DirectSurface3 implementation.
	Stubs for D3D (NOT coming soon, just there so it fails safely).

	* [multimedia/dsound.c][include/dsound.h]
	Actually works now for a lot of cases. Some DirectX5 stuff
	added. Still lacking several features.

	* [windows/dinput.c][include/dinput.h]
	Started implementing DirectInput. Doesn't work yet, don't 
	know why.

	* [if1632/thunk.c][misc/callbacks.c]
	  [win32/kernel.c][include/callbacks.h]
	Added WOWCallback16Ex, WOWHandle32.

	* [misc/cpu.c]
	Fixed GetSystemInfo, IsProcessorFeaturePresent.

	* [multimedia/joystick.c][multimedia/time.c]
	Several fixes. Small hack to get timerevents in timeGetTime() loops.

Tue Jan 20 11:26:27 1998  Slaven Rezic  <eserte@cs.tu-berlin.de>

	* [configure.in]
	Fixed check for union semun on FreeBSD systems.

Sun Jan 18 23:05:04 1998  Karl Backström <karl_b@geocities.com>

	* [misc/ole2nls.c] [programs/progman/Sw.rc] [programs/winhelp/Sw.rc]
	  [resources/sysres_Sw.rc]
	Added/updated Swedish language support.

Sun Jan 18 18:49:01 1998  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [misc/winsock.c] [misc/winsock_dns.c] [windows/event.c]
	  [windows/win.c] [windows/dce.c] [windows/winpos.c]
	Bug fixes.

Sun Jan 18 12:45:23 1997  Andreas Mohr <100.30936@germany.net>

	* [msdos/int25.c] [msdos/int26.c]
        Implemented "native" absolute disk read/write access.

	* [msdos/int13.c] [msdos/ioports.c]
	Enhanced GET DRIVE PARAMETERS (int13 AH=08).

	* [graphics/win16drv/prtdrv.c] [if1632/gdi.spec]
	Fixed typos, implemented dmEnumDFonts,
	Started implementation of dmRealizeObject.

	* [if1632/compobj.spec] [ole/compobj.c] [relay32/ole32.spec]
	Stubs CoCreateInstance, CoFreeUnusedLibraries, implemented
	CoFileTimeNow.

	* [if1632/kernel.spec] [include/windows.h] [memory/global.c]
	  [memory/string.c] [misc/kernel.c] [misc/Makefile.in]
	  [misc/toolhelp.c] [msdos/int21.c]
	Implemented GlobalHandleNoRIP, GetFreeMemInfo, DebugFillBuffer, 
	stubs GetSetKernelDOSProc, DiagQuery, DiagOutput, ToolHelpHook
	(Undocumented Windows).

	* [if1632/user.spec] [if1632/win32s16.spec] [misc/win32s16.c]
	Misc stubs.

	* [if1632/winaspi.spec] [misc/aspi.c]
	Implemented GetASPIDLLVersion.

	* [if1632/wprocs.spec] [msdos/int20.c] [msdos/Makefile.in]
	Added handler for Int 0x20 (terminate program, _very_ old-fashioned).

	* [misc/w32scomb.c]
	Implemented Get16DLLAddress() partially
	(big thanks to Marcus and Alexandre).

	* [relay32/Makefile.in] [relay32/builtin32.c] [relay32/dplay.spec]
	Added built-in DPLAY.DLL.

	* [relay32/winmm.spec] [multimedia/joystick.c]
	Added joySetThreshold.

	* [misc/windebug.c]
	Added WinNotify.

	* [win32/console.c]
	Stubs CreateConsoleScreenBuffer, SetConsoleActiveScreenBuffer,
	WriteConsoleOutput32A.

	* [windows/user.c]
	Stub SetEventHook.

Sat Jan 17 19:30:35 1998  Matthew Toseland  <Paul.Toseland@btinternet.com>

	* [windows/painting.c]
	Fixed broken restore-to-maximized.

Mon Jan 12 21:25:32 1998  Perceval - Marc Huguet Puig <mhp@tinet.fut.es>

	* [documentation/wine.man] [include/options.h]
	  [misc/main.c] [ole/ole2nls.c] [resources/sysres.c]
	  [resources/sysres_Ca.rc] [resources/Makefile.in]
	Added language catalan. (Afegit l'idioma catalĂ ).
diff --git a/ANNOUNCE b/ANNOUNCE
index e7555fe..143313c 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,13 +1,15 @@
-This is release 980118 of Wine, the MS Windows emulator.  This is still a
+This is release 980201 of Wine, the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work correctly.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-980118: (see ChangeLog for details)
-	- New region implementation based on X11 code.
-	- Improvements to DirectDraw and DirectSound.
+WHAT'S NEW with Wine-980201: (see ChangeLog for details)
+	- Support for Catalan and Swedish languages.
+	- More Direct* support.
+	- X11 thread-safe wrappers.
+	- Support for Postscript printer fonts.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -16,10 +18,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980118.tar.gz
-  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980118.tar.gz
-  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-980118.tar.gz
-  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980118.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-980201.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-980201.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-980201.tar.gz
+  ftp://ftp.progsoc.uts.edu.au/pub/Wine/development/Wine-980201.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/BUGS b/BUGS
index 8e339b2..7ca200c 100644
--- a/BUGS
+++ b/BUGS
@@ -30,6 +30,10 @@
 	- You can find information about most of the Win32 API calls
           on the www.microsoft.com (go to 'search').
 
+ * A lot of the extensions to the GDI that were introduced with Win32 are
+   not supported at all or only in a very rudimentary way. (World transforms,
+   arc direction, GM_ADVANCED to name but a few)
+
 Miscellaneous:
 
  * 16-bit Eudora 1.5.2 goes into recursion trying to display
@@ -64,8 +68,6 @@
  * AllocCSToDSAlias() shouldn't alloc alias for the same segment multiple
    times.
 
- * X11DRV_PaintRgn doesn't respect mapping modes
-
 Where to look in source files:
 
  * grep for FIXME in the source files.
diff --git a/ChangeLog b/ChangeLog
index 65a51a7..2a08206 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,183 @@
 ----------------------------------------------------------------------
+Sun Feb  1 13:24:54 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [files/drive.c]
+	Added Device= parameter to drive configuration.
+
+	* [if1632/relay.c]
+	Throw() and Catch() now use the correct CATCHBUF layout (untested).
+
+	* [tools/build.c] [include/stackframe.h] [loader/task.c]
+	Moved 16-bit stack pointer into thread database.
+	Save current %fs while running 16-bit code.
+
+Fri Jan 30 09:25:49 1998  Martin Boehme  <boehme@informatik.mu-luebeck.de>
+
+	* [graphics/mapping.c]
+	Made DPtoLP32 and LPtoDP32 respect world transforms.
+
+	* [graphics/path.c] [graphics/painting.c] [if1632/gdi.spec]
+	  [include/path.h]
+	More path support.
+
+	* [include/gdi.h] [include/windows.h] [objects/dc.c]
+	  [relay/gdi32.spec]
+	Support for Get/SetArcDirection and Get/SetWorldTransform
+
+	* [windows/hook.c]
+	Fixed a bug in HOOK_Map16To32Common.
+
+Thu Jan 29 23:43:18 1998  Douglas Ridgway <ridgway@taiga.gmcl.com>
+
+	* [graphics/metafiledrv/init.c] [objects/metafile.c]
+	Documentation for metafile related API calls. Fixed a bug to avoid
+	documenting it.
+
+	* [include/windows.h]
+	Declaration for LoadImage.
+
+Thu Jan 29 21:44:45 1998  Huw D M Davies <h.davies1@physics.oxford.ac.uk>
+
+	* [graphics/win16drv/*]
+	Changes to printing code to enable use of printer fonts with the
+	win3.1 postscript driver. Remember to add printer=on to [wine]
+	section of wine.conf . You will also need to disable truetype
+	fonts from control panel. Winword 6.0 and Write seem to be happy
+	with this...
+
+	* [include/bitmap.h]
+	Fix Widthbytes for 15bpp displays.
+
+Tue Jan 27 20:54:08 1998  Kristian Nielsen <kristian.nielsen@risoe.dk>
+
+	* [tsx11/*] [include/ts*] [tools/make_X11wrappers]
+	Implemented thread-safe X11 wrappers.
+
+Tue Jan 27 13:54:09 1998  Constantine Sapuntzakis  <csapuntz@tma-1.lcs.mit.edu>
+
+	* [windows/queue.c]
+	Forgot to convert thdb to thread_id.
+
+	* [misc/registry.c]
+	Sped up Windows 95 registry reading. Changed code to traverse
+	registry as a tree rather than read in all possible keys
+	(including dead ones). 
+
+Tue Jan 27 12:46:09 1998  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [loader/pe_image.c][Makefile.in][scheduler/thread.c]
+	  [libtest/hello5.c]
+	Don't exit() on failed to load referenced dlls.
+	Fixed static tls allocation for multiple threads.
+	WINELIB should now be able to load PE dlls. A sample
+	winelib program, that dynamically loads a internal dll
+	is included.
+
+	* [graphics/ddraw.c][include/ddraw.h][include/d3d.h]
+	Cleaned up and enhanced further. Added several DirectX5
+	interface definitions and DirectSurface3 implementation.
+	Stubs for D3D (NOT coming soon, just there so it fails safely).
+
+	* [multimedia/dsound.c][include/dsound.h]
+	Actually works now for a lot of cases. Some DirectX5 stuff
+	added. Still lacking several features.
+
+	* [windows/dinput.c][include/dinput.h]
+	Started implementing DirectInput. Doesn't work yet, don't 
+	know why.
+
+	* [if1632/thunk.c][misc/callbacks.c]
+	  [win32/kernel.c][include/callbacks.h]
+	Added WOWCallback16Ex, WOWHandle32.
+
+	* [misc/cpu.c]
+	Fixed GetSystemInfo, IsProcessorFeaturePresent.
+
+	* [multimedia/joystick.c][multimedia/time.c]
+	Several fixes. Small hack to get timerevents in timeGetTime() loops.
+
+Tue Jan 20 11:26:27 1998  Slaven Rezic  <eserte@cs.tu-berlin.de>
+
+	* [configure.in]
+	Fixed check for union semun on FreeBSD systems.
+
+Sun Jan 18 23:05:04 1998  Karl Backström <karl_b@geocities.com>
+
+	* [misc/ole2nls.c] [programs/progman/Sw.rc] [programs/winhelp/Sw.rc]
+	  [resources/sysres_Sw.rc]
+	Added/updated Swedish language support.
+
+Sun Jan 18 18:49:01 1998  Alex Korobka <alex@trantor.pharm.sunysb.edu>
+
+	* [misc/winsock.c] [misc/winsock_dns.c] [windows/event.c]
+	  [windows/win.c] [windows/dce.c] [windows/winpos.c]
+	Bug fixes.
+
+Sun Jan 18 12:45:23 1997  Andreas Mohr <100.30936@germany.net>
+
+	* [msdos/int25.c] [msdos/int26.c]
+        Implemented "native" absolute disk read/write access.
+
+	* [msdos/int13.c] [msdos/ioports.c]
+	Enhanced GET DRIVE PARAMETERS (int13 AH=08).
+
+	* [graphics/win16drv/prtdrv.c] [if1632/gdi.spec]
+	Fixed typos, implemented dmEnumDFonts,
+	Started implementation of dmRealizeObject.
+
+	* [if1632/compobj.spec] [ole/compobj.c] [relay32/ole32.spec]
+	Stubs CoCreateInstance, CoFreeUnusedLibraries, implemented
+	CoFileTimeNow.
+
+	* [if1632/kernel.spec] [include/windows.h] [memory/global.c]
+	  [memory/string.c] [misc/kernel.c] [misc/Makefile.in]
+	  [misc/toolhelp.c] [msdos/int21.c]
+	Implemented GlobalHandleNoRIP, GetFreeMemInfo, DebugFillBuffer, 
+	stubs GetSetKernelDOSProc, DiagQuery, DiagOutput, ToolHelpHook
+	(Undocumented Windows).
+
+	* [if1632/user.spec] [if1632/win32s16.spec] [misc/win32s16.c]
+	Misc stubs.
+
+	* [if1632/winaspi.spec] [misc/aspi.c]
+	Implemented GetASPIDLLVersion.
+
+	* [if1632/wprocs.spec] [msdos/int20.c] [msdos/Makefile.in]
+	Added handler for Int 0x20 (terminate program, _very_ old-fashioned).
+
+	* [misc/w32scomb.c]
+	Implemented Get16DLLAddress() partially
+	(big thanks to Marcus and Alexandre).
+
+	* [relay32/Makefile.in] [relay32/builtin32.c] [relay32/dplay.spec]
+	Added built-in DPLAY.DLL.
+
+	* [relay32/winmm.spec] [multimedia/joystick.c]
+	Added joySetThreshold.
+
+	* [misc/windebug.c]
+	Added WinNotify.
+
+	* [win32/console.c]
+	Stubs CreateConsoleScreenBuffer, SetConsoleActiveScreenBuffer,
+	WriteConsoleOutput32A.
+
+	* [windows/user.c]
+	Stub SetEventHook.
+
+Sat Jan 17 19:30:35 1998  Matthew Toseland  <Paul.Toseland@btinternet.com>
+
+	* [windows/painting.c]
+	Fixed broken restore-to-maximized.
+
+Mon Jan 12 21:25:32 1998  Perceval - Marc Huguet Puig <mhp@tinet.fut.es>
+
+	* [documentation/wine.man] [include/options.h]
+	  [misc/main.c] [ole/ole2nls.c] [resources/sysres.c]
+	  [resources/sysres_Ca.rc] [resources/Makefile.in]
+	Added language catalan. (Afegit l'idioma català).
+
+----------------------------------------------------------------------
 Sun Jan 18 17:05:58 1998  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [include/stackframe.h] [tools/build.c]
diff --git a/Makefile.in b/Makefile.in
index e6db31e..7e31639 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -40,8 +40,10 @@
 	multimedia \
 	objects \
 	ole \
+	relay32 \
 	resources \
 	scheduler \
+	tsx11 \
 	win32 \
 	windows
 
@@ -49,8 +51,7 @@
 	debugger \
 	graphics/win16drv \
 	if1632 \
-	miscemu \
-	relay32
+	miscemu
 
 PROGSUBDIRS = libtest programs
 
@@ -83,8 +84,10 @@
 	multimedia/multimedia.o \
 	objects/objects.o \
 	ole/ole.o \
+	relay32/relay32.o \
 	resources/resources.o \
 	scheduler/scheduler.o \
+	tsx11/tsx11.o \
 	win32/win32.o \
 	windows/windows.o
 
@@ -92,8 +95,7 @@
 	debugger/debugger.o \
 	graphics/win16drv/win16drv.o \
 	if1632/if1632.o \
-	miscemu/miscemu.o \
-	relay32/relay32.o
+	miscemu/miscemu.o
 
 all: $(MAIN_TARGET)
 
diff --git a/configure b/configure
index 84d8791..44efdae 100755
--- a/configure
+++ b/configure
@@ -2039,8 +2039,8 @@
 #include <sys/soundcard.h>
 int main() {
 
-/* check for open sound system and one of the SNDCTL_ defines to be sure */
-#if !defined(OPEN_SOUND_SYSTEM) || !defined(SNDCTL_DSP_STEREO)
+/* check for one of the Open Sound System specific SNDCTL_ defines */
+#if !defined(SNDCTL_DSP_STEREO)
 #error No open sound system
 #endif
 
@@ -2077,12 +2077,13 @@
   cat > conftest.$ac_ext <<EOF
 #line 2079 "configure"
 #include "confdefs.h"
+#include <sys/types.h>
 #include <sys/sem.h>
 int main() {
 union semun foo
 ; return 0; }
 EOF
-if { (eval echo configure:2086: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2087: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_union_semun="yes"
 else
@@ -2110,7 +2111,7 @@
 then
   CFLAGS="$CFLAGS -Wall"
   echo $ac_n "checking "for gcc strength-reduce bug"""... $ac_c" 1>&6
-echo "configure:2114: checking "for gcc strength-reduce bug"" >&5
+echo "configure:2115: checking "for gcc strength-reduce bug"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_gcc_strength_bug'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2118,7 +2119,7 @@
   ac_cv_c_gcc_strength_bug="yes"
 else
   cat > conftest.$ac_ext <<EOF
-#line 2122 "configure"
+#line 2123 "configure"
 #include "confdefs.h"
 
 int main(void) {
@@ -2129,7 +2130,7 @@
   exit( Array[1] != -2 );
 }
 EOF
-if { (eval echo configure:2133: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   ac_cv_c_gcc_strength_bug="no"
 else
@@ -2152,7 +2153,7 @@
 
 
 echo $ac_n "checking "whether external symbols need an underscore prefix"""... $ac_c" 1>&6
-echo "configure:2156: checking "whether external symbols need an underscore prefix"" >&5
+echo "configure:2157: checking "whether external symbols need an underscore prefix"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_extern_prefix'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2164,14 +2165,14 @@
 	.long 0
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2168 "configure"
+#line 2169 "configure"
 #include "confdefs.h"
 extern int ac_test;
 int main() {
 if (ac_test) return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2175: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2176: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_extern_prefix="yes"
 else
@@ -2195,7 +2196,7 @@
 
 
 echo $ac_n "checking "whether assembler accepts .string"""... $ac_c" 1>&6
-echo "configure:2199: checking "whether assembler accepts .string"" >&5
+echo "configure:2200: checking "whether assembler accepts .string"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_asm_string'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2205,14 +2206,14 @@
 	.string "test"
 EOF
 cat > conftest.$ac_ext <<EOF
-#line 2209 "configure"
+#line 2210 "configure"
 #include "confdefs.h"
 
 int main() {
 
 ; return 0; }
 EOF
-if { (eval echo configure:2216: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2217: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_asm_string="yes"
 else
@@ -2239,21 +2240,21 @@
 if test "$LIB_TARGET" = "libwine.so.1.0"
 then
   echo $ac_n "checking "whether we can build a dll"""... $ac_c" 1>&6
-echo "configure:2243: checking "whether we can build a dll"" >&5
+echo "configure:2244: checking "whether we can build a dll"" >&5
 if eval "test \"`echo '$''{'ac_cv_c_dll'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   saved_cflags=$CFLAGS
   CFLAGS="$CFLAGS -fPIC -shared -Wl,-soname,conftest.so.1.0"
   cat > conftest.$ac_ext <<EOF
-#line 2250 "configure"
+#line 2251 "configure"
 #include "confdefs.h"
 
 int main() {
 return 1
 ; return 0; }
 EOF
-if { (eval echo configure:2257: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   ac_cv_c_dll="yes"
 else
@@ -2281,12 +2282,12 @@
 for ac_func in clone memmove strerror tcgetattr usleep wait4 waitpid
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2285: checking for $ac_func" >&5
+echo "configure:2286: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2290 "configure"
+#line 2291 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2309,7 +2310,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+if { (eval echo configure:2314: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2337,17 +2338,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:2341: checking for $ac_hdr" >&5
+echo "configure:2342: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2346 "configure"
+#line 2347 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2351: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2352: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2374,12 +2375,12 @@
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:2378: checking whether stat file-mode macros are broken" >&5
+echo "configure:2379: checking whether stat file-mode macros are broken" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2383 "configure"
+#line 2384 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2430,12 +2431,12 @@
 fi
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:2434: checking for working const" >&5
+echo "configure:2435: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2439 "configure"
+#line 2440 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -2484,7 +2485,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2488: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:2489: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -2505,12 +2506,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:2509: checking for ANSI C header files" >&5
+echo "configure:2510: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2514 "configure"
+#line 2515 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -2518,7 +2519,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2522: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2523: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2535,7 +2536,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 2539 "configure"
+#line 2540 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -2553,7 +2554,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 2557 "configure"
+#line 2558 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -2574,7 +2575,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 2578 "configure"
+#line 2579 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -2585,7 +2586,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:2589: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2590: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -2609,12 +2610,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:2613: checking for size_t" >&5
+echo "configure:2614: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2618 "configure"
+#line 2619 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -2780,6 +2781,7 @@
 resources/Makefile
 scheduler/Makefile
 tools/Makefile
+tsx11/Makefile
 win32/Makefile
 windows/Makefile  include/config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
 EOF
@@ -2905,6 +2907,7 @@
 resources/Makefile
 scheduler/Makefile
 tools/Makefile
+tsx11/Makefile
 win32/Makefile
 windows/Makefile "}
 EOF
diff --git a/configure.in b/configure.in
index 83da896..c70d80c 100644
--- a/configure.in
+++ b/configure.in
@@ -58,8 +58,8 @@
 AC_CACHE_CHECK("for Open Sound System",
 	ac_cv_c_opensoundsystem,
 	AC_TRY_COMPILE([#include <sys/soundcard.h>],[
-/* check for open sound system and one of the SNDCTL_ defines to be sure */
-#if !defined(OPEN_SOUND_SYSTEM) || !defined(SNDCTL_DSP_STEREO)
+/* check for one of the Open Sound System specific SNDCTL_ defines */
+#if !defined(SNDCTL_DSP_STEREO)
 #error No open sound system
 #endif
 ],ac_cv_c_opensoundsystem="yes",ac_cv_c_opensoundsystem="no"))
@@ -72,7 +72,8 @@
 dnl **** Check for union semun ****
 
 AC_CACHE_CHECK("for union semun", ac_cv_c_union_semun,
- AC_TRY_COMPILE([#include <sys/sem.h>],[union semun foo],
+ AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/sem.h>],[union semun foo],
                 ac_cv_c_union_semun="yes", ac_cv_c_union_semun="no"))
 if test "$ac_cv_c_union_semun" = "yes"
 then
@@ -207,6 +208,7 @@
 resources/Makefile
 scheduler/Makefile
 tools/Makefile
+tsx11/Makefile
 win32/Makefile
 windows/Makefile ])
 
diff --git a/controls/combo.c b/controls/combo.c
index 59b51cb..af61d63 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -362,10 +362,9 @@
     UINT32 	x, y;
     BOOL32 	bBool;
 
-    if( lphc->wState & CBF_NOREDRAW )
-        return;
+    if( lphc->wState & CBF_NOREDRAW ) return;
 
-    hPrevBrush=(HBRUSH32)SelectObject32(hdc,GetSysColorBrush32(COLOR_BTNFACE));
+    hPrevBrush = (HBRUSH32)SelectObject32(hdc, GetSysColorBrush32(COLOR_BTNFACE));
     CONV_RECT16TO32( &lphc->RectButton, &r );
 
     Rectangle32(hdc, r.left, r.top, r.right, r.bottom );
@@ -403,8 +402,7 @@
    INT32	id, size = 0;
    LPSTR	pText = NULL;
 
-   if( lphc->wState & CBF_NOREDRAW )
-        return;
+   if( lphc->wState & CBF_NOREDRAW ) return;
 
    /* follow Windows combobox that sends a bunch of text 
     * inquiries to its listbox while processing WM_PAINT. */
@@ -537,9 +535,9 @@
 	  /* paint text field */
 
 	  GRAPH_DrawRectangle( hDC, lphc->RectEdit.left, lphc->RectEdit.top,
-			       lphc->RectEdit.right - lphc->RectEdit.left, 
-			       lphc->RectButton.bottom - lphc->RectButton.top,
-			       GetSysColorPen32(COLOR_WINDOWFRAME) ); 
+				    lphc->RectEdit.right - lphc->RectEdit.left, 
+				    lphc->RectButton.bottom - lphc->RectButton.top,
+				    GetSysColorPen32(COLOR_WINDOWFRAME) ); 
 	  CBPaintText( lphc, hDC );
       }
       if( hPrevBrush ) SelectObject32( hDC, hPrevBrush );
@@ -679,13 +677,12 @@
    SetWindowPos32( lphc->hWndLBox, HWND_TOP, rect.left, rect.top, 
 		 rect.right - rect.left, rect.bottom - rect.top, 
 		 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOREDRAW);
+
    if( !(lphc->wState & CBF_NOREDRAW) )
-   {
        if( pRect )
            RedrawWindow16( lphc->self->hwndSelf, pRect, 0, RDW_INVALIDATE | 
 			   RDW_ERASE | RDW_UPDATENOW | RDW_NOCHILDREN );
-       ShowWindow32( lphc->hWndLBox, SW_SHOWNA );
-   }
+   ShowWindow32( lphc->hWndLBox, SW_SHOWNA );
 }
 
 /***********************************************************************
@@ -953,7 +950,7 @@
 	     break;
    }
 
-  return SendMessage32A( lphc->owner, msg, lphc->self->wIDmenu, lParam );
+   return SendMessage32A( lphc->owner, msg, lphc->self->wIDmenu, lParam );
 }
 
 /***********************************************************************
@@ -961,41 +958,42 @@
  */
 static LRESULT COMBO_GetText( LPHEADCOMBO lphc, UINT32 N, LPSTR lpText)
 {
-   INT32	idx;
-
    if( lphc->wState & CBF_EDIT )
        return SendMessage32A( lphc->hWndEdit, WM_GETTEXT, 
 			     (WPARAM32)N, (LPARAM)lpText );     
 
    /* get it from the listbox */
 
-   idx = SendMessage32A( lphc->hWndLBox, LB_GETCURSEL32, 0, 0 );
-   if( idx != LB_ERR )
+   if( lphc->hWndLBox )
    {
-       LPSTR        lpBuffer;
-       INT32	    length = SendMessage32A( lphc->hWndLBox, LB_GETTEXTLEN32,
-					    (WPARAM32)idx, 0 );
-
-       /* 'length' is without the terminating character */
-       if( length >= N )
-	   lpBuffer = (LPSTR) HeapAlloc( GetProcessHeap(), 0, length + 1 );
-       else 
-	   lpBuffer = lpText;
-
-       if( lpBuffer )
+       INT32 idx = SendMessage32A( lphc->hWndLBox, LB_GETCURSEL32, 0, 0 );
+       if( idx != LB_ERR )
        {
-	   INT32    n = SendMessage32A( lphc->hWndLBox, LB_GETTEXT32, 
-				       (WPARAM32)idx, (LPARAM)lpText );
+           LPSTR	lpBuffer;
+           INT32	length = SendMessage32A( lphc->hWndLBox, LB_GETTEXTLEN32,
+					        (WPARAM32)idx, 0 );
 
-	   /* truncate if buffer is too short */
+           /* 'length' is without the terminating character */
+           if( length >= N )
+	       lpBuffer = (LPSTR) HeapAlloc( GetProcessHeap(), 0, length + 1 );
+           else 
+	       lpBuffer = lpText;
 
-	   if( length >= N )
-	   {
-	       if( n != LB_ERR ) memcpy( lpText, lpBuffer, (N>n) ? n+1 : N-1 );
-	       lpText[N - 1] = '\0';
-	       HeapFree( GetProcessHeap(), 0, lpBuffer );
+           if( lpBuffer )
+           {
+	       INT32    n = SendMessage32A( lphc->hWndLBox, LB_GETTEXT32, 
+					   (WPARAM32)idx, (LPARAM)lpText );
+
+	       /* truncate if buffer is too short */
+
+	       if( length >= N )
+	       {
+	           if( n != LB_ERR ) memcpy( lpText, lpBuffer, (N>n) ? n+1 : N-1 );
+	           lpText[N - 1] = '\0';
+	           HeapFree( GetProcessHeap(), 0, lpBuffer );
+	       }
+	       return (LRESULT)n;
 	   }
-	   return (LRESULT)n;
        }
    }
    return 0;
@@ -1044,6 +1042,7 @@
                        lphc->RectEdit.bottom - lphc->RectEdit.top,
                        SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW );
        lphc->wState &= ~CBF_NORESIZE;
+
        if( bRedraw && !(lphc->wState & CBF_NOREDRAW) )
            RedrawWindow32( lphc->self->hwndSelf, NULL, 0,
                            RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW );
@@ -1352,7 +1351,7 @@
 		if( lphc->wState & CBF_EDIT )
 		    SendMessage32A( lphc->hWndEdit, message, wParam, lParam );
 		SendMessage32A( lphc->hWndLBox, message, wParam, lParam );
-		break;
+		return 0;
 		
 	case WM_SYSKEYDOWN:
 		if( KEYDATA_ALT & HIWORD(lParam) )
diff --git a/controls/listbox.c b/controls/listbox.c
index f163c47..81d6654 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -2566,6 +2566,11 @@
 		     }
 		     return LISTBOX_HandleKeyDown( wnd, descr, wParam );
 
+		case WM_NCDESTROY:
+		     if( CB_GETTYPE(lphc) != CBS_SIMPLE )
+			 lphc->hWndLBox = 0;
+		     /* fall through */
+
 	        default:
 		     return ListBoxWndProc( hwnd, msg, wParam, lParam );
 	    }
diff --git a/debugger/hash.c b/debugger/hash.c
index ba87473..aba001b 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -798,16 +798,11 @@
     int i, j;
     IMAGE_SECTION_HEADER *pe_seg;
     IMAGE_EXPORT_DIRECTORY *exports;
-    IMAGE_DATA_DIRECTORY *debug_dir;
+    IMAGE_DATA_DIRECTORY *dir;
     WORD *ordinals;
     void **functions;
     const char **names;
 
-    PE_MODREF *pem = PROCESS_Current()->modref_list;
-    while (pem && (pem->module != hModule)) pem = pem->next;
-    if (!pem) return;
-    exports = pem->pe_export;
-
     addr.seg = 0;
     addr.type = NULL;
 
@@ -835,7 +830,10 @@
 
     /* Add exported functions */
 
-    if (!exports) return;
+    dir = &PE_HEADER(hModule)->OptionalHeader.
+                                   DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
+    if (!dir->Size) return;
+    exports   = (IMAGE_EXPORT_DIRECTORY *)RVA( dir->VirtualAddress );
     ordinals  = (WORD *)RVA( exports->AddressOfNameOrdinals );
     names     = (const char **)RVA( exports->AddressOfNames );
     functions = (void **)RVA( exports->AddressOfFunctions );
@@ -860,10 +858,9 @@
         DEBUG_AddSymbol( buffer, &addr, NULL, SYM_WIN32 | SYM_FUNC );
     }
 
-    debug_dir = &PE_HEADER(hModule)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
-    if (debug_dir->Size)
-        DEBUG_RegisterDebugInfo( hModule, name,
-                                 debug_dir->VirtualAddress, debug_dir->Size );
+    dir = &PE_HEADER(hModule)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
+    if (dir->Size)
+        DEBUG_RegisterDebugInfo(hModule, name, dir->VirtualAddress, dir->Size);
 #undef RVA
 }
 
diff --git a/debugger/stabs.c b/debugger/stabs.c
index 98bcc38..bb670f1 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -96,7 +96,7 @@
 
 #define NR_STAB_HASH 521
 
-struct known_typedef * ktd_head[NR_STAB_HASH];
+struct known_typedef * ktd_head[NR_STAB_HASH] = {NULL,};
 
 static unsigned int stab_hash( const char * name )
 {
diff --git a/documentation/internals b/documentation/internals
index 5ffd800..40ca690 100644
--- a/documentation/internals
+++ b/documentation/internals
@@ -6,7 +6,39 @@
 GDI MODULE
 ==========
 
-...
+1. X Windows System interface
+-----------------------------
+
+The X libraries used to implement X clients (such as Wine) do not work
+properly if multiple threads access the same display concurrently. It is
+possible to compile the X libraries to perform their own synchronization
+(initiated by calling XInitThreads()). However, Wine does not use this
+approach. Instead Wine performs its own synchronization py putting a
+wrapper around every X call that is used. This wrapper protects library
+access with a critical section, and also arranges things so that X
+libraries compiled without -D_REENTRANT (eg. with global errno variable)
+will work with Wine.
+
+To make this scheme work, all calls to X must use the proper wrapper
+functions (or do their own synchronization that is compatible with the
+wrappers). The wrapper for a function X...() is calles TSX...() (for
+"Thread Safe X ..."). So for example, instead of calling XOpenDisplay()
+in the code, TSXOpenDisplay() must be used. Likewise, X include files
+that contain function prototypes are wrapped, so that eg. "TSXutil.h" must
+be included rather than <X11/Xutil.h>. It is important that this scheme
+is used everywhere to avoid the introduction of nondeterministic and
+hard-to-find errors in Wine.
+
+The code for the thread safe X wrappers is contained in the tsx11/
+directory and in include/TS*.h. To use a new (ie. not previously used) X
+function in Wine, a new wrapper must be created. The wrappers are
+generated (semi-)automatically from the X11R6 includes using the
+tools/make_X11wrappers perl script. In simple cases it should be enough
+to add the name of the new function to the list in tsx11/X11_calls; if
+this does not work the wrapper must be added manually to the
+make_X11wrappers script. See comments in tsx11/X11_calls and
+tools/make_X11wrappers for further details.
+
 
 USER MODULE
 ===========
diff --git a/documentation/wine.man b/documentation/wine.man
index c4d24eb..7eeb53c 100644
--- a/documentation/wine.man
+++ b/documentation/wine.man
@@ -109,7 +109,7 @@
 .I -language xx
 Set the language to
 .I xx
-(one of En, Es, De, No, Fr, Fi, Da, Cz, Eo, It, Ko, Hu, Pl, Po)
+(one of En, Es, De, No, Fr, Fi, Da, Cz, Eo, It, Ko, Hu, Pl, Po, Sw, Ca)
 .TP
 .I -managed
 Create each top-level window as a properly managed X window
diff --git a/files/drive.c b/files/drive.c
index 7aca8b6..34859a7 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -40,6 +40,7 @@
     char     *root;      /* root dir in Unix format without trailing / */
     char     *dos_cwd;   /* cwd in DOS format without leading or trailing \ */
     char     *unix_cwd;  /* cwd in Unix format without leading or trailing / */
+    char     *device;    /* raw device path */
     char      label[12]; /* drive label */
     DWORD     serial;    /* drive serial number */
     DRIVETYPE type;      /* drive type */
@@ -126,7 +127,7 @@
     int i, len, count = 0;
     char name[] = "Drive A";
     char path[MAX_PATHNAME_LEN];
-    char buffer[20];
+    char buffer[80];
     struct stat drive_stat_buffer;
     char *p;
     DOSDRIVE *drive;
@@ -157,6 +158,7 @@
             drive->dos_cwd  = HEAP_strdupA( SystemHeap, 0, "" );
             drive->unix_cwd = HEAP_strdupA( SystemHeap, 0, "" );
             drive->type     = DRIVE_GetDriveType( name );
+            drive->device   = NULL;
             drive->flags    = 0;
             drive->dev      = drive_stat_buffer.st_dev;
             drive->ino      = drive_stat_buffer.st_ino;
@@ -180,6 +182,12 @@
                                       buffer, sizeof(buffer) );
             drive->flags = DRIVE_GetFSFlags( name, buffer );
 
+            /* Get the device */
+            PROFILE_GetWineIniString( name, "Device", "",
+                                      buffer, sizeof(buffer) );
+            if (buffer[0])
+                drive->device = HEAP_strdupA( SystemHeap, 0, buffer );
+
             /* Make the first hard disk the current drive */
             if ((DRIVE_CurDrive == -1) && (drive->type == TYPE_HD))
                 DRIVE_CurDrive = i;
@@ -550,6 +558,17 @@
 }
 
 
+/***********************************************************************
+ *           DRIVE_OpenDevice
+ *
+ * Open the drive raw device and return a Unix fd (or -1 on error).
+ */
+int DRIVE_OpenDevice( int drive, int flags )
+{
+    if (!DRIVE_IsValid( drive )) return NULL;
+    return open( DOSDrives[drive].device, flags );
+}
+
 
 /***********************************************************************
  *           DRIVE_GetFreeSpace
diff --git a/graphics/ddraw.c b/graphics/ddraw.c
index d2fd0bd..ce417f7 100644
--- a/graphics/ddraw.c
+++ b/graphics/ddraw.c
@@ -13,10 +13,10 @@
  */
 /* Progress on following programs:
  *
- * - Diablo:
- *   The movies play. The game doesn't yet. No sound. (Needs clone())
+ * - Diablo [640x480x8]:
+ *   The movies play. The game doesn't work yet.
  *
- * - WingCommander 4 (not 5!) / Win95 Patch:
+ * - WingCommander 4 / Win95 Patch [640x480x8]:
  *   The intromovie plays, in 8 bit mode (to reconfigure wc4, run wine
  *   "wc4w.exe -I"). The 16bit mode looks broken, but I think this is due to
  *   my Matrox Mystique which uses 565 (rgb) colorweight instead of the usual
@@ -24,22 +24,29 @@
  *   Requires to be run in 640x480xdepth mode (doesn't seem to heed
  *   DDSURFACEDESC.lPitch).
  *
- * - Monkey Island 3:
+ * - Monkey Island 3 [640x480x8]:
  *   Goes to the easy/hard selection screen, then hangs due to not MT safe
  *   XLibs.
  * 
- * - Dark Angel Demo (Some shoot and run game):
- *   The graphics stuff works fine, you can play it.
+ * - DiscWorld 2 [640x480x8]:
+ *   Plays through nearly all intro movies. Sound and animation a bit broken.
+ * 
+ * - XvT [640x480x16]:
+ *   Shows the splash screen, then fails with missing Joystick.
  *
- * - XvT:
- *   Doesn't work, I am still unsure why not.
+ * - Tomb Raider 2 Demo (using 8 bit renderer) [640x480x8]:
+ *   Shows selection screen, but keyboard input doesn't work.
+ *
+ * - WingCommander Prophecy Demo (using software renderer) [640x480x16]:
+ *   Plays intromovie, hangs in selection screen (no keyboard input, probably
+ *   DirectInput problem).
  */
 
 #include "config.h"
 #include <stdio.h>
 #include <unistd.h>
 #include <assert.h>
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 #include <sys/signal.h>
 
 #include "windows.h"
@@ -50,30 +57,35 @@
 #include "ldt.h"
 #include "dc.h"
 #include "win.h"
-#include "debug.h"
-#include "stddebug.h"
 #include "miscemu.h"
 #include "mmsystem.h"
 #include "ddraw.h"
+#include "d3d.h"
+#include "stddebug.h"
+#include "debug.h"
 
 #ifdef HAVE_LIBXXF86DGA
 #include <X11/extensions/xf86dga.h>
 #endif
 
-static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE,REFIID,LPVOID*);
-static HRESULT WINAPI IDirectDraw_QueryInterface(LPDIRECTDRAW this,REFIID refiid,LPVOID *obj);
-static HRESULT WINAPI IDirectDraw2_CreateSurface( LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk);
-static HRESULT WINAPI IDirectDraw_CreateSurface( LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk);
-static struct IDirectDrawSurface2_VTable dds2vt;
-static struct IDirectDrawSurface_VTable ddsvt;
+/* restore signal handlers overwritten by XF86DGA 
+ * this is a define, for it will only work in emulator mode
+ */
+#undef RESTORE_SIGNALS
+
+static struct IDirectDrawSurface3_VTable	dds3vt;
+static struct IDirectDrawSurface2_VTable	dds2vt;
+static struct IDirectDrawSurface_VTable		ddsvt;
+static struct IDirectDraw_VTable		ddvt;
+static struct IDirectDraw2_VTable		dd2vt;
+static struct IDirect3D_VTable			d3dvt;
+static struct IDirect3D2_VTable			d3d2vt;
 
 
 HRESULT WINAPI
 DirectDrawEnumerate32A(LPDDENUMCALLBACK32A ddenumproc,LPVOID data) {
-	fprintf(stderr,"DirectDrawEnumerateA(%p,%p).\n",ddenumproc,data);
+	/* we have just one display driver right now ... */
 	ddenumproc(0,"WINE Display","display",data);
-	ddenumproc((void*)&IID_IDirectDraw,"WINE DirectDraw","directdraw",data);
-	ddenumproc((void*)&IID_IDirectDrawPalette,"WINE DirectPalette","directpalette",data);
 	return 0;
 }
 
@@ -83,8 +95,90 @@
 	return 0;
 }
 
+
 #ifdef HAVE_LIBXXF86DGA
 
+/******************************************************************************
+ *		internal helper functions
+ */
+static void _dump_DDBLTFX(DWORD flagmask) {
+	int	i;
+	const struct {
+		DWORD	mask;
+		char	*name;
+	} flags[] = {
+#define FE(x) { x, #x},
+		FE(DDBLTFX_ARITHSTRETCHY)
+		FE(DDBLTFX_MIRRORLEFTRIGHT)
+		FE(DDBLTFX_MIRRORUPDOWN)
+		FE(DDBLTFX_NOTEARING)
+		FE(DDBLTFX_ROTATE180)
+		FE(DDBLTFX_ROTATE270)
+		FE(DDBLTFX_ROTATE90)
+		FE(DDBLTFX_ZBUFFERRANGE)
+		FE(DDBLTFX_ZBUFFERBASEDEST)
+	};
+	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+		if (flags[i].mask & flagmask)
+			fprintf(stderr,"%s ",flags[i].name);
+}
+
+static void _dump_DDBLTFAST(DWORD flagmask) {
+	int	i;
+	const struct {
+		DWORD	mask;
+		char	*name;
+	} flags[] = {
+#define FE(x) { x, #x},
+		FE(DDBLTFAST_NOCOLORKEY)
+		FE(DDBLTFAST_SRCCOLORKEY)
+		FE(DDBLTFAST_DESTCOLORKEY)
+		FE(DDBLTFAST_WAIT)
+	};
+	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+		if (flags[i].mask & flagmask)
+			fprintf(stderr,"%s ",flags[i].name);
+}
+
+static void _dump_DDBLT(DWORD flagmask) {
+	int	i;
+	const struct {
+		DWORD	mask;
+		char	*name;
+	} flags[] = {
+#define FE(x) { x, #x},
+		FE(DDBLT_ALPHADEST)
+		FE(DDBLT_ALPHADESTCONSTOVERRIDE)
+		FE(DDBLT_ALPHADESTNEG)
+		FE(DDBLT_ALPHADESTSURFACEOVERRIDE)
+		FE(DDBLT_ALPHAEDGEBLEND)
+		FE(DDBLT_ALPHASRC)
+		FE(DDBLT_ALPHASRCCONSTOVERRIDE)
+		FE(DDBLT_ALPHASRCNEG)
+		FE(DDBLT_ALPHASRCSURFACEOVERRIDE)
+		FE(DDBLT_ASYNC)
+		FE(DDBLT_COLORFILL)
+		FE(DDBLT_DDFX)
+		FE(DDBLT_DDROPS)
+		FE(DDBLT_KEYDEST)
+		FE(DDBLT_KEYDESTOVERRIDE)
+		FE(DDBLT_KEYSRC)
+		FE(DDBLT_KEYSRCOVERRIDE)
+		FE(DDBLT_ROP)
+		FE(DDBLT_ROTATIONANGLE)
+		FE(DDBLT_ZBUFFER)
+		FE(DDBLT_ZBUFFERDESTCONSTOVERRIDE)
+		FE(DDBLT_ZBUFFERDESTOVERRIDE)
+		FE(DDBLT_ZBUFFERSRCCONSTOVERRIDE)
+		FE(DDBLT_ZBUFFERSRCOVERRIDE)
+		FE(DDBLT_WAIT)
+		FE(DDBLT_DEPTHFILL)
+	};
+	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+		if (flags[i].mask & flagmask)
+			fprintf(stderr,"%s ",flags[i].name);
+}
+
 static void _dump_DDSCAPS(DWORD flagmask) {
 	int	i;
 	const struct {
@@ -92,7 +186,7 @@
 		char	*name;
 	} flags[] = {
 #define FE(x) { x, #x},
-		FE(DDSCAPS_3D)
+		FE(DDSCAPS_RESERVED1)
 		FE(DDSCAPS_ALPHA)
 		FE(DDSCAPS_BACKBUFFER)
 		FE(DDSCAPS_COMPLEX)
@@ -115,7 +209,13 @@
 		FE(DDSCAPS_HWCODEC)
 		FE(DDSCAPS_MODEX)
 		FE(DDSCAPS_MIPMAP)
+		FE(DDSCAPS_RESERVED2)
 		FE(DDSCAPS_ALLOCONLOAD)
+		FE(DDSCAPS_VIDEOPORT)
+		FE(DDSCAPS_LOCALVIDMEM)
+		FE(DDSCAPS_NONLOCALVIDMEM)
+		FE(DDSCAPS_STANDARDVGAMODE)
+		FE(DDSCAPS_OPTIMIZED)
 	};
 	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
 		if (flags[i].mask & flagmask)
@@ -187,6 +287,8 @@
 		FE(DDSD_CKSRCBLT)
 		FE(DDSD_MIPMAPCOUNT)
 		FE(DDSD_REFRESHRATE)
+		FE(DDSD_LINEARSIZE)
+		FE(DDSD_LPSURFACE)
 	};
 	for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
 		if (flags[i].mask & flagmask)
@@ -222,131 +324,145 @@
 	return DDERR_GENERIC;
 }
 
+/******************************************************************************
+ *			IDirectDrawSurface
+ */
 
 static HRESULT WINAPI IDirectDrawSurface_Lock(
     LPDIRECTDRAWSURFACE this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
 ) {
-	/*
-	fprintf(stderr,"IDirectDrawSurface(%p)->Lock(%p,%p,%08lx,%08lx)\n",
-		this,lprect,lpddsd,flags,(DWORD)hnd
-	);
-	fprintf(stderr,".");
-	*/
-	if (lprect) {
-		/*
-		fprintf(stderr,"	lprect: %dx%d-%dx%d\n",
-			lprect->top,lprect->left,lprect->bottom,lprect->right
+	if (debugging_ddraw || (flags & ~(DDLOCK_WAIT|DDLOCK_READONLY|DDLOCK_WRITEONLY)))
+		fprintf(stderr,"IDirectDrawSurface(%p)->Lock(%p,%p,%08lx,%08lx)\n",
+			this,lprect,lpddsd,flags,(DWORD)hnd
 		);
-		 */
-		lpddsd->lpSurface =	this->surface+
-					(lprect->top*this->lpitch)+
-					(lprect->left*(this->ddraw->d.depth/8));
-	} else
-		lpddsd->lpSurface = this->surface;
-	lpddsd->dwWidth		= this->width;
-	lpddsd->dwHeight	= this->height;
-	lpddsd->lPitch		= this->lpitch;
-	_getpixelformat(this->ddraw,&(lpddsd->ddpfPixelFormat));
-	return 0;
-}
 
-static HRESULT WINAPI IDirectDrawSurface2_Lock(
-    LPDIRECTDRAWSURFACE2 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
-) {
-	fprintf(stderr,"IDirectDrawSurface2(%p)->Lock(%p,%p,%08lx,%08lx)\n",
-		this,lprect,lpddsd,flags,(DWORD)hnd
-	);
-	/*fprintf(stderr,".");*/
 	if (lprect) {
 		/*
 		fprintf(stderr,"	lprect: %dx%d-%dx%d\n",
 			lprect->top,lprect->left,lprect->bottom,lprect->right
 		);
 		 */
-		lpddsd->lpSurface =	this->surface+
-					(lprect->top*this->lpitch)+
-					(lprect->left*(this->ddraw->d.depth/8));
+		lpddsd->y.lpSurface =	this->s.surface+
+					(lprect->top*this->s.lpitch)+
+					(lprect->left*(this->s.ddraw->d.depth/8));
 	} else
-		lpddsd->lpSurface = this->surface;
-	lpddsd->dwWidth		= this->width;
-	lpddsd->dwHeight	= this->height;
-	lpddsd->lPitch		= this->lpitch;
-	_getpixelformat(this->ddraw,&(lpddsd->ddpfPixelFormat));
+		lpddsd->y.lpSurface = this->s.surface;
+	lpddsd->dwWidth		= this->s.width;
+	lpddsd->dwHeight	= this->s.height;
+	lpddsd->lPitch		= this->s.lpitch;
+	_getpixelformat(this->s.ddraw,&(lpddsd->ddpfPixelFormat));
 	return 0;
 }
 
 static HRESULT WINAPI IDirectDrawSurface_Unlock(
 	LPDIRECTDRAWSURFACE this,LPVOID surface
 ) {
-	dprintf_relay(stderr,"IDirectDrawSurface(%p)->Unlock(%p)\n",this,surface);
+	dprintf_ddraw(stderr,"IDirectDrawSurface(%p)->Unlock(%p)\n",this,surface);
 	return 0;
 }
 
 static HRESULT WINAPI IDirectDrawSurface_Flip(
 	LPDIRECTDRAWSURFACE this,LPDIRECTDRAWSURFACE flipto,DWORD dwFlags
 ) {
-/*	fprintf(stderr,"IDirectDrawSurface(%p)->Flip(%p,%08lx),STUB\n",this,flipto,dwFlags);*/
+	dprintf_ddraw(stderr,"IDirectDrawSurface(%p)->Flip(%p,%08lx)\n",this,flipto,dwFlags);
 	if (!flipto) {
-		if (this->backbuffer)
-			flipto = this->backbuffer;
+		if (this->s.backbuffer)
+			flipto = this->s.backbuffer;
 		else
 			flipto = this;
 	}
-/*	fprintf(stderr,"f>%ld",flipto->fb_height);*/
-	XF86DGASetViewPort(display,DefaultScreen(display),0,flipto->fb_height);
-	if (flipto->palette && flipto->palette->cm)
-		XF86DGAInstallColormap(display,DefaultScreen(display),flipto->palette->cm);
+	XF86DGASetViewPort(display,DefaultScreen(display),0,flipto->s.fb_height);
+	if (flipto->s.palette && flipto->s.palette->cm)
+		XF86DGAInstallColormap(display,DefaultScreen(display),flipto->s.palette->cm);
 	while (!XF86DGAViewPortChanged(display,DefaultScreen(display),2)) {
-		fprintf(stderr,"w");
 	}
-	/* is this a good idea ? */
 	if (flipto!=this) {
 		int	tmp;
 		LPVOID	ptmp;
 
-		tmp = this->fb_height;
-		this->fb_height = flipto->fb_height;
-		flipto->fb_height = tmp;
+		tmp = this->s.fb_height;
+		this->s.fb_height = flipto->s.fb_height;
+		flipto->s.fb_height = tmp;
 
-		ptmp = this->surface;
-		this->surface = flipto->surface;
-		flipto->surface = ptmp;
+		ptmp = this->s.surface;
+		this->s.surface = flipto->s.surface;
+		flipto->s.surface = ptmp;
 	}
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDrawSurface2_Unlock(
-	LPDIRECTDRAWSURFACE2 this,LPVOID surface
-) {
-	dprintf_relay(stderr,"IDirectDrawSurface2(%p)->Unlock(%p)\n",this,surface);
-	return 0;
-}
-
 static HRESULT WINAPI IDirectDrawSurface_SetPalette(
 	LPDIRECTDRAWSURFACE this,LPDIRECTDRAWPALETTE pal
 ) {
-	fprintf(stderr,"IDirectDrawSurface(%p)->SetPalette(%p)\n",this,pal);
-	this->palette = pal;
-	return 0;
-}
-
-static HRESULT WINAPI IDirectDrawSurface2_SetPalette(
-	LPDIRECTDRAWSURFACE2 this,LPDIRECTDRAWPALETTE pal
-) {
-	fprintf(stderr,"IDirectDrawSurface2(%p)->SetPalette(%p)\n",this,pal);
-	this->palette = pal;
+	dprintf_ddraw(stderr,"IDirectDrawSurface(%p)->SetPalette(%p)\n",this,pal);
+	this->s.palette = pal; /* probably addref it too */
 	return 0;
 }
 
 static HRESULT WINAPI IDirectDrawSurface_Blt(
 	LPDIRECTDRAWSURFACE this,LPRECT32 rdst,LPDIRECTDRAWSURFACE src,LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
 ) {
-	fprintf(stderr,"IDirectDrawSurface(%p)->Blt(%p,%p,%p,%08lx,%p),stub!\n",
-		this,rdst,src,rsrc,dwFlags,lpbltfx
-	);
-	if (rdst) fprintf(stderr,"	destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
-	if (rsrc) fprintf(stderr,"	srcrect  :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
-	fprintf(stderr,"	blitfx: 0x%08lx\n",lpbltfx->dwDDFX);
+	RECT32	xdst,xsrc;
+	int	i,j;
+
+	if (rdst)
+		memcpy(&xdst,rdst,sizeof(xdst));
+	else {
+		xdst.top	= 0;
+		xdst.bottom	= this->s.height;
+		xdst.left	= 0;
+		xdst.right	= this->s.width;
+	}
+	if (rsrc)
+		memcpy(&xsrc,rsrc,sizeof(xsrc));
+	else if (src) {
+		xsrc.top	= 0;
+		xsrc.bottom	= src->s.height;
+		xsrc.left	= 0;
+		xsrc.right	= src->s.width;
+	}
+
+	if (dwFlags & DDBLT_COLORFILL) {
+		int	bpp = this->s.ddraw->d.depth/8;
+		LPBYTE	xline,xpixel;
+
+		xline = (LPBYTE)this->s.surface+xdst.top*this->s.lpitch;
+		for (i=xdst.top;i<xdst.bottom;i++) {
+			xpixel = xline+bpp*xdst.left;
+
+			for (j=xdst.left;j<xdst.right;j++) {
+				/* FIXME: this only works on little endian
+				 * architectures, where DWORD starts with low
+				 * byte first!
+				 */
+				memcpy(xpixel,&(lpbltfx->b.dwFillColor),bpp);
+				xpixel += bpp;
+			}
+			xline += this->s.lpitch;
+		}
+		dwFlags &= ~(DDBLT_COLORFILL);
+	}
+	dwFlags &= ~(DDBLT_WAIT|DDBLT_ASYNC);/* FIXME: can't handle right now */
+	if (	(xsrc.top ==0) && (xsrc.bottom ==this->s.height) &&
+		(xsrc.left==0) && (xsrc.right  ==this->s.width) &&
+		(xdst.top ==0) && (xdst.bottom ==this->s.height) &&
+		(xdst.left==0) && (xdst.right  ==this->s.width)  &&
+		!dwFlags
+	) {
+		memcpy(this->s.surface,src->s.surface,this->s.height*this->s.lpitch);
+		return 0;
+	}
+	if (dwFlags) {
+		fprintf(stderr,"IDirectDrawSurface(%p)->Blt(%p,%p,%p,%08lx,%p),stub!\n",
+			this,rdst,src,rsrc,dwFlags,lpbltfx
+		);
+		if (rdst) fprintf(stderr,"	destrect :%dx%d-%dx%d\n",rdst->left,rdst->top,rdst->right,rdst->bottom);
+		if (rsrc) fprintf(stderr,"	srcrect  :%dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
+		fprintf(stderr,"\tflags: ");_dump_DDBLT(dwFlags);fprintf(stderr,"\n");
+	}
+	if (dwFlags & DDBLT_DDFX) {
+		fprintf(stderr,"	blitfx: ");_dump_DDBLTFX(lpbltfx->dwDDFX);fprintf(stderr,"\n");
+	}
 	return 0;
 }
 
@@ -357,11 +473,12 @@
 	fprintf(stderr,"IDirectDrawSurface(%p)->BltFast(%ld,%ld,%p,%p,%08lx),stub!\n",
 		this,dstx,dsty,src,rsrc,trans
 	);
+	fprintf(stderr,"	trans:");_dump_DDBLTFAST(trans);fprintf(stderr,"\n");
 	fprintf(stderr,"	srcrect: %dx%d-%dx%d\n",rsrc->left,rsrc->top,rsrc->right,rsrc->bottom);
-	bpp = this->ddraw->d.depth/8;
+	bpp = this->s.ddraw->d.depth/8;
 	for (i=0;i<rsrc->bottom-rsrc->top;i++) {
-		memcpy(	this->surface+((i+dsty)*this->width*bpp)+dstx*bpp,
-			src->surface +(rsrc->top+i)*src->width*bpp+rsrc->left*bpp,
+		memcpy(	this->s.surface+((i+dsty)*this->s.width*bpp)+dstx*bpp,
+			src->s.surface +(rsrc->top+i)*src->s.width*bpp+rsrc->left*bpp,
 			(rsrc->right-rsrc->left)*bpp
 		);
 	}
@@ -380,7 +497,7 @@
 static HRESULT WINAPI IDirectDrawSurface_GetCaps(
 	LPDIRECTDRAWSURFACE this,LPDDSCAPS caps
 ) {
-	fprintf(stderr,"IDirectDrawSurface(%p)->GetCaps(%p)\n",this,caps);
+	dprintf_ddraw(stderr,"IDirectDrawSurface(%p)->GetCaps(%p)\n",this,caps);
 	caps->dwCaps = DDCAPS_PALETTE; /* probably more */
 	return 0;
 }
@@ -388,99 +505,69 @@
 static HRESULT WINAPI IDirectDrawSurface_GetSurfaceDesc(
 	LPDIRECTDRAWSURFACE this,LPDDSURFACEDESC ddsd
 ) { 
-	fprintf(stderr,"IDirectDrawSurface(%p)->GetSurfaceDesc(%p)\n",this,ddsd);
-	fprintf(stderr,"	flags: ");
-	_dump_DDSD(ddsd->dwFlags);
-	fprintf(stderr,"\n");
+	if (debugging_ddraw) {
+		fprintf(stderr,"IDirectDrawSurface(%p)->GetSurfaceDesc(%p)\n",this,ddsd);
+		fprintf(stderr,"	flags: ");
+		_dump_DDSD(ddsd->dwFlags);
+		fprintf(stderr,"\n");
+	}
 
 	ddsd->dwFlags |= DDSD_PIXELFORMAT|DDSD_CAPS|DDSD_BACKBUFFERCOUNT|DDSD_HEIGHT|DDSD_WIDTH;
 	ddsd->ddsCaps.dwCaps	= DDSCAPS_PALETTE;
 	ddsd->dwBackBufferCount	= 1;
-	ddsd->dwHeight		= this->height;
-	ddsd->dwWidth		= this->width;
-	ddsd->lPitch		= this->lpitch;
-	if (this->backbuffer)
+	ddsd->dwHeight		= this->s.height;
+	ddsd->dwWidth		= this->s.width;
+	ddsd->lPitch		= this->s.lpitch;
+	if (this->s.backbuffer)
 		ddsd->ddsCaps.dwCaps |= DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
-	_getpixelformat(this->ddraw,&(ddsd->ddpfPixelFormat));
+	_getpixelformat(this->s.ddraw,&(ddsd->ddpfPixelFormat));
 	
 	return 0;
 }
 
 static ULONG WINAPI IDirectDrawSurface_AddRef(LPDIRECTDRAWSURFACE this) {
-	dprintf_relay(stderr,"IDirectDrawSurface(%p)->AddRef()\n",this);
+	dprintf_ddraw(stderr,"IDirectDrawSurface(%p)->AddRef()\n",this);
 	return ++(this->ref);
 }
 
 static ULONG WINAPI IDirectDrawSurface_Release(LPDIRECTDRAWSURFACE this) {
-	dprintf_relay(stderr,"IDirectDrawSurface(%p)->Release()\n",this);
+	dprintf_ddraw(stderr,"IDirectDrawSurface(%p)->Release()\n",this);
 	if (!--(this->ref)) {
-		this->ddraw->lpvtbl->fnRelease(this->ddraw);
+		this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
 		/* clear out of surface list */
-		this->ddraw->d.vpmask &= ~(1<<(this->fb_height/this->ddraw->d.fb_height));
+		this->s.ddraw->d.vpmask &= ~(1<<(this->s.fb_height/this->s.ddraw->d.fb_height));
 		HeapFree(GetProcessHeap(),0,this);
 		return 0;
 	}
 	return this->ref;
 }
 
-static ULONG WINAPI IDirectDrawSurface2_AddRef(LPDIRECTDRAWSURFACE2 this) {
-	dprintf_relay(stderr,"IDirectDrawSurface2(%p)->AddRef()\n",this);
-	return ++(this->ref);
-}
-
-static ULONG WINAPI IDirectDrawSurface2_Release(LPDIRECTDRAWSURFACE2 this) {
-	dprintf_relay(stderr,"IDirectDrawSurface2(%p)->Release()\n",this);
-	if (!--(this->ref)) {
-		this->ddraw->lpvtbl->fnRelease(this->ddraw);
-		this->ddraw->d.vpmask &= ~(1<<(this->fb_height/this->ddraw->d.fb_height));
-		HeapFree(GetProcessHeap(),0,this);
-		return 0;
-	}
-	return this->ref;
-}
-
-static HRESULT WINAPI IDirectDrawSurface2_GetAttachedSurface(
-	LPDIRECTDRAWSURFACE2 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE2 *lpdsf
-) {
-	fprintf(stderr,"IDirectDrawSurface2(%p)->GetAttachedSurface(%p,%p)\n",this,lpddsd,lpdsf);
-	fprintf(stderr,"	caps ");_dump_DDSCAPS(lpddsd->dwCaps);fprintf(stderr,"\n");
-	if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
-		fprintf(stderr,"whoops, can only handle backbuffers for now\n");
-		return E_FAIL;
-	}
-	/* FIXME: should handle more than one backbuffer */
-	*lpdsf = this->backbuffer;
-	return 0;
-}
-
 static HRESULT WINAPI IDirectDrawSurface_GetAttachedSurface(
 	LPDIRECTDRAWSURFACE this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE *lpdsf
 ) {
-	fprintf(stderr,"IDirectDrawSurface(%p)->GetAttachedSurface(%p,%p)\n",this,lpddsd,lpdsf);
-	fprintf(stderr,"	caps ");_dump_DDSCAPS(lpddsd->dwCaps);fprintf(stderr,"\n");
+	if (debugging_ddraw) {
+		fprintf(stderr,"IDirectDrawSurface(%p)->GetAttachedSurface(%p,%p)\n",this,lpddsd,lpdsf);
+		fprintf(stderr,"	caps ");_dump_DDSCAPS(lpddsd->dwCaps);fprintf(stderr,"\n");
+	}
 	if (!(lpddsd->dwCaps & DDSCAPS_BACKBUFFER)) {
-		fprintf(stderr,"whoops, can only handle backbuffers for now\n");
+		fprintf(stderr,"IDirectDrawSurface::GetAttachedSurface():whoops, can only handle backbuffers for now\n");
 		return E_FAIL;
 	}
 	/* FIXME: should handle more than one backbuffer */
-	*lpdsf = this->backbuffer;
+	*lpdsf = this->s.backbuffer;
 	return 0;
 }
 
 static HRESULT WINAPI IDirectDrawSurface_Initialize(
 	LPDIRECTDRAWSURFACE this,LPDIRECTDRAW ddraw,LPDDSURFACEDESC lpdsfd
 ) {
-	fprintf(stderr,"IDirectDrawSurface(%p)->Initialize(%p,%p)\n",
-		this,ddraw,lpdsfd
-	);
 	return DDERR_ALREADYINITIALIZED;
 }
 
 static HRESULT WINAPI IDirectDrawSurface_GetPixelFormat(
 	LPDIRECTDRAWSURFACE this,LPDDPIXELFORMAT pf
 ) {
-	fprintf(stderr,"IDirectDrawSurface(%p)->GetPixelFormat(%p)\n",this,pf);
-	return _getpixelformat(this->ddraw,pf);
+	return _getpixelformat(this->s.ddraw,pf);
 }
 
 static HRESULT WINAPI IDirectDrawSurface_GetBltStatus(LPDIRECTDRAWSURFACE this,DWORD dwFlags) {
@@ -499,18 +586,167 @@
 	return 0;
 }
 
+static HRESULT WINAPI IDirectDrawSurface_SetClipper(
+	LPDIRECTDRAWSURFACE this,LPDIRECTDRAWCLIPPER clipper
+) {
+	fprintf(stderr,"IDirectDrawSurface(%p)->SetClipper(%p),stub!\n",this,clipper);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectDrawSurface_AddAttachedSurface(
+	LPDIRECTDRAWSURFACE this,LPDIRECTDRAWSURFACE surf
+) {
+	fprintf(stderr,"IDirectDrawSurface(%p)->AddAttachedSurface(%p),stub!\n",this,surf);
+	this->s.backbuffer = surf;
+	return 0;
+}
+
 static HRESULT WINAPI IDirectDrawSurface_GetDC(LPDIRECTDRAWSURFACE this,HDC32* lphdc) {
 	fprintf(stderr,"IDirectDrawSurface(%p)->GetDC(%p),stub!\n",this,lphdc);
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDrawSurface2_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE2 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
-	/* none yet? */
+static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE this,REFIID refiid,LPVOID *obj) {
+        char    xrefiid[50];
+
+        StringFromCLSID((LPCLSID)refiid,xrefiid);
+        dprintf_ddraw(stderr,"IDirectDrawSurface(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
+	
+	/* thats version 3 (DirectX 5) */
+	if (	!memcmp(&IID_IDirectDrawSurface3,refiid,sizeof(IID_IDirectDrawSurface3))) {
+		this->lpvtbl->fnAddRef(this);
+		this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds3vt;
+		*obj = this;
+		return 0;
+	}
+	/* thats version 2 (DirectX 3) */
+	if (	!memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID_IDirectDrawSurface2))) {
+		this->lpvtbl->fnAddRef(this);
+		this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds2vt;
+		*obj = this;
+		return 0;
+	}
+	/* thats us */
+	if (!memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID_IDirectDrawSurface))) {
+		this->lpvtbl->fnAddRef(this);
+		*obj = this;
+		return 0;
+	}
+	fprintf(stderr,"IDirectDrawSurface(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
+    	return OLE_E_ENUM_NOMORE;
+}
+
+static HRESULT WINAPI IDirectDrawSurface_IsLost(LPDIRECTDRAWSURFACE this) {
+	return 0; /* hmm */
+}
+
+static struct IDirectDrawSurface_VTable ddsvt = {
+	IDirectDrawSurface_QueryInterface,
+	IDirectDrawSurface_AddRef,
+	IDirectDrawSurface_Release,
+	IDirectDrawSurface_AddAttachedSurface,
+	(void*)5,
+	IDirectDrawSurface_Blt,
+	IDirectDrawSurface_BltBatch,
+	IDirectDrawSurface_BltFast,
+	(void*)9,
+	(void*)10,
+	(void*)11,
+	IDirectDrawSurface_Flip,
+	IDirectDrawSurface_GetAttachedSurface,
+	IDirectDrawSurface_GetBltStatus,
+	IDirectDrawSurface_GetCaps,
+	(void*)16,
+	(void*)17,
+	IDirectDrawSurface_GetDC,
+	(void*)19,
+	IDirectDrawSurface_GetOverlayPosition,
+	(void*)21,
+	IDirectDrawSurface_GetPixelFormat,
+	IDirectDrawSurface_GetSurfaceDesc,
+	IDirectDrawSurface_Initialize,
+	IDirectDrawSurface_IsLost,
+	IDirectDrawSurface_Lock,
+	(void*)27,
+	(void*)28,
+	IDirectDrawSurface_SetClipper,
+	(void*)30,
+	(void*)31,
+	IDirectDrawSurface_SetPalette,
+	IDirectDrawSurface_Unlock,
+	(void*)34,
+	(void*)35,
+	(void*)36,
+};
+
+/******************************************************************************
+ *			IDirectDrawSurface2
+ *
+ * calls IDirectDrawSurface methods where possible
+ */
+static HRESULT WINAPI IDirectDrawSurface2_Lock(
+    LPDIRECTDRAWSURFACE2 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
+) {
+	return IDirectDrawSurface_Lock((LPDIRECTDRAWSURFACE)this,lprect,lpddsd,flags,hnd);
+}
+
+static HRESULT WINAPI IDirectDrawSurface2_Unlock(
+	LPDIRECTDRAWSURFACE2 this,LPVOID surface
+) {
+	dprintf_ddraw(stderr,"IDirectDrawSurface2(%p)->Unlock(%p)\n",this,surface);
 	return 0;
 }
 
+static HRESULT WINAPI IDirectDrawSurface2_SetPalette(
+	LPDIRECTDRAWSURFACE2 this,LPDIRECTDRAWPALETTE pal
+) {
+	return IDirectDrawSurface_SetPalette((LPDIRECTDRAWSURFACE)this,pal);
+}
+
+static ULONG WINAPI IDirectDrawSurface2_AddRef(LPDIRECTDRAWSURFACE2 this) {
+	dprintf_ddraw(stderr,"IDirectDrawSurface2(%p)->AddRef()\n",this);
+	return ++(this->ref);
+}
+
+static ULONG WINAPI IDirectDrawSurface2_Release(LPDIRECTDRAWSURFACE2 this) {
+	dprintf_ddraw(stderr,"IDirectDrawSurface2(%p)->Release()\n",this);
+	if (!--(this->ref)) {
+		this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
+		this->s.ddraw->d.vpmask &= ~(1<<(this->s.fb_height/this->s.ddraw->d.fb_height));
+		HeapFree(GetProcessHeap(),0,this);
+		return 0;
+	}
+	return this->ref;
+}
+
+static HRESULT WINAPI IDirectDrawSurface2_GetAttachedSurface(
+	LPDIRECTDRAWSURFACE2 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE2 *lpdsf
+) {
+	HRESULT	ret = IDirectDrawSurface_GetAttachedSurface((LPDIRECTDRAWSURFACE)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf);
+
+	if (!ret)
+		(*lpdsf)->lpvtbl = &dds2vt;
+	return ret;
+}
+
+static HRESULT WINAPI IDirectDrawSurface2_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE2 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
+	fprintf(stderr,"IDirectDrawSurface(%p)->EnumAttachedSurfaces(%p,%p),stub!\n",this,context,esfcb);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectDrawSurface2_QueryInterface(
+	LPDIRECTDRAWSURFACE2 this,REFIID riid,LPVOID *ppobj
+) {
+	return IDirectDrawSurface_QueryInterface((LPDIRECTDRAWSURFACE)this,riid,ppobj);
+}
+
+static HRESULT WINAPI IDirectDrawSurface2_IsLost(LPDIRECTDRAWSURFACE2 this) {
+	return 0; /* hmm */
+}
+
+
 static struct IDirectDrawSurface2_VTable dds2vt = {
-	(void*)1/*IDirectDrawSurface2_QueryInterface*/,
+	IDirectDrawSurface2_QueryInterface,
 	IDirectDrawSurface2_AddRef,
 	IDirectDrawSurface2_Release,
 	(void*)4,
@@ -534,7 +770,7 @@
 	(void*)22,
 	(void*)23/*IDirectDrawSurface_GetSurfaceDesc*/,
 	(void*)24,
-	(void*)25,
+	IDirectDrawSurface2_IsLost,
 	IDirectDrawSurface2_Lock,
 	(void*)27,
 	(void*)28,
@@ -551,78 +787,326 @@
 	(void*)39,
 };
 
-
-static HRESULT WINAPI IDirectDrawSurface_QueryInterface(LPDIRECTDRAWSURFACE this,REFIID refiid,LPVOID *obj) {
-        char    xrefiid[50];
-
-        StringFromCLSID((LPCLSID)refiid,xrefiid);
-        fprintf(stderr,"IDirectDrawSurface(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
-	
-	/* thats version 2 */
-	if (	!memcmp(&IID_IDirectDrawSurface2,refiid,sizeof(IID_IDirectDrawSurface2))) {
-		this->lpvtbl->fnAddRef(this);
-		this->lpvtbl = (LPDIRECTDRAWSURFACE_VTABLE)&dds2vt;
-		*obj = this;
-		return 0;
-	}
-	/* thats us */
-	if (!memcmp(&IID_IDirectDrawSurface,refiid,sizeof(IID_IDirectDrawSurface))) {
-		this->lpvtbl->fnAddRef(this);
-		*obj = this;
-		return 0;
-	}
-    	return OLE_E_ENUM_NOMORE;
+/******************************************************************************
+ *			IDirectDrawSurface3
+ */
+static HRESULT WINAPI IDirectDrawSurface3_SetPalette(
+	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWPALETTE pal
+) {
+	return IDirectDrawSurface_SetPalette((LPDIRECTDRAWSURFACE)this,pal);
 }
 
-static struct IDirectDrawSurface_VTable ddsvt = {
-	IDirectDrawSurface_QueryInterface,
-	IDirectDrawSurface_AddRef,
-	IDirectDrawSurface_Release,
+static HRESULT WINAPI IDirectDrawSurface3_GetPixelFormat(
+	LPDIRECTDRAWSURFACE3 this,LPDDPIXELFORMAT pf
+) {
+	return _getpixelformat(this->s.ddraw,pf);
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_GetAttachedSurface(
+	LPDIRECTDRAWSURFACE3 this,LPDDSCAPS lpddsd,LPDIRECTDRAWSURFACE3 *lpdsf
+) {
+	HRESULT	ret = IDirectDrawSurface_GetAttachedSurface((LPDIRECTDRAWSURFACE)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf);
+
+	if (!ret)
+		(*lpdsf)->lpvtbl = &dds3vt;
+	return ret;
+}
+
+static ULONG WINAPI IDirectDrawSurface3_AddRef(LPDIRECTDRAWSURFACE3 this) {
+	dprintf_ddraw(stderr,"IDirectDrawSurface3(%p)->AddRef()\n",this);
+	return ++(this->ref);
+}
+
+static ULONG WINAPI IDirectDrawSurface3_Release(LPDIRECTDRAWSURFACE3 this) {
+	dprintf_ddraw(stderr,"IDirectDrawSurface3(%p)->Release()\n",this);
+	if (!--(this->ref)) {
+		this->s.ddraw->lpvtbl->fnRelease(this->s.ddraw);
+		this->s.ddraw->d.vpmask &= ~(1<<(this->s.fb_height/this->s.ddraw->d.fb_height));
+		HeapFree(GetProcessHeap(),0,this);
+		return 0;
+	}
+	return this->ref;
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_Blt(
+        LPDIRECTDRAWSURFACE3 this,LPRECT32 rdst,LPDIRECTDRAWSURFACE3 src,
+	LPRECT32 rsrc,DWORD dwFlags,LPDDBLTFX lpbltfx
+) {
+	return IDirectDrawSurface_Blt((LPDIRECTDRAWSURFACE)this,rdst,(LPDIRECTDRAWSURFACE)src,rsrc,dwFlags,lpbltfx);
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_IsLost(LPDIRECTDRAWSURFACE3 this) {
+	return 0; /* hmm */
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_Restore(LPDIRECTDRAWSURFACE3 this) {
+	return 0;
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_GetBltStatus(
+	LPDIRECTDRAWSURFACE3 this,DWORD dwflags
+) {
+	return IDirectDrawSurface_GetBltStatus((LPDIRECTDRAWSURFACE)this,dwflags);
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_Flip(
+	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWSURFACE3 flipto,DWORD dwFlags
+) {
+	return IDirectDrawSurface_Flip((LPDIRECTDRAWSURFACE)this,(LPDIRECTDRAWSURFACE)flipto,dwFlags);
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_Lock(
+    LPDIRECTDRAWSURFACE3 this,LPRECT32 lprect,LPDDSURFACEDESC lpddsd,DWORD flags, HANDLE32 hnd
+) {
+	return IDirectDrawSurface_Lock((LPDIRECTDRAWSURFACE)this,lprect,lpddsd,flags,hnd); 
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_Unlock(
+	LPDIRECTDRAWSURFACE3 this,LPVOID surface
+) {
+	return IDirectDrawSurface_Unlock((LPDIRECTDRAWSURFACE)this,surface);
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_EnumAttachedSurfaces(LPDIRECTDRAWSURFACE3 this,LPVOID context,LPDDENUMSURFACESCALLBACK esfcb) {
+	fprintf(stderr,"IDirectDrawSurface3(%p)->EnumAttachedSurfaces(%p,%p),stub!\n",this,context,esfcb);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_SetClipper(
+	LPDIRECTDRAWSURFACE3 this,LPDIRECTDRAWCLIPPER clipper
+) {
+	return IDirectDrawSurface_SetClipper((LPDIRECTDRAWSURFACE)this,clipper);
+}
+
+static HRESULT WINAPI IDirectDrawSurface3_QueryInterface(
+	LPDIRECTDRAWSURFACE3 this,REFIID riid,LPVOID *ppobj
+) {
+	return IDirectDrawSurface_QueryInterface((LPDIRECTDRAWSURFACE)this,riid,ppobj);
+}
+
+static struct IDirectDrawSurface3_VTable dds3vt = {
+	IDirectDrawSurface3_QueryInterface,
+	IDirectDrawSurface3_AddRef,
+	IDirectDrawSurface3_Release,
 	(void*)4,
 	(void*)5,
-	IDirectDrawSurface_Blt,
-	IDirectDrawSurface_BltBatch,
-	IDirectDrawSurface_BltFast,
+	IDirectDrawSurface3_Blt,
+	(void*)7,
+	(void*)8,
 	(void*)9,
-	(void*)10,
+	IDirectDrawSurface3_EnumAttachedSurfaces,
 	(void*)11,
-	IDirectDrawSurface_Flip,
-	IDirectDrawSurface_GetAttachedSurface,
-	IDirectDrawSurface_GetBltStatus,
-	IDirectDrawSurface_GetCaps,
+	IDirectDrawSurface3_Flip,
+	IDirectDrawSurface3_GetAttachedSurface,
+	IDirectDrawSurface3_GetBltStatus,
+	(void*)15,
 	(void*)16,
 	(void*)17,
-	IDirectDrawSurface_GetDC,
+	(void*)18,
 	(void*)19,
-	IDirectDrawSurface_GetOverlayPosition,
+	(void*)20,
 	(void*)21,
-	IDirectDrawSurface_GetPixelFormat,
-	IDirectDrawSurface_GetSurfaceDesc,
-	IDirectDrawSurface_Initialize,
-	(void*)25,
-	IDirectDrawSurface_Lock,
+	IDirectDrawSurface3_GetPixelFormat,
+	(void*)23,
+	(void*)24,
+	IDirectDrawSurface3_IsLost,
+	IDirectDrawSurface3_Lock,
 	(void*)27,
-	(void*)28,
-	(void*)29,
+	IDirectDrawSurface3_Restore,
+	IDirectDrawSurface3_SetClipper,
 	(void*)30,
 	(void*)31,
-	IDirectDrawSurface_SetPalette,
-	IDirectDrawSurface_Unlock,
+	IDirectDrawSurface3_SetPalette,
+	IDirectDrawSurface3_Unlock,
 	(void*)34,
 	(void*)35,
 	(void*)36,
+	(void*)37,
+	(void*)38,
+	(void*)39,
+	(void*)40,
 };
 
+
+/******************************************************************************
+ *			IDirectDrawClipper
+ */
+static HRESULT WINAPI IDirectDrawClipper_SetHwnd(
+	LPDIRECTDRAWCLIPPER this,DWORD x,HWND32 hwnd
+) {
+	fprintf(stderr,"IDirectDrawClipper(%p)->SetHwnd(0x%08lx,0x%08lx),stub!\n",this,x,(DWORD)hwnd);
+	return 0;
+}
+
+static ULONG WINAPI IDirectDrawClipper_Release(LPDIRECTDRAWCLIPPER this) {
+	this->ref--;
+	if (this->ref)
+		return this->ref;
+	HeapFree(GetProcessHeap(),0,this);
+	return 0;
+}
+
+static struct IDirectDrawClipper_VTable ddclipvt = {
+	(void*)1,
+	(void*)2,
+	IDirectDrawClipper_Release,
+	(void*)4,
+	(void*)5,
+	(void*)6,
+	(void*)7,
+	(void*)8,
+	IDirectDrawClipper_SetHwnd
+};
+
+/******************************************************************************
+ *			IDirectDrawPalette
+ */
+static HRESULT WINAPI IDirectDrawPalette_GetEntries(
+	LPDIRECTDRAWPALETTE this,DWORD x,DWORD y,DWORD z,LPPALETTEENTRY palent
+) {
+	fprintf(stderr,"IDirectDrawPalette(%p)->GetEntries(%08lx,%08lx,%08lx,%p),stub!\n",
+		this,x,y,z,palent
+	);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectDrawPalette_SetEntries(
+	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
+) {
+	XColor		xc;
+	int		i;
+
+	dprintf_ddraw(stderr,"IDirectDrawPalette(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
+		this,x,start,end,palent
+	);
+	if (!this->cm) /* should not happen */ {
+		fprintf(stderr,"no colormap in SetEntries???\n");
+		return DDERR_GENERIC;
+	}
+/* FIXME: free colorcells instead of freeing whole map */
+	XFreeColormap(display,this->cm);
+	this->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
+	if (start>0) {
+		xc.red = xc.blue = xc.green = 0; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 0; TSXStoreColor(display,this->cm,&xc);
+	}
+	if (end<256) {
+		xc.red = xc.blue = xc.green = 0xffff; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 255; TSXStoreColor(display,this->cm,&xc);
+	}
+	for (i=start;i<end;i++) {
+		xc.red = palent[i-start].peRed<<8;
+		xc.blue = palent[i-start].peBlue<<8;
+		xc.green = palent[i-start].peGreen<<8;
+		xc.flags = DoRed|DoBlue|DoGreen;
+		xc.pixel = i;
+		TSXStoreColor(display,this->cm,&xc);
+	}
+	XF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
+	return 0;
+}
+
+static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
+	if (!--(this->ref)) {
+		if (this->cm) {
+			XFreeColormap(display,this->cm);
+			this->cm = 0;
+		}
+		HeapFree(GetProcessHeap(),0,this);
+		return 0;
+	}
+	return this->ref;
+}
+
+static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
+	return ++(this->ref);
+}
+
+static HRESULT WINAPI IDirectDrawPalette_Initialize(
+	LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
+) {
+	return DDERR_ALREADYINITIALIZED;
+}
+
+static struct IDirectDrawPalette_VTable ddpalvt = {
+	(void*)1,
+	IDirectDrawPalette_AddRef,
+	IDirectDrawPalette_Release,
+	(void*)4,
+	IDirectDrawPalette_GetEntries,
+	IDirectDrawPalette_Initialize,
+	IDirectDrawPalette_SetEntries
+};
+
+/*******************************************************************************
+ *				IDirect3D
+ */
+static struct IDirect3D_VTable d3dvt = {
+	(void*)1,
+	(void*)2,
+	(void*)3,
+	(void*)4,
+	(void*)5,
+	(void*)6,
+	(void*)7,
+	(void*)8,
+	(void*)9,
+};
+
+/*******************************************************************************
+ *				IDirect3D2
+ */
+static ULONG WINAPI IDirect3D2_Release(LPDIRECT3D2 this) {
+	this->ref--;
+	if (!this->ref) {
+		this->ddraw->lpvtbl->fnRelease(this->ddraw);
+		HeapFree(GetProcessHeap(),0,this);
+		return 0;
+	}
+	return this->ref;
+}
+
+static HRESULT WINAPI IDirect3D2_EnumDevices(
+	LPDIRECT3D2 this,LPD3DENUMDEVICESCALLBACK cb, LPVOID context
+) {
+	D3DDEVICEDESC	d1,d2;
+
+	fprintf(stderr,"IDirect3D2(%p)->EnumDevices(%p,%p),stub!\n",this,cb,context);
+	d1.dwSize	= sizeof(d1);
+	d1.dwFlags	= 0;
+
+	d2.dwSize	= sizeof(d2);
+	d2.dwFlags	= 0;
+	cb(&IID_IDirect3DHALDevice,"WINE Direct3D HAL","direct3d",&d1,&d2,context);
+	return 0;
+}
+
+static struct IDirect3D2_VTable d3d2vt = {
+	(void*)1,
+	(void*)2,
+	IDirect3D2_Release,
+	IDirect3D2_EnumDevices,
+	(void*)5,
+	(void*)6,
+	(void*)7,
+	(void*)8,
+	(void*)9,
+};
+
+/*******************************************************************************
+ *				IDirectDraw
+ */
 static HRESULT WINAPI IDirectDraw_CreateSurface(
 	LPDIRECTDRAW this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
 ) {
 	int	i;
 
-	fprintf(stderr,"IDirectDraw(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
-	fprintf(stderr," [w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
-	_dump_DDSD(lpddsd->dwFlags);
-	fprintf(stderr,"caps ");_dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
-	fprintf(stderr,"]\n");
+	if (debugging_ddraw) {
+		fprintf(stderr,"IDirectDraw(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
+		fprintf(stderr," [w=%ld,h=%ld,flags ",lpddsd->dwWidth,lpddsd->dwHeight);
+		_dump_DDSD(lpddsd->dwFlags);
+		fprintf(stderr,"caps ");
+		_dump_DDSCAPS(lpddsd->ddsCaps.dwCaps);
+		fprintf(stderr,"]\n");
+	}
 
 	*lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
 	this->lpvtbl->fnAddRef(this);
@@ -631,41 +1115,41 @@
 	for (i=0;i<32;i++)
 		if (!(this->d.vpmask & (1<<i)))
 			break;
-	fprintf(stderr,"using viewport %d for a primary surface\n",i);
+	dprintf_ddraw(stderr,"using viewport %d for a primary surface\n",i);
 	/* if i == 32 or maximum ... return error */
 	this->d.vpmask|=(1<<i);
-	(*lpdsf)->surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
-	(*lpdsf)->fb_height = i*this->d.fb_height;
+	(*lpdsf)->s.surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
+	(*lpdsf)->s.fb_height = i*this->d.fb_height;
 
-	(*lpdsf)->width = this->d.width;
-	(*lpdsf)->height = this->d.height;
-	(*lpdsf)->ddraw = this;
-	(*lpdsf)->lpitch = this->d.fb_width*this->d.depth/8;
-	(*lpdsf)->backbuffer = NULL;
+	(*lpdsf)->s.width = this->d.width;
+	(*lpdsf)->s.height = this->d.height;
+	(*lpdsf)->s.ddraw = this;
+	(*lpdsf)->s.lpitch = this->d.fb_width*this->d.depth/8;
+	(*lpdsf)->s.backbuffer = NULL;
 	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
 		LPDIRECTDRAWSURFACE	back;
 
 		if (lpddsd->dwBackBufferCount>1)
 			fprintf(stderr,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
 
-		(*lpdsf)->backbuffer = back = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
+		(*lpdsf)->s.backbuffer = back = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
 		this->lpvtbl->fnAddRef(this);
 		back->ref = 1;
 		back->lpvtbl = &ddsvt;
 		for (i=0;i<32;i++)
 			if (!(this->d.vpmask & (1<<i)))
 				break;
-		fprintf(stderr,"using viewport %d for backbuffer\n",i);
+		dprintf_ddraw(stderr,"using viewport %d for backbuffer\n",i);
 		/* if i == 32 or maximum ... return error */
 		this->d.vpmask|=(1<<i);
-		back->surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
-		back->fb_height = i*this->d.fb_height;
+		back->s.surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
+		back->s.fb_height = i*this->d.fb_height;
 
-		back->width = this->d.width;
-		back->height = this->d.height;
-		back->ddraw = this;
-		back->lpitch = this->d.fb_width*this->d.depth/8;
-		back->backbuffer = NULL; /* does not have a backbuffer, it is
+		back->s.width = this->d.width;
+		back->s.height = this->d.height;
+		back->s.ddraw = this;
+		back->s.lpitch = this->d.fb_width*this->d.depth/8;
+		back->s.backbuffer = NULL; /* does not have a backbuffer, it is
 					  * one! */
 	}
 	return 0;
@@ -679,59 +1163,6 @@
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDraw2_CreateSurface(
-	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
-) {
-	int	i;
-
-	fprintf(stderr,"IDirectDraw2(%p)->CreateSurface(%p,%p,%p)\n",this,lpddsd,lpdsf,lpunk);
-	*lpdsf = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface));
-	this->lpvtbl->fnAddRef(this);
-	(*lpdsf)->ref = 1;
-	(*lpdsf)->lpvtbl = &ddsvt;
-
-	for (i=0;i<32;i++)
-		if (!(this->d.vpmask & (1<<i)))
-			break;
-	fprintf(stderr,"using viewport %d for primary\n",i);
-	/* if i == 32 or maximum ... return error */
-	this->d.vpmask|=(1<<i);
-	(*lpdsf)->surface = this->d.fb_addr+((i*this->d.fb_height)*this->d.fb_width*this->d.depth/8);
-	(*lpdsf)->width = this->d.width;
-	(*lpdsf)->height = this->d.height;
-	(*lpdsf)->ddraw = (LPDIRECTDRAW)this;
-	(*lpdsf)->fb_height = i*this->d.fb_height;
-	(*lpdsf)->lpitch = this->d.fb_width*this->d.depth/8;
-	(*lpdsf)->backbuffer = NULL;
-	if (lpddsd->dwFlags & DDSD_BACKBUFFERCOUNT) {
-		LPDIRECTDRAWSURFACE	back;
-
-		if (lpddsd->dwBackBufferCount>1)
-			fprintf(stderr,"urks, wants to have more than one backbuffer (%ld)!\n",lpddsd->dwBackBufferCount);
-
-		(*lpdsf)->backbuffer = back = (LPDIRECTDRAWSURFACE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawSurface2));
-		this->lpvtbl->fnAddRef(this);
-		back->ref = 1;
-		back->lpvtbl = &ddsvt;
-		for (i=0;i<32;i++)
-			if (!(this->d.vpmask & (1<<i)))
-				break;
-		fprintf(stderr,"using viewport %d for backbuffer\n",i);
-		/* if i == 32 or maximum ... return error */
-		this->d.vpmask|=(1<<i);
-		back->surface = this->d.fb_addr+((i*this->d.vp_height)*this->d.fb_width*this->d.depth/8);
-		back->fb_height = i*this->d.fb_height;
-
-		back->width = this->d.width;
-		back->height = this->d.height;
-		back->ddraw = (LPDIRECTDRAW)this;
-		back->lpitch = this->d.fb_width*this->d.depth/8;
-		back->backbuffer = NULL; /* does not have a backbuffer, it is
-					  * one! */
-	}
-	return 0;
-}
-
 static HRESULT WINAPI IDirectDraw_SetCooperativeLevel(
 	LPDIRECTDRAW this,HWND32 hwnd,DWORD cooplevel
 ) {
@@ -746,20 +1177,23 @@
 		FE(DDSCL_NORMAL)
 		FE(DDSCL_ALLOWMODEX)
 		FE(DDSCL_EXCLUSIVE)
+		FE(DDSCL_SETFOCUSWINDOW)
+		FE(DDSCL_SETDEVICEWINDOW)
+		FE(DDSCL_CREATEDEVICEWINDOW)
 	};
-	fprintf(stderr,"IDirectDraw(%p)->SetCooperativeLevel(%08lx,%08lx),stub!\n",
+
+	dprintf_ddraw(stderr,"IDirectDraw(%p)->SetCooperativeLevel(%08lx,%08lx)\n",
 		this,(DWORD)hwnd,cooplevel
 	);
-	fprintf(stderr,"	cooperative level ");
+	dprintf_ddraw(stderr,"	cooperative level ");
 	for (i=0;i<sizeof(flagmap)/sizeof(flagmap[0]);i++)
 		if (flagmap[i].mask & cooplevel)
-			fprintf(stderr,"%s ",flagmap[i].name);
-	fprintf(stderr,"\n");
+			dprintf_ddraw(stderr,"%s ",flagmap[i].name);
+	dprintf_ddraw(stderr,"\n");
 	this->d.mainwindow = hwnd;
 	return 0;
 }
 
-extern BOOL32 SIGNAL_InitEmulator(void);
 
 static HRESULT WINAPI IDirectDraw_SetDisplayMode(
 	LPDIRECTDRAW this,DWORD width,DWORD height,DWORD depth
@@ -767,13 +1201,13 @@
 	int	i,*depths,depcount;
 	char	buf[200];
 
-	fprintf(stderr,"IDirectDraw(%p)->SetDisplayMode(%ld,%ld,%ld),stub!\n",this,width,height,depth);
+	dprintf_ddraw(stderr,"IDirectDraw(%p)->SetDisplayMode(%ld,%ld,%ld),stub!\n",this,width,height,depth);
 
-	depths = XListDepths(display,DefaultScreen(display),&depcount);
+	depths = TSXListDepths(display,DefaultScreen(display),&depcount);
 	for (i=0;i<depcount;i++)
 		if (depths[i]==depth)
 			break;
-	XFree(depths);
+	TSXFree(depths);
 	if (i==depcount) {/* not found */
 		sprintf(buf,"SetDisplayMode(w=%ld,h=%ld,d=%ld), unsupported depth!",width,height,depth);
 		MessageBox32A(0,buf,"WINE DirectDraw",MB_OK|MB_ICONSTOP);
@@ -796,40 +1230,27 @@
 	 * it works for the library too?
 	 */
 	XF86DGADirectVideo(display,DefaultScreen(display),XF86DGADirectGraphics);
-/* FIXME:  can't call this in winelib... so comment only in for debugging.
+#ifdef RESTORE_SIGNALS
 	SIGNAL_InitEmulator();
- */
+#endif
 	return 0;
 }
 
 static HRESULT WINAPI IDirectDraw_GetCaps(
 	LPDIRECTDRAW this,LPDDCAPS caps1,LPDDCAPS caps2
 )  {
-	fprintf(stderr,"IDirectDraw(%p)->GetCaps(%p,%p),stub!\n",this,caps1,caps2);
+	dprintf_ddraw(stderr,"IDirectDraw(%p)->GetCaps(%p,%p)\n",this,caps1,caps2);
 	caps1->dwVidMemTotal = this->d.fb_memsize;
-	caps1->dwCaps = 0; /* we cannot do anything */
-	caps1->ddsCaps.dwCaps = 0; /* we cannot do anything */
+	caps1->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
+	caps1->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
+	if (caps2) {
+		caps2->dwVidMemTotal = this->d.fb_memsize;
+		caps2->dwCaps = 0xffffffff&~(DDCAPS_BANKSWITCHED);		/* we can do anything */
+		caps2->ddsCaps.dwCaps = 0xffffffff;	/* we can do anything */
+	}
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDraw2_GetCaps(
-	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
-)  {
-	fprintf(stderr,"IDirectDraw2(%p)->GetCaps(%p,%p),stub!\n",this,caps1,caps2);
-	caps1->dwVidMemTotal = this->d.fb_memsize;
-	caps1->dwCaps = 0; /* we cannot do anything */
-	caps1->ddsCaps.dwCaps = 0;
-	return 0;
-}
-
-
-static struct IDirectDrawClipper_VTable ddclipvt = {
-	(void*)1,
-	(void*)2,(void*)3,(void*)4,(void*)5,
-	(void*)6,
-	(void*)7,(void*)8,(void*)9
-};
-
 static HRESULT WINAPI IDirectDraw_CreateClipper(
 	LPDIRECTDRAW this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
 ) {
@@ -842,91 +1263,10 @@
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDrawPalette_GetEntries(
-	LPDIRECTDRAWPALETTE this,DWORD x,DWORD y,DWORD z,LPPALETTEENTRY palent
-) {
-	fprintf(stderr,"IDirectDrawPalette(%p)->GetEntries(%08lx,%08lx,%08lx,%p),stub!\n",
-		this,x,y,z,palent
-	);
-	return 0;
-}
-
-static HRESULT WINAPI IDirectDrawPalette_SetEntries(
-	LPDIRECTDRAWPALETTE this,DWORD x,DWORD start,DWORD end,LPPALETTEENTRY palent
-) {
-	XColor		xc;
-	int		i;
-
-/*
-	fprintf(stderr,"IDirectDrawPalette(%p)->SetEntries(%08lx,%ld,%ld,%p)\n",
-		this,x,start,end,palent
-	);
- */
-	if (!this->cm) /* should not happen */ {
-		fprintf(stderr,"no colormap in SetEntries???\n");
-		return DDERR_GENERIC;
-	}
-/* FIXME: free colorcells instead of freeing whole map */
-	XFreeColormap(display,this->cm);
-	this->cm = XCreateColormap(display,DefaultRootWindow(display),DefaultVisual(display,DefaultScreen(display)),AllocAll);
-	if (start>0) {
-		xc.red = xc.blue = xc.green = 0; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 0; XStoreColor(display,this->cm,&xc);
-	}
-	if (end<256) {
-		xc.red = xc.blue = xc.green = 0xffff; xc.flags = DoRed|DoGreen|DoBlue; xc.pixel = 255; XStoreColor(display,this->cm,&xc);
-	}
-	for (i=start;i<end;i++) {
-		xc.red = palent[i-start].peRed<<8;
-		xc.blue = palent[i-start].peBlue<<8;
-		xc.green = palent[i-start].peGreen<<8;
-		xc.flags = DoRed|DoBlue|DoGreen;
-		xc.pixel = i;
-		XStoreColor(display,this->cm,&xc);
-	}
-	XF86DGAInstallColormap(display,DefaultScreen(display),this->cm);
-	return 0;
-}
-
-static ULONG WINAPI IDirectDrawPalette_Release(LPDIRECTDRAWPALETTE this) {
-	fprintf(stderr,"IDirectDrawPalette(%p)->Release()\n",this);
-	if (!--(this->ref)) {
-		fprintf(stderr,"IDirectDrawPalette(%p) freed!\n",this);
-		if (this->cm) {
-			XFreeColormap(display,this->cm);
-			this->cm = 0;
-		}
-		HeapFree(GetProcessHeap(),0,this);
-		return 0;
-	}
-	return this->ref;
-}
-
-static ULONG WINAPI IDirectDrawPalette_AddRef(LPDIRECTDRAWPALETTE this) {
-	fprintf(stderr,"IDirectDrawPalette(%p)->AddRef()\n",this);
-	return ++(this->ref);
-}
-
-static HRESULT WINAPI IDirectDrawPalette_Initialize(
-	LPDIRECTDRAWPALETTE this,LPDIRECTDRAW ddraw,DWORD x,LPPALETTEENTRY palent
-) {
-	fprintf(stderr,"IDirectDrawPalette(%p)->Initialize(%p,0x%08lx,%p)\n",this,ddraw,x,palent);
-	return DDERR_ALREADYINITIALIZED;
-}
-
-static struct IDirectDrawPalette_VTable ddpalvt = {
-	(void*)1,
-	IDirectDrawPalette_AddRef,
-	IDirectDrawPalette_Release,
-	(void*)4,
-	IDirectDrawPalette_GetEntries,
-	IDirectDrawPalette_Initialize,
-	IDirectDrawPalette_SetEntries
-};
-
 static HRESULT WINAPI IDirectDraw_CreatePalette(
 	LPDIRECTDRAW this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
 ) {
-	fprintf(stderr,"IDirectDraw(%p)->CreatePalette(%08lx,%p,%p,%p),stub!\n",
+	dprintf_ddraw(stderr,"IDirectDraw(%p)->CreatePalette(%08lx,%p,%p,%p)\n",
 		this,x,palent,lpddpal,lpunk
 	);
 	*lpddpal = (LPDIRECTDRAWPALETTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDrawPalette));
@@ -934,20 +1274,24 @@
 	(*lpddpal)->lpvtbl = &ddpalvt;
 	(*lpddpal)->ddraw = this;
 	if (this->d.depth<=8) {
-		(*lpddpal)->cm = XCreateColormap(display,DefaultRootWindow(display),DefaultVisual(display,DefaultScreen(display)),AllocAll);
-		fprintf(stderr,"created colormap...\n");
+		(*lpddpal)->cm = TSXCreateColormap(display,DefaultRootWindow(display),DefaultVisualOfScreen(screen),AllocAll);
 	} else /* we don't want palettes in hicolor or truecolor */
 		(*lpddpal)->cm = 0;
 
 	return 0;
 }
 
-static HRESULT WINAPI IDirectDraw2_CreatePalette(
-	LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
-) {
-	return IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk);
+static HRESULT WINAPI IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) {
+	dprintf_ddraw(stderr,"IDirectDraw(%p)->RestoreDisplayMode(),stub!\n",this);
+	Sleep(1000);
+	XF86DGADirectVideo(display,DefaultScreen(display),0);
+#ifdef RESTORE_SIGNALS
+	SIGNAL_InitEmulator();
+#endif
+	return 0;
 }
 
+
 static HRESULT WINAPI IDirectDraw_WaitForVerticalBlank(
 	LPDIRECTDRAW this,DWORD x,HANDLE32 h
 ) {
@@ -956,118 +1300,67 @@
 }
 
 static ULONG WINAPI IDirectDraw_AddRef(LPDIRECTDRAW this) {
-	dprintf_relay(stderr,"IDirectDraw(%p)->AddRef()\n",this);
 	return ++(this->ref);
 }
 
 static ULONG WINAPI IDirectDraw_Release(LPDIRECTDRAW this) {
-	dprintf_relay(stderr,"IDirectDraw(%p)->Release()\n",this);
 	if (!--(this->ref)) {
-		fprintf(stderr,"IDirectDraw::Release:freeing IDirectDraw(%p)\n",this);
 		XF86DGADirectVideo(display,DefaultScreen(display),0);
+#ifdef RESTORE_SIGNALS
+		SIGNAL_InitEmulator();
+#endif
 		HeapFree(GetProcessHeap(),0,this);
 		return 0;
 	}
 	return this->ref;
 }
 
-static HRESULT WINAPI IDirectDraw2_QueryInterface(
-	LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
-) {
-	return IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj);
-}
-
-static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
-	return IDirectDraw_AddRef((LPDIRECTDRAW)this);
-}
-
-static ULONG WINAPI IDirectDraw2_Release(LPDIRECTDRAW2 this) {
-	return IDirectDraw_Release((LPDIRECTDRAW)this);
-}
-
-static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
-	LPDIRECTDRAW2 this,HWND32 hwnd,DWORD x
-) {
-	fprintf(stderr,"IDirectDraw2(%p)->SetCooperativeLevel(%08lx,%08lx),stub!\n",
-		this,(DWORD)hwnd,x
-	);
-	this->d.mainwindow = hwnd;
-	return 0;
-}
-
-static HRESULT WINAPI IDirectDraw2_SetDisplayMode(
-	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
-) {
-	fprintf(stderr,"IDirectDraw2(%p)->SetDisplayMode(%ld,%ld,%ld,%08lx,%08lx),stub!\n",this,width,height,depth,xx,yy);
-
-	return IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
-}
-
-static HRESULT WINAPI IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
-	fprintf(stderr,"IDirectDraw2(%p)->RestoreDisplayMode(),stub!\n",this);
-	XF86DGADirectVideo(display,DefaultScreen(display),0);
-	return 0;
-}
-
-static HRESULT WINAPI IDirectDraw_RestoreDisplayMode(LPDIRECTDRAW this) {
-	fprintf(stderr,"IDirectDraw(%p)->RestoreDisplayMode(),stub!\n",this);
-	XF86DGADirectVideo(display,DefaultScreen(display),0);
-	return 0;
-}
-
-static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
-	LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
-) {
-	fprintf(stderr,"IDirectDraw2(%p)->EnumSurfaces(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
-	return 0;
-}
-
-static IDirectDraw2_VTable dd2vt = {
-	IDirectDraw2_QueryInterface,
-	IDirectDraw2_AddRef,
-	IDirectDraw2_Release,
-	(void*)4,
-	(void*)5/*IDirectDraw_CreateClipper*/,
-	IDirectDraw2_CreatePalette,
-	IDirectDraw2_CreateSurface,
-	(void*)8,
-	(void*)9,
-	IDirectDraw2_EnumSurfaces,
-	(void*)11,
-	IDirectDraw2_GetCaps,
-	(void*)13,
-	(void*)14,
-	(void*)15,
-	(void*)16,
-	(void*)17,
-	(void*)18,
-	(void*)19,
-	IDirectDraw2_RestoreDisplayMode,
-	IDirectDraw2_SetCooperativeLevel,
-	IDirectDraw2_SetDisplayMode,
-	(void*)23/*IDirectDraw_WaitForVerticalBlank*/,
-	(void*)24
-};
-
 static HRESULT WINAPI IDirectDraw_QueryInterface(
 	LPDIRECTDRAW this,REFIID refiid,LPVOID *obj
 ) {
         char    xrefiid[50];
 
         StringFromCLSID((LPCLSID)refiid,xrefiid);
-        fprintf(stderr,"IDirectDraw(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
+        dprintf_ddraw(stderr,"IDirectDraw(%p)->QueryInterface(%s,%p)\n",this,xrefiid,obj);
+        if (!memcmp(&IID_IUnknown,refiid,sizeof(IID_IUnknown))) {
+                *obj = this;
+		this->lpvtbl->fnAddRef(this);
+                return 0;
+        }
         if (!memcmp(&IID_IDirectDraw,refiid,sizeof(IID_IDirectDraw))) {
                 *obj = this;
 		this->lpvtbl->fnAddRef(this);
                 return 0;
         }
         if (!memcmp(&IID_IDirectDraw2,refiid,sizeof(IID_IDirectDraw2))) {
-		/* FIXME FIXME FIXME */
 		this->lpvtbl = (LPDIRECTDRAW_VTABLE)&dd2vt;
 		this->lpvtbl->fnAddRef(this);
                 *obj = this;
                 return 0;
         }
+	if (!memcmp(&IID_IDirect3D,refiid,sizeof(IID_IDirect3D))) {
+		LPDIRECT3D	d3d;
+
+		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
+		d3d->ref = 1;
+		d3d->ddraw = this;
+		this->lpvtbl->fnAddRef(this);
+		d3d->lpvtbl = &d3dvt;
+		*obj = d3d;
+		return 0;
+	}
+	if (!memcmp(&IID_IDirect3D2,refiid,sizeof(IID_IDirect3D))) {
+		LPDIRECT3D2	d3d;
+
+		d3d = HeapAlloc(GetProcessHeap(),0,sizeof(*d3d));
+		d3d->ref = 1;
+		d3d->ddraw = this;
+		this->lpvtbl->fnAddRef(this);
+		d3d->lpvtbl = &d3d2vt;
+		*obj = d3d;
+		return 0;
+	}
+	fprintf(stderr,"IDirectDraw(%p):interface for IID %s _NOT_ found!\n",this,xrefiid);
         return OLE_E_ENUM_NOMORE;
 }
 
@@ -1084,26 +1377,42 @@
 ) {
 	DDSURFACEDESC	ddsfd;
 
-	fprintf(stderr,"IDirectDraw(%p)->EnumDisplayModes(0x%08lx,%p,%p,%p),stub!\n",this,dwFlags,lpddsfd,context,modescb);
-	ddsfd.dwSize = sizeof(ddsfd);
-	fprintf(stderr,"size is %d\n",sizeof(ddsfd));
-	ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
-	ddsfd.dwHeight = 480;
-	ddsfd.dwWidth = 640;
-	ddsfd.lPitch = 640;
-	ddsfd.dwBackBufferCount = 1;
-	ddsfd.x.dwRefreshRate = 60;
-	ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
-	this->d.depth = 8;
+	dprintf_ddraw(stderr,"IDirectDraw(%p)->EnumDisplayModes(0x%08lx,%p,%p,%p)\n",this,dwFlags,lpddsfd,context,modescb);
+
+
 	_getpixelformat(this,&(ddsfd.ddpfPixelFormat));
-	fprintf(stderr,"modescb returned: 0x%lx\n",(DWORD)modescb(&ddsfd,context));
+	ddsfd.dwSize = sizeof(ddsfd);
+	ddsfd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
+	if (dwFlags & DDEDM_REFRESHRATES) {
+		ddsfd.dwFlags |= DDSD_REFRESHRATE;
+		ddsfd.x.dwRefreshRate = 60;
+	}
+
+	ddsfd.dwWidth = 640;
+	ddsfd.dwHeight = 480;
+	ddsfd.dwBackBufferCount = 1;
+	ddsfd.ddsCaps.dwCaps = DDSCAPS_PALETTE;
+
+	if (!modescb(&ddsfd,context)) return 0;
+
+	ddsfd.dwWidth = 800;
+	ddsfd.dwHeight = 600;
+	if (!modescb(&ddsfd,context)) return 0;
+
+	if (!(dwFlags & DDEDM_STANDARDVGAMODES)) {
+		/* modeX is not standard VGA */
+
+		ddsfd.dwHeight = 200;
+		ddsfd.dwWidth = 320;
+		if (!modescb(&ddsfd,context)) return 0;
+	}
 	return DD_OK;
 }
 
 static HRESULT WINAPI IDirectDraw_GetDisplayMode(
 	LPDIRECTDRAW this,LPDDSURFACEDESC lpddsfd
 ) {
-	fprintf(stderr,"IDirectDraw(%p)->GetDisplayMode(%p),stub!\n",this,lpddsfd);
+	dprintf_ddraw(stderr,"IDirectDraw(%p)->GetDisplayMode(%p)\n",this,lpddsfd);
 	lpddsfd->dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PITCH|DDSD_BACKBUFFERCOUNT|DDSD_PIXELFORMAT|DDSD_CAPS;
 	lpddsfd->dwHeight = this->d.vp_height;
 	lpddsfd->dwWidth = this->d.vp_width;
@@ -1115,6 +1424,11 @@
 	return DD_OK;
 }
 
+static HRESULT WINAPI IDirectDraw_FlipToGDISurface(LPDIRECTDRAW this) {
+	fprintf(stderr,"IDirectDraw(%p)->FlipToGDISurface(),stub!\n",this);
+	return DD_OK;
+}
+
 
 static IDirectDraw_VTable ddvt = {
 	IDirectDraw_QueryInterface,
@@ -1127,7 +1441,7 @@
 	IDirectDraw_DuplicateSurface,
 	IDirectDraw_EnumDisplayModes,
 	(void*)10,
-	(void*)11,
+	IDirectDraw_FlipToGDISurface,
 	IDirectDraw_GetCaps,
 	IDirectDraw_GetDisplayMode,
 	(void*)14,
@@ -1142,22 +1456,151 @@
 	IDirectDraw_WaitForVerticalBlank,
 };
 
+/*****************************************************************************
+ * 	IDirectDraw2
+ *
+ */
+static HRESULT WINAPI IDirectDraw2_CreateClipper(
+	LPDIRECTDRAW2 this,DWORD x,LPDIRECTDRAWCLIPPER *lpddclip,LPUNKNOWN lpunk
+) {
+	return IDirectDraw_CreateClipper((LPDIRECTDRAW)this,x,lpddclip,lpunk);
+}
+
+static HRESULT WINAPI IDirectDraw2_CreateSurface(
+	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsd,LPDIRECTDRAWSURFACE *lpdsf,IUnknown *lpunk
+) {
+	return IDirectDraw_CreateSurface((LPDIRECTDRAW)this,lpddsd,(LPDIRECTDRAWSURFACE*)lpdsf,lpunk);
+}
+
+static HRESULT WINAPI IDirectDraw2_QueryInterface(
+	LPDIRECTDRAW2 this,REFIID refiid,LPVOID *obj
+) {
+	return IDirectDraw_QueryInterface((LPDIRECTDRAW)this,refiid,obj);
+}
+
+static ULONG WINAPI IDirectDraw2_AddRef(LPDIRECTDRAW2 this) {
+	return IDirectDraw_AddRef((LPDIRECTDRAW)this);
+}
+
+static ULONG WINAPI IDirectDraw2_Release(LPDIRECTDRAW2 this) {
+	return IDirectDraw_Release((LPDIRECTDRAW)this);
+}
+
+static HRESULT WINAPI IDirectDraw2_GetCaps(
+	LPDIRECTDRAW2 this,LPDDCAPS caps1,LPDDCAPS caps2
+)  {
+	return IDirectDraw_GetCaps((LPDIRECTDRAW)this,caps1,caps2);
+}
+
+static HRESULT WINAPI IDirectDraw2_SetCooperativeLevel(
+	LPDIRECTDRAW2 this,HWND32 hwnd,DWORD x
+) {
+	return IDirectDraw_SetCooperativeLevel((LPDIRECTDRAW)this,hwnd,x);
+}
+
+static HRESULT WINAPI IDirectDraw2_CreatePalette(
+	LPDIRECTDRAW2 this,DWORD x,LPPALETTEENTRY palent,LPDIRECTDRAWPALETTE *lpddpal,LPUNKNOWN lpunk
+) {
+	return IDirectDraw_CreatePalette((LPDIRECTDRAW)this,x,palent,lpddpal,lpunk);
+}
+
+
+static HRESULT WINAPI IDirectDraw2_SetDisplayMode(
+	LPDIRECTDRAW2 this,DWORD width,DWORD height,DWORD depth,DWORD xx,DWORD yy
+) {
+	dprintf_ddraw(stderr,"IDirectDraw2(%p)->SetDisplayMode(%ld,%ld,%ld,%08lx,%08lx),stub!\n",this,width,height,depth,xx,yy);
+
+	return IDirectDraw_SetDisplayMode((LPDIRECTDRAW)this,width,height,depth);
+}
+
+static HRESULT WINAPI IDirectDraw2_RestoreDisplayMode(LPDIRECTDRAW2 this) {
+	return IDirectDraw_RestoreDisplayMode((LPDIRECTDRAW)this);
+}
+
+static HRESULT WINAPI IDirectDraw2_EnumSurfaces(
+	LPDIRECTDRAW2 this,DWORD x,LPDDSURFACEDESC ddsfd,LPVOID context,LPDDENUMSURFACESCALLBACK ddsfcb
+) {
+	fprintf(stderr,"IDirectDraw2(%p)->EnumSurfaces(0x%08lx,%p,%p,%p),stub!\n",this,x,ddsfd,context,ddsfcb);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectDraw2_EnumDisplayModes(
+	LPDIRECTDRAW2 this,DWORD dwFlags,LPDDSURFACEDESC lpddsfd,LPVOID context,LPDDENUMMODESCALLBACK modescb
+) {
+	return IDirectDraw_EnumDisplayModes((LPDIRECTDRAW)this,dwFlags,lpddsfd,context,modescb);
+}
+
+static HRESULT WINAPI IDirectDraw2_GetDisplayMode(
+	LPDIRECTDRAW2 this,LPDDSURFACEDESC lpddsfd
+) {
+	return IDirectDraw_GetDisplayMode((LPDIRECTDRAW)this,lpddsfd);
+}
+
+static HRESULT WINAPI IDirectDraw2_GetAvailableVidMem(
+	LPDIRECTDRAW2 this,LPDDSCAPS ddscaps,LPDWORD total,LPDWORD free
+) {
+	fprintf(stderr,"IDirectDraw2(%p)->GetAvailableVidMem(%p,%p,%p),stub!\n",
+		this,ddscaps,total,free
+	);
+	if (total) *total = this->d.fb_memsize * 1024;
+	if (free) *free = this->d.fb_memsize * 1024;
+	return 0;
+}
+
+static HRESULT WINAPI IDirectDraw2_GetMonitorFrequency(
+	LPDIRECTDRAW2 this,LPDWORD freq
+) {
+	fprintf(stderr,"IDirectDraw2(%p)->GetMonitorFrequency(%p)\n",this,freq);
+	*freq = 60;
+	return 0;
+}
+
+static IDirectDraw2_VTable dd2vt = {
+	IDirectDraw2_QueryInterface,
+	IDirectDraw2_AddRef,
+	IDirectDraw2_Release,
+	(void*)4,
+	IDirectDraw2_CreateClipper,
+	IDirectDraw2_CreatePalette,
+	IDirectDraw2_CreateSurface,
+	(void*)8,
+	IDirectDraw2_EnumDisplayModes,
+	IDirectDraw2_EnumSurfaces,
+	(void*)11,
+	IDirectDraw2_GetCaps,
+	IDirectDraw2_GetDisplayMode,
+	(void*)14,
+	(void*)15,
+	IDirectDraw2_GetMonitorFrequency,
+	(void*)17,
+	(void*)18,
+	(void*)19,
+	IDirectDraw2_RestoreDisplayMode,
+	IDirectDraw2_SetCooperativeLevel,
+	IDirectDraw2_SetDisplayMode,
+	(void*)23/*IDirectDraw_WaitForVerticalBlank*/,
+	IDirectDraw2_GetAvailableVidMem
+	
+};
+
+/******************************************************************************
+ * 				DirectDrawCreate
+ */
 
 HRESULT WINAPI DirectDrawCreate( LPGUID lpGUID, LPDIRECTDRAW *lplpDD, LPUNKNOWN pUnkOuter ) {
 
 	char	xclsid[50];
 	int	memsize,banksize,width,evbase,evret,major,minor,flags,height;
 	char	*addr;
-	
 
 	if (lpGUID)
 		StringFromCLSID(lpGUID,xclsid);
 	else
 		strcpy(xclsid,"<null>");
 
-	fprintf(stderr,"DirectDrawCreate(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
+	dprintf_ddraw(stderr,"DirectDrawCreate(%s,%p,%p)\n",xclsid,lplpDD,pUnkOuter);
 	if (getuid()) {
-		MessageBox32A(0,"Using the XF86DGA extensions requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
+		MessageBox32A(0,"Using the XF86DGA extension requires the program to be run using UID 0.","WINE DirectDraw",MB_OK|MB_ICONSTOP);
 		return E_UNEXPECTED;
 	}
 	*lplpDD = (LPDIRECTDRAW)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectDraw));
@@ -1168,12 +1611,12 @@
 		return 0;
 	}
 	XF86DGAQueryVersion(display,&major,&minor);
-	fprintf(stderr,"XF86DGA is version %d.%d\n",major,minor);
+	dprintf_ddraw(stderr,"XF86DGA is version %d.%d\n",major,minor);
 	XF86DGAQueryDirectVideo(display,DefaultScreen(display),&flags);
 	if (!(flags & XF86DGADirectPresent))
 		fprintf(stderr,"direct video is NOT ENABLED.\n");
 	XF86DGAGetVideo(display,DefaultScreen(display),&addr,&width,&banksize,&memsize);
-	fprintf(stderr,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
+	dprintf_ddraw(stderr,"video framebuffer: begin %p, width %d,banksize %d,memsize %d\n",
 		addr,width,banksize,memsize
 	);
 	(*lplpDD)->d.fb_width = width;
@@ -1187,6 +1630,12 @@
 	(*lplpDD)->d.vp_height = height;
 	(*lplpDD)->d.fb_height = height;
 	(*lplpDD)->d.vpmask = 0;
+
+	/* just assume the default depth is the DGA depth too */
+	(*lplpDD)->d.depth = DefaultDepthOfScreen(screen);
+#ifdef RESTORE_SIGNALS
+	SIGNAL_InitEmulator();
+#endif
 	return 0;
 }
 #else
diff --git a/graphics/mapping.c b/graphics/mapping.c
index 576eb34..0ced954 100644
--- a/graphics/mapping.c
+++ b/graphics/mapping.c
@@ -57,13 +57,35 @@
  */
 BOOL32 WINAPI DPtoLP32( HDC32 hdc, LPPOINT32 points, INT32 count )
 {
+    FLOAT determinant=1.0, x, y;
+    
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return FALSE;
 
+    if (dc->w.UseWorldXform)
+    {
+        determinant = dc->w.WorldXform.eM11*dc->w.WorldXform.eM22 -
+            dc->w.WorldXform.eM12*dc->w.WorldXform.eM21;
+        if (determinant > -1e-12 && determinant < 1e-12)
+            return FALSE;
+    }
+
     while (count--)
     {
-	points->x = XDPTOLP( dc, points->x );
-	points->y = YDPTOLP( dc, points->y );
+	if (dc->w.UseWorldXform)
+	{
+            x = (FLOAT)points->x - dc->w.WorldXform.eDx;
+	    y = (FLOAT)points->y - dc->w.WorldXform.eDy;
+	    points->x = (INT32)( (x*dc->w.WorldXform.eM22 -
+	       y*dc->w.WorldXform.eM21) / determinant );
+	    points->y = (INT32)( (-x*dc->w.WorldXform.eM12 +
+	       y*dc->w.WorldXform.eM11) / determinant );
+	}
+	else
+	{
+	    points->x = XLPTODP( dc, points->x );
+	    points->y = YLPTODP( dc, points->y );
+	}
         points++;
     }
     return TRUE;
@@ -93,13 +115,30 @@
  */
 BOOL32 WINAPI LPtoDP32( HDC32 hdc, LPPOINT32 points, INT32 count )
 {
+    FLOAT x, y;
+
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return FALSE;
 
     while (count--)
     {
-	points->x = XLPTODP( dc, points->x );
-	points->y = YLPTODP( dc, points->y );
+	if (dc->w.UseWorldXform)
+	{
+	    x = (FLOAT)points->x * dc->w.WorldXform.eM11 +
+	    	(FLOAT)points->y * dc->w.WorldXform.eM21 +
+		dc->w.WorldXform.eDx;
+	    y = (FLOAT)points->x * dc->w.WorldXform.eM12 +
+	        (FLOAT)points->y * dc->w.WorldXform.eM22 +
+		dc->w.WorldXform.eDy;
+	    points->x = XDPTOLP( dc, (INT32)x );
+	    points->y = YDPTOLP( dc, (INT32)y );
+	    
+	}
+	else
+	{
+	    points->x = XDPTOLP( dc, points->x );
+	    points->y = YDPTOLP( dc, points->y );
+	}
         points++;
     }
     return TRUE;
diff --git a/graphics/metafiledrv/init.c b/graphics/metafiledrv/init.c
index c55832a..58587f0 100644
--- a/graphics/metafiledrv/init.c
+++ b/graphics/metafiledrv/init.c
@@ -135,9 +135,17 @@
 
 
 /**********************************************************************
- *	     CreateMetafile16   (GDI.125)
+ *	     CreateMetaFile16   (GDI.125)
+ *
+ *  Create a new DC and associate it with a metafile. Pass a filename
+ *  to create a disk-based metafile, NULL to create a memory metafile.
+ *
+ * RETURNS
+ *  A handle to the metafile DC if successful, NULL on failure.
  */
-HDC16 WINAPI CreateMetaFile16( LPCSTR filename )
+HDC16 WINAPI CreateMetaFile16( 
+			      LPCSTR filename /* Filename of disk metafile */
+)
 {
     DC *dc;
     METAFILEDRV_PDEVICE *physDev;
@@ -174,9 +182,17 @@
 
 
 /******************************************************************
- *	     CloseMetafile16   (GDI.126)
+ *	     CloseMetaFile16   (GDI.126)
+ *
+ *  Stop recording graphics operations in metafile associated with
+ *  hdc and retrieve metafile.
+ *
+ * RETURNS
+ *  Handle of newly created metafile on success, NULL on failure.
  */
-HMETAFILE16 WINAPI CloseMetaFile16( HDC16 hdc )
+HMETAFILE16 WINAPI CloseMetaFile16( 
+				   HDC16 hdc /* Metafile DC to close */
+)
 {
     DC *dc;
     HMETAFILE16 hmf;
@@ -228,9 +244,16 @@
 
 
 /******************************************************************
- *	     DeleteMetafile16   (GDI.127)
+ *	     DeleteMetaFile16   (GDI.127)
+ *
+ *  Delete a memory-based metafile.
+ *
  */
-BOOL16 WINAPI DeleteMetaFile16( HMETAFILE16 hmf )
+BOOL16 WINAPI DeleteMetaFile16( 
+			       HMETAFILE16 hmf 
+			       /* Handle of memory metafile to delete */
+)
 {
     return !GlobalFree16( hmf );
 }
+
diff --git a/graphics/painting.c b/graphics/painting.c
index cec3d9c..6756c43 100644
--- a/graphics/painting.c
+++ b/graphics/painting.c
@@ -7,8 +7,8 @@
 
 #include <math.h>
 #include <stdlib.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xutil.h"
 #include <X11/Intrinsic.h>
 #ifndef PI
 #define PI M_PI
@@ -117,6 +117,11 @@
 {
     DC * dc = DC_GetDCPtr( hdc );
   
+    if(dc && PATH_IsPathOpen(dc->w.path))
+        if(!PATH_Arc(hdc, left, top, right, bottom, xstart, ystart, xend,
+	   yend))
+	   return FALSE;
+    
     return dc && dc->funcs->pArc &&
     	   dc->funcs->pArc(dc,left,top,right,bottom,xstart,ystart,xend,yend);
 }
@@ -533,7 +538,7 @@
     dc->u.x.pen.pixel = (1 << screenDepth) - 1;
 
     if (DC_SetupGCForPen( dc ))
-	XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+	TSXDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
 		        dc->w.DCOrgX + left, dc->w.DCOrgY + top,
 		        right-left-1, bottom-top-1 );
 
diff --git a/graphics/path.c b/graphics/path.c
index e4e4013..d53acd9 100644
--- a/graphics/path.c
+++ b/graphics/path.c
@@ -1,11 +1,12 @@
 /*
  * Graphics paths (BeginPath, EndPath etc.)
  *
- * Copyright 1997 Martin Boehme
+ * Copyright 1997, 1998 Martin Boehme
  */
 
 #include <assert.h>
 #include <malloc.h>
+#include <math.h>
 
 #include "windows.h"
 #include "winerror.h"
@@ -64,6 +65,22 @@
 static BOOL32 PATH_AddEntry(GdiPath *pPath, POINT32 point, BYTE flags);
 static BOOL32 PATH_ReserveEntries(GdiPath *pPath, INT32 numEntries);
 static BOOL32 PATH_GetPathFromHDC(HDC32 hdc, GdiPath **ppPath);
+static BOOL32 PATH_DoArcPart(GdiPath *pPath, POINT32 corners[],
+   double angleStart, double angleEnd, BOOL32 addMoveTo);
+static void PATH_ScaleNormalizedPoint(POINT32 corners[], double x, double y,
+   POINT32 *pPoint);
+static void PATH_NormalizePoint(POINT32 corners[], const POINT32 *pPoint,
+   double *pX, double *pY);
+
+
+/***********************************************************************
+ *           BeginPath16    (GDI.512)
+ */
+BOOL16 WINAPI BeginPath16(HDC16 hdc)
+{
+   return (BOOL16)BeginPath32((HDC32)hdc);
+}
+
 
 /***********************************************************************
  *           BeginPath32    (GDI32.9)
@@ -95,6 +112,15 @@
 
 
 /***********************************************************************
+ *           EndPath16    (GDI.514)
+ */
+BOOL16 WINAPI EndPath16(HDC16 hdc)
+{
+   return (BOOL16)EndPath32((HDC32)hdc);
+}
+
+
+/***********************************************************************
  *           EndPath32    (GDI32.78)
  */
 BOOL32 WINAPI EndPath32(HDC32 hdc)
@@ -123,6 +149,15 @@
 
 
 /***********************************************************************
+ *           AbortPath16    (GDI.511)
+ */
+BOOL16 WINAPI AbortPath16(HDC16 hdc)
+{
+   return (BOOL16)AbortPath32((HDC32)hdc);
+}
+
+
+/***********************************************************************
  *           AbortPath32    (GDI32.1)
  */
 BOOL32 WINAPI AbortPath32(HDC32 hdc)
@@ -145,6 +180,15 @@
 
 
 /***********************************************************************
+ *           CloseFigure16    (GDI.513)
+ */
+BOOL16 WINAPI CloseFigure16(HDC16 hdc)
+{
+   return (BOOL16)CloseFigure32((HDC32)hdc);
+}
+
+
+/***********************************************************************
  *           CloseFigure32    (GDI32.16)
  */
 BOOL32 WINAPI CloseFigure32(HDC32 hdc)
@@ -178,13 +222,25 @@
 
 
 /***********************************************************************
+ *           GetPath16    (GDI.517)
+ */
+INT16 WINAPI GetPath16(HDC16 hdc, LPPOINT16 pPoints, LPBYTE pTypes,
+   INT16 nSize)
+{
+   /* FIXME: Not implemented */
+   fprintf(stdnimp, "GetPath16: Unimplemented stub\n");
+
+   return 0;
+}
+
+
+/***********************************************************************
  *           GetPath32    (GDI32.210)
  */
 INT32 WINAPI GetPath32(HDC32 hdc, LPPOINT32 pPoints, LPBYTE pTypes,
    INT32 nSize)
 {
    GdiPath *pPath;
-   BOOL32  temp_flag;
    
    /* Get pointer to path */
    if(!PATH_GetPathFromHDC(hdc, &pPath))
@@ -213,10 +269,12 @@
       memcpy(pTypes, pPath->pFlags, sizeof(BYTE)*pPath->numEntriesUsed);
 
       /* Convert the points to logical coordinates */
-      temp_flag=DPtoLP32(hdc, pPoints, pPath->numEntriesUsed);
-
-      /* Since hdc is valid, conversion should never fail */
-      assert(temp_flag);
+      if(!DPtoLP32(hdc, pPoints, pPath->numEntriesUsed))
+      {
+	 /* FIXME: Is this the correct value? */
+         SetLastError(ERROR_CAN_NOT_COMPLETE);
+         return -1;
+      }
       
       return pPath->numEntriesUsed;
    }
@@ -266,8 +324,9 @@
 /* FIXME: Check that SetLastError is being called correctly */
 {
    GdiPath *pPath;
-   INT32   mapMode;
+   INT32   mapMode, graphicsMode;
    POINT32 ptViewportExt, ptViewportOrg, ptWindowExt, ptWindowOrg;
+   XFORM   xform;
    HRGN32  hrgn;
    
    /* Get pointer to path */
@@ -290,6 +349,9 @@
       /* Since PaintRgn interprets the region as being in logical coordinates
        * but the points we store for the path are already in device
        * coordinates, we have to set the mapping mode to MM_TEXT temporarily.
+       * Using SaveDC to save information about the mapping mode / world
+       * transform would be easier but would require more overhead, especially
+       * now that SaveDC saves the current path.
        */
        
       /* Save the information about the old mapping mode */
@@ -299,13 +361,14 @@
       GetWindowExtEx32(hdc, &ptWindowExt);
       GetWindowOrgEx32(hdc, &ptWindowOrg);
       
-      /* FIXME: Once world transforms become available, we will have to do
-       * a GetWorldTransform, too (along with a SetWorldTransform later on).
-       * Moral: Perhaps I should have used SaveDC right away. The reason why
-       * I didn't is that I wanted to avoid the overhead of a full SaveDC
-       * (especially since SaveDC now saves the current path as well).
+      /* Save world transform
+       * NB: The Windows documentation on world transforms would lead one to
+       * believe that this has to be done only in GM_ADVANCED; however, my
+       * tests show that resetting the graphics mode to GM_COMPATIBLE does
+       * not reset the world transform.
        */
-
+      GetWorldTransform(hdc, &xform);
+      
       /* Set MM_TEXT */
       SetMapMode32(hdc, MM_TEXT);
       
@@ -319,6 +382,12 @@
       SetWindowExtEx32(hdc, ptWindowExt.x, ptWindowExt.y, NULL);
       SetWindowOrgEx32(hdc, ptWindowOrg.x, ptWindowOrg.y, NULL);
 
+      /* Go to GM_ADVANCED temporarily to restore the world transform */
+      graphicsMode=GetGraphicsMode(hdc);
+      SetGraphicsMode(hdc, GM_ADVANCED);
+      SetWorldTransform(hdc, &xform);
+      SetGraphicsMode(hdc, graphicsMode);
+
       /* Empty the path */
       PATH_EmptyPath(pPath);
       return TRUE;
@@ -335,12 +404,12 @@
 /***********************************************************************
  *           SelectClipPath32    (GDI32.296)
  */
-BOOL32 WINAPI SelectClipPath32(HDC32 hdc, int iMode)
+BOOL32 WINAPI SelectClipPath32(HDC32 hdc, INT32 iMode)
 /* FIXME: Check that SetLastError is being called correctly */
 {
    GdiPath *pPath;
    HRGN32  hrgnPath, hrgnClip;
-   BOOL32  success = FALSE;
+   BOOL32  success;
    
    /* Get pointer to path */
    if(!PATH_GetPathFromHDC(hdc, &pPath))
@@ -360,7 +429,9 @@
    if(PATH_PathToRegion(pPath, GetPolyFillMode32(hdc), &hrgnPath))
    {
       hrgnClip=CreateRectRgn32(0, 0, 0, 0);
-      if(hrgnClip!=NULL)
+      if(hrgnClip==NULL)
+         success=FALSE;
+      else
       {
          success=(GetClipRgn32(hdc, hrgnClip)!=-1) &&
 	    (CombineRgn32(hrgnClip, hrgnClip, hrgnPath, iMode)!=ERROR) &&
@@ -510,6 +581,152 @@
    return PATH_AddEntry(pPath, point, PT_LINETO);
 }
 
+/* PATH_Ellipse
+ * 
+ * Should be called when a call to Ellipse is performed on a DC that has
+ * an open path. This adds four Bezier splines representing the ellipse
+ * to the path. Returns TRUE if successful, else FALSE.
+ */
+BOOL32 PATH_Ellipse(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2)
+{
+   return PATH_Arc(hdc, x1, y1, x2, y2, x1, 0, x1, 0);
+}
+
+/* PATH_Arc
+ *
+ * Should be called when a call to Arc is performed on a DC that has
+ * an open path. This adds up to five Bezier splines representing the arc
+ * to the path. Returns TRUE if successful, else FALSE.
+ */
+BOOL32 PATH_Arc(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2,
+   INT32 xStart, INT32 yStart, INT32 xEnd, INT32 yEnd)
+{
+   GdiPath *pPath;
+   double  angleStart, angleEnd, angleStartQuadrant, angleEndQuadrant=0.0;
+           /* Initialize angleEndQuadrant to silence gcc's warning */
+   double  x, y;
+   POINT32 corners[2], pointStart, pointEnd;
+   BOOL32  start, end;
+   INT32   temp;
+
+   /* FIXME: This function should check for all possible error returns */
+   
+   /* Get pointer to path */
+   if(!PATH_GetPathFromHDC(hdc, &pPath))
+      return FALSE;
+   
+   /* Check that path is open */
+   if(pPath->state!=PATH_Open)
+      return FALSE;
+
+   /* Check for zero height / width */
+   /* FIXME: Should we do this before or after LPtoDP? */
+   if(x1==x2 || y1==y2)
+      return TRUE;
+   
+   /* In GM_COMPATIBLE, don't include bottom and right edges */
+   if(GetGraphicsMode(hdc)==GM_COMPATIBLE)
+   {
+      /* FIXME: Should we do this before or after LPtoDP? */
+      x2--;
+      y2--;
+   }
+
+   /* Convert points to device coordinates */
+   corners[0].x=x1;
+   corners[0].y=y1;
+   corners[1].x=x2;
+   corners[1].y=y2;
+   pointStart.x=xStart;
+   pointStart.y=yStart;
+   pointEnd.x=xEnd;
+   pointEnd.y=yEnd;
+   if(!LPtoDP32(hdc, corners, 2) || !LPtoDP32(hdc, &pointStart, 1) ||
+      !LPtoDP32(hdc, &pointEnd, 1))
+      return FALSE;
+
+   /* Make sure first corner is top left and right corner is bottom right */
+   /* FIXME: Should we do this before or after LPtoDP? */
+   if(corners[0].x>corners[1].x)
+   {
+      temp=corners[0].x;
+      corners[0].x=corners[1].x;
+      corners[1].x=temp;
+   }
+   if(corners[0].y>corners[1].y)
+   {
+      temp=corners[0].y;
+      corners[0].y=corners[1].y;
+      corners[1].y=temp;
+   }
+
+   /* Compute start and end angle */
+   PATH_NormalizePoint(corners, &pointStart, &x, &y);
+   angleStart=atan2(y, x);
+   PATH_NormalizePoint(corners, &pointEnd, &x, &y);
+   angleEnd=atan2(y, x);
+
+   /* Make sure the end angle is "on the right side" of the start angle */
+   if(GetArcDirection32(hdc)==AD_CLOCKWISE)
+   {
+      if(angleEnd<=angleStart)
+      {
+         angleEnd+=2*M_PI;
+	 assert(angleEnd>=angleStart);
+      }
+   }
+   else
+   {
+      if(angleEnd>=angleStart)
+      {
+         angleEnd-=2*M_PI;
+	 assert(angleEnd<=angleStart);
+      }
+   }
+
+   /* Add the arc to the path with one Bezier spline per quadrant that the
+    * arc spans */
+   start=TRUE;
+   end=FALSE;
+   do
+   {
+      /* Determine the start and end angles for this quadrant */
+      if(start)
+      {
+         angleStartQuadrant=angleStart;
+	 if(GetArcDirection32(hdc)==AD_CLOCKWISE)
+	    angleEndQuadrant=(floor(angleStart/M_PI_2)+1.0)*M_PI_2;
+	 else
+	    angleEndQuadrant=(ceil(angleStart/M_PI_2)-1.0)*M_PI_2;
+      }
+      else
+      {
+	 angleStartQuadrant=angleEndQuadrant;
+	 if(GetArcDirection32(hdc)==AD_CLOCKWISE)
+	    angleEndQuadrant+=M_PI_2;
+	 else
+	    angleEndQuadrant-=M_PI_2;
+      }
+
+      /* Have we reached the last part of the arc? */
+      if((GetArcDirection32(hdc)==AD_CLOCKWISE &&
+         angleEnd<=angleEndQuadrant) ||
+	 (GetArcDirection32(hdc)==AD_COUNTERCLOCKWISE &&
+	 angleEnd>=angleEndQuadrant))
+      {
+	 /* Adjust the end angle for this quadrant */
+         angleEndQuadrant=angleEnd;
+	 end=TRUE;
+      }
+
+      /* Add the Bezier spline to the path */
+      PATH_DoArcPart(pPath, corners, angleStartQuadrant, angleEndQuadrant,
+         start);
+      start=FALSE;
+   }  while(!end);
+
+   return TRUE;
+}
 
 /***********************************************************************
  * Internal functions
@@ -702,3 +919,85 @@
    else
       return FALSE;
 }
+
+/* PATH_DoArcPart
+ *
+ * Creates a Bezier spline that corresponds to part of an arc and appends the
+ * corresponding points to the path. The start and end angles are passed in
+ * "angleStart" and "angleEnd"; these angles should span a quarter circle
+ * at most. If "addMoveTo" is true, a PT_MOVETO entry for the first control
+ * point is added to the path; otherwise, it is assumed that the current
+ * position is equal to the first control point.
+ */
+static BOOL32 PATH_DoArcPart(GdiPath *pPath, POINT32 corners[],
+   double angleStart, double angleEnd, BOOL32 addMoveTo)
+{
+   double  halfAngle, a;
+   double  xNorm[4], yNorm[4];
+   POINT32 point;
+   int     i;
+
+   assert(fabs(angleEnd-angleStart)<=M_PI_2);
+
+   /* FIXME: Is there an easier way of computing this? */
+
+   /* Compute control points */
+   halfAngle=(angleEnd-angleStart)/2.0;
+   a=4.0/3.0*(1-cos(halfAngle))/sin(halfAngle);
+   xNorm[0]=cos(angleStart);
+   yNorm[0]=sin(angleStart);
+   xNorm[1]=xNorm[0] - a*yNorm[0];
+   yNorm[1]=yNorm[0] + a*xNorm[0];
+   xNorm[3]=cos(angleEnd);
+   yNorm[3]=sin(angleEnd);
+   xNorm[2]=xNorm[3] + a*yNorm[3];
+   yNorm[2]=yNorm[3] - a*xNorm[3];
+   
+   /* Add starting point to path if desired */
+   if(addMoveTo)
+   {
+      PATH_ScaleNormalizedPoint(corners, xNorm[0], yNorm[0], &point);
+      if(!PATH_AddEntry(pPath, point, PT_MOVETO))
+         return FALSE;
+   }
+
+   /* Add remaining control points */
+   for(i=1; i<4; i++)
+   {
+      PATH_ScaleNormalizedPoint(corners, xNorm[i], yNorm[i], &point);
+      if(!PATH_AddEntry(pPath, point, PT_BEZIERTO))
+         return FALSE;
+   }
+
+   return TRUE;
+}
+
+/* PATH_ScaleNormalizedPoint
+ *
+ * Scales a normalized point (x, y) with respect to the box whose corners are
+ * passed in "corners". The point is stored in "*pPoint". The normalized
+ * coordinates (-1.0, -1.0) correspond to corners[0], the coordinates
+ * (1.0, 1.0) correspond to corners[1].
+ */
+static void PATH_ScaleNormalizedPoint(POINT32 corners[], double x, double y,
+   POINT32 *pPoint)
+{
+   pPoint->x=(INT32)floor( (double)corners[0].x +
+      (double)(corners[1].x-corners[0].x)*0.5*(x+1.0) );
+   pPoint->y=(INT32)floor( (double)corners[0].y +
+      (double)(corners[1].y-corners[0].y)*0.5*(y+1.0) );
+}
+
+/* PATH_NormalizePoint
+ *
+ * Normalizes a point with respect to the box whose corners are passed in
+ * "corners". The normalized coordinates are stored in "*pX" and "*pY".
+ */
+static void PATH_NormalizePoint(POINT32 corners[], const POINT32 *pPoint,
+   double *pX, double *pY)
+{
+   *pX=(double)(pPoint->x-corners[0].x)/(double)(corners[1].x-corners[0].x) *
+      2.0 - 1.0;
+   *pY=(double)(pPoint->y-corners[0].y)/(double)(corners[1].y-corners[0].y) *
+      2.0 - 1.0;
+}
diff --git a/graphics/win16drv/brush.c b/graphics/win16drv/brush.c
index 7edc8b7..305cde5 100644
--- a/graphics/win16drv/brush.c
+++ b/graphics/win16drv/brush.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include "brush.h"
 #include "win16drv.h"
+#include "heap.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -21,14 +22,26 @@
     lBrush16.lbStyle = brush->logbrush.lbStyle;
     lBrush16.lbColor = brush->logbrush.lbColor;
     lBrush16.lbHatch = brush->logbrush.lbHatch;
-    nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, DRVOBJ_BRUSH,
-                                  &lBrush16, NULL, 
-                                  0); 
-    /*  may need to realloc segptrFOntInfo*/
-    physDev->segptrBrushInfo = WIN16_GlobalLock16(GlobalAlloc16(GHND, nSize));
+
+
+    if ( physDev->BrushInfo )
+    {
+        dprintf_win16drv(stddeb, "UnRealizing BrushInfo\n");
+        nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, -DRVOBJ_BRUSH,
+				      physDev->BrushInfo,
+				      physDev->BrushInfo, 0);
+    }
+    else 
+    {
+        nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, DRVOBJ_BRUSH,
+                                  &lBrush16, 0, 0); 
+	physDev->BrushInfo = SEGPTR_ALLOC( nSize );
+    }
+
+
     nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, DRVOBJ_BRUSH,
                                  &lBrush16, 
-                                 (LPVOID)physDev->segptrBrushInfo, 
+                                 physDev->BrushInfo, 
                                  win16drv_SegPtr_TextXForm); 
                          
     return prevHandle;
diff --git a/graphics/win16drv/font.c b/graphics/win16drv/font.c
index 85edff4..a669f4c 100644
--- a/graphics/win16drv/font.c
+++ b/graphics/win16drv/font.c
@@ -2,13 +2,18 @@
  * Windows driver font functions
  *
  * Copyright 1996 John Harvey
+ *           1998 Huw Davies
  */
 
 #include <stdio.h>
 #include "windows.h"
 #include "win16drv.h"
 #include "gdi.h"
+#include "module.h"
 #include "font.h"
+#include "heap.h"
+#include "stddebug.h"
+#include "debug.h"
 
 
 /***********************************************************************
@@ -20,22 +25,18 @@
     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
     DWORD dwRet;
     
-    printf("LPGDI_GetTextExtPoint: %04x %s %d %p\n", dc->hSelf, str, count, size);
-
-	/* TTD support PS fonts */
-	/* Assume fixed font */
-    size->cx = count * physDev->tm.tmAveCharWidth;
-    size->cy = physDev->tm.tmHeight;
-
-
-    printf("LPGDI_GetTextExtPoint: cx=%d, cy=%d\n", size->cx,size->cy);
+    dprintf_win16drv(stddeb, "WIN16DRV_GetTextExtPoint: %04x %s %d %p\n",
+		                dc->hSelf, str, count, size);
 
     dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
 			      NULL, str, 
-			      -count,  physDev->segptrFontInfo, win16drv_SegPtr_DrawMode, 
+			      -count,  physDev->FontInfo, 
+			      win16drv_SegPtr_DrawMode, 
 			      win16drv_SegPtr_TextXForm, NULL, NULL, 0);
-    printf("LPGDI_GetTextExtPoint: cx=0x%x, cy=0x%x Ret 0x%lx\n", size->cx, size->cy, dwRet);
-
+    size->cx = XDSTOLS(dc,LOWORD(dwRet));
+    size->cy = YDSTOLS(dc,HIWORD(dwRet));
+    dprintf_win16drv(stddeb, "WIN16DRV_GetTextExtPoint: cx=0x%x, cy=0x%x\n",
+		size->cx, size->cy );
     return TRUE;
 }
 
@@ -47,30 +48,90 @@
 {
     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
 
-    printf("LPGDI_GetTextMetrics: %04x \n", dc->hSelf);
+    dprintf_win16drv(stddeb, "WIN16DRV_GetTextMetrics: %04x \n", dc->hSelf);
 
-    metrics->tmHeight           = physDev->tm.tmHeight;
-    metrics->tmAscent           = physDev->tm.tmAscent;
-    metrics->tmDescent          = physDev->tm.tmDescent;
-    metrics->tmInternalLeading  = physDev->tm.tmInternalLeading;
-    metrics->tmExternalLeading  = physDev->tm.tmExternalLeading;
-    metrics->tmAveCharWidth     = physDev->tm.tmAveCharWidth;
-    metrics->tmMaxCharWidth     = physDev->tm.tmMaxCharWidth;
-    metrics->tmWeight           = physDev->tm.tmWeight;
-    metrics->tmOverhang         = physDev->tm.tmOverhang;
-    metrics->tmDigitizedAspectX = physDev->tm.tmDigitizedAspectX;
-    metrics->tmDigitizedAspectY = physDev->tm.tmDigitizedAspectY;
-    metrics->tmFirstChar        = physDev->tm.tmFirstChar;
-    metrics->tmLastChar         = physDev->tm.tmLastChar;
-    metrics->tmDefaultChar      = physDev->tm.tmDefaultChar;
-    metrics->tmBreakChar        = physDev->tm.tmBreakChar;
-    metrics->tmItalic           = physDev->tm.tmItalic;
-    metrics->tmUnderlined       = physDev->tm.tmUnderlined;
-    metrics->tmStruckOut        = physDev->tm.tmStruckOut;
-    metrics->tmPitchAndFamily   = physDev->tm.tmPitchAndFamily;
-    metrics->tmCharSet          = physDev->tm.tmCharSet;
+    FONT_TextMetric16to32A( &physDev->tm, metrics );
 
-    printf("H %d, A %d, D %d, Int %d, Ext %d, AW %d, MW %d, W %d\n",
+    dprintf_win16drv(stddeb,
+	   "H %d, A %d, D %d, Int %d, Ext %d, AW %d, MW %d, W %d\n",
+           metrics->tmHeight,
+           metrics->tmAscent,
+           metrics->tmDescent,
+           metrics->tmInternalLeading,
+           metrics->tmExternalLeading,
+           metrics->tmAveCharWidth,
+           metrics->tmMaxCharWidth,
+           metrics->tmWeight);
+
+    return TRUE;
+}
+
+HFONT32 WIN16DRV_FONT_SelectObject( DC * dc, HFONT32 hfont, FONTOBJ * font)
+{
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    HPEN32 prevHandle = dc->w.hFont;
+    int	nSize;
+
+    dc->w.hFont = hfont;
+
+    dprintf_win16drv(stddeb, "WIN16DRV_FONT_SelectObject '%s' h=%d\n",
+		     font->logfont.lfFaceName, font->logfont.lfHeight);
+
+
+    if( physDev->FontInfo )
+    {
+        dprintf_win16drv(stddeb, "UnRealizing FontInfo\n");
+        nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, -DRVOBJ_FONT,
+				      physDev->FontInfo,
+				      physDev->FontInfo, 0);
+    }
+
+    memcpy(&physDev->lf, &font->logfont, sizeof(LOGFONT16));
+    nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, DRVOBJ_FONT,
+                                  &physDev->lf, 0, 0); 
+
+    if( physDev->FontInfo && 
+	HeapSize( SegptrHeap, 0, physDev->FontInfo ) < nSize )
+    {
+        SEGPTR_FREE( physDev->FontInfo );
+	physDev->FontInfo = NULL;
+    }
+    
+    if( !physDev->FontInfo )
+        physDev->FontInfo = SEGPTR_ALLOC( nSize );
+
+
+    nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, DRVOBJ_FONT,
+                                 &physDev->lf, 
+                                 physDev->FontInfo, 
+                                 win16drv_SegPtr_TextXForm ); 
+
+#define fi physDev->FontInfo    
+    physDev->tm.tmHeight           = YDSTOLS(dc, fi->dfPixHeight);
+    physDev->tm.tmAscent           = YDSTOLS(dc, fi->dfAscent);
+    physDev->tm.tmDescent          = physDev->tm.tmHeight -
+					    physDev->tm.tmAscent; 
+    physDev->tm.tmInternalLeading  = YDSTOLS(dc, fi->dfInternalLeading);
+    physDev->tm.tmExternalLeading  = YDSTOLS(dc, fi->dfExternalLeading);
+    physDev->tm.tmAveCharWidth     = XDSTOLS(dc, fi->dfAvgWidth);
+    physDev->tm.tmMaxCharWidth     = XDSTOLS(dc, fi->dfMaxWidth);
+    physDev->tm.tmWeight           = fi->dfWeight;
+    physDev->tm.tmOverhang         = 0; /*FIXME*/
+    physDev->tm.tmDigitizedAspectX = fi->dfHorizRes;
+    physDev->tm.tmDigitizedAspectY = fi->dfVertRes;
+    physDev->tm.tmFirstChar        = fi->dfFirstChar;
+    physDev->tm.tmLastChar         = fi->dfLastChar;
+    physDev->tm.tmDefaultChar      = fi->dfDefaultChar;
+    physDev->tm.tmBreakChar        = fi->dfBreakChar;
+    physDev->tm.tmItalic           = fi->dfItalic;
+    physDev->tm.tmUnderlined       = fi->dfUnderline;
+    physDev->tm.tmStruckOut        = fi->dfStrikeOut;
+    physDev->tm.tmPitchAndFamily   = fi->dfPitchAndFamily;
+    physDev->tm.tmCharSet          = fi->dfCharSet;
+#undef fi
+
+    dprintf_win16drv(stddeb,
+           "H %d, A %d, D %d, Int %d, Ext %d, AW %d, MW %d, W %d\n",
            physDev->tm.tmHeight,
            physDev->tm.tmAscent,
            physDev->tm.tmDescent,
@@ -80,14 +141,7 @@
            physDev->tm.tmMaxCharWidth,
            physDev->tm.tmWeight);
 
-    return TRUE;
-}
-
-HFONT32 WIN16DRV_FONT_SelectObject( DC * dc, HFONT32 hfont, FONTOBJ * font)
-{
-    /* TTD */
-    printf("In WIN16DRV_FONT_SelectObject\n");
-    return GetStockObject32(SYSTEM_FIXED_FONT);
+    return prevHandle;
 }
 
 /***********************************************************************
@@ -97,12 +151,64 @@
 			    LPINT32 buffer )
 {
     int i;
+    WORD wRet;
+
     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
-    /* TTD Need to cope with PS fonts */    
-    for (i = firstChar; i <= lastChar; i++)
-         *buffer++ = physDev->tm.tmAveCharWidth;
-    return TRUE;
+    
+    dprintf_win16drv( stddeb, "WIN16DRV_GetCharWidth: %d - %d into %p\n",
+		      firstChar, lastChar, buffer );
+
+    wRet = PRTDRV_GetCharWidth( physDev->segptrPDEVICE, buffer, firstChar, 
+				lastChar, physDev->FontInfo, 
+				win16drv_SegPtr_DrawMode, 
+				win16drv_SegPtr_TextXForm );
+    if( debugging_win16drv )
+        for(i = 0; i <= lastChar - firstChar; i++)
+	    dprintf_win16drv(stddeb, "Char %x: width %d\n", i + firstChar,
+			                 buffer[i]);
+
+    return wRet;
 }
 
+/***********************************************************************
+ *
+ *           WIN16DRV_EnumDeviceFonts
+ */
 
+BOOL32	WIN16DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf, 
+				        DEVICEFONTENUMPROC proc, LPARAM lp )
+{
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    WORD wRet;
+    WEPFC wepfc = {proc, lp};
+
+    /* EnumDFontCallback is GDI.158 */
+    FARPROC16 pfnCallback = MODULE_GetEntryPoint( GetModuleHandle16("GDI"),
+						              158 );
+
+    wRet = PRTDRV_EnumDFonts(physDev->segptrPDEVICE, plf->lfFaceName[0] ?
+			     plf->lfFaceName : NULL , pfnCallback , &wepfc );
+    return wRet;
+}
+
+/*
+ * EnumCallback (GDI.158)
+ * 
+ * This is the callback function used when EnumDFonts is called. 
+ * (The printer drivers uses it to pass info on available fonts).
+ *
+ * lpvClientData is the pointer passed to EnumDFonts, which points to a WEPFC
+ * structure (WEPFC = WINE_ENUM_PRINTER_FONT_CALLBACK).
+ *
+ */
+
+
+WORD WINAPI WineEnumDFontCallback(LPLOGFONT16 lpLogFont,
+                                  LPTEXTMETRIC16 lpTextMetrics,
+                                  WORD wFontType, LONG lpClientData) 
+{
+    dprintf_win16drv(stddeb, "In WineEnumDFontCallback plf=%p\n", lpLogFont);
+    return (*(((WEPFC *)lpClientData)->proc))( lpLogFont, lpTextMetrics, 
+				     wFontType, ((WEPFC *)lpClientData)->lp );
+}
 
diff --git a/graphics/win16drv/graphics.c b/graphics/win16drv/graphics.c
index 2452542..7294acb 100644
--- a/graphics/win16drv/graphics.c
+++ b/graphics/win16drv/graphics.c
@@ -41,9 +41,9 @@
     points[1].y = dc->w.DCOrgY + YLPTODP( dc, y );
     bRet = PRTDRV_Output(physDev->segptrPDEVICE,
                          OS_POLYLINE, 2, points, 
-                         physDev->segptrPenInfo,
+                         physDev->PenInfo,
                          NULL,
-                         win16drv_SegPtr_DrawMode, NULL);
+                         win16drv_SegPtr_DrawMode, dc->w.hClipRgn);
 
     dc->w.CursPosX = x;
     dc->w.CursPosY = y;
@@ -60,6 +60,7 @@
     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
     BOOL32 bRet = 0;
     POINT16 points[2];
+
     dprintf_win16drv(stddeb, "In WIN16DRV_Rectangle, x %d y %d DCOrgX %d y %d\n",
            left, top, dc->w.DCOrgX, dc->w.DCOrgY);
     dprintf_win16drv(stddeb, "In WIN16DRV_Rectangle, VPortOrgX %d y %d\n",
@@ -70,10 +71,10 @@
     points[1].x = XLPTODP(dc, right);
     points[1].y = YLPTODP(dc, bottom);
     bRet = PRTDRV_Output(physDev->segptrPDEVICE,
-                         OS_RECTANGLE, 2, points, 
-                         physDev->segptrPenInfo,
-                         physDev->segptrBrushInfo,
-                         win16drv_SegPtr_DrawMode, NULL);
+                           OS_RECTANGLE, 2, points, 
+                           physDev->PenInfo,
+			   physDev->BrushInfo,
+			   win16drv_SegPtr_DrawMode, dc->w.hClipRgn);
     return bRet;
 }
 
@@ -90,17 +91,90 @@
     BOOL32 bRet = 0;
     LPPOINT16 points;
     int i;
+
+    if(count < 2) return TRUE;
+    if(pt[0].x != pt[count-1].x || pt[0].y != pt[count-1].y)
+        count++; /* Ensure polygon is closed */
+
     points = HEAP_xalloc( GetProcessHeap(), 0, count * sizeof(POINT16) );
-    for (i = 0; i<count ; i++)
+    for (i = 0; i < count - 1; i++)
     {
-      points[i].x = ((pt[i].x - dc->wndOrgX) * dc->vportExtX/ dc->wndExtX) + dc->vportOrgX;
-      points[i].y = ((pt[i].y - dc->wndOrgY) * dc->vportExtY/ dc->wndExtY) + dc->vportOrgY;
+      points[i].x = XLPTODP( dc, pt[i].x );
+      points[i].y = YLPTODP( dc, pt[i].y );
     }
+    points[count-1].x = points[0].x;
+    points[count-1].y = points[0].y;
     bRet = PRTDRV_Output(physDev->segptrPDEVICE,
-                         OS_WINDPOLYGON, 2, points, 
-                         physDev->segptrPenInfo,
-                         physDev->segptrBrushInfo,
-                         win16drv_SegPtr_DrawMode, NULL);
+                         OS_WINDPOLYGON, count, points, 
+                         physDev->PenInfo,
+                         physDev->BrushInfo,
+                         win16drv_SegPtr_DrawMode, dc->w.hClipRgn);
     HeapFree( GetProcessHeap(), 0, points );
     return bRet;
 }
+
+
+/***********************************************************************
+ *           WIN16DRV_Polyline
+ */
+BOOL32
+WIN16DRV_Polyline(DC *dc, LPPOINT32 pt, INT32 count )
+{
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    BOOL32 bRet = 0;
+    LPPOINT16 points;
+    int i;
+
+    if(count < 2) return TRUE;
+
+    points = HEAP_xalloc( GetProcessHeap(), 0, count * sizeof(POINT16) );
+    for (i = 0; i < count; i++)
+    {
+      points[i].x = XLPTODP( dc, pt[i].x );
+      points[i].y = YLPTODP( dc, pt[i].y );
+    }
+    bRet = PRTDRV_Output(physDev->segptrPDEVICE,
+                         OS_POLYLINE, count, points, 
+                         physDev->PenInfo,
+                         NULL,
+                         win16drv_SegPtr_DrawMode, dc->w.hClipRgn);
+    HeapFree( GetProcessHeap(), 0, points );
+    return bRet;
+}
+
+
+
+/***********************************************************************
+ *           WIN16DRV_Ellipse
+ */
+BOOL32
+WIN16DRV_Ellipse(DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom)
+{
+    WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
+    BOOL32 bRet = 0;
+    POINT16 points[2];
+    dprintf_win16drv(stddeb, "In WIN16DRV_Ellipse, x %d y %d DCOrgX %d y %d\n",
+           left, top, dc->w.DCOrgX, dc->w.DCOrgY);
+    dprintf_win16drv(stddeb, "In WIN16DRV_Ellipse, VPortOrgX %d y %d\n",
+           dc->vportOrgX, dc->vportOrgY);
+    points[0].x = XLPTODP(dc, left);
+    points[0].y = YLPTODP(dc, top);
+
+    points[1].x = XLPTODP(dc, right);
+    points[1].y = YLPTODP(dc, bottom);
+
+    bRet = PRTDRV_Output(physDev->segptrPDEVICE,
+                         OS_ELLIPSE, 2, points, 
+                         physDev->PenInfo,
+                         physDev->BrushInfo,
+                         win16drv_SegPtr_DrawMode, dc->w.hClipRgn);
+    return bRet;
+}
+
+
+
+
+
+
+
+
diff --git a/graphics/win16drv/init.c b/graphics/win16drv/init.c
index faac26e..e81e565 100644
--- a/graphics/win16drv/init.c
+++ b/graphics/win16drv/init.c
@@ -2,6 +2,7 @@
  * Windows Device Context initialisation functions
  *
  * Copyright 1996 John Harvey
+ *           1998 Huw Davies
  */
 
 #include <stdlib.h>
@@ -12,7 +13,6 @@
 #include <unistd.h>
 #include <errno.h>
 #include "windows.h"
-#include "module.h"
 #include "win16drv.h"
 #include "gdi.h"
 #include "bitmap.h"
@@ -20,6 +20,7 @@
 #include "color.h"
 #include "font.h"
 #include "callback.h"
+#include "options.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -54,8 +55,8 @@
     WIN16DRV_CreateDC,               /* pCreateDC */
     NULL,                            /* pDeleteDC */
     NULL,                            /* pDeleteObject */
-    NULL,                            /* pEllipse */
-    NULL,                            /* pEnumDeviceFonts */
+    WIN16DRV_Ellipse,                /* pEllipse */
+    WIN16DRV_EnumDeviceFonts,        /* pEnumDeviceFonts */
     WIN16DRV_Escape,                 /* pEscape */
     NULL,                            /* pExcludeClipRect */
     NULL,                            /* pExcludeVisRect */
@@ -77,9 +78,9 @@
     NULL,                            /* pPie */
     NULL,                            /* pPolyPolygon */
     WIN16DRV_Polygon,                /* pPolygon */
-    NULL,                            /* pPolyline */
+    WIN16DRV_Polyline,               /* pPolyline */
     NULL,                            /* pRealizePalette */
-    WIN16DRV_Rectangle,                            /* pRectangle */
+    WIN16DRV_Rectangle,              /* pRectangle */
     NULL,                            /* pRestoreDC */
     NULL,                            /* pRoundRect */
     NULL,                            /* pSaveDC */
@@ -159,74 +160,15 @@
     lpDrawMode->LTextColor	= 0x00000000;     
 }
 
-/*
- * EnumCallback (GDI.158)
- * 
- * This is the callback function used when EnumDFonts is called. 
- * (The printer drivers uses it to pass info on available fonts).
- *
- * lpvClientData is the pointer passed to EnumDFonts, which points to a WEPFC
- * structure (WEPFC = WINE_ENUM_PRINTER_FONT_CALLBACK).  This structure 
- * contains infomation on how to store the data passed .
- *
- * There are two modes:
- * 	1) Just count the number of fonts available.
- * 	2) Store all font data passed.
- */
-WORD WINAPI WineEnumDFontCallback(LPLOGFONT16 lpLogFont,
-                                  LPTEXTMETRIC16 lpTextMetrics,
-                                  WORD wFontType, LONG lpvClientData) 
-{
-    int wRet = 0;
-    WEPFC *pWEPFC = (WEPFC *)lpvClientData; 
-    
-    /* Make sure we have the right structure */
-    if (pWEPFC != NULL )
-    {
-        dprintf_win16drv(stddeb, "mode is 0x%x\n",pWEPFC->nMode);
-        
-	switch (pWEPFC->nMode)
-	{
-	    /* Count how many fonts */
-	  case 1:
-	    pWEPFC->nCount++;
-	    break;
-
-	    /* Store the fonts in the printer driver structure */
-	  case 2:
-	  {
-	      PRINTER_FONTS_INFO *pPFI;
-                  
-	      dprintf_win16drv(stddeb, "WineEnumDFontCallback: Found %s %x\n", 
-		     lpLogFont->lfFaceName, wFontType);
-	      
-	      pPFI = &pWEPFC->pLPD->paPrinterFonts[pWEPFC->nCount];
-	      memcpy(&(pPFI->lf), lpLogFont, sizeof(LOGFONT16));
-	      memcpy(&(pPFI->tm), lpTextMetrics, sizeof(TEXTMETRIC16));	      
-	      pWEPFC->nCount++;
-              
-	  }
-	    break;
-	}
-	wRet = 1;
-    }
-    dprintf_win16drv(stddeb, "WineEnumDFontCallback: returnd %d\n", wRet);
-    return wRet;
-}
-
 BOOL32 WIN16DRV_CreateDC( DC *dc, LPCSTR driver, LPCSTR device, LPCSTR output,
                           const DEVMODE16* initData )
 {
     LOADED_PRINTER_DRIVER *pLPD;
     WORD wRet;
     DeviceCaps *printerDevCaps;
-    FARPROC16 pfnCallback;
     int nPDEVICEsize;
     PDEVICE_HEADER *pPDH;
     WIN16DRV_PDEVICE *physDev;
-    int numFonts;
-    /* Realizing fonts */
-    int nSize;
     char printerEnabled[20];
     PROFILE_GetWineIniString( "wine", "printer", "off",
                              printerEnabled, sizeof(printerEnabled) );
@@ -290,93 +232,14 @@
     /* Now get the printer driver to initialise this data */
     wRet = PRTDRV_Enable((LPVOID)physDev->segptrPDEVICE, INITPDEVICE, device, driver, output, NULL); 
 
-    /* Now enumerate the fonts supported by the printer driver*/
-    /* GDI.158 is EnumCallback, which is called by the 16bit printer driver */
-    /* passing information on the available fonts */
-    if (pLPD->paPrinterFonts == NULL)
-    {
-	pfnCallback = MODULE_GetEntryPoint( GetModuleHandle16("GDI"), 158 );
-        
-	if (pfnCallback != NULL)
-	{
-	    WEPFC wepfc;
-	    
-	    wepfc.nMode = 1;
-	    wepfc.nCount = 0;
-	    wepfc.pLPD = pLPD;
-	    
-	    /* First count the number of fonts */
-            
-	    PRTDRV_EnumDFonts(physDev->segptrPDEVICE, NULL, pfnCallback, 
-			      (void *)&wepfc);
-	    
-	    /* Allocate a buffer to store all of the fonts */
-	    pLPD->nPrinterFonts = wepfc.nCount;
-            dprintf_win16drv(stddeb, "Got %d fonts\n",wepfc.nCount);
-            
-	    if (wepfc.nCount > 0)
-	    {
-
-		pLPD->paPrinterFonts = malloc(sizeof(PRINTER_FONTS_INFO) * wepfc.nCount);
-		
-		/* Now get all of the fonts */
-		wepfc.nMode = 2;
-		wepfc.nCount = 0;
-		PRTDRV_EnumDFonts(physDev->segptrPDEVICE, NULL, pfnCallback, 
-				  (void *)&wepfc);
-                numFonts = wepfc.nCount;
-	    }
-            else
-            {
-                /* If the number of fonts returned are zero we can not continue */
-                fprintf( stderr, "No fonts? Aborting CreateDC...\n");
-                return FALSE;
-            }
-	}
-    }
-		
-    /* Select the first font into the DC */
-    /* Set up the logfont */
-    memcpy(&physDev->lf, 
-	   &pLPD->paPrinterFonts[0].lf, 
-	   sizeof(LOGFONT16));
-
-    /* Set up the textmetrics */
-    memcpy(&physDev->tm, 
-	   &pLPD->paPrinterFonts[0].tm, 
-	   sizeof(TEXTMETRIC16));
-
+    physDev->FontInfo = NULL;
+    physDev->BrushInfo = NULL;
+    physDev->PenInfo = NULL;
     win16drv_SegPtr_TextXForm = WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(TEXTXFORM16)));
     win16drv_TextXFormP = PTR_SEG_TO_LIN(win16drv_SegPtr_TextXForm);
     
     InitTextXForm(win16drv_TextXFormP);
-#ifdef SUPPORT_REALIZED_FONTS
-    /* TTD should calculate this */
-    
-    /* First get the size of the realized font */
-    nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, DRVOBJ_FONT,
-				 &pLPD->paPrinterFonts[0], NULL, 
-				 0);
-    
-    physDev->segptrFontInfo = WIN16_GlobalLock16(GlobalAlloc16(GHND, nSize));
-    /* Realize the font */
-    PRTDRV_RealizeObject(physDev->segptrPDEVICE, DRVOBJ_FONT,
-			 &pLPD->paPrinterFonts[0], 
-			 (LPVOID)physDev->segptrFontInfo, 
-			 win16drv_SegPtr_TextXForm);
-    /* Quick look at structure */
-    if (physDev->segptrFontInfo)
-    {  
-	FONTINFO16 *p = (FONTINFO16 *)PTR_SEG_TO_LIN(physDev->segptrFontInfo);
 
-	dprintf_win16drv(stddeb, "T:%d VR:%d HR:%d, F:%d L:%d\n",
-	       p->dfType,
-	       p->dfVertRes, p->dfHorizRes,
-	       p->dfFirstCHAR, p->dfLastCHAR
-	       );
-    }
-
-#endif
     /* TTD Lots more to do here */
     win16drv_SegPtr_DrawMode = WIN16_GlobalLock16(GlobalAlloc16(GHND, sizeof(DRAWMODE)));
     win16drv_DrawModeP = PTR_SEG_TO_LIN(win16drv_SegPtr_DrawMode);
@@ -393,8 +256,8 @@
     WIN16DRV_PDEVICE *physDev = (WIN16DRV_PDEVICE *)dc->physDev;
     BOOL32 bRet = 0;
 
-    bRet = PRTDRV_StretchBlt( physDev->segptrPDEVICE, left, top, width, height, NULL, 0, 0, width, height,
-                       PATCOPY, physDev->segptrBrushInfo, win16drv_SegPtr_DrawMode, NULL);
+    bRet = PRTDRV_StretchBlt( physDev->segptrPDEVICE, left, top, width, height, (SEGPTR)NULL, 0, 0, width, height,
+                       PATCOPY, physDev->BrushInfo, win16drv_SegPtr_DrawMode, NULL);
 
     return bRet;
 }
@@ -417,6 +280,10 @@
 	    fprintf(stderr,"Escape: ENABLEPAIRKERNING ignored.\n");
             nRet = 1;
 	    break;
+	  case GETPAIRKERNTABLE:
+	    fprintf(stderr,"Escape: GETPAIRKERNTABLE ignored.\n");
+            nRet = 0;
+	    break;
           case SETABORTPROC:
 	    printf("Escape: SetAbortProc ignored should be stored in dc somewhere\n");
             /* Make calling application believe this worked */
@@ -439,7 +306,7 @@
 
               textData->nSize = cbInput;
               textData->lpindata = lpInData;
-              textData->lpFont = physDev->segptrFontInfo;
+              textData->lpFont = SEGPTR_GET( physDev->FontInfo );
               textData->lpXForm = win16drv_SegPtr_TextXForm;
               textData->lpDrawMode = win16drv_SegPtr_DrawMode;
               nRet = PRTDRV_Control(physDev->segptrPDEVICE, nEscape,
diff --git a/graphics/win16drv/pen.c b/graphics/win16drv/pen.c
index a26ea99..c2e5454 100644
--- a/graphics/win16drv/pen.c
+++ b/graphics/win16drv/pen.c
@@ -7,6 +7,7 @@
 #include "pen.h"
 #include "color.h"
 #include "win16drv.h"
+#include "heap.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -20,21 +21,30 @@
     int		 nSize;
     LOGPEN16 	 lPen16;
     dc->w.hPen = hpen;
-    printf("In WIN16DRV_PEN_SelectObject\n");
+    dprintf_win16drv(stddeb, "In WIN16DRV_PEN_SelectObject\n");
     lPen16.lopnStyle   = pen->logpen.lopnStyle;
     lPen16.lopnWidth.x = pen->logpen.lopnWidth.x;
     lPen16.lopnWidth.y = pen->logpen.lopnWidth.y;
     lPen16.lopnColor   = pen->logpen.lopnColor;
-    nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, DRVOBJ_PEN,
-                                  &lPen16, NULL, 
-                                  0); 
-    /*  may need to realloc segptrFOntInfo*/
-    physDev->segptrPenInfo = WIN16_GlobalLock16(GlobalAlloc16(GHND, nSize));
+
+    if ( physDev->PenInfo )
+    {
+        dprintf_win16drv(stddeb, "UnRealizing PenInfo\n");
+        nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, -DRVOBJ_PEN,
+				      physDev->PenInfo,
+				      physDev->PenInfo, 0);
+    }
+    else 
+    {
+        nSize = PRTDRV_RealizeObject (physDev->segptrPDEVICE, DRVOBJ_PEN,
+                                  &lPen16, 0, 0); 
+	physDev->PenInfo = SEGPTR_ALLOC( nSize );
+    }
+
     nSize = PRTDRV_RealizeObject(physDev->segptrPDEVICE, DRVOBJ_PEN,
                                  &lPen16, 
-                                 (LPVOID)physDev->segptrPenInfo, 
+                                 physDev->PenInfo, 
                                  0); 
-                         
 
     return prevHandle;
 }
diff --git a/graphics/win16drv/prtdrv.c b/graphics/win16drv/prtdrv.c
index 8d7f550..fac1757 100644
--- a/graphics/win16drv/prtdrv.c
+++ b/graphics/win16drv/prtdrv.c
@@ -17,6 +17,8 @@
 #include "callback.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "bitmap.h"
+#include "pen.h"
 
 #define MAX_PRINTER_DRIVERS 	16
 static LOADED_PRINTER_DRIVER *gapLoadedPrinterDrivers[MAX_PRINTER_DRIVERS];
@@ -244,11 +246,11 @@
 	lP5 = (LONG)lpData;
         
 	wRet = Callbacks->CallDrvEnableProc(pLPD->fn[FUNC_ENABLE], 
-				   (wStyle==INITPDEVICE)?lP1:SEGPTR_GET(lP1),
-				   wP2,
-				   SEGPTR_GET(lP3),
-				   SEGPTR_GET(lP4),
-				   lP5);
+			     (wStyle==INITPDEVICE)?(SEGPTR)lP1:SEGPTR_GET(lP1),
+			     wP2,
+			     SEGPTR_GET(lP3),
+			     SEGPTR_GET(lP4),
+			     lP5);
 	SEGPTR_FREE(lP3);
 	SEGPTR_FREE(lP4);
 
@@ -272,7 +274,8 @@
     WORD wRet = 0;
     LOADED_PRINTER_DRIVER *pLPD = NULL;
 
-    dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts:\n");
+    dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: %08lx %s %p %p\n",
+		     lpDestDev, lpFaceName, lpCallbackFunc, lpClientData);
 
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
@@ -285,12 +288,15 @@
 	}
 
 	lP1 = (SEGPTR)lpDestDev;
-	lP2 = SEGPTR_STRDUP(lpFaceName);
+	if(lpFaceName)
+	    lP2 = SEGPTR_STRDUP(lpFaceName);
+	else
+	    lP2 = NULL;
 	lP4 = (LONG)lpClientData;
         wRet = Callbacks->CallDrvEnumDFontsProc( pLPD->fn[FUNC_ENUMDFONTS], 
-                                                 lP1, SEGPTR_GET(lP2),
-                                                 lpCallbackFunc, lP4);
-	SEGPTR_FREE(lP2);
+                                lP1, SEGPTR_GET(lP2), lpCallbackFunc, lP4);
+	if(lpFaceName)
+	    SEGPTR_FREE(lP2);
     } else 
         fprintf(stderr,"Failed to find device\n");
     
@@ -306,7 +312,7 @@
     WORD wRet = 0;
     LOADED_PRINTER_DRIVER *pLPD = NULL;
 
-    dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts:\n");
+    dprintf_win16drv(stddeb, "PRTDRV_EnumObj:\n");
 
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
@@ -314,9 +320,9 @@
         FARPROC16 lP3;
 	WORD wP2;
 
-	if (pLPD->fn[FUNC_ENUMDFONTS] == NULL)
+	if (pLPD->fn[FUNC_ENUMOBJ] == NULL)
 	{
-	    dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: Not supported by driver\n");
+	    dprintf_win16drv(stddeb, "PRTDRV_EnumObj: Not supported by driver\n");
 	    return 0;
 	}
 
@@ -337,7 +343,7 @@
     else 
         fprintf(stderr,"Failed to find device\n");
     
-    dprintf_win16drv(stddeb, "PRTDRV_EnumDFonts: return %x\n", wRet);
+    dprintf_win16drv(stddeb, "PRTDRV_EnumObj: return %x\n", wRet);
     return wRet;
 }
 
@@ -347,16 +353,16 @@
 WORD PRTDRV_Output(LPPDEVICE 	 lpDestDev,
                    WORD 	 wStyle, 
                    WORD 	 wCount,
-                   POINT16     **points, 
-                   SEGPTR 	 lpPPen,
-                   SEGPTR	 lpPBrush,
+                   POINT16      *points, 
+                   LPLOGPEN16 	 lpPen,
+                   LPLOGBRUSH16	 lpBrush,
                    SEGPTR	 lpDrawMode,
-                   RECT16 	*lpClipRect)
+                   HRGN32 	 hClipRgn)
 {
     WORD wRet = 0;
     LOADED_PRINTER_DRIVER *pLPD = NULL;
     
-    dprintf_win16drv(stddeb, "PRTDRV_OUTPUT\n");
+    dprintf_win16drv(stddeb, "PRTDRV_OUTPUT %d\n", wStyle );
     
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
@@ -377,24 +383,58 @@
         nSize = sizeof(POINT16) * wCount;
  	lP4 = (LPPOINT16 )SEGPTR_ALLOC(nSize);
  	memcpy(lP4,points,nSize);
-        lP5 = lpPPen;
-        lP6 = lpPBrush;
+        lP5 = SEGPTR_GET( lpPen );
+        lP6 = SEGPTR_GET( lpBrush );
         lP7 = lpDrawMode;
         
-	if (lpClipRect != NULL)
+	if (hClipRgn)
 	{
-	    lP8 = SEGPTR_NEW(RECT16);
-	    memcpy(lP8,lpClipRect,sizeof(RECT16));
+	    DWORD size;
+	    RGNDATA *clip;
 
-	}
-	else
-	  lP8 = 0L;
-	wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT], 
+	    size = GetRegionData( hClipRgn, 0, NULL );
+	    clip = HeapAlloc( SystemHeap, 0, size );
+	    if(!clip) 
+	    {
+	        fprintf(stderr, "Can't alloc clip array in PRTDRV_Output\n");
+		return FALSE;
+	    }
+	    GetRegionData( hClipRgn, size, clip );
+	    if( clip->rdh.nCount == 0 )
+	    {
+		wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT], 
+                                            lP1, wP2, wP3, SEGPTR_GET(lP4),
+                                            lP5, lP6, lP7, (SEGPTR) NULL);
+	    }
+	    else
+	    {
+	        RECT32 *pRect;
+	        lP8 = SEGPTR_NEW(RECT16);
+	    
+		for(pRect = (RECT32 *)clip->Buffer; 
+		    pRect < (RECT32 *)clip->Buffer + clip->rdh.nCount; pRect++)
+	        {
+		    CONV_RECT32TO16( pRect, lP8 );
+
+		    dprintf_win16drv(stddeb, "rect = %d,%d - %d,%d\n",
+			    lP8->left, lP8->top, lP8->right, lP8->bottom );
+		    wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT], 
                                             lP1, wP2, wP3, SEGPTR_GET(lP4),
                                             lP5, lP6, lP7, SEGPTR_GET(lP8));
+		}
+		SEGPTR_FREE(lP8);
+	    }
+	    HeapFree( SystemHeap, 0, clip );
+	}
+	else
+	{
+	    wRet = Callbacks->CallDrvOutputProc(pLPD->fn[FUNC_OUTPUT], 
+                                            lP1, wP2, wP3, SEGPTR_GET(lP4),
+                                            lP5, lP6, lP7, (SEGPTR) NULL);
+	}
         SEGPTR_FREE(lP4);
-        SEGPTR_FREE(lP8);
     }
+    dprintf_win16drv(stddeb, "PRTDRV_Output return %d\n", wRet);
     return wRet;
 }
 
@@ -408,25 +448,28 @@
     WORD dwRet = 0;
     LOADED_PRINTER_DRIVER *pLPD = NULL;
     
-    dprintf_win16drv(stddeb, "PRTDRV_RealizeObject:\n");
+    dprintf_win16drv(stddeb,
+		     "PRTDRV_RealizeObject: %08lx %04x %p %p %08lx\n",
+		     lpDestDev, wStyle, lpInObj, lpOutObj, lpTextXForm);
     
     if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
     {
-	LONG	lP1, lP4, lP5;  
-	LPBYTE	lP3;
-	WORD	wP2;
+        LONG lP1, lP3, lP4, lP5;  
+	WORD wP2;
+	LPBYTE lpBuf = NULL;
 	unsigned int	nSize;
 
 	if (pLPD->fn[FUNC_REALIZEOBJECT] == NULL)
 	{
-	    dprintf_win16drv(stddeb, "PRTDRV_RealizeObject: Not supported by driver\n");
+	    dprintf_win16drv(stddeb,
+			    "PRTDRV_RealizeObject: Not supported by driver\n");
 	    return 0;
 	}
 
 	lP1 = lpDestDev;
 	wP2 = wStyle;
 	
-	switch (wStyle)
+	switch ((INT16)wStyle)
 	{
         case DRVOBJ_BRUSH:
             nSize = sizeof (LOGBRUSH16);
@@ -437,23 +480,40 @@
         case DRVOBJ_PEN:
             nSize = sizeof(LOGPEN16); 
             break;
+
+        case -DRVOBJ_BRUSH:
+        case -DRVOBJ_FONT: 
+        case -DRVOBJ_PEN:
+	    nSize = -1;
+            break;
+
         case DRVOBJ_PBITMAP:
         default:
-	    fprintf(stderr, "PRTDRV_RealizeObject: Object type %d not supported\n", wStyle);
+	    fprintf(stderr, 
+	       "PRTDRV_RealizeObject: Object type %d not supported\n", wStyle);
             nSize = 0;
             
 	}
- 	lP3 = SEGPTR_ALLOC(nSize);
- 	memcpy(lP3,lpInObj,nSize);
-	
-	lP4 = (LONG)lpOutObj;
+
+	if(nSize != -1)
+	{
+	    lpBuf = SEGPTR_ALLOC(nSize);
+	    memcpy(lpBuf, lpInObj, nSize);
+	    lP3 = SEGPTR_GET(lpBuf);
+	} 
+	else
+	    lP3 = SEGPTR_GET( lpInObj );
+
+	lP4 = SEGPTR_GET( lpOutObj );
 
         lP5 = lpTextXForm;
-
+	dprintf_win16drv(stddeb,
+			 "Calling Realize %08lx %04x %08lx %08lx %08lx\n",
+	                                      lP1, wP2, lP3, lP4, lP5);
 	dwRet = Callbacks->CallDrvRealizeProc(pLPD->fn[FUNC_REALIZEOBJECT], 
-                                              lP1, wP2, SEGPTR_GET(lP3),
-                                              lP4, lP5);
-        SEGPTR_FREE(lP3);
+                                              lP1, wP2, lP3, lP4, lP5);
+	if(lpBuf)
+	    SEGPTR_FREE(lpBuf);
 
     }
     dprintf_win16drv(stddeb, "PRTDRV_RealizeObject: return %x\n", dwRet);
@@ -470,7 +530,7 @@
                         WORD wSrcX, WORD wSrcY,
                         WORD wSrcXext, WORD wSrcYext, 
                         DWORD Rop3,
-                        SEGPTR lpPBrush,
+                        LPLOGBRUSH16 lpBrush,
                         SEGPTR lpDrawMode,
                         RECT16 *lpClipRect)
 {
@@ -501,7 +561,7 @@
         wP9  = wSrcXext;
         wP10 = wSrcYext;
         lP11 = Rop3;
-        lP12 = lpPBrush;
+        lP12 = SEGPTR_GET( lpBrush );
         lP13 = lpDrawMode;
 	if (lpClipRect != NULL)
 	{
@@ -524,7 +584,7 @@
 
 DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
                         RECT16 *lpClipRect, LPCSTR lpString, WORD wCount, 
-                        SEGPTR lpFontInfo, SEGPTR lpDrawMode, 
+                        LPFONTINFO16 lpFontInfo, SEGPTR lpDrawMode, 
                         SEGPTR lpTextXForm, SHORT *lpCharWidths,
                         RECT16 *     lpOpaqueRect, WORD wOptions)
 {
@@ -560,20 +620,20 @@
 	  lP4 = 0L;
 
 	if (lpString != NULL) {
-	    /* TTD WARNING THIS STRING ISNT NULL TERMINATED */
 	    nSize = strlen(lpString);
 	    if (nSize>abs(wCount))
 	    	nSize = abs(wCount);
-	    lP5 = SEGPTR_ALLOC(nSize);
+	    lP5 = SEGPTR_ALLOC(nSize+1);
             dprintf_win16drv(stddeb, "Adding lpString (nSize is %d)\n",nSize);
 	    memcpy(lP5,lpString,nSize);
+	    *((char *)lP5 + nSize) = '\0';
 	} else
 	  lP5 = 0L;
 	
 	iP6 = wCount;
 	
 	/* This should be realized by the driver, so in 16bit data area */
-	lP7 = lpFontInfo;
+	lP7 = SEGPTR_GET( lpFontInfo );
         lP8 = lpDrawMode;
         lP9 = lpTextXForm;
 	
@@ -603,3 +663,131 @@
     dprintf_win16drv(stddeb, "PRTDRV_ExtTextOut: return %lx\n", dwRet);
     return dwRet;
 }
+
+int WINAPI dmEnumDFonts(LPPDEVICE lpDestDev, LPSTR lpFaceName, FARPROC16 lpCallbackFunc, LPVOID lpClientData)
+{
+        /* Windows 3.1 just returns 1 */
+        return 1;
+}
+
+int WINAPI dmRealizeObject(LPPDEVICE lpDestDev, INT16 wStyle, LPSTR lpInObj, LPSTR lpOutObj, SEGPTR lpTextXForm)
+{
+    fprintf(stderr, "dmRealizeObject(lpDestDev: %08x, wStyle: %04x, lpInObj: %08x, lpOutObj: %08x, lpTextXForm: %08x): stub: ", (UINT32)lpDestDev, wStyle, (UINT32)lpInObj, (UINT32)lpOutObj, (UINT32)lpTextXForm);
+    if (wStyle < 0) { /* Free extra memory of given object's structure */
+	switch ( -wStyle ) {
+            case DRVOBJ_PEN:    {
+                                LPLOGPEN16 DeletePen = (LPLOGPEN16)lpInObj;
+
+                                fprintf(stderr, "DRVOBJ_PEN_delete\n");
+				break;
+                                }
+            case DRVOBJ_BRUSH:	{
+				fprintf(stderr, "DRVOBJ_BRUSH_delete\n");
+                                break;
+				}
+            case DRVOBJ_FONT:	{
+				LPTEXTXFORM16 TextXForm
+					= (LPTEXTXFORM16)lpTextXForm;
+				fprintf(stderr, "DRVOBJ_FONT_delete\n");
+                                break;
+				}
+            case DRVOBJ_PBITMAP:        fprintf(stderr, "DRVOBJ_PBITMAP_delete\n");
+                                break;
+	}
+    }
+    else { /* Realize given object */
+
+	switch (wStyle) {
+	    case DRVOBJ_PEN: {
+				LPLOGPEN16 InPen  = (LPLOGPEN16)lpInObj;
+
+				fprintf(stderr, "DRVOBJ_PEN\n");
+				if (lpOutObj) {
+				    if (InPen->lopnStyle == PS_NULL) {
+					*(DWORD *)lpOutObj = 0;
+					*(WORD *)(lpOutObj+4) = InPen->lopnStyle;
+				    }
+				    else
+				    if ((InPen->lopnWidth.x > 1) || (InPen->lopnStyle > PS_NULL) ) {
+					*(DWORD *)lpOutObj = InPen->lopnColor;
+					*(WORD *)(lpOutObj+4) = 0;
+				    }
+				    else {
+					*(DWORD *)lpOutObj = InPen->lopnColor & 0xffff0000;
+					*(WORD *)(lpOutObj+4) = InPen->lopnStyle;
+				    }
+				}
+				return sizeof(LOGPEN16);
+			     }
+	    case DRVOBJ_BRUSH: {
+				LPLOGBRUSH16 InBrush  = (LPLOGBRUSH16)lpInObj;
+				LPLOGBRUSH16 OutBrush = (LPLOGBRUSH16)lpOutObj;
+                                LPPOINT16 Point = (LPPOINT16)lpTextXForm;
+
+				fprintf(stderr, "DRVOBJ_BRUSH\n");
+				if (!lpOutObj) return sizeof(LOGBRUSH16);
+				else {
+				    OutBrush->lbStyle = InBrush->lbStyle;
+				    OutBrush->lbColor = InBrush->lbColor;
+				    OutBrush->lbHatch = InBrush->lbHatch;
+				    if (InBrush->lbStyle == BS_SOLID) 
+				    return 0x8002; /* FIXME: diff mono-color */
+				    else return 0x8000;
+				}
+		               }
+	    case DRVOBJ_FONT: {
+                                LPTEXTXFORM16 TextXForm
+                                        = (LPTEXTXFORM16)lpTextXForm;
+                                fprintf(stderr, "DRVOBJ_FONT\n");
+				return 0;/* DISPLAY.DRV doesn't realize fonts */
+			      }
+	    case DRVOBJ_PBITMAP:	fprintf(stderr, "DRVOBJ_PBITMAP\n");
+					return 0; /* create memory bitmap */
+	}
+    }
+    return 1;
+}
+
+
+WORD PRTDRV_GetCharWidth(LPPDEVICE lpDestDev, LPINT32 lpBuffer, 
+		      WORD wFirstChar, WORD wLastChar, LPFONTINFO16 lpFontInfo,
+		      SEGPTR lpDrawMode, SEGPTR lpTextXForm )
+{
+
+    WORD wRet = 0;
+    LOADED_PRINTER_DRIVER *pLPD = NULL;
+    
+    dprintf_win16drv(stddeb, "PRTDRV_GetCharWidth:\n");
+    
+    if ((pLPD = FindPrinterDriverFromPDEVICE(lpDestDev)) != NULL)
+    {
+	LONG		lP1, lP5, lP6, lP7;  
+	LPWORD		lP2;
+	WORD		wP3, wP4, i;
+	
+	if (pLPD->fn[FUNC_GETCHARWIDTH] == NULL)
+	{
+	    dprintf_win16drv(stddeb,
+		"PRTDRV_GetCharWidth: Not supported by driver\n");
+	    return 0;
+	}
+
+	lP1 = lpDestDev;
+	lP2 = SEGPTR_ALLOC( (wLastChar - wFirstChar + 1) * sizeof(WORD) );
+	wP3 = wFirstChar;
+	wP4 = wLastChar;
+	lP5 = SEGPTR_GET( lpFontInfo );
+        lP6 = lpDrawMode;
+        lP7 = lpTextXForm;
+	
+	wRet = Callbacks->CallDrvGetCharWidthProc(pLPD->fn[FUNC_GETCHARWIDTH], 
+                                                 lP1, SEGPTR_GET(lP2), wP3,
+                                                 wP4, lP5, lP6, lP7 );
+
+	for(i = 0; i <= wLastChar - wFirstChar; i++)
+	    lpBuffer[i] = (INT32) lP2[i];
+
+	SEGPTR_FREE(lP2);
+    }
+    return wRet;
+}
diff --git a/graphics/win16drv/text.c b/graphics/win16drv/text.c
index e4b1cc4..58d771d 100644
--- a/graphics/win16drv/text.c
+++ b/graphics/win16drv/text.c
@@ -2,6 +2,7 @@
  * win16 driver text functions
  *
  * Copyright 1996 John Harvey
+ *           1998 Huw Davies
  */
 
 #include <stdlib.h>
@@ -10,7 +11,6 @@
 #include "dc.h"
 #include "gdi.h"
 #include "stddebug.h"
-/* #define DEBUG_WIN16DRV */
 #include "debug.h"
 
 /***********************************************************************
@@ -27,32 +27,19 @@
     RECT16 	*lpOpaqueRect = NULL; 
     WORD wOptions = 0;
     WORD wCount = count;
-
-    static BOOL32 bInit = FALSE;
-    
-
+    INT16 width;
 
     if (count == 0)
       return FALSE;
 
-    dprintf_win16drv(stddeb, "WIN16DRV_ExtTextOut: %04x %d %d %x %p %*s %p\n", dc->hSelf, x, y, 
-	   flags,  lprect, count > 0 ? count : 8, str, lpDx);
+    dprintf_win16drv(stddeb, "WIN16DRV_ExtTextOut: %04x %d %d %x %p %*s %p\n",
+	   dc->hSelf, x, y, flags,  lprect, count > 0 ? count : 8, str, lpDx);
 
 
-    if (bInit == FALSE)
-    {
-	DWORD dwRet;
-
-	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
-				  NULL, " ", 
-				  -1,  physDev->segptrFontInfo, win16drv_SegPtr_DrawMode, 
-				  win16drv_SegPtr_TextXForm, NULL, NULL, 0);
-	bInit = TRUE;
-    }
-
     if (dc != NULL)   
     {
 	DWORD dwRet;
+
 	clipRect.left = 0;
 	clipRect.top = 0;
         
@@ -68,39 +55,65 @@
             
         }
         
-#ifdef NOTDEF
-    {
-        RECT16 rcPageSize;
-	FONTINFO16 *p = (FONTINFO16 *)PTR_SEG_TO_LIN(physDev->segptrFontInfo);
-        rcPageSize.left = 0;
-        rcPageSize.right = 0x3c0;
-        
-        rcPageSize.top = 0;
-        rcPageSize.bottom = 0x630;
-        
+	dprintf_win16drv(stddeb, "textalign = %d\n", dc->w.textAlign);
 
+	if (dc->w.textAlign & TA_UPDATECP)
+	{
+	    x = dc->w.CursPosX;
+	    y = dc->w.CursPosY;
+	}
 
+	x = XLPTODP( dc, x );
+	y = YLPTODP( dc, y );
 
-        if(y < rcPageSize.top  ||  y + p->dfPixHeight > rcPageSize.bottom)
-        {
-            printf("Failed 1 y %d top %d y +height %d bottom %d\n",
-                   y, rcPageSize.top  ,  y + p->dfPixHeight , rcPageSize.bottom);
-        }
-        
+	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 0, 0, 
+		 NULL, str, -count,  physDev->FontInfo, 
+		 win16drv_SegPtr_DrawMode, win16drv_SegPtr_TextXForm,
+		 NULL, NULL, 0);
 
-        if(x >= rcPageSize.right  ||
-            x + wCount * p->dfPixWidth < rcPageSize.left)
-        {
-            printf("Faile 2\n");
-        }
-        
-    }
-#endif        
+	width = LOWORD(dwRet);
 
-	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, XLPTODP(dc,x), YLPTODP(dc,y), 
-				  &clipRect, str, 
-				  wCount,  physDev->segptrFontInfo, win16drv_SegPtr_DrawMode, 
-				  win16drv_SegPtr_TextXForm, NULL, lpOpaqueRect, wOptions);
+	switch( dc->w.textAlign & (TA_LEFT | TA_RIGHT | TA_CENTER) )
+	{
+	case TA_LEFT:
+ 	    if (dc->w.textAlign & TA_UPDATECP)
+	        dc->w.CursPosX = XDPTOLP( dc, x + width );
+	    break;
+	case TA_RIGHT:
+	     x -= width;
+	     if (dc->w.textAlign & TA_UPDATECP)
+	         dc->w.CursPosX = XDPTOLP( dc, x );
+	     break;
+	case TA_CENTER:
+	    x -= width / 2;
+	    break;
+	}
+
+	switch( dc->w.textAlign & (TA_TOP | TA_BOTTOM | TA_BASELINE) )
+	{
+	case TA_TOP:
+	    break;
+	case TA_BOTTOM:
+	    y -= physDev->FontInfo->dfPixHeight;
+	    break;
+	case TA_BASELINE:
+	    y -= physDev->FontInfo->dfAscent;
+	    break;    
+	}
+
+	dwRet = PRTDRV_ExtTextOut(physDev->segptrPDEVICE, 
+	      x, y, &clipRect, str, wCount,
+	      physDev->FontInfo, win16drv_SegPtr_DrawMode, 
+	      win16drv_SegPtr_TextXForm, NULL, lpOpaqueRect, wOptions);
     }
     return bRet;
 }
+
+
+
+
+
+
+
+
+
diff --git a/graphics/wing.c b/graphics/wing.c
index f2b71dd..be3c901 100644
--- a/graphics/wing.c
+++ b/graphics/wing.c
@@ -4,8 +4,8 @@
  * Started by Robert Pouliot <krynos@clic.net>
  */
 
-#include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
+#include "ts_xlib.h"
+#include "ts_xshm.h"
 #include <sys/types.h>
 #include <sys/ipc.h>
 #ifndef __EMX__
@@ -48,10 +48,10 @@
 {
   if( __WinGOK < 0 )
   {
-    Status s = XShmQueryExtension(display);
+    Status s = TSXShmQueryExtension(display);
     if( s )
     {
-      int i = XShmPixmapFormat(display);
+      int i = TSXShmPixmapFormat(display);
       if( i == ZPixmap && screenDepth == 8 ) 
       {
         __WinGOK = True;
@@ -157,7 +157,7 @@
                         sel = SELECTOR_AllocBlock( p->si.shmaddr, bytes,
                                                    SEGMENT_DATA, FALSE, FALSE);
                         if (sel) p->bits = PTR_SEG_OFF_TO_SEGPTR(sel,0);
-			else XFreePixmap( display, bmpObjPtr->pixmap );
+			else TSXFreePixmap( display, bmpObjPtr->pixmap );
 		    }
 		    if( !sel )
 		    {
@@ -278,8 +278,8 @@
     widDest = widDest * dcDst->vportExtX / dcDst->wndExtX;
     heiDest = heiDest * dcDst->vportExtY / dcDst->wndExtY;
 
-    XSetFunction( display, dcDst->u.x.gc, GXcopy );
-    XCopyArea( display, dcSrc->u.x.drawable,
+    TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
+    TSXCopyArea( display, dcSrc->u.x.drawable,
                dcDst->u.x.drawable, dcDst->u.x.gc,
                xSrc, ySrc, widDest, heiDest, xDest, yDest );
     return TRUE;
diff --git a/graphics/x11drv/bitblt.c b/graphics/x11drv/bitblt.c
index f2f89fd..95039c3 100644
--- a/graphics/x11drv/bitblt.c
+++ b/graphics/x11drv/bitblt.c
@@ -7,7 +7,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 #include <X11/Intrinsic.h>
 #include "bitmap.h"
 #include "callback.h"
@@ -596,14 +596,14 @@
     {
         if (COLOR_PixelToPalette && (depthDst != 1))
             if (swap) for (i = 0; i < width; i++)
-                *pdata-- = COLOR_PixelToPalette[XGetPixel( image, i, row )];
+                *pdata-- = COLOR_PixelToPalette[TSXGetPixel( image, i, row )];
             else for (i = 0; i < width; i++)
-                *pdata++ = COLOR_PixelToPalette[XGetPixel( image, i, row )];
+                *pdata++ = COLOR_PixelToPalette[TSXGetPixel( image, i, row )];
         else
             if (swap) for (i = 0; i < width; i++)
-                *pdata-- = XGetPixel( image, i, row );
+                *pdata-- = TSXGetPixel( image, i, row );
             else for (i = 0; i < width; i++)
-                *pdata++ = XGetPixel( image, i, row );
+                *pdata++ = TSXGetPixel( image, i, row );
     }
     else
     {
@@ -615,16 +615,16 @@
                 bg = COLOR_PixelToPalette[bg];
             }
             if (swap) for (i = 0; i < width; i++)
-                *pdata-- = XGetPixel( image, i, row ) ? bg : fg;
+                *pdata-- = TSXGetPixel( image, i, row ) ? bg : fg;
             else for (i = 0; i < width; i++)
-                *pdata++ = XGetPixel( image, i, row ) ? bg : fg;
+                *pdata++ = TSXGetPixel( image, i, row ) ? bg : fg;
         }
         else  /* color -> monochrome */
         {
             if (swap) for (i = 0; i < width; i++)
-                *pdata-- = (XGetPixel( image, i, row ) == bg) ? 1 : 0;
+                *pdata-- = (TSXGetPixel( image, i, row ) == bg) ? 1 : 0;
             else for (i = 0; i < width; i++)
-                *pdata++ = (XGetPixel( image, i, row ) == bg) ? 1 : 0;
+                *pdata++ = (TSXGetPixel( image, i, row ) == bg) ? 1 : 0;
         }
     }
 }
@@ -720,7 +720,7 @@
             pixel = rowDst + visRectDst->right - 1;
             y = ydst - visRectDst->top;
             for (x = visRectDst->right-visRectDst->left-1; x >= 0; x--)
-                XPutPixel( dstImage, x, y, *pixel-- );
+                TSXPutPixel( dstImage, x, y, *pixel-- );
             if (mode != STRETCH_DELETESCANS)
                 memset( rowDst, (mode == STRETCH_ANDSCANS) ? 0xff : 0x00,
                         widthDst*sizeof(int) );
@@ -794,7 +794,7 @@
             pixel = rowDst + visRectDst->right - 1;
             y = (ydst >> 16) - visRectDst->top;
             for (x = visRectDst->right-visRectDst->left-1; x >= 0; x--)
-                XPutPixel( dstImage, x, y, *pixel-- );
+                TSXPutPixel( dstImage, x, y, *pixel-- );
             if (mode != STRETCH_DELETESCANS)
                 memset( rowDst, (mode == STRETCH_ANDSCANS) ? 0xff : 0x00,
                         widthDst*sizeof(int) );
@@ -831,7 +831,7 @@
     OffsetRect32( &rectDst, -xDst, -yDst );
 
     /* FIXME: avoid BadMatch errors */
-    imageSrc = XGetImage( display, dcSrc->u.x.drawable,
+    imageSrc = TSXGetImage( display, dcSrc->u.x.drawable,
                           visRectSrc->left, visRectSrc->top,
                           visRectSrc->right - visRectSrc->left,
                           visRectSrc->bottom - visRectSrc->top,
@@ -843,10 +843,10 @@
                          dcDst->w.textPixel, dcDst->w.bitsPerPixel != 1 ?
                            dcDst->w.backgroundPixel : dcSrc->w.backgroundPixel,
                          dcDst->w.stretchBltMode );
-    XPutImage( display, pixmap, gc, imageDst, 0, 0, 0, 0,
+    TSXPutImage( display, pixmap, gc, imageDst, 0, 0, 0, 0,
                rectDst.right - rectDst.left, rectDst.bottom - rectDst.top );
-    XDestroyImage( imageSrc );
-    XDestroyImage( imageDst );
+    TSXDestroyImage( imageSrc );
+    TSXDestroyImage( imageDst );
 }
 
 
@@ -869,31 +869,31 @@
         if (!COLOR_PixelToPalette ||
             (dcDst->w.bitsPerPixel == 1))  /* monochrome -> monochrome */
         {
-            XCopyArea( display, dcSrc->u.x.drawable, pixmap, gc,
+            TSXCopyArea( display, dcSrc->u.x.drawable, pixmap, gc,
                        visRectSrc->left, visRectSrc->top, width, height, 0, 0);
         }
         else  /* color -> color */
         {
             if (dcSrc->w.flags & DC_MEMORY)
-                imageSrc = XGetImage( display, dcSrc->u.x.drawable,
+                imageSrc = TSXGetImage( display, dcSrc->u.x.drawable,
                                       visRectSrc->left, visRectSrc->top,
                                       width, height, AllPlanes, ZPixmap );
             else
             {
                 /* Make sure we don't get a BadMatch error */
-                XCopyArea( display, dcSrc->u.x.drawable, pixmap, gc,
+                TSXCopyArea( display, dcSrc->u.x.drawable, pixmap, gc,
                            visRectSrc->left, visRectSrc->top,
                            width, height, 0, 0);
-                imageSrc = XGetImage( display, pixmap, 0, 0, width, height,
+                imageSrc = TSXGetImage( display, pixmap, 0, 0, width, height,
                                       AllPlanes, ZPixmap );
             }
             for (y = 0; y < height; y++)
                 for (x = 0; x < width; x++)
-                    XPutPixel(imageSrc, x, y,
-                              COLOR_PixelToPalette[XGetPixel(imageSrc, x, y)]);
-            XPutImage( display, pixmap, gc, imageSrc,
+                    TSXPutPixel(imageSrc, x, y,
+                              COLOR_PixelToPalette[TSXGetPixel(imageSrc, x, y)]);
+            TSXPutImage( display, pixmap, gc, imageSrc,
                        0, 0, 0, 0, width, height );
-            XDestroyImage( imageSrc );
+            TSXDestroyImage( imageSrc );
         }
     }
     else
@@ -902,35 +902,35 @@
         {
             if (COLOR_PixelToPalette)
             {
-                XSetBackground( display, gc, 
+                TSXSetBackground( display, gc, 
                                COLOR_PixelToPalette[dcDst->w.textPixel] );
-                XSetForeground( display, gc,
+                TSXSetForeground( display, gc,
                                COLOR_PixelToPalette[dcDst->w.backgroundPixel]);
             }
             else
             {
-                XSetBackground( display, gc, dcDst->w.textPixel );
-                XSetForeground( display, gc, dcDst->w.backgroundPixel );
+                TSXSetBackground( display, gc, dcDst->w.textPixel );
+                TSXSetForeground( display, gc, dcDst->w.backgroundPixel );
             }
-            XCopyPlane( display, dcSrc->u.x.drawable, pixmap, gc,
+            TSXCopyPlane( display, dcSrc->u.x.drawable, pixmap, gc,
                         visRectSrc->left, visRectSrc->top,
                         width, height, 0, 0, 1 );
         }
         else  /* color -> monochrome */
         {
             /* FIXME: avoid BadMatch error */
-            imageSrc = XGetImage( display, dcSrc->u.x.drawable,
+            imageSrc = TSXGetImage( display, dcSrc->u.x.drawable,
                                   visRectSrc->left, visRectSrc->top,
                                   width, height, AllPlanes, ZPixmap );
             XCREATEIMAGE( imageDst, width, height, dcDst->w.bitsPerPixel );
             for (y = 0; y < height; y++)
                 for (x = 0; x < width; x++)
-                    XPutPixel(imageDst, x, y, (XGetPixel(imageSrc,x,y) ==
+                    TSXPutPixel(imageDst, x, y, (TSXGetPixel(imageSrc,x,y) ==
                                                dcSrc->w.backgroundPixel) );
-            XPutImage( display, pixmap, gc, imageDst,
+            TSXPutImage( display, pixmap, gc, imageDst,
                        0, 0, 0, 0, width, height );
-            XDestroyImage( imageSrc );
-            XDestroyImage( imageDst );
+            TSXDestroyImage( imageSrc );
+            TSXDestroyImage( imageDst );
         }
     }
 }
@@ -950,7 +950,7 @@
     if (!COLOR_PixelToPalette || (dc->w.bitsPerPixel == 1) ||
 	(COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
     {
-        XCopyArea( display, dc->u.x.drawable, pixmap, gc,
+        TSXCopyArea( display, dc->u.x.drawable, pixmap, gc,
                    visRectDst->left, visRectDst->top, width, height, 0, 0 );
     }
     else
@@ -959,23 +959,23 @@
         XImage *image;
 
         if (dc->w.flags & DC_MEMORY)
-            image = XGetImage( display, dc->u.x.drawable,
+            image = TSXGetImage( display, dc->u.x.drawable,
                                visRectDst->left, visRectDst->top,
                                width, height, AllPlanes, ZPixmap );
         else
         {
             /* Make sure we don't get a BadMatch error */
-            XCopyArea( display, dc->u.x.drawable, pixmap, gc,
+            TSXCopyArea( display, dc->u.x.drawable, pixmap, gc,
                        visRectDst->left, visRectDst->top, width, height, 0, 0);
-            image = XGetImage( display, pixmap, 0, 0, width, height,
+            image = TSXGetImage( display, pixmap, 0, 0, width, height,
                                AllPlanes, ZPixmap );
         }
         for (y = 0; y < height; y++)
             for (x = 0; x < width; x++)
-                XPutPixel( image, x, y,
-                           COLOR_PixelToPalette[XGetPixel( image, x, y )]);
-        XPutImage( display, pixmap, gc, image, 0, 0, 0, 0, width, height );
-	XDestroyImage( image );
+                TSXPutPixel( image, x, y,
+                           COLOR_PixelToPalette[TSXGetPixel( image, x, y )]);
+        TSXPutImage( display, pixmap, gc, image, 0, 0, 0, 0, width, height );
+	TSXDestroyImage( image );
     }
 }
 
@@ -996,23 +996,23 @@
     if (!COLOR_PaletteToPixel || (dc->w.bitsPerPixel == 1) || 
         (COLOR_GetSystemPaletteFlags() & COLOR_VIRTUAL) )
     {
-        XCopyArea( display, pixmap, dc->u.x.drawable, gc, 0, 0,
+        TSXCopyArea( display, pixmap, dc->u.x.drawable, gc, 0, 0,
                    width, height, visRectDst->left, visRectDst->top );
     }
     else
     {
         register INT32 x, y;
-        XImage *image = XGetImage( display, pixmap, 0, 0, width, height,
+        XImage *image = TSXGetImage( display, pixmap, 0, 0, width, height,
                                    AllPlanes, ZPixmap );
         for (y = 0; y < height; y++)
             for (x = 0; x < width; x++)
             {
-                XPutPixel( image, x, y,
-                           COLOR_PaletteToPixel[XGetPixel( image, x, y )]);
+                TSXPutPixel( image, x, y,
+                           COLOR_PaletteToPixel[TSXGetPixel( image, x, y )]);
             }
-        XPutImage( display, dc->u.x.drawable, gc, image, 0, 0,
+        TSXPutImage( display, dc->u.x.drawable, gc, image, 0, 0,
                    visRectDst->left, visRectDst->top, width, height );
-        XDestroyImage( image );
+        TSXDestroyImage( image );
     }
 }
 
@@ -1171,14 +1171,14 @@
     {
     case BLACKNESS:  /* 0x00 */
         if ((dcDst->w.bitsPerPixel == 1) || !COLOR_PaletteToPixel)
-            XSetFunction( display, dcDst->u.x.gc, GXclear );
+            TSXSetFunction( display, dcDst->u.x.gc, GXclear );
         else
         {
-            XSetFunction( display, dcDst->u.x.gc, GXcopy );
-            XSetForeground( display, dcDst->u.x.gc, COLOR_PaletteToPixel[0] );
-            XSetFillStyle( display, dcDst->u.x.gc, FillSolid );
+            TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
+            TSXSetForeground( display, dcDst->u.x.gc, COLOR_PaletteToPixel[0] );
+            TSXSetFillStyle( display, dcDst->u.x.gc, FillSolid );
         }
-        XFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
+        TSXFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
                         visRectDst.left, visRectDst.top, width, height );
         return TRUE;
 
@@ -1186,10 +1186,10 @@
         if ((dcDst->w.bitsPerPixel == 1) || !COLOR_PaletteToPixel ||
             !Options.perfectGraphics)
         {
-            XSetFunction( display, dcDst->u.x.gc, GXinvert );
+            TSXSetFunction( display, dcDst->u.x.gc, GXinvert );
 
             if( COLOR_GetSystemPaletteFlags() & (COLOR_PRIVATE | COLOR_VIRTUAL) )
-                XSetFunction( display, dcDst->u.x.gc, GXinvert);
+                TSXSetFunction( display, dcDst->u.x.gc, GXinvert);
             else
             {
                 /* Xor is much better when we do not have full colormap.   */
@@ -1197,11 +1197,11 @@
                 /* and white. */
                 Pixel xor_pix = (WhitePixelOfScreen(screen) ^
                                  BlackPixelOfScreen(screen));
-                XSetFunction( display, dcDst->u.x.gc, GXxor );
-                XSetForeground( display, dcDst->u.x.gc, xor_pix);
-                XSetFillStyle( display, dcDst->u.x.gc, FillSolid ); 
+                TSXSetFunction( display, dcDst->u.x.gc, GXxor );
+                TSXSetForeground( display, dcDst->u.x.gc, xor_pix);
+                TSXSetFillStyle( display, dcDst->u.x.gc, FillSolid ); 
             }
-            XFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
+            TSXFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
                             visRectDst.left, visRectDst.top, width, height ); 
             return TRUE;
         }
@@ -1211,8 +1211,8 @@
 	if (Options.perfectGraphics) break;
         if (DC_SetupGCForBrush( dcDst ))
         {
-            XSetFunction( display, dcDst->u.x.gc, GXxor );
-            XFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
+            TSXSetFunction( display, dcDst->u.x.gc, GXxor );
+            TSXFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
 			    visRectDst.left, visRectDst.top, width, height );
         }
         return TRUE;
@@ -1221,8 +1221,8 @@
 	if (Options.perfectGraphics) break;
 	if (DC_SetupGCForBrush( dcDst ))
 	{
-	    XSetFunction( display, dcDst->u.x.gc, GXequiv );
-	    XFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
+	    TSXSetFunction( display, dcDst->u.x.gc, GXequiv );
+	    TSXFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
 			    visRectDst.left, visRectDst.top, width, height );
 	}
 	return TRUE;
@@ -1230,58 +1230,58 @@
     case SRCCOPY:  /* 0xcc */
         if (dcSrc->w.bitsPerPixel == dcDst->w.bitsPerPixel)
         {
-            XSetGraphicsExposures( display, dcDst->u.x.gc, True );
-            XSetFunction( display, dcDst->u.x.gc, GXcopy );
-	    XCopyArea( display, dcSrc->u.x.drawable,
+            TSXSetGraphicsExposures( display, dcDst->u.x.gc, True );
+            TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
+	    TSXCopyArea( display, dcSrc->u.x.drawable,
                        dcDst->u.x.drawable, dcDst->u.x.gc,
                        visRectSrc.left, visRectSrc.top,
                        width, height, visRectDst.left, visRectDst.top );
-            XSetGraphicsExposures( display, dcDst->u.x.gc, False );
+            TSXSetGraphicsExposures( display, dcDst->u.x.gc, False );
             return TRUE;
         }
         if (dcSrc->w.bitsPerPixel == 1)
         {
-            XSetBackground( display, dcDst->u.x.gc, dcDst->w.textPixel );
-            XSetForeground( display, dcDst->u.x.gc, dcDst->w.backgroundPixel );
-            XSetFunction( display, dcDst->u.x.gc, GXcopy );
-            XSetGraphicsExposures( display, dcDst->u.x.gc, True );
-	    XCopyPlane( display, dcSrc->u.x.drawable,
+            TSXSetBackground( display, dcDst->u.x.gc, dcDst->w.textPixel );
+            TSXSetForeground( display, dcDst->u.x.gc, dcDst->w.backgroundPixel );
+            TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
+            TSXSetGraphicsExposures( display, dcDst->u.x.gc, True );
+	    TSXCopyPlane( display, dcSrc->u.x.drawable,
                         dcDst->u.x.drawable, dcDst->u.x.gc,
                         visRectSrc.left, visRectSrc.top,
                         width, height, visRectDst.left, visRectDst.top, 1 );
-            XSetGraphicsExposures( display, dcDst->u.x.gc, False );
+            TSXSetGraphicsExposures( display, dcDst->u.x.gc, False );
             return TRUE;
         }
         break;
 
     case PATCOPY:  /* 0xf0 */
         if (!DC_SetupGCForBrush( dcDst )) return TRUE;
-        XSetFunction( display, dcDst->u.x.gc, GXcopy );
-        XFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
+        TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
+        TSXFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
                         visRectDst.left, visRectDst.top, width, height );
         return TRUE;
 
     case WHITENESS:  /* 0xff */
         if ((dcDst->w.bitsPerPixel == 1) || !COLOR_PaletteToPixel)
-            XSetFunction( display, dcDst->u.x.gc, GXset );
+            TSXSetFunction( display, dcDst->u.x.gc, GXset );
         else
         {
-            XSetFunction( display, dcDst->u.x.gc, GXcopy );
-            XSetForeground( display, dcDst->u.x.gc, 
+            TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
+            TSXSetForeground( display, dcDst->u.x.gc, 
                             COLOR_PaletteToPixel[COLOR_GetSystemPaletteSize() - 1]);
-            XSetFillStyle( display, dcDst->u.x.gc, FillSolid );
+            TSXSetFillStyle( display, dcDst->u.x.gc, FillSolid );
         }
-        XFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
+        TSXFillRectangle( display, dcDst->u.x.drawable, dcDst->u.x.gc,
                         visRectDst.left, visRectDst.top, width, height );
         return TRUE;
     }
 
-    tmpGC = XCreateGC( display, dcDst->u.x.drawable, 0, NULL );
-    pixmaps[DST] = XCreatePixmap( display, rootWindow, width, height,
+    tmpGC = TSXCreateGC( display, dcDst->u.x.drawable, 0, NULL );
+    pixmaps[DST] = TSXCreatePixmap( display, rootWindow, width, height,
                                   dcDst->w.bitsPerPixel );
     if (useSrc)
     {
-        pixmaps[SRC] = XCreatePixmap( display, rootWindow, width, height,
+        pixmaps[SRC] = TSXCreatePixmap( display, rootWindow, width, height,
                                       dcDst->w.bitsPerPixel );
         if (fStretch)
             BITBLT_GetSrcAreaStretch( dcSrc, dcDst, pixmaps[SRC], tmpGC,
@@ -1300,13 +1300,13 @@
     for (opcode = BITBLT_Opcodes[(rop >> 16) & 0xff]; *opcode; opcode++)
     {
         if (OP_DST(*opcode) == DST) destUsed = TRUE;
-        XSetFunction( display, tmpGC, OP_ROP(*opcode) );
+        TSXSetFunction( display, tmpGC, OP_ROP(*opcode) );
         switch(OP_SRCDST(*opcode))
         {
         case OP_ARGS(DST,TMP):
         case OP_ARGS(SRC,TMP):
             if (!pixmaps[TMP])
-                pixmaps[TMP] = XCreatePixmap( display, rootWindow,
+                pixmaps[TMP] = TSXCreatePixmap( display, rootWindow,
                                               width, height,
                                               dcDst->w.bitsPerPixel );
             /* fall through */
@@ -1314,32 +1314,32 @@
         case OP_ARGS(SRC,DST):
         case OP_ARGS(TMP,SRC):
         case OP_ARGS(TMP,DST):
-            XCopyArea( display, pixmaps[OP_SRC(*opcode)],
+            TSXCopyArea( display, pixmaps[OP_SRC(*opcode)],
                        pixmaps[OP_DST(*opcode)], tmpGC,
                        0, 0, width, height, 0, 0 );
             break;
 
         case OP_ARGS(PAT,TMP):
             if (!pixmaps[TMP] && !fNullBrush)
-                pixmaps[TMP] = XCreatePixmap( display, rootWindow,
+                pixmaps[TMP] = TSXCreatePixmap( display, rootWindow,
                                               width, height,
                                               dcDst->w.bitsPerPixel );
             /* fall through */
         case OP_ARGS(PAT,DST):
         case OP_ARGS(PAT,SRC):
             if (!fNullBrush)
-                XFillRectangle( display, pixmaps[OP_DST(*opcode)],
+                TSXFillRectangle( display, pixmaps[OP_DST(*opcode)],
                                 tmpGC, 0, 0, width, height );
             break;
         }
     }
-    XSetFunction( display, dcDst->u.x.gc, GXcopy );
+    TSXSetFunction( display, dcDst->u.x.gc, GXcopy );
     BITBLT_PutDstArea( dcDst, pixmaps[destUsed ? DST : SRC],
                        dcDst->u.x.gc, &visRectDst );
-    XFreePixmap( display, pixmaps[DST] );
-    if (pixmaps[SRC]) XFreePixmap( display, pixmaps[SRC] );
-    if (pixmaps[TMP]) XFreePixmap( display, pixmaps[TMP] );
-    XFreeGC( display, tmpGC );
+    TSXFreePixmap( display, pixmaps[DST] );
+    if (pixmaps[SRC]) TSXFreePixmap( display, pixmaps[SRC] );
+    if (pixmaps[TMP]) TSXFreePixmap( display, pixmaps[TMP] );
+    TSXFreeGC( display, tmpGC );
     return TRUE;
 }
 
diff --git a/graphics/x11drv/bitmap.c b/graphics/x11drv/bitmap.c
index 33bf1f6..1c3cb8b 100644
--- a/graphics/x11drv/bitmap.c
+++ b/graphics/x11drv/bitmap.c
@@ -6,8 +6,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xutil.h"
 #include "gdi.h"
 #include "callback.h"
 #include "dc.h"
@@ -27,20 +27,20 @@
     
       /* Create the necessary GCs */
     
-    if ((tmpPixmap = XCreatePixmap( display, rootWindow, 1, 1, 1 )))
+    if ((tmpPixmap = TSXCreatePixmap( display, rootWindow, 1, 1, 1 )))
     {
-	BITMAP_monoGC = XCreateGC( display, tmpPixmap, 0, NULL );
-	XSetGraphicsExposures( display, BITMAP_monoGC, False );
-	XFreePixmap( display, tmpPixmap );
+	BITMAP_monoGC = TSXCreateGC( display, tmpPixmap, 0, NULL );
+	TSXSetGraphicsExposures( display, BITMAP_monoGC, False );
+	TSXFreePixmap( display, tmpPixmap );
     }
 
     if (screenDepth != 1)
     {
-	if ((tmpPixmap = XCreatePixmap(display, rootWindow, 1,1,screenDepth)))
+	if ((tmpPixmap = TSXCreatePixmap(display, rootWindow, 1,1,screenDepth)))
 	{
-	    BITMAP_colorGC = XCreateGC( display, tmpPixmap, 0, NULL );
-	    XSetGraphicsExposures( display, BITMAP_colorGC, False );
-	    XFreePixmap( display, tmpPixmap );
+	    BITMAP_colorGC = TSXCreateGC( display, tmpPixmap, 0, NULL );
+	    TSXSetGraphicsExposures( display, BITMAP_colorGC, False );
+	    TSXFreePixmap( display, tmpPixmap );
 	}
     }
     return TRUE;
@@ -74,8 +74,8 @@
 
     if (dc->w.bitsPerPixel != bmp->bitmap.bmBitsPixel)
     {
-	XFreeGC( display, dc->u.x.gc );
-	dc->u.x.gc = XCreateGC( display, dc->u.x.drawable, 0, NULL );
+	TSXFreeGC( display, dc->u.x.gc );
+	dc->u.x.gc = TSXCreateGC( display, dc->u.x.drawable, 0, NULL );
 	dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
         DC_InitDC( dc );
     }
diff --git a/graphics/x11drv/brush.c b/graphics/x11drv/brush.c
index 5b38fa6..efb7bb1 100644
--- a/graphics/x11drv/brush.c
+++ b/graphics/x11drv/brush.c
@@ -122,15 +122,15 @@
 		int dr = ((r + d) / MATRIX_SIZE_2) / 256;
 		int dg = ((g + d) / MATRIX_SIZE_2) / 256;
 		int db = ((b + d) / MATRIX_SIZE_2) / 256;
-		XPutPixel( ditherImage, x, y, PIXEL_VALUE(dr,dg,db) );
+		TSXPutPixel( ditherImage, x, y, PIXEL_VALUE(dr,dg,db) );
 	    }
 	}
 	prevColor = color;
     }
     
-    pixmap = XCreatePixmap( display, rootWindow,
+    pixmap = TSXCreatePixmap( display, rootWindow,
 			    MATRIX_SIZE, MATRIX_SIZE, screenDepth );
-    XPutImage( display, pixmap, BITMAP_colorGC, ditherImage, 0, 0,
+    TSXPutImage( display, pixmap, BITMAP_colorGC, ditherImage, 0, 0,
 	       0, 0, MATRIX_SIZE, MATRIX_SIZE );
     return pixmap;
 }
@@ -168,16 +168,16 @@
     if ((dc->w.bitsPerPixel == 1) && (bmp->bitmap.bmBitsPixel != 1))
     {
         /* Special case: a color pattern on a monochrome DC */
-        dc->u.x.brush.pixmap = XCreatePixmap( display, rootWindow, 8, 8, 1 );
+        dc->u.x.brush.pixmap = TSXCreatePixmap( display, rootWindow, 8, 8, 1 );
         /* FIXME: should probably convert to monochrome instead */
-        XCopyPlane( display, bmp->pixmap, dc->u.x.brush.pixmap,
+        TSXCopyPlane( display, bmp->pixmap, dc->u.x.brush.pixmap,
                     BITMAP_monoGC, 0, 0, 8, 8, 0, 0, 1 );
     }
     else
     {
-        dc->u.x.brush.pixmap = XCreatePixmap( display, rootWindow,
+        dc->u.x.brush.pixmap = TSXCreatePixmap( display, rootWindow,
                                               8, 8, bmp->bitmap.bmBitsPixel );
-        XCopyArea( display, bmp->pixmap, dc->u.x.brush.pixmap,
+        TSXCopyArea( display, bmp->pixmap, dc->u.x.brush.pixmap,
                    BITMAP_GC(bmp), 0, 0, 8, 8, 0, 0 );
     }
     
@@ -234,7 +234,7 @@
 
     if (dc->u.x.brush.pixmap)
     {
-	XFreePixmap( display, dc->u.x.brush.pixmap );
+	TSXFreePixmap( display, dc->u.x.brush.pixmap );
 	dc->u.x.brush.pixmap = 0;
     }
     dc->u.x.brush.style = brush->logbrush.lbStyle;
@@ -253,7 +253,7 @@
       case BS_HATCHED:
 	dprintf_gdi( stddeb, "BS_HATCHED\n" );
 	dc->u.x.brush.pixel = COLOR_ToPhysical( dc, brush->logbrush.lbColor );
-	dc->u.x.brush.pixmap = XCreateBitmapFromData( display, rootWindow,
+	dc->u.x.brush.pixmap = TSXCreateBitmapFromData( display, rootWindow,
 				 HatchBrushes[brush->logbrush.lbHatch], 8, 8 );
 	dc->u.x.brush.fillStyle = FillStippled;
 	break;
diff --git a/graphics/x11drv/clipping.c b/graphics/x11drv/clipping.c
index d6cbc08..a778c1e 100644
--- a/graphics/x11drv/clipping.c
+++ b/graphics/x11drv/clipping.c
@@ -15,7 +15,7 @@
 /***********************************************************************
  *           X11DRV_SetDeviceClipping
  *           Copy RECT32s to a temporary buffer of XRectangles and call
- *           XSetClipRectangles().
+ *           TSXSetClipRectangles().
  *
  *           Could write using GetRegionData but this would be slower.
  */
@@ -54,7 +54,7 @@
     else
         pXrect = NULL;
 
-    XSetClipRectangles( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY, 
+    TSXSetClipRectangles( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY, 
                 pXrect, obj->rgn->numRects, YXBanded );
 
     if(pXrect)
diff --git a/graphics/x11drv/graphics.c b/graphics/x11drv/graphics.c
index af3fd94..cdb1073 100644
--- a/graphics/x11drv/graphics.c
+++ b/graphics/x11drv/graphics.c
@@ -9,8 +9,8 @@
 #include <float.h>
 #endif
 #include <stdlib.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xutil.h"
 #include <X11/Intrinsic.h>
 #ifndef PI
 #define PI M_PI
@@ -56,7 +56,7 @@
 X11DRV_LineTo( DC *dc, INT32 x, INT32 y )
 {
     if (DC_SetupGCForPen( dc ))
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, 
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, 
 		  dc->w.DCOrgX + XLPTODP( dc, dc->w.CursPosX ),
 		  dc->w.DCOrgY + YLPTODP( dc, dc->w.CursPosY ),
 		  dc->w.DCOrgX + XLPTODP( dc, x ),
@@ -109,8 +109,8 @@
 
     if ((lines > 0) && DC_SetupGCForBrush( dc ))
     {
-        XSetArcMode( display, dc->u.x.gc, (lines==1) ? ArcChord : ArcPieSlice);
-        XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+        TSXSetArcMode( display, dc->u.x.gc, (lines==1) ? ArcChord : ArcPieSlice);
+        TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
                  dc->w.DCOrgX + left, dc->w.DCOrgY + top,
                  right-left-1, bottom-top-1, istart_angle, idiff_angle );
     }
@@ -118,7 +118,7 @@
       /* Draw arc and lines */
 
     if (!DC_SetupGCForPen( dc )) return TRUE;
-    XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+    TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
 	      dc->w.DCOrgX + left, dc->w.DCOrgY + top,
 	      right-left-1, bottom-top-1, istart_angle, idiff_angle );
     if (!lines) return TRUE;
@@ -133,7 +133,7 @@
 	points[1].x = dc->w.DCOrgX + xcenter;
 	points[1].y = dc->w.DCOrgY + ycenter;
     }
-    XDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
+    TSXDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
 	        points, lines+1, CoordModeOrigin );
     return TRUE;
 }
@@ -200,11 +200,11 @@
     }
 
     if (DC_SetupGCForBrush( dc ))
-	XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+	TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
 		  dc->w.DCOrgX + left, dc->w.DCOrgY + top,
 		  right-left-1, bottom-top-1, 0, 360*64 );
     if (DC_SetupGCForPen( dc ))
-	XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+	TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
 		  dc->w.DCOrgX + left, dc->w.DCOrgY + top,
 		  right-left-1, bottom-top-1, 0, 360*64 );
     return TRUE;
@@ -229,7 +229,7 @@
     if ((left == right) || (top == bottom))
     {
 	if (DC_SetupGCForPen( dc ))
-	    XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, 
+	    TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, 
 		  dc->w.DCOrgX + left,
 		  dc->w.DCOrgY + top,
 		  dc->w.DCOrgX + right,
@@ -252,13 +252,13 @@
     if ((right > left + width) && (bottom > top + width))
     {
         if (DC_SetupGCForBrush( dc ))
-            XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
                             dc->w.DCOrgX + left + (width + 1) / 2,
                             dc->w.DCOrgY + top + (width + 1) / 2,
                             right-left-width-1, bottom-top-width-1);
     }
     if (DC_SetupGCForPen( dc ))
-	XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+	TSXDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
 		        dc->w.DCOrgX + left, dc->w.DCOrgY + top,
 		        right-left-1, bottom-top-1 );
     return TRUE;
@@ -292,34 +292,34 @@
     {
         if (ell_width && ell_height)
         {
-            XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + left, dc->w.DCOrgY + top,
                       ell_width, ell_height, 90 * 64, 90 * 64 );
-            XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + left, dc->w.DCOrgY + bottom - ell_height,
                       ell_width, ell_height, 180 * 64, 90 * 64 );
-            XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + right - ell_width,
                       dc->w.DCOrgY + bottom - ell_height,
                       ell_width, ell_height, 270 * 64, 90 * 64 );
-            XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXFillArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top,
                       ell_width, ell_height, 0, 90 * 64 );
         }
         if (ell_width < right - left)
         {
-            XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
                             dc->w.DCOrgX + left + ell_width / 2,
                             dc->w.DCOrgY + top,
                             right - left - ell_width, ell_height / 2 );
-            XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
                             dc->w.DCOrgX + left + ell_width / 2,
                             dc->w.DCOrgY + bottom - (ell_height+1) / 2,
                             right - left - ell_width, (ell_height+1) / 2 );
         }
         if  (ell_height < bottom - top)
         {
-            XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
                             dc->w.DCOrgX + left,
                             dc->w.DCOrgY + top + ell_height / 2,
                             right - left, bottom - top - ell_height );
@@ -329,28 +329,28 @@
     {
         if (ell_width && ell_height)
         {
-            XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + left, dc->w.DCOrgY + top,
                       ell_width, ell_height, 90 * 64, 90 * 64 );
-            XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + left, dc->w.DCOrgY + bottom - ell_height,
                       ell_width, ell_height, 180 * 64, 90 * 64 );
-            XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + right - ell_width,
                       dc->w.DCOrgY + bottom - ell_height,
                       ell_width, ell_height, 270 * 64, 90 * 64 );
-            XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+            TSXDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
                       dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top,
                       ell_width, ell_height, 0, 90 * 64 );
 	}
         if (ell_width < right - left)
         {
-            XDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+            TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
                        dc->w.DCOrgX + left + ell_width / 2,
                        dc->w.DCOrgY + top,
                        dc->w.DCOrgX + right - ell_width / 2,
                        dc->w.DCOrgY + top );
-            XDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+            TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
                        dc->w.DCOrgX + left + ell_width / 2,
                        dc->w.DCOrgY + bottom,
                        dc->w.DCOrgX + right - ell_width / 2,
@@ -358,12 +358,12 @@
         }
         if (ell_height < bottom - top)
         {
-            XDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+            TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
                        dc->w.DCOrgX + right,
                        dc->w.DCOrgY + top + ell_height / 2,
                        dc->w.DCOrgX + right,
                        dc->w.DCOrgY + bottom - ell_height / 2 );
-            XDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+            TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
                        dc->w.DCOrgX + left,
                        dc->w.DCOrgY + top + ell_height / 2,
                        dc->w.DCOrgX + left,
@@ -386,9 +386,9 @@
     y = dc->w.DCOrgY + YLPTODP( dc, y );
     pixel = COLOR_ToPhysical( dc, color );
     
-    XSetForeground( display, dc->u.x.gc, pixel );
-    XSetFunction( display, dc->u.x.gc, GXcopy );
-    XDrawPoint( display, dc->u.x.drawable, dc->u.x.gc, x, y );
+    TSXSetForeground( display, dc->u.x.gc, pixel );
+    TSXSetFunction( display, dc->u.x.gc, GXcopy );
+    TSXDrawPoint( display, dc->u.x.drawable, dc->u.x.gc, x, y );
 
     /* inefficient but simple... */
 
@@ -410,21 +410,21 @@
     y = dc->w.DCOrgY + YLPTODP( dc, y );
     if (dc->w.flags & DC_MEMORY)
     {
-        image = XGetImage( display, dc->u.x.drawable, x, y, 1, 1,
+        image = TSXGetImage( display, dc->u.x.drawable, x, y, 1, 1,
                            AllPlanes, ZPixmap );
     }
     else
     {
         /* If we are reading from the screen, use a temporary copy */
         /* to avoid a BadMatch error */
-        if (!pixmap) pixmap = XCreatePixmap( display, rootWindow,
+        if (!pixmap) pixmap = TSXCreatePixmap( display, rootWindow,
                                              1, 1, dc->w.bitsPerPixel );
-        XCopyArea( display, dc->u.x.drawable, pixmap, BITMAP_colorGC,
+        TSXCopyArea( display, dc->u.x.drawable, pixmap, BITMAP_colorGC,
                    x, y, 1, 1, 0, 0 );
-        image = XGetImage( display, pixmap, 0, 0, 1, 1, AllPlanes, ZPixmap );
+        image = TSXGetImage( display, pixmap, 0, 0, 1, 1, AllPlanes, ZPixmap );
     }
-    pixel = XGetPixel( image, 0, 0 );
-    XDestroyImage( image );
+    pixel = TSXGetPixel( image, 0, 0 );
+    TSXDestroyImage( image );
     
     return COLOR_ToLogical(pixel);
 }
@@ -461,7 +461,7 @@
 
     GetRgnBox32( dc->w.hGCClipRgn, &box );
     if (DC_SetupGCForBrush( dc ))
-	XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+	TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
 		        dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top,
 		        box.right-box.left, box.bottom-box.top );
 
@@ -481,7 +481,7 @@
 
     if (DC_SetupGCForPen( dc ))
 	for (i = 0; i < count-1; i ++)
-	    XDrawLine (display, dc->u.x.drawable, dc->u.x.gc,  
+	    TSXDrawLine (display, dc->u.x.drawable, dc->u.x.gc,  
 		       dc->w.DCOrgX + XLPTODP(dc, pt [i].x),
 		       dc->w.DCOrgY + YLPTODP(dc, pt [i].y),
 		       dc->w.DCOrgX + XLPTODP(dc, pt [i+1].x),
@@ -508,11 +508,11 @@
     points[count] = points[0];
 
     if (DC_SetupGCForBrush( dc ))
-	XFillPolygon( display, dc->u.x.drawable, dc->u.x.gc,
+	TSXFillPolygon( display, dc->u.x.drawable, dc->u.x.gc,
 		     points, count+1, Complex, CoordModeOrigin);
 
     if (DC_SetupGCForPen ( dc ))
-	XDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
+	TSXDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
 		   points, count+1, CoordModeOrigin );
 
     free( points );
@@ -555,7 +555,7 @@
 		pt++;
 	    }
 	    points[j] = points[0];
-	    XDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
+	    TSXDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
 		        points, j + 1, CoordModeOrigin );
 	}
 	free( points );
@@ -579,8 +579,8 @@
     int left, right;
 
 #define TO_FLOOD(x,y)  ((fillType == FLOODFILLBORDER) ? \
-                        (XGetPixel(image,x,y) != pixel) : \
-                        (XGetPixel(image,x,y) == pixel))
+                        (TSXGetPixel(image,x,y) != pixel) : \
+                        (TSXGetPixel(image,x,y) == pixel))
 
     if (!TO_FLOOD(x,y)) return;
 
@@ -589,15 +589,15 @@
     left = right = x;
     while ((left > 0) && TO_FLOOD( left-1, y )) left--;
     while ((right < image->width) && TO_FLOOD( right, y )) right++;
-    XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+    TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
                     xOrg + left, yOrg + y, right-left, 1 );
 
       /* Set the pixels of this line so we don't fill it again */
 
     for (x = left; x < right; x++)
     {
-        if (fillType == FLOODFILLBORDER) XPutPixel( image, x, y, pixel );
-        else XPutPixel( image, x, y, ~pixel );
+        if (fillType == FLOODFILLBORDER) TSXPutPixel( image, x, y, pixel );
+        else TSXPutPixel( image, x, y, ~pixel );
     }
 
       /* Fill the line above */
@@ -656,7 +656,7 @@
 
     if (GetRgnBox32( dc->w.hGCClipRgn, &rect ) == ERROR) return FALSE;
 
-    if (!(image = XGetImage( display, dc->u.x.drawable,
+    if (!(image = TSXGetImage( display, dc->u.x.drawable,
                              dc->w.DCOrgX + rect.left,
                              dc->w.DCOrgY + rect.top,
                              rect.right - rect.left,
@@ -666,7 +666,7 @@
     if (DC_SetupGCForBrush( dc ))
     {
           /* ROP mode is always GXcopy for flood-fill */
-        XSetFunction( display, dc->u.x.gc, GXcopy );
+        TSXSetFunction( display, dc->u.x.gc, GXcopy );
         X11DRV_InternalFloodFill(image, dc,
                                  XLPTODP(dc,params->x) - rect.left,
                                  YLPTODP(dc,params->y) - rect.top,
@@ -676,7 +676,7 @@
                                  params->fillType );
     }
 
-    XDestroyImage( image );
+    TSXDestroyImage( image );
     return TRUE;
 }
 
diff --git a/graphics/x11drv/init.c b/graphics/x11drv/init.c
index e415104..80ea04c 100644
--- a/graphics/x11drv/init.c
+++ b/graphics/x11drv/init.c
@@ -5,6 +5,7 @@
  */
 
 #include <string.h>
+#include "tsx11defs.h"
 #include "x11drv.h"
 #include "color.h"
 #include "bitmap.h"
@@ -108,6 +109,8 @@
  */
 BOOL32 X11DRV_Init(void)
 {
+    if (!TSX11_Init()) return FALSE;
+
     /* FIXME: colormap management should be merged with the X11DRV */
 
     if( !COLOR_Init() ) return FALSE;
@@ -173,7 +176,7 @@
         BITMAPOBJ *bmp = (BITMAPOBJ *) GDI_GetObjPtr( dc->w.hBitmap,
                                                       BITMAP_MAGIC );
         physDev->drawable  = bmp->pixmap;
-        physDev->gc        = XCreateGC( display, physDev->drawable, 0, NULL );
+        physDev->gc        = TSXCreateGC( display, physDev->drawable, 0, NULL );
         dc->w.bitsPerPixel = bmp->bitmap.bmBitsPixel;
         dc->w.hVisRgn      = CreateRectRgn32( 0, 0, bmp->bitmap.bmWidth,
                                               bmp->bitmap.bmHeight );
@@ -182,19 +185,19 @@
     else
     {
         physDev->drawable  = rootWindow;
-        physDev->gc        = XCreateGC( display, physDev->drawable, 0, NULL );
+        physDev->gc        = TSXCreateGC( display, physDev->drawable, 0, NULL );
         dc->w.bitsPerPixel = screenDepth;
         dc->w.hVisRgn      = CreateRectRgn32( 0, 0, screenWidth, screenHeight);
     }
 
     if (!dc->w.hVisRgn)
     {
-        XFreeGC( display, physDev->gc );
+        TSXFreeGC( display, physDev->gc );
         return FALSE;
     }
 
-    XSetGraphicsExposures( display, physDev->gc, False );
-    XSetSubwindowMode( display, physDev->gc, IncludeInferiors );
+    TSXSetGraphicsExposures( display, physDev->gc, False );
+    TSXSetSubwindowMode( display, physDev->gc, IncludeInferiors );
 
     return TRUE;
 }
@@ -206,7 +209,7 @@
 static BOOL32 X11DRV_DeleteDC( DC *dc )
 {
     X11DRV_PDEVICE *physDev = (X11DRV_PDEVICE *)dc->physDev;
-    XFreeGC( display, physDev->gc );
+    TSXFreeGC( display, physDev->gc );
     return TRUE;
 }
 
diff --git a/graphics/x11drv/text.c b/graphics/x11drv/text.c
index 357d8e2..cd76974 100644
--- a/graphics/x11drv/text.c
+++ b/graphics/x11drv/text.c
@@ -5,7 +5,7 @@
  */
 
 #include <stdlib.h>
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 #include <X11/Xatom.h>
 #include "windows.h"
 #include "dc.h"
@@ -94,8 +94,8 @@
 
     if (flags & ETO_OPAQUE)
     {
-        XSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel );
-        XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+        TSXSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel );
+        TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
                         dc->w.DCOrgX + rect.left, dc->w.DCOrgY + rect.top,
                         rect.right-rect.left, rect.bottom-rect.top );
     }
@@ -111,7 +111,7 @@
     }
     else
     {
-	XTextExtents( font, str, count, &dir, &ascent, &descent, &info );
+	TSXTextExtents( font, str, count, &dir, &ascent, &descent, &info );
         info.width += count*dc->w.charExtra + dc->w.breakExtra*dc->w.breakCount;
     }
 
@@ -166,8 +166,8 @@
                 (y-font->ascent < rect.top) ||
                 (y+font->descent >= rect.bottom))
             {
-                XSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel );
-                XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+                TSXSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel );
+                TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
                                 dc->w.DCOrgX + x,
                                 dc->w.DCOrgY + y - font->ascent,
                                 info.width,
@@ -178,10 +178,10 @@
     
     /* Draw the text (count > 0 verified) */
 
-    XSetForeground( display, dc->u.x.gc, dc->w.textPixel );
+    TSXSetForeground( display, dc->u.x.gc, dc->w.textPixel );
     if (!dc->w.charExtra && !dc->w.breakExtra && !lpDx)
     {
-        XDrawString( display, dc->u.x.drawable, dc->u.x.gc, 
+        TSXDrawString( display, dc->u.x.drawable, dc->u.x.gc, 
                      dc->w.DCOrgX + x, dc->w.DCOrgY + y, str, count );
     }
     else  /* Now the fun begins... */
@@ -214,7 +214,7 @@
 		do
 		{
 		    delta += (lpDx[i] * dc->vportExtX + extra) / dc->wndExtX
-					    - XTextWidth( font, str + i, 1);
+					    - TSXTextWidth( font, str + i, 1);
 		    pitem->nchars++;
 		} while ((++i < count) && !delta);
 		pitem++;
@@ -240,7 +240,7 @@
             } 
         }
 
-        XDrawText( display, dc->u.x.drawable, dc->u.x.gc,
+        TSXDrawText( display, dc->u.x.drawable, dc->u.x.gc,
                    dc->w.DCOrgX + x, dc->w.DCOrgY + y, items, pitem - items );
         HeapFree( GetProcessHeap(), 0, items );
     }
@@ -251,27 +251,27 @@
     {
 	long linePos, lineWidth;       
 
-	if (!XGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
+	if (!TSXGetFontProperty( font, XA_UNDERLINE_POSITION, &linePos ))
 	    linePos = font->descent-1;
-	if (!XGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
+	if (!TSXGetFontProperty( font, XA_UNDERLINE_THICKNESS, &lineWidth ))
 	    lineWidth = 0;
 	else if (lineWidth == 1) lineWidth = 0;
-	XSetLineAttributes( display, dc->u.x.gc, lineWidth,
+	TSXSetLineAttributes( display, dc->u.x.gc, lineWidth,
 			    LineSolid, CapRound, JoinBevel ); 
-        XDrawLine( display, dc->u.x.drawable, dc->u.x.gc,
+        TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc,
 		   dc->w.DCOrgX + x, dc->w.DCOrgY + y + linePos,
 		   dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y + linePos );
     }
     if (lfStrikeOut)
     {
 	long lineAscent, lineDescent;
-	if (!XGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
+	if (!TSXGetFontProperty( font, XA_STRIKEOUT_ASCENT, &lineAscent ))
 	    lineAscent = font->ascent / 2;
-	if (!XGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
+	if (!TSXGetFontProperty( font, XA_STRIKEOUT_DESCENT, &lineDescent ))
 	    lineDescent = -lineAscent * 2 / 3;
-	XSetLineAttributes( display, dc->u.x.gc, lineAscent + lineDescent,
+	TSXSetLineAttributes( display, dc->u.x.gc, lineAscent + lineDescent,
 			    LineSolid, CapRound, JoinBevel ); 
-	XDrawLine( display, dc->u.x.drawable, dc->u.x.gc,
+	TSXDrawLine( display, dc->u.x.drawable, dc->u.x.gc,
 		   dc->w.DCOrgX + x, dc->w.DCOrgY + y - lineAscent,
 		   dc->w.DCOrgX + x + info.width, dc->w.DCOrgY + y - lineAscent );
     }
diff --git a/graphics/x11drv/xfont.c b/graphics/x11drv/xfont.c
index be3bb66..1a99b7d 100644
--- a/graphics/x11drv/xfont.c
+++ b/graphics/x11drv/xfont.c
@@ -16,7 +16,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 #include <X11/Xatom.h>
 #include "heap.h"
 #include "options.h"
@@ -543,7 +543,7 @@
     BOOL32 bHaveCapHeight = (pFI->dfCharSet == ANSI_CHARSET && 'X' >= min && 'X' <= max );
 
     if( pEL ) *pEL = 0;
-    if( XGetFontProperty(x_fs, XA_CAP_HEIGHT, &height) == False )
+    if( TSXGetFontProperty(x_fs, XA_CAP_HEIGHT, &height) == False )
     {
 	if( x_fs->per_char )
 	    if( bHaveCapHeight )
@@ -1322,7 +1322,7 @@
 
   res = XFONT_GetPointResolution( pDevCaps );
       
-  x_pattern = XListFonts(display, "*", MAX_FONT_FAMILIES * 16, &x_count );
+  x_pattern = TSXListFonts(display, "*", MAX_FONT_FAMILIES * 16, &x_count );
 
   dprintf_font(stddeb,"Font Mapper: initializing %i fonts [LPY=%i, XDR=%i, DR=%i]\n", 
 				    x_count, pDevCaps->logPixelsY, DefResolution, res);
@@ -1433,12 +1433,12 @@
 	}
 	else lpstr = typeface;
 
-	if( (x_fs = XLoadQueryFont(display, lpstr)) )
+	if( (x_fs = TSXLoadQueryFont(display, lpstr)) )
 	{
 	   fi->df.dfHorizRes = fi->df.dfVertRes = res;
 
 	   XFONT_SetFontMetric( fi, fr, x_fs );
-           XFreeFont( display, x_fs );
+           TSXFreeFont( display, x_fs );
 
 #ifdef DEBUG_FONT_INIT
 	   dprintf_font(stddeb,"\t[% 2ipt] '%s'\n", fi->df.dfPoints, typeface );
@@ -1464,15 +1464,15 @@
   }
 
   if( fi ) HeapFree(SystemHeap, 0, fi);
-  XFreeFontNames(x_pattern);
+  TSXFreeFontNames(x_pattern);
 
   /* check if we're dealing with X11 R6 server */
 
   lstrcpy32A(buffer, "-*-*-*-*-normal-*-[12 0 0 12]-*-72-*-*-*-iso8859-1");
-  if( (x_fs = XLoadQueryFont(display, buffer)) )
+  if( (x_fs = TSXLoadQueryFont(display, buffer)) )
   {
        XTextCaps |= TC_SF_X_YINDEP;
-       XFreeFont(display, x_fs);
+       TSXFreeFont(display, x_fs);
   }
 
   XFONT_WindowsNames( buffer );
@@ -1622,8 +1622,6 @@
    }
    else if( !(pfi->fi_flags & FI_NORMAL) ) penalty++;
 
-   if( pfi->lfd_resolution != DefResolution ) penalty++;
-
    if( plf->lfWeight != FW_DONTCARE )
    {
        penalty += abs(plf->lfWeight - pfi->df.dfWeight) / 40;
@@ -1639,6 +1637,9 @@
    if( plf->lfUnderline ) pfm->flags |= FO_SYNTH_UNDERLINE;
    if( plf->lfStrikeOut ) pfm->flags |= FO_SYNTH_STRIKEOUT;
 
+   if( penalty && pfi->lfd_resolution != DefResolution ) 
+       penalty++;
+
    dprintf_font(stddeb,"-> %i\n", penalty );
 
    return penalty;
@@ -1875,7 +1876,7 @@
 	    else fontMRU = (INT16)fontCache[j].lru;
 
 	    /* FIXME: lpXForm, lpPixmap */
-	    XFreeFont( display, fontCache[j].fs );
+	    TSXFreeFont( display, fontCache[j].fs );
 
 	    memset( fontCache + j, 0, sizeof(fontObject) );
 	    return (fontCache + j);
@@ -1957,7 +1958,7 @@
 		do
 		{
 		    LFD_ComposeLFD( pfo, fm.height, lpLFD, uRelaxLevel++ );
-		    if( (pfo->fs = XLoadQueryFont( display, lpLFD )) ) break;
+		    if( (pfo->fs = TSXLoadQueryFont( display, lpLFD )) ) break;
 		} while( uRelaxLevel );
 
 		if( XFONT_GetLeading( &pfo->fi->df, pfo->fs, &i, NULL ) )
@@ -2118,6 +2119,9 @@
 }
 
 
+static char* test_string = "Abc Def Ghi Jkl Mno Pqr Stu Vwx Yz";
+
+
 /***********************************************************************
  *           X11DRV_GetTextExtentPoint
  */
@@ -2130,10 +2134,11 @@
 	int dir, ascent, descent;
 	XCharStruct info;
 
-	XTextExtents( pfs, str, count, &dir, &ascent, &descent, &info );
+	TSXTextExtents( pfs, str, count, &dir, &ascent, &descent, &info );
 	size->cx = abs((info.width + dc->w.breakRem + count * dc->w.charExtra)
 						* dc->wndExtX / dc->vportExtX);
 	size->cy = abs((pfs->ascent + pfs->descent) * dc->wndExtY / dc->vportExtY);
+
 	return TRUE;
     }
     return FALSE;
@@ -2149,6 +2154,7 @@
     {
 	fontObject* pfo = __PFONT(dc->u.x.font);
 	XFONT_GetTextMetric( pfo, metrics );
+
 	return TRUE;
     }
     return FALSE;
@@ -2187,6 +2193,7 @@
 		*buffer++ = MAX(cs->width, 0 );
 	    }
 	}
+
 	return TRUE;
     }
     return FALSE;
diff --git a/if1632/builtin.c b/if1632/builtin.c
index 7076b1e..159ddc9 100644
--- a/if1632/builtin.c
+++ b/if1632/builtin.c
@@ -361,6 +361,8 @@
         {
             if (!lstrncmpi32A( str, dll->descr->name, (int)(p - str) ))
             {
+	        if (dll->descr->name[(int)(p-str)])  /* only partial match */
+			continue;
                 if (str[-1] == '-')
                 {
                     if (dll->flags & DLL_FLAG_ALWAYS_USED) return FALSE;
diff --git a/if1632/compobj.spec b/if1632/compobj.spec
index 1969f38..55eb7e9 100644
--- a/if1632/compobj.spec
+++ b/if1632/compobj.spec
@@ -5,7 +5,7 @@
 2 pascal CoInitialize(long) CoInitialize
 3 pascal CoUninitialize() CoUnitialize
 4 pascal CoGetMalloc(long ptr) CoGetMalloc
-5 stub COREGISTERCLASSOBJECT
+5 pascal CoRegisterClassObject(ptr ptr long long ptr) CoRegisterClassObject
 6 stub COREVOKECLASSOBJECT
 7 stub COGETCLASSOBJECT
 8 stub COMARSHALINTERFACE
@@ -13,11 +13,11 @@
 10 stub COLOADLIBRARY
 11 stub COFREELIBRARY
 12 stub COFREEALLLIBRARIES
-13 stub COCREATEINSTANCE
+13 pascal CoCreateInstance(ptr ptr long ptr ptr) CoCreateInstance
 14 stub STRINGFROMIID
 15 pascal CoDisconnectObject(ptr long) CoDisconnectObject
 16 stub CORELEASEMARSHALDATA
-17 stub COFREEUNUSEDLIBRARIES
+17 pascal16 COFREEUNUSEDLIBRARIES() CoFreeUnusedLibraries
 18 pascal16 IsEqualGUID(ptr ptr) IsEqualGUID
 19 pascal StringFromCLSID(ptr ptr) StringFromCLSID
 20 pascal CLSIDFromString(str ptr) CLSIDFromString
@@ -27,11 +27,11 @@
 24 stub ISVALIDIID
 25 stub RESULTFROMSCODE
 26 stub GETSCODE
-27 stub COREGISTERMESSAGEFILTER
+27 pascal CoRegisterMessageFilter(ptr ptr) CoRegisterMessageFilter16
 28 stub COISHANDLERCONNECTED
 #29 WEP
-30 stub COFILETIMETODOSDATETIME
-31 stub CODOSDATETIMETOFILETIME
+30 pascal CoFileTimeToDosDateTime(ptr ptr ptr) FileTimeToDosDateTime
+31 pascal CoDosDateTimeToFileTime(word word ptr) DosDateTimeToFileTime
 32 stub COMARSHALHRESULT
 33 stub COUNMARSHALHRESULT
 34 stub COGETCURRENTPROCESS
@@ -61,7 +61,7 @@
 58 stub _IID_IDFRESERVED2
 59 stub _IID_IDFRESERVED3
 60 stub _IID_IMESSAGEFILTER
-61 stub CLSIDFROMPROGID
+61 pascal CLSIDFromProgID(str ptr) CLSIDFromProgID
 62 stub PROGIDFROMCLSID
 63 stub COLOCKOBJECTEXTERNAL
 64 stub _CLSID_STDMARSHAL
@@ -81,7 +81,7 @@
 79 stub CLSIDFROMOLE1CLASS
 80 stub COOPENCLASSKEY
 81 stub GUIDFROMSTRING
-82 stub COFILETIMENOW
+82 pascal CoFileTimeNow(ptr) CoFileTimeNow
 83 stub REMALLOCOID
 84 stub REMFREEOID
 85 stub REMCREATEREMOTEHANDLER
@@ -93,7 +93,7 @@
 91 stub LRPCREVOKEMONITOR
 92 stub LRPCGETTHREADWINDOW
 93 stub TIMERCALLBACKPROC
-94 stub LOOKUPETASK
+94 pascal LookupETask(ptr ptr) LookupETask
 95 stub SETETASK
 96 stub LRPCFREEMONITORDATA
 97 stub REMLOOKUPSHUNK
@@ -143,3 +143,7 @@
 160 stub CORUNMODALLOOP
 161 stub COHANDLEINCOMINGCALL
 162 stub COSETACKSTATE
+
+201 pascal CALLOBJECTINWOW(ptr ptr) CallObjectInWOW
+204 stub COMPOBJ_204
+207 stub COMPOBJ_207
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index f792059..5fafc0d 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -166,11 +166,11 @@
 196 pascal16 SetMetaFileBitsBetter(word) SetMetaFileBitsBetter
 201 stub DMBITBLT
 202 stub DMCOLORINFO
-206 stub DMENUMDFONTS
+206 pascal16 dmEnumDFonts(ptr str ptr ptr) dmEnumDFonts
 207 stub DMENUMOBJ
 208 stub DMOUTPUT
 209 stub DMPIXEL
-210 stub DMREALIZEOBJECT
+210 pascal16 dmRealizeObject(ptr word ptr ptr segptr) dmRealizeObject
 211 stub DMSTRBLT
 212 stub DMSCANLR
 213 stub BRUTE
@@ -332,21 +332,21 @@
 505 stub SetEnhMetafileBits
 506 stub SetMetaRgn
 508 stub ExtSelectClipRgn
-511 stub AbortPath
-512 stub BeginPath
-513 stub CloseFigure
-514 stub EndPath
+511 pascal16 AbortPath(word) AbortPath16
+512 pascal16 BeginPath(word) BeginPath16
+513 pascal16 CloseFigure(word) CloseFigure16
+514 pascal16 EndPath(word) EndPath16
 515 stub FillPath
 516 stub FlattenPath
-517 stub GetPath
+517 pascal16 GetPath(word ptr ptr word) GetPath16
 518 stub PathToRegion
 519 stub SelectClipPath
 520 stub StrokeAndFillPath
 521 stub StrokePath
 522 stub WidenPath
 523 stub ExtCreatePen
-524 stub GetArcDirection
-525 stub SetArcDirection
+524 pascal16 GetArcDirection(word) GetArcDirection16
+525 pascal16 SetArcDirection(word word) SetArcDirection16
 526 stub GetMiterLimit
 527 stub SetMiterLimit
 528 stub GDIParametersInfo
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 69ee55f..3c347c7 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -74,17 +74,18 @@
 74  pascal16 OpenFile(str ptr word) OpenFile16
 75  stub OpenPathName
 76  stub DeletePathName
-77 stub KERNEL_77		#RESERVED1
-78 stub KERNEL_78 		#RESERVED2
-#79 RESERVED3
-#80 RESERVED4
+# Reserved*: old Win 2.x functions now moved to USER (Win 3.0+)
+77  pascal Reserved1(segptr) AnsiNext16
+78  pascal Reserved2(segptr segptr) AnsiPrev16
+79  pascal Reserved3(segstr) AnsiUpper16
+80  pascal Reserved4(segstr) AnsiLower16
 81  pascal16 _lclose(word) _lclose16
 82  pascal16 _lread(word segptr word) WIN16_lread
 83  pascal16 _lcreat(str word) _lcreat16
 84  pascal   _llseek(word long word) _llseek16
 85  pascal16 _lopen(str word) _lopen16
 86  pascal16 _lwrite(word ptr word) _lwrite16
-87  pascal16 RESERVED5(str str) lstrcmp16
+87  pascal16 Reserved5(str str) lstrcmp16
 88  pascal   lstrcpy(segptr str) lstrcpy16
 89  pascal   lstrcat(segstr str) lstrcat16
 90  pascal16 lstrlen(str) lstrlen16
@@ -120,7 +121,7 @@
 120 stub UndefDynLink
 121 pascal16 LocalShrink(word word) LocalShrink16
 122 pascal16 IsTaskLocked() IsTaskLocked
-123 stub KbdRst
+123 return KbdRst 0 0
 124 return EnableKernel 0 0
 125 return DisableKernel 0 0
 126 stub MemoryFreed
@@ -157,7 +158,7 @@
 156 return LimitEMSPages 4 0
 157 return GetCurPID 4 0
 158 return IsWinOldApTask 2 0
-159 stub GlobalHandleNoRIP
+159 pascal GlobalHandleNoRIP(word) GlobalHandleNoRIP
 160 stub EMSCopy
 161 pascal16 LocalCountFree() LocalCountFree
 162 pascal16 LocalHeapSize() LocalHeapSize
@@ -237,10 +238,10 @@
 262 stub KERNEL_262
 263 stub KERNEL_263
 310 pascal16 LocalHandleDelta(word) LocalHandleDelta
-311 stub GetSetKernelDosProc
+311 pascal GetSetKernelDOSProc(ptr) GetSetKernelDOSProc
 314 stub DebugDefineSegment
 315 pascal16 WriteOutProfiles() WriteOutProfiles
-316 stub GetFreeMemInfo
+316 pascal GetFreeMemInfo() GetFreeMemInfo
 318 stub FatalExitHook
 319 stub FlushCachedFileHandle
 320 pascal16 IsTask(word) IsTask
@@ -251,16 +252,16 @@
 326 return IsRomFile 2 0
 327 stub KERNEL_327
 328 stub _DebugOutput
-#329 K329
+329 pascal16 K329(str word) DebugFillBuffer
 #332 stub THHOOK
 334 pascal16 IsBadReadPtr(segptr word) IsBadReadPtr16
 335 pascal16 IsBadWritePtr(segptr word) IsBadWritePtr16
 336 pascal16 IsBadCodePtr(segptr) IsBadCodePtr16
 337 pascal16 IsBadStringPtr(segptr word) IsBadStringPtr16
 338 stub HasGPHandler
-339 stub DiagQuery
-340 stub DiagOutput
-341 stub ToolHelpHook
+339 pascal16 DiagQuery() DiagQuery
+340 pascal16 DiagOutput() DiagOutput
+341 pascal ToolHelpHook(ptr) ToolHelpHook
 342 stub __GP
 343 stub RegisterWinOldApHook
 344 stub GetWinOldApHooks
diff --git a/if1632/ole2disp.spec b/if1632/ole2disp.spec
index 8b50520..7985aa2 100644
--- a/if1632/ole2disp.spec
+++ b/if1632/ole2disp.spec
@@ -31,11 +31,11 @@
 28 stub DISPGETPARAM
 29 stub DISPGETIDSOFNAMES
 30 stub DISPINVOKE
-31 stub CREATEDISPTYPEINFO
+31 pascal CreateDispTypeInfo(ptr long ptr) CreateDispTypeInfo
 32 stub CREATESTDDISPATCH
 33 stub _IID_IDISPATCH
 34 stub _IID_IENUMVARIANT
-35 stub REGISTERACTIVEOBJECT
+35 pascal RegisterActiveObject(ptr ptr long ptr) RegisterActiveObject
 36 stub REVOKEACTIVEOBJECT
 37 stub GETACTIVEOBJECT
 38 stub SAFEARRAYALLOCDESCRIPTOR
diff --git a/if1632/relay.c b/if1632/relay.c
index 6e188bb..b475753 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -34,10 +34,9 @@
       /* Allocate the code selector for CallTo16 routines */
 
     extern void CALLTO16_Start(), CALLTO16_End();
-    extern void CALLTO16_Ret_word(), CALLTO16_Ret_long(), CALLTO16_Ret_regs();
+    extern void CALLTO16_Ret_word(), CALLTO16_Ret_long();
     extern DWORD CALLTO16_RetAddr_word;
     extern DWORD CALLTO16_RetAddr_long;
-    extern DWORD CALLTO16_RetAddr_regs;
 
     codesel = GLOBAL_CreateBlock( GMEM_FIXED, (void *)CALLTO16_Start,
                                    (int)CALLTO16_End - (int)CALLTO16_Start,
@@ -50,8 +49,6 @@
                                     codesel );
     CALLTO16_RetAddr_long=MAKELONG( (int)CALLTO16_Ret_long-(int)CALLTO16_Start,
                                     codesel );
-    CALLTO16_RetAddr_regs=MAKELONG( (int)CALLTO16_Ret_regs-(int)CALLTO16_Start,
-                                    codesel );
 
     /* Create built-in modules */
     if (!BUILTIN_Init()) return FALSE;
@@ -238,12 +235,15 @@
  */
 void RELAY_DebugCallTo16( int* stack, int nb_args )
 {
+    THDB *thdb;
+
     if (!debugging_relay) return;
+    thdb = THREAD_Current();
 
     if (nb_args == -1)  /* Register function */
     {
         CONTEXT *context = (CONTEXT *)stack[0];
-        WORD *stack16 = (WORD *)CURRENT_STACK16;
+        WORD *stack16 = (WORD *)THREAD_STACK16(thdb);
         printf( "CallTo16(func=%04lx:%04x,ds=%04lx",
                 CS_reg(context), IP_reg(context), DS_reg(context) );
         nb_args = stack[1] / sizeof(WORD);
@@ -258,7 +258,7 @@
     {
         printf( "CallTo16(func=%04x:%04x,ds=%04x",
                 HIWORD(stack[0]), LOWORD(stack[0]),
-                SELECTOROF(IF1632_Saved16_ss_sp) );
+                SELECTOROF(thdb->cur_stack) );
         stack++;
         while (nb_args--) printf( ",0x%04x", *stack++ );
         printf( ")\n" );
@@ -277,7 +277,6 @@
     VA_LIST16 valist;
     SEGPTR buf;
     LPCATCHBUF lpbuf;
-    STACK16FRAME *pFrame = CURRENT_STACK16;
 
     VA_START16( valist );
     buf   = VA_ARG16( valist, SEGPTR );
@@ -302,13 +301,13 @@
 
     lpbuf[0] = IP_reg(context);
     lpbuf[1] = CS_reg(context);
-    lpbuf[2] = LOWORD(pFrame->frame32);
+    lpbuf[2] = SP_reg(context);
     lpbuf[3] = BP_reg(context);
     lpbuf[4] = SI_reg(context);
     lpbuf[5] = DI_reg(context);
     lpbuf[6] = DS_reg(context);
-    lpbuf[7] = OFFSETOF(IF1632_Saved16_ss_sp);
-    lpbuf[8] = HIWORD(pFrame->frame32);
+    lpbuf[7] = 0;
+    lpbuf[8] = SS_reg(context);
     AX_reg(context) = 0;  /* Return 0 */
 }
 
@@ -325,6 +324,8 @@
     SEGPTR buf;
     LPCATCHBUF lpbuf;
     STACK16FRAME *pFrame;
+    STACK32FRAME *frame32;
+    THDB *thdb = THREAD_Current();
 
     VA_START16( valist );
     AX_reg(context) = VA_ARG16( valist, WORD );  /* retval */
@@ -332,10 +333,17 @@
     lpbuf  = (LPCATCHBUF)PTR_SEG_TO_LIN( buf );
     VA_END16( valist );
 
-    IF1632_Saved16_ss_sp = MAKELONG( lpbuf[7] - sizeof(WORD),
-                                     HIWORD(IF1632_Saved16_ss_sp) );
-    pFrame = CURRENT_STACK16;
-    pFrame->frame32 = MAKELONG( lpbuf[2], lpbuf[8] );
+    /* Find the frame32 corresponding to the frame16 we are jumping to */
+    frame32 = THREAD_STACK16( thdb )->frame32;
+    while (frame32 && frame32->frame16)
+    {
+        if (OFFSETOF(frame32->frame16) > lpbuf[2]) break;
+        frame32 = ((STACK16FRAME *)PTR_SEG_TO_LIN(frame32->frame16))->frame32;
+    }
+
+    thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( lpbuf[8], lpbuf[2]-sizeof(WORD) );
+    pFrame = THREAD_STACK16( thdb );
+    pFrame->frame32 = frame32;
     IP_reg(context) = lpbuf[0];
     CS_reg(context) = lpbuf[1];
     BP_reg(context) = lpbuf[3];
@@ -373,7 +381,7 @@
         nrofargs    = VA_ARG16( valist, DWORD );
         argconvmask = VA_ARG16( valist, DWORD );
         proc32      = VA_ARG16( valist, FARPROC32 );
-	fprintf(stderr,"CallProc32W(%ld,%ld,%p, Ex%d args[",nrofargs,argconvmask,proc32,Ex);
+	dprintf_relay(stddeb,"CallProc32W(%ld,%ld,%p, Ex%d args[",nrofargs,argconvmask,proc32,Ex);
 	args = (DWORD*)HEAP_xalloc( GetProcessHeap(), 0,
                                     sizeof(DWORD)*nrofargs );
 	for (i=0;i<nrofargs;i++) {
@@ -381,15 +389,15 @@
                 {
                     SEGPTR ptr = VA_ARG16( valist, SEGPTR );
                     args[nrofargs-i-1] = (DWORD)PTR_SEG_TO_LIN(ptr);
-                    fprintf(stderr,"%08lx(%p),",ptr,PTR_SEG_TO_LIN(ptr));
+                    dprintf_relay(stddeb,"%08lx(%p),",ptr,PTR_SEG_TO_LIN(ptr));
 		}
                 else
                 {
                     args[nrofargs-i-1] = VA_ARG16( valist, DWORD );
-                    fprintf(stderr,"%ld,",args[nrofargs-i-1]);
+                    dprintf_relay(stddeb,"%ld,",args[nrofargs-i-1]);
 		}
 	}
-	fprintf(stderr,"]) - ");
+	dprintf_relay(stddeb,"]) - ");
         VA_END16( valist );
 
 	switch (nrofargs) {
@@ -424,9 +432,10 @@
 		break;
 	}
 	/* POP nrofargs DWORD arguments and 3 DWORD parameters */
-        if (!Ex) STACK16_POP( (3 + nrofargs) * sizeof(DWORD) );
+        if (!Ex) STACK16_POP( THREAD_Current(),
+                              (3 + nrofargs) * sizeof(DWORD) );
 
-	fprintf(stderr,"returns %08lx\n",ret);
+	dprintf_relay(stddeb,"returns %08lx\n",ret);
 	HeapFree( GetProcessHeap(), 0, args );
 	return ret;
 }
diff --git a/if1632/thunk.c b/if1632/thunk.c
index 88b0281..9cf9bcf4 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -29,35 +29,73 @@
 extern LONG CALLBACK CallTo16_sreg_(const CONTEXT *context, INT32 offset);
 extern LONG CALLBACK CallTo16_lreg_(const CONTEXT *context, INT32 offset);
 extern WORD CALLBACK CallTo16_word_     (FARPROC16);
+extern LONG CALLBACK CallTo16_long_     (FARPROC16);
 extern WORD CALLBACK CallTo16_word_w    (FARPROC16,WORD);
 extern LONG CALLBACK CallTo16_long_l    (FARPROC16,LONG);
 extern WORD CALLBACK CallTo16_word_ww   (FARPROC16,WORD,WORD);
 extern WORD CALLBACK CallTo16_word_wl   (FARPROC16,WORD,LONG);
 extern WORD CALLBACK CallTo16_word_ll   (FARPROC16,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_ll   (FARPROC16,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_www  (FARPROC16,WORD,WORD,WORD);
 extern WORD CALLBACK CallTo16_word_wwl  (FARPROC16,WORD,WORD,LONG);
 extern WORD CALLBACK CallTo16_word_wlw  (FARPROC16,WORD,LONG,WORD);
 extern LONG CALLBACK CallTo16_long_wwl  (FARPROC16,WORD,WORD,LONG);
+extern LONG CALLBACK CallTo16_long_lll  (FARPROC16,LONG,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_llwl (FARPROC16,LONG,LONG,WORD,LONG);
 extern WORD CALLBACK CallTo16_word_lwll (FARPROC16,LONG,WORD,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_lwww (FARPROC16,LONG,WORD,WORD,WORD);
 extern WORD CALLBACK CallTo16_word_wwll (FARPROC16,WORD,WORD,LONG,LONG);
+extern WORD CALLBACK CallTo16_word_llll (FARPROC16,LONG,LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_llll (FARPROC16,LONG,LONG,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_wllwl(FARPROC16,WORD,LONG,LONG,WORD,LONG);
 extern LONG CALLBACK CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_wwlll(FARPROC16,WORD,WORD,LONG,LONG,LONG);
 extern WORD CALLBACK CallTo16_word_wwwww(FARPROC16,WORD,WORD,WORD,WORD,WORD);
 extern WORD CALLBACK CallTo16_word_lwlll(FARPROC16,LONG,WORD,LONG,LONG,LONG);
-extern WORD CALLBACK CallTo16_word_llll (FARPROC16,LONG,LONG,LONG,LONG);
 extern LONG CALLBACK CallTo16_long_lwlll(FARPROC16,LONG,WORD,LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_lllll(FARPROC16,LONG,LONG,LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_llllll(FARPROC16,LONG,LONG,LONG,LONG,LONG,
+                                          LONG);
+extern LONG CALLBACK CallTo16_long_lllllll(FARPROC16,LONG,LONG,LONG,LONG,LONG,
+                                           LONG,LONG);
+extern WORD CALLBACK CallTo16_word_llwwlll(FARPROC16,LONG,LONG,WORD,WORD,LONG,
+                                           LONG,LONG);
 extern LONG CALLBACK CallTo16_word_lwwlllll(FARPROC16,LONG,WORD,WORD,LONG,LONG,
-                                            LONG,LONG,WORD);
+                                            LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_llllllll(FARPROC16,LONG,LONG,LONG,LONG,LONG,
+                                            LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_lllllllll(FARPROC16,LONG,LONG,LONG,LONG,
+                                             LONG,LONG,LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_llllllllll(FARPROC16,LONG,LONG,LONG,LONG,
+                                              LONG,LONG,LONG,LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_lllllllllll(FARPROC16,LONG,LONG,LONG,LONG,
+                                               LONG,LONG,LONG,LONG,LONG,LONG,
+                                               LONG);
+extern LONG CALLBACK CallTo16_long_llllllllllll(FARPROC16,LONG,LONG,LONG,LONG,
+                                                LONG,LONG,LONG,LONG,LONG,LONG,
+                                                LONG,LONG);
 extern LONG CALLBACK CallTo16_long_lwwllwlllllw(FARPROC16,LONG,WORD,WORD,LONG,
                                                 LONG,WORD,LONG,LONG,LONG,LONG,
                                                 LONG,WORD);
+extern LONG CALLBACK CallTo16_long_lllllllllllll(FARPROC16,LONG,LONG,LONG,LONG,
+                                                 LONG,LONG,LONG,LONG,LONG,LONG,
+                                                 LONG,LONG,LONG);
+extern LONG CALLBACK CallTo16_long_llllllllllllll(FARPROC16,LONG,LONG,LONG,
+                                                  LONG,LONG,LONG,LONG,LONG,
+                                                  LONG,LONG,LONG,LONG,LONG,
+                                                  LONG);
 extern LONG CALLBACK CallTo16_word_lwwwwlwwwwllll(FARPROC16,LONG,WORD,WORD,
                                                   WORD,WORD,LONG,WORD,WORD,
                                                   WORD,WORD,LONG,LONG,LONG,
                                                   LONG);
+extern LONG CALLBACK CallTo16_long_lllllllllllllll(FARPROC16,LONG,LONG,LONG,
+                                                   LONG,LONG,LONG,LONG,LONG,
+                                                   LONG,LONG,LONG,LONG,LONG,
+                                                   LONG,LONG);
+extern LONG CALLBACK CallTo16_long_llllllllllllllll(FARPROC16,LONG,LONG,LONG,
+                                                    LONG,LONG,LONG,LONG,LONG,
+                                                    LONG,LONG,LONG,LONG,LONG,
+                                                    LONG,LONG,LONG);
 /* ### stop build ### */
 
 
@@ -89,6 +127,8 @@
                                            UINT16 msg, WPARAM16 wParam,
                                            LPARAM lParam );
 static void WINAPI THUNK_CallTaskReschedule(void);
+static BOOL32 WINAPI THUNK_WOWCallback16Ex( FARPROC16,DWORD,DWORD,
+                                            LPVOID,LPDWORD );
 
 /* TASK_Reschedule() 16-bit entry point */
 static FARPROC16 TASK_RescheduleProc;
@@ -112,6 +152,7 @@
     (void *)CallTo16_word_www,             /* CallLoadAppSegProc */
     (void *)CallTo16_word_,                /* CallSystemTimerProc */
     (void *)CallTo16_long_l,               /* CallWOWCallbackProc */
+    THUNK_WOWCallback16Ex,                 /* CallWOWCallback16Ex */
     (void *)CallTo16_long_l,               /* CallASPIPostProc */
     (void *)CallTo16_word_lwll,            /* CallDrvControlProc */
     (void *)CallTo16_word_lwlll,           /* CallDrvEnableProc */
@@ -120,7 +161,8 @@
     (void *)CallTo16_word_lwwlllll,        /* CallDrvOutputProc */
     (void *)CallTo16_long_lwlll,           /* CallDrvRealizeProc */
     (void *)CallTo16_word_lwwwwlwwwwllll,  /* CallDrvStretchBltProc */
-    (void *)CallTo16_long_lwwllwlllllw     /* CallDrvExtTextOutProc */
+    (void *)CallTo16_long_lwwllwlllllw,    /* CallDrvExtTextOutProc */
+    (void *)CallTo16_word_llwwlll          /* CallDrvGetCharWidth */ 
 };
 
 
@@ -203,15 +245,16 @@
     WORD *args;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     DWORD offset = 0;
+    THDB *thdb = THREAD_Current();
 
     /* Window procedures want ax = hInstance, ds = es = ss */
 
-    DS_reg(&context)  = SELECTOROF(IF1632_Saved16_ss_sp);
+    DS_reg(&context)  = SELECTOROF(thdb->cur_stack);
     ES_reg(&context)  = DS_reg(&context);
     EAX_reg(&context) = wndPtr ? wndPtr->hInstance : DS_reg(&context);
     CS_reg(&context)  = SELECTOROF(proc);
     EIP_reg(&context) = OFFSETOF(proc);
-    EBP_reg(&context) = OFFSETOF(IF1632_Saved16_ss_sp)
+    EBP_reg(&context) = OFFSETOF(thdb->cur_stack)
                         + (WORD)&((STACK16FRAME*)0)->bp;
 
     if (lParam)
@@ -235,12 +278,12 @@
 	if (offset)
 	{
 	    void *s = PTR_SEG_TO_LIN(lParam);
-	    lParam = STACK16_PUSH( offset );
+	    lParam = STACK16_PUSH( thdb, offset );
 	    memcpy( PTR_SEG_TO_LIN(lParam), s, offset );
 	}
     }
 
-    args = (WORD *)CURRENT_STACK16 - 5;
+    args = (WORD *)THREAD_STACK16(thdb) - 5;
     args[0] = LOWORD(lParam);
     args[1] = HIWORD(lParam);
     args[2] = wParam;
@@ -248,7 +291,7 @@
     args[4] = hwnd;
 
     ret = CallTo16_sreg_( &context, 5 * sizeof(WORD) );
-    if (offset) STACK16_POP(offset);
+    if (offset) STACK16_POP( thdb, offset );
     return ret;
 }
 
@@ -573,3 +616,94 @@
     }
     return NULL;
 }
+
+/***********************************************************************
+ *           THUNK_WOWCallback16Ex	(WOW32.3)(KERNEL32.55)
+ */
+static BOOL32 WINAPI THUNK_WOWCallback16Ex(
+	FARPROC16 proc,DWORD dwFlags,DWORD cbArgs,LPVOID xargs,LPDWORD pdwret
+) {
+    LPDWORD     args = (LPDWORD)xargs;
+    DWORD       ret,i;
+
+    dprintf_relay(stddeb,"WOWCallback16Ex(%p,0x%08lx,%ld,%p,%p)\n",
+    	proc,dwFlags,cbArgs,xargs,pdwret
+    );
+    if (dwFlags == WCB16_CDECL) {
+	/* swap the arguments */
+	args = HeapAlloc(GetProcessHeap(),0,cbArgs*sizeof(DWORD));
+	for (i=0;i<cbArgs;i++)
+	    args[i] = ((DWORD*)xargs)[cbArgs-i-1];
+    }
+    switch (cbArgs) {
+    case 0: ret = CallTo16_long_(proc);break;
+    case 1: ret = CallTo16_long_l(proc,args[0]);break;
+    case 2: ret = CallTo16_long_ll(proc,args[0],args[1]);break;
+    case 3: ret = CallTo16_long_lll(proc,args[0],args[1],args[2]);break;
+    case 4: ret = CallTo16_long_llll(proc,args[0],args[1],args[2],args[3]);
+	    break;
+    case 5: ret = CallTo16_long_lllll(proc,args[0],args[1],args[2],args[3],
+		args[4]
+	    );
+	    break;
+    case 6: ret = CallTo16_long_llllll(proc,args[0],args[1],args[2],args[3],
+		args[4],args[5]
+	    );
+	    break;
+    case 7: ret = CallTo16_long_lllllll(proc,args[0],args[1],args[2],args[3],
+		args[4],args[5],args[6]
+	    );
+	    break;
+    case 8: ret = CallTo16_long_llllllll(proc,args[0],args[1],args[2],args[3],
+  		args[4],args[5],args[6],args[7]
+	    );
+	    break;
+    case 9: ret = CallTo16_long_lllllllll(proc,args[0],args[1],args[2],args[3],
+    		args[4],args[5],args[6],args[7],args[8]
+	    );
+	    break;
+    case 10:ret = CallTo16_long_llllllllll(proc,args[0],args[1],args[2],args[3],
+    		args[4],args[5],args[6],args[7],args[8],args[9]
+	    );
+	    break;
+    case 11:ret = CallTo16_long_lllllllllll(proc,args[0],args[1],args[2],
+    		args[3],args[4],args[5],args[6],args[7],args[8],args[9],args[10]
+	    );
+	    break;
+    case 12:ret = CallTo16_long_llllllllllll(proc,args[0],args[1],args[2],
+    		args[3],args[4],args[5],args[6],args[7],args[8],args[9],
+		args[10],args[11]
+	    );
+	    break;
+    case 13:ret = CallTo16_long_lllllllllllll(proc,args[0],args[1],args[2],
+    		args[3],args[4],args[5],args[6],args[7],args[8],args[9],
+		args[10],args[11],args[12]
+	    );
+	    break;
+    case 14:ret = CallTo16_long_llllllllllllll(proc,args[0],args[1],args[2],
+    		args[3],args[4],args[5],args[6],args[7],args[8],args[9],
+		args[10],args[11],args[12],args[13]
+	    );
+	    break;
+    case 15:ret = CallTo16_long_lllllllllllllll(proc,args[0],args[1],args[2],
+    		args[3],args[4],args[5],args[6],args[7],args[8],args[9],
+		args[10],args[11],args[12],args[13],args[14]
+	    );
+	    break;
+    case 16:ret = CallTo16_long_llllllllllllllll(proc,args[0],args[1],args[2],
+    		args[3],args[4],args[5],args[6],args[7],args[8],args[9],
+		args[10],args[11],args[12],args[13],args[14],args[15]
+	    );
+	    break;
+    default:
+	    fprintf(stderr,"CALLBACK_CallWOWCallback16Ex(), %ld arguments not supported.!n",cbArgs);
+	    if (dwFlags == WCB16_CDECL)
+		HeapFree(GetProcessHeap(),0,args);
+	    return FALSE;
+    }
+    if (dwFlags == WCB16_CDECL)
+    	HeapFree(GetProcessHeap(),0,args);
+    if (pdwret) 
+    	*pdwret = ret;
+    return TRUE;
+}
diff --git a/if1632/user.spec b/if1632/user.spec
index 814a19f..33d8c3c 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -306,15 +306,25 @@
 #306 BEAR306
 308 pascal   DefDlgProc(word word word long) DefDlgProc16
 309 pascal16 GetClipCursor(ptr) GetClipCursor16
+#310 ContScroll
+#312 SendMessage2
+#313 PostMessage2
 314 pascal16 SignalProc(word word word word word) USER_SignalProc
+#315 XCStoDS
+#316 CompUpdateRect
+#317 CompUpdateRgn
+#318 GetWC2
 319 pascal16 ScrollWindowEx(word s_word s_word ptr ptr word ptr word) ScrollWindowEx16
 320 stub SysErrorBox
-321 stub SetEventHook
+321 pascal   SetEventHook(segptr) SetEventHook
 322 stub WinOldAppHackOMatic
 323 stub GetMessage2
 324 pascal16 FillWindow(word word word word) FillWindow
 325 pascal16 PaintRect(word word word word ptr) PaintRect
 326 pascal16 GetControlBrush(word word word) GetControlBrush
+#327 KillTimer2
+#328 SetTimer2
+#330 SetGetKbdState
 331 pascal16 EnableHardwareInput(word) EnableHardwareInput
 332 pascal16 UserYield() UserYield
 333 pascal16 IsUserIdle() IsUserIdle
@@ -322,8 +332,11 @@
 335 pascal16 GetInputState() GetInputState16
 336 pascal16 LoadCursorIconHandler(word word word) LoadCursorIconHandler
 337 pascal   GetMouseEventProc() GetMouseEventProc
+#340 WinFarFrame
 #341 _FFFE_FARFRAME
 343 stub GetFilePortName
+#354 TabTheTextOutForWimps
+#355 BroadcastMessage
 356 pascal16 LoadDIBCursorHandler(word word word) LoadDIBCursorHandler
 357 pascal16 LoadDIBIconHandler(word word word) LoadDIBIconHandler
 358 pascal16 IsMenu(word) IsMenu16
diff --git a/if1632/win32s16.spec b/if1632/win32s16.spec
index a82aff2..468b56e 100644
--- a/if1632/win32s16.spec
+++ b/if1632/win32s16.spec
@@ -43,7 +43,7 @@
 40 stub RMEMCPY
 41 stub INITRESLOADER
 42 stub FREESELECTOROFFSET
-43 stub STACKLINEARTOSEGMENTED
+43 pascal StackLinearToSegmented(word word) StackLinearToSegmented
 44 stub GETMODULEFILENAME32S
 45 stub FAPILOG16
 46 stub ALLOCCALLBACK
@@ -56,3 +56,4 @@
 53 stub FINDGLOBALHANDLE
 
 #54-289 exist, but function names blanked out
+143 equate win32s16_143  0x100
diff --git a/if1632/winaspi.spec b/if1632/winaspi.spec
index 9474b71..ab2d77b 100644
--- a/if1632/winaspi.spec
+++ b/if1632/winaspi.spec
@@ -3,5 +3,6 @@
 
 1	pascal16 GetASPISupportInfo() GetASPISupportInfo16
 2	pascal16 SendASPICommand(segptr) SendASPICommand16
-#3	stub GETASPIDLLVERSION
-#3	stub INSERTINASPICHAIN
+3       stub INSERTINASPICHAIN
+4	pascal GETASPIDLLVERSION() GetASPIDLLVersion
+5	stub ___EXPORTEDSTUB
diff --git a/if1632/windebug.spec b/if1632/windebug.spec
index 7b4fb6b..437068f 100644
--- a/if1632/windebug.spec
+++ b/if1632/windebug.spec
@@ -3,4 +3,4 @@
 
   1 stub     WINDEBUG
   2 stub     WEP
-  3 pascal   WinNotify() WinNotify
+  3 register WinNotify() WinNotify
diff --git a/if1632/wprocs.spec b/if1632/wprocs.spec
index 61ce5f3..ee24229 100644
--- a/if1632/wprocs.spec
+++ b/if1632/wprocs.spec
@@ -48,7 +48,7 @@
 129 register INT_Int1dHandler(word) BUILTIN_DefaultIntHandler
 130 register INT_Int1eHandler(word) BUILTIN_DefaultIntHandler
 131 register INT_Int1fHandler(word) BUILTIN_DefaultIntHandler
-132 register INT_Int20Handler(word) BUILTIN_DefaultIntHandler
+132 register INT_Int20Handler(word) INT_Int20Handler
 133 register INT_Int21Handler(word) DOS3Call
 134 register INT_Int22Handler(word) BUILTIN_DefaultIntHandler
 135 register INT_Int23Handler(word) BUILTIN_DefaultIntHandler
diff --git a/include/bitmap.h b/include/bitmap.h
index ae02e76..3690de2 100644
--- a/include/bitmap.h
+++ b/include/bitmap.h
@@ -12,7 +12,7 @@
 
 #ifdef PRELIMINARY_WING16_SUPPORT
 /* FIXME: this doesn't belong here */
-#include <X11/extensions/XShm.h>
+#include "ts_xshm.h"
 
 typedef struct
 {
@@ -38,12 +38,13 @@
   (((bmp)->bitmap.bmBitsPixel == 1) ? BITMAP_monoGC : BITMAP_colorGC)
 
 #define BITMAP_WIDTH_BYTES(width,bpp) \
-    (((bpp) == 24) ? (width) * 4 : ((width) * (bpp) + 15) / 16 * 2)
+    (((bpp) == 24) ? (width) * 4 : ( ((bpp) == 15) ? (width) * 2 : \
+				    ((width) * (bpp) + 15) / 16 * 2 ))
 
 #define XCREATEIMAGE(image,width,height,bpp) \
 { \
     int width_bytes = DIB_GetXImageWidthBytes( (width), (bpp) ); \
-    (image) = XCreateImage(display, DefaultVisualOfScreen(screen), \
+    (image) = TSXCreateImage(display, DefaultVisualOfScreen(screen), \
                            (bpp), ZPixmap, 0, xmalloc( (height)*width_bytes ),\
                            (width), (height), 32, width_bytes ); \
 }
diff --git a/include/callback.h b/include/callback.h
index c02abcc..a8668a3 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -38,6 +38,8 @@
     WORD (CALLBACK *CallLoadAppSegProc)( FARPROC16, HANDLE16, HFILE16, WORD );
     VOID (CALLBACK *CallSystemTimerProc)( FARPROC16 );
     DWORD (CALLBACK *CallWOWCallbackProc)( FARPROC16, DWORD );
+    BOOL32 (CALLBACK *CallWOWCallback16Ex)( FARPROC16, DWORD, DWORD, LPVOID, 
+                                            LPDWORD );
     LRESULT (CALLBACK *CallASPIPostProc)( FARPROC16, SEGPTR );
     /* Following are the graphics driver callbacks */
     WORD (CALLBACK *CallDrvControlProc)( FARPROC16, SEGPTR, WORD,
@@ -60,6 +62,8 @@
                                              SEGPTR, SEGPTR, INT16, SEGPTR,
                                              SEGPTR, SEGPTR, SEGPTR, SEGPTR,
                                              WORD );
+    WORD (CALLBACK *CallDrvGetCharWidthProc)( FARPROC16, SEGPTR, SEGPTR, WORD,
+					      WORD, SEGPTR, SEGPTR, SEGPTR );
 } CALLBACKS_TABLE;
 
 extern const CALLBACKS_TABLE *Callbacks;
diff --git a/include/commdlg.h b/include/commdlg.h
index 4f6e78e..f33a3ad 100644
--- a/include/commdlg.h
+++ b/include/commdlg.h
@@ -29,6 +29,14 @@
 #define OFN_NOREADONLYRETURN         0x00008000
 #define OFN_NOTESTFILECREATE         0x00010000
 
+/*      OFN_?                        0x00020000 */
+
+#define OFN_NOLONGNAMES              0x00040000
+#define OFN_EXPLORER                 0x00080000
+#define OFN_NODEREFERENCELINKS       0x00100000
+#define OFN_LONGNAMES                0x00200000
+
+/* WINE internal flags */
 #define OFN_UNICODE		     0x40000000	/*to differ between 32W/A hook*/
 #define OFN_WINE32		     0x80000000	/* comdlg32 */
 
diff --git a/include/compobj.h b/include/compobj.h
index 6f2289f..9b74eda 100644
--- a/include/compobj.h
+++ b/include/compobj.h
@@ -11,7 +11,7 @@
     BYTE  Data4[8];
 };
 
-typedef struct tagGUID	GUID,*LPGUID;
+typedef struct tagGUID	GUID,*LPGUID,*REFGUID;
 typedef struct tagGUID	CLSID,*LPCLSID,*REFCLSID;
 typedef struct tagGUID	IID,*REFIID,*LPIID;
 
diff --git a/include/cursoricon.h b/include/cursoricon.h
index 691487e..5a9312a 100644
--- a/include/cursoricon.h
+++ b/include/cursoricon.h
@@ -7,7 +7,7 @@
 #ifndef __WINE_CURSORICON_H
 #define __WINE_CURSORICON_H
 
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 #include "windows.h"
 
 #pragma pack(1)
diff --git a/include/d3d.h b/include/d3d.h
new file mode 100644
index 0000000..bf10f3c
--- /dev/null
+++ b/include/d3d.h
@@ -0,0 +1,418 @@
+#ifndef _WINE_D3D_H
+#define _WINE_D3D_H
+
+typedef LPVOID LPDIRECT3DMATERIAL,LPDIRECT3DVIEWPORT;
+typedef LPVOID LPDIRECT3DMATERIAL2,LPDIRECT3DVIEWPORT2;
+typedef LPVOID LPDIRECT3DDEVICE2;
+
+DEFINE_GUID(IID_IDirect3D,		0x3BBA0080,0x2421,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56 );
+DEFINE_GUID(IID_IDirect3D2,		0x6aae1ec1,0x662a,0x11d0,0x88,0x9d,0x00,0xaa,0x00,0xbb,0xb7,0x6a);
+
+DEFINE_GUID(IID_IDirect3DRampDevice,	0xF2086B20,0x259F,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56 );
+DEFINE_GUID(IID_IDirect3DRGBDevice,	0xA4665C60,0x2673,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56 );
+DEFINE_GUID(IID_IDirect3DHALDevice,	0x84E63dE0,0x46AA,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E );
+DEFINE_GUID(IID_IDirect3DMMXDevice,	0x881949a1,0xd6f3,0x11d0,0x89,0xab,0x00,0xa0,0xc9,0x05,0x41,0x29 );
+
+DEFINE_GUID(IID_IDirect3DDevice,	0x64108800,0x957d,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29 );
+DEFINE_GUID(IID_IDirect3DDevice2,	0x93281501,0x8CF8,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29);
+DEFINE_GUID(IID_IDirect3DTexture,	0x2CDCD9E0,0x25A0,0x11CF,0xA3,0x1A,0x00,0xAA,0x00,0xB9,0x33,0x56);
+DEFINE_GUID(IID_IDirect3DTexture2,	0x93281502,0x8CF8,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29);
+DEFINE_GUID(IID_IDirect3DLight,		0x4417C142,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E);
+DEFINE_GUID(IID_IDirect3DMaterial,	0x4417C144,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E);
+DEFINE_GUID(IID_IDirect3DMaterial2,	0x93281503,0x8CF8,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29);
+DEFINE_GUID(IID_IDirect3DExecuteBuffer,	0x4417C145,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E);
+DEFINE_GUID(IID_IDirect3DViewport,	0x4417C146,0x33AD,0x11CF,0x81,0x6F,0x00,0x00,0xC0,0x20,0x15,0x6E);
+DEFINE_GUID(IID_IDirect3DViewport2,	0x93281500,0x8CF8,0x11D0,0x89,0xAB,0x00,0xA0,0xC9,0x05,0x41,0x29);
+
+typedef struct IDirect3D	IDirect3D ,*LPDIRECT3D ;
+typedef struct IDirect3D2	IDirect3D2,*LPDIRECT3D2;
+typedef struct IDirect3DLight	IDirect3DLight,*LPDIRECT3DLIGHT;
+
+typedef struct {
+	DWORD	dwSize;
+	DWORD	dwCaps;
+} D3DTRANSFORMCAPS,*LPD3DTRANSFORMCAPS;
+
+#define D3DTRANSFORMCAPS_CLIP	0x00000001
+
+typedef struct {
+	DWORD	dwSize;
+	DWORD	dwCaps;
+	DWORD	dwLightingModel;
+	DWORD	dwNumLights;
+} D3DLIGHTINGCAPS, *LPD3DLIGHTINGCAPS;
+
+#define D3DLIGHTINGMODEL_RGB		0x00000001
+#define D3DLIGHTINGMODEL_MONO		0x00000002
+
+#define D3DLIGHTCAPS_POINT		0x00000001
+#define D3DLIGHTCAPS_SPOT		0x00000002
+#define D3DLIGHTCAPS_DIRECTIONAL	0x00000004
+#define D3DLIGHTCAPS_PARALLELPOINT	0x00000008
+
+
+#define D3DCOLOR_MONO	1
+#define D3DCOLOR_RGB	2
+
+typedef DWORD D3DCOLORMODEL;
+
+typedef struct {
+    DWORD dwSize;
+    DWORD dwMiscCaps;                 /* Capability flags */
+    DWORD dwRasterCaps;
+    DWORD dwZCmpCaps;
+    DWORD dwSrcBlendCaps;
+    DWORD dwDestBlendCaps;
+    DWORD dwAlphaCmpCaps;
+    DWORD dwShadeCaps;
+    DWORD dwTextureCaps;
+    DWORD dwTextureFilterCaps;
+    DWORD dwTextureBlendCaps;
+    DWORD dwTextureAddressCaps;
+    DWORD dwStippleWidth;             /* maximum width and height of */
+    DWORD dwStippleHeight;            /* of supported stipple (up to 32x32) */
+} D3DPRIMCAPS, *LPD3DPRIMCAPS;
+
+/* D3DPRIMCAPS.dwMiscCaps */
+#define D3DPMISCCAPS_MASKPLANES		0x00000001
+#define D3DPMISCCAPS_MASKZ		0x00000002
+#define D3DPMISCCAPS_LINEPATTERNREP	0x00000004
+#define D3DPMISCCAPS_CONFORMANT		0x00000008
+#define D3DPMISCCAPS_CULLNONE		0x00000010
+#define D3DPMISCCAPS_CULLCW		0x00000020
+#define D3DPMISCCAPS_CULLCCW		0x00000040
+
+/* D3DPRIMCAPS.dwRasterCaps */
+#define D3DPRASTERCAPS_DITHER			0x00000001
+#define D3DPRASTERCAPS_ROP2			0x00000002
+#define D3DPRASTERCAPS_XOR			0x00000004
+#define D3DPRASTERCAPS_PAT			0x00000008
+#define D3DPRASTERCAPS_ZTEST			0x00000010
+#define D3DPRASTERCAPS_SUBPIXEL			0x00000020
+#define D3DPRASTERCAPS_SUBPIXELX		0x00000040
+#define D3DPRASTERCAPS_FOGVERTEX		0x00000080
+#define D3DPRASTERCAPS_FOGTABLE			0x00000100
+#define D3DPRASTERCAPS_STIPPLE			0x00000200
+#define D3DPRASTERCAPS_ANTIALIASSORTDEPENDENT	0x00000400
+#define D3DPRASTERCAPS_ANTIALIASSORTINDEPENDENT	0x00000800
+#define D3DPRASTERCAPS_ANTIALIASEDGES		0x00001000
+#define D3DPRASTERCAPS_MIPMAPLODBIAS		0x00002000
+#define D3DPRASTERCAPS_ZBIAS			0x00004000
+#define D3DPRASTERCAPS_ZBUFFERLESSHSR		0x00008000
+#define D3DPRASTERCAPS_FOGRANGE			0x00010000
+#define D3DPRASTERCAPS_ANISOTROPY		0x00020000
+
+/* D3DPRIMCAPS.dwZCmpCaps and dwAlphaCmpCaps */
+#define D3DPCMPCAPS_NEVER		0x00000001
+#define D3DPCMPCAPS_LESS		0x00000002
+#define D3DPCMPCAPS_EQUAL		0x00000004
+#define D3DPCMPCAPS_LESSEQUAL		0x00000008
+#define D3DPCMPCAPS_GREATER		0x00000010
+#define D3DPCMPCAPS_NOTEQUAL		0x00000020
+#define D3DPCMPCAPS_GREATEREQUAL	0x00000040
+#define D3DPCMPCAPS_ALWAYS		0x00000080
+
+/* D3DPRIMCAPS.dwSourceBlendCaps, dwDestBlendCaps */
+#define D3DPBLENDCAPS_ZERO		0x00000001
+#define D3DPBLENDCAPS_ONE		0x00000002
+#define D3DPBLENDCAPS_SRCCOLOR		0x00000004
+#define D3DPBLENDCAPS_INVSRCCOLOR	0x00000008
+#define D3DPBLENDCAPS_SRCALPHA		0x00000010
+#define D3DPBLENDCAPS_INVSRCALPHA	0x00000020
+#define D3DPBLENDCAPS_DESTALPHA		0x00000040
+#define D3DPBLENDCAPS_INVDESTALPHA	0x00000080
+#define D3DPBLENDCAPS_DESTCOLOR		0x00000100
+#define D3DPBLENDCAPS_INVDESTCOLOR	0x00000200
+#define D3DPBLENDCAPS_SRCALPHASAT	0x00000400
+#define D3DPBLENDCAPS_BOTHSRCALPHA	0x00000800
+#define D3DPBLENDCAPS_BOTHINVSRCALPHA	0x00001000
+
+/* D3DPRIMCAPS.dwShadeCaps */
+#define D3DPSHADECAPS_COLORFLATMONO	0x00000001
+#define D3DPSHADECAPS_COLORFLATRGB	0x00000002
+#define D3DPSHADECAPS_COLORGOURAUDMONO	0x00000004
+#define D3DPSHADECAPS_COLORGOURAUDRGB	0x00000008
+#define D3DPSHADECAPS_COLORPHONGMONO	0x00000010
+#define D3DPSHADECAPS_COLORPHONGRGB	0x00000020
+
+#define D3DPSHADECAPS_SPECULARFLATMONO	0x00000040
+#define D3DPSHADECAPS_SPECULARFLATRGB	0x00000080
+#define D3DPSHADECAPS_SPECULARGOURAUDMONO	0x00000100
+#define D3DPSHADECAPS_SPECULARGOURAUDRGB	0x00000200
+#define D3DPSHADECAPS_SPECULARPHONGMONO	0x00000400
+#define D3DPSHADECAPS_SPECULARPHONGRGB	0x00000800
+
+#define D3DPSHADECAPS_ALPHAFLATBLEND	0x00001000
+#define D3DPSHADECAPS_ALPHAFLATSTIPPLED	0x00002000
+#define D3DPSHADECAPS_ALPHAGOURAUDBLEND	0x00004000
+#define D3DPSHADECAPS_ALPHAGOURAUDSTIPPLED	0x00008000
+#define D3DPSHADECAPS_ALPHAPHONGBLEND	0x00010000
+#define D3DPSHADECAPS_ALPHAPHONGSTIPPLED	0x00020000
+
+#define D3DPSHADECAPS_FOGFLAT		0x00040000
+#define D3DPSHADECAPS_FOGGOURAUD	0x00080000
+#define D3DPSHADECAPS_FOGPHONG		0x00100000
+
+/* D3DPRIMCAPS.dwTextureCaps */
+#define D3DPTEXTURECAPS_PERSPECTIVE	0x00000001
+#define D3DPTEXTURECAPS_POW2		0x00000002
+#define D3DPTEXTURECAPS_ALPHA		0x00000004
+#define D3DPTEXTURECAPS_TRANSPARENCY	0x00000008
+#define D3DPTEXTURECAPS_BORDER		0x00000010
+#define D3DPTEXTURECAPS_SQUAREONLY	0x00000020
+
+/* D3DPRIMCAPS.dwTextureFilterCaps */
+#define D3DPTFILTERCAPS_NEAREST		0x00000001
+#define D3DPTFILTERCAPS_LINEAR		0x00000002
+#define D3DPTFILTERCAPS_MIPNEAREST	0x00000004
+#define D3DPTFILTERCAPS_MIPLINEAR	0x00000008
+#define D3DPTFILTERCAPS_LINEARMIPNEAREST	0x00000010
+#define D3DPTFILTERCAPS_LINEARMIPLINEAR	0x00000020
+
+/* D3DPRIMCAPS.dwTextureBlendCaps */
+#define D3DPTBLENDCAPS_DECAL		0x00000001
+#define D3DPTBLENDCAPS_MODULATE		0x00000002
+#define D3DPTBLENDCAPS_DECALALPHA	0x00000004
+#define D3DPTBLENDCAPS_MODULATEALPHA	0x00000008
+#define D3DPTBLENDCAPS_DECALMASK	0x00000010
+#define D3DPTBLENDCAPS_MODULATEMASK	0x00000020
+#define D3DPTBLENDCAPS_COPY		0x00000040
+#define D3DPTBLENDCAPS_ADD		0x00000080
+
+/* D3DPRIMCAPS.dwTextureAddressCaps */
+#define D3DPTADDRESSCAPS_WRAP		0x00000001
+#define D3DPTADDRESSCAPS_MIRROR		0x00000002
+#define D3DPTADDRESSCAPS_CLAMP		0x00000004
+#define D3DPTADDRESSCAPS_BORDER		0x00000008
+#define D3DPTADDRESSCAPS_INDEPENDENTUV	0x00000010
+
+
+/* D3DDEVICEDESC.dwFlags */
+#define D3DDD_COLORMODEL		0x00000001
+#define D3DDD_DEVCAPS			0x00000002
+#define D3DDD_TRANSFORMCAPS		0x00000004
+#define D3DDD_LIGHTINGCAPS		0x00000008
+#define D3DDD_BCLIPPING			0x00000010
+#define D3DDD_LINECAPS			0x00000020
+#define D3DDD_TRICAPS			0x00000040
+#define D3DDD_DEVICERENDERBITDEPTH	0x00000080
+#define D3DDD_DEVICEZBUFFERBITDEPTH	0x00000100
+#define D3DDD_MAXBUFFERSIZE		0x00000200
+#define D3DDD_MAXVERTEXCOUNT		0x00000400
+
+/* D3DDEVICEDESC.dwDevCaps */
+#define D3DDEVCAPS_SORTINCREASINGZ      0x00000002
+#define D3DDEVCAPS_SORTDECREASINGZ      0X00000004
+#define D3DDEVCAPS_SORTEXACT            0x00000008
+#define D3DDEVCAPS_EXECUTESYSTEMMEMORY  0x00000010
+#define D3DDEVCAPS_EXECUTEVIDEOMEMORY   0x00000020
+#define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040
+#define D3DDEVCAPS_TLVERTEXVIDEOMEMORY  0x00000080
+#define D3DDEVCAPS_TEXTURESYSTEMMEMORY  0x00000100
+#define D3DDEVCAPS_TEXTUREVIDEOMEMORY   0x00000200
+#define D3DDEVCAPS_DRAWPRIMTLVERTEX     0x00000400
+#define D3DDEVCAPS_CANRENDERAFTERFLIP   0x00000800
+#define D3DDEVCAPS_TEXTURENONLOCALVIDMEM 0x00001000
+
+typedef struct _D3DDeviceDesc {
+	DWORD		dwSize;
+	DWORD		dwFlags;
+	D3DCOLORMODEL	dcmColorModel;
+	DWORD		dwDevCaps;
+	D3DTRANSFORMCAPS dtcTransformCaps;
+	BOOL32		bClipping;
+	D3DLIGHTINGCAPS	dlcLightingCaps;
+	D3DPRIMCAPS	dpcLineCaps;
+	D3DPRIMCAPS	dpcTriCaps;
+	DWORD		dwDeviceRenderBitDepth;
+	DWORD		dwDeviceZBufferBitDepth;
+	DWORD		dwMaxBufferSize;
+	DWORD		dwMaxVertexCount;
+	/* *** New fields for DX5 *** */
+	DWORD		dwMinTextureWidth,dwMinTextureHeight;
+	DWORD		dwMaxTextureWidth,dwMaxTextureHeight;
+	DWORD		dwMinStippleWidth,dwMaxStippleWidth;
+	DWORD		dwMinStippleHeight,dwMaxStippleHeight;
+} D3DDEVICEDESC,*LPD3DDEVICEDESC;
+ 
+typedef HRESULT (CALLBACK * LPD3DENUMDEVICESCALLBACK)(LPGUID lpGuid,LPSTR lpDeviceDescription,LPSTR lpDeviceName,LPD3DDEVICEDESC,LPD3DDEVICEDESC,LPVOID);
+
+/* dwflags for FindDevice */
+#define D3DFDS_COLORMODEL		0x00000001
+#define D3DFDS_GUID			0x00000002
+#define D3DFDS_HARDWARE			0x00000004
+#define D3DFDS_TRIANGLES		0x00000008
+#define D3DFDS_LINES			0x00000010
+#define D3DFDS_MISCCAPS			0x00000020
+#define D3DFDS_RASTERCAPS		0x00000040
+#define D3DFDS_ZCMPCAPS			0x00000080
+#define D3DFDS_ALPHACMPCAPS		0x00000100
+#define D3DFDS_DSTBLENDCAPS		0x00000400
+#define D3DFDS_SHADECAPS		0x00000800
+#define D3DFDS_TEXTURECAPS		0x00001000
+#define D3DFDS_TEXTUREFILTERCAPS	0x00002000
+#define D3DFDS_TEXTUREBLENDCAPS		0x00004000
+#define D3DFDS_TEXTUREADDRESSCAPS	0x00008000
+
+typedef struct {
+    DWORD		dwSize;
+    DWORD		dwFlags;
+    BOOL32		bHardware;
+    D3DCOLORMODEL	dcmColorModel;
+    GUID		guid;
+    DWORD		dwCaps;
+    D3DPRIMCAPS		dpcPrimCaps;
+} D3DFINDDEVICESEARCH,*LPD3DFINDDEVICESEARCH;
+
+typedef struct {
+    DWORD		dwSize;
+    GUID		guid;
+    D3DDEVICEDESC	ddHwDesc;
+    D3DDEVICEDESC	ddSwDesc;
+} D3DFINDDEVICERESULT,*LPD3DFINDDEVICERESULT;
+
+#define D3DVALP(val, prec)	((float)(val))
+#define D3DVAL(val)		((float)(val))
+typedef float D3DVALUE,*LPD3DVALUE;
+#define D3DDivide(a, b)		(float)((double) (a) / (double) (b))
+#define D3DMultiply(a, b)	((a) * (b))
+
+typedef struct {
+	union {
+		D3DVALUE x;
+		D3DVALUE dvX;
+	} x;
+	union {
+		D3DVALUE y;
+		D3DVALUE dvY;
+	} y;
+	union {
+		D3DVALUE z;
+		D3DVALUE dvZ;
+	} z;
+	/* the c++ variant has operator overloads etc. too */
+} D3DVECTOR,*LPD3DVECTOR;
+
+
+typedef enum {
+    D3DLIGHT_POINT          = 1,
+    D3DLIGHT_SPOT           = 2,
+    D3DLIGHT_DIRECTIONAL    = 3,
+    D3DLIGHT_PARALLELPOINT  = 4,
+    D3DLIGHT_FORCE_DWORD    = 0x7fffffff, /* force 32-bit size enum */
+} D3DLIGHTTYPE;
+
+typedef struct _D3DCOLORVALUE {
+	union {
+		D3DVALUE r;
+		D3DVALUE dvR;
+	} r;
+	union {
+		D3DVALUE g;
+		D3DVALUE dvG;
+	} g;
+	union {
+		D3DVALUE b;
+		D3DVALUE dvB;
+	} b;
+	union {
+		D3DVALUE a;
+		D3DVALUE dvA;
+	} a;
+} D3DCOLORVALUE,*LPD3DCOLORVALUE;
+
+typedef struct {
+    DWORD           dwSize;
+    D3DLIGHTTYPE    dltType;
+    D3DCOLORVALUE   dcvColor;
+    D3DVECTOR       dvPosition;		/* Position in world space */
+    D3DVECTOR       dvDirection;	/* Direction in world space */
+    D3DVALUE        dvRange;		/* Cutoff range */
+    D3DVALUE        dvFalloff;		/* Falloff */
+    D3DVALUE        dvAttenuation0;	/* Constant attenuation */
+    D3DVALUE        dvAttenuation1;	/* Linear attenuation */
+    D3DVALUE        dvAttenuation2;	/* Quadratic attenuation */
+    D3DVALUE        dvTheta;		/* Inner angle of spotlight cone */
+    D3DVALUE        dvPhi;		/* Outer angle of spotlight cone */
+} D3DLIGHT,*LPD3DLIGHT;
+
+/* flags bits */
+#define D3DLIGHT_ACTIVE		0x00000001
+#define D3DLIGHT_NO_SPECULAR	0x00000002
+
+
+#define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn)
+#define STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn)
+#define PURE
+#define FAR
+#define THIS_ THIS ,
+
+#define THIS LPDIRECT3D	this
+typedef struct IDirect3D_VTable {
+	/*** IUnknown methods ***/
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+	STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+	STDMETHOD_(ULONG, Release) (THIS) PURE;
+	/*** IDirect3D methods ***/
+	STDMETHOD(Initialize) (THIS_ REFIID) PURE;
+	STDMETHOD(EnumDevices)(THIS_ LPD3DENUMDEVICESCALLBACK, LPVOID) PURE;
+	STDMETHOD(CreateLight) (THIS_ LPDIRECT3DLIGHT*, IUnknown*) PURE;
+	STDMETHOD(CreateMaterial) (THIS_ LPDIRECT3DMATERIAL*, IUnknown*) PURE;
+	STDMETHOD(CreateViewport) (THIS_ LPDIRECT3DVIEWPORT*, IUnknown*) PURE;
+	STDMETHOD(FindDevice)(THIS_ LPD3DFINDDEVICESEARCH, LPD3DFINDDEVICERESULT) PURE;
+} *LPDIRECT3D_VTABLE,IDirect3D_VTable;
+
+struct IDirect3D {
+	LPDIRECT3D_VTABLE	lpvtbl;
+	DWORD			ref;
+	LPDIRECTDRAW		ddraw;
+};
+#undef THIS
+
+#define THIS LPDIRECT3D2 this
+typedef struct IDirect3D2_VTable {
+	/*** IUnknown methods ***/
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+	STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+	STDMETHOD_(ULONG, Release) (THIS) PURE;
+	/*** IDirect3D2 methods ***/
+	STDMETHOD(EnumDevices)(THIS_ LPD3DENUMDEVICESCALLBACK, LPVOID) PURE;
+	STDMETHOD(CreateLight) (THIS_ LPDIRECT3DLIGHT*, IUnknown*) PURE;
+	STDMETHOD(CreateMaterial) (THIS_ LPDIRECT3DMATERIAL2*, IUnknown*) PURE;
+	STDMETHOD(CreateViewport) (THIS_ LPDIRECT3DVIEWPORT2*, IUnknown*) PURE;
+	STDMETHOD(FindDevice)(THIS_ LPD3DFINDDEVICESEARCH, LPD3DFINDDEVICERESULT) PURE;
+	STDMETHOD(CreateDevice)(THIS_ REFCLSID, LPDIRECTDRAWSURFACE, LPDIRECT3DDEVICE2 *) PURE;
+} *LPDIRECT3D2_VTABLE,IDirect3D2_VTable;
+
+struct IDirect3D2 {
+	LPDIRECT3D2_VTABLE	lpvtbl;
+	DWORD			ref;
+	LPDIRECTDRAW		ddraw;
+};
+#undef THIS
+
+#define THIS LPDIRECT3DLIGHT this
+typedef struct IDirect3DLight_VTable {
+	/*** IUnknown methods ***/
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID* ppvObj) PURE;
+	STDMETHOD_(ULONG, AddRef) (THIS) PURE;
+	STDMETHOD_(ULONG, Release) (THIS) PURE;
+	/*** IDirect3DLight methods ***/
+	STDMETHOD(Initialize) (THIS_ LPDIRECT3D) PURE;
+	STDMETHOD(SetLight) (THIS_ LPD3DLIGHT) PURE;
+	STDMETHOD(GetLight) (THIS_ LPD3DLIGHT) PURE;
+} IDirect3DLight_VTable,*LPDIRECT3DLIGHT_VTABLE;
+
+struct IDirect3DLight {
+	LPDIRECT3DLIGHT_VTABLE	lpvtbl;
+	DWORD			ref;
+};
+
+#undef THIS
+
+#undef THIS_
+#undef STDMETHOD
+#undef STDMETHOD_
+#undef PURE
+#undef FAR
+#endif
diff --git a/include/ddraw.h b/include/ddraw.h
index 26f72ac..7078757 100644
--- a/include/ddraw.h
+++ b/include/ddraw.h
@@ -1,7 +1,11 @@
 #ifndef __WINE_DDRAW_H
 #define __WINE_DDRAW_H
 
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
+
+#ifndef	DIRECTDRAW_VERSION
+#define	DIRECTDRAW_VERSION	0x0500
+#endif /* DIRECTDRAW_VERSION */
 
 
 DEFINE_GUID( CLSID_DirectDraw,		0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 );
@@ -10,8 +14,10 @@
 DEFINE_GUID( IID_IDirectDraw2,		0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 );
 DEFINE_GUID( IID_IDirectDrawSurface,	0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
 DEFINE_GUID( IID_IDirectDrawSurface2,	0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 );
+DEFINE_GUID( IID_IDirectDrawSurface3,	0xDA044E00,0x69B2,0x11D0,0xA1,0xD5,0x00,0xAA,0x00,0xB8,0xDF,0xBB );
 DEFINE_GUID( IID_IDirectDrawPalette,	0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
 DEFINE_GUID( IID_IDirectDrawClipper,	0x6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 );
+DEFINE_GUID( IID_IDirectDrawColorControl,0x4B9F0EE0,0x0D7E,0x11D0,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8 );
 
 typedef struct IDirectDraw IDirectDraw,*LPDIRECTDRAW;
 typedef struct IDirectDraw2 IDirectDraw2,*LPDIRECTDRAW2;
@@ -19,6 +25,8 @@
 typedef struct IDirectDrawPalette IDirectDrawPalette,*LPDIRECTDRAWPALETTE;
 typedef struct IDirectDrawSurface IDirectDrawSurface,*LPDIRECTDRAWSURFACE;
 typedef struct IDirectDrawSurface2 IDirectDrawSurface2,*LPDIRECTDRAWSURFACE2;
+typedef struct IDirectDrawSurface3 IDirectDrawSurface3,*LPDIRECTDRAWSURFACE3;
+typedef struct IDirectDrawColorControl IDirectDrawColorControl,*LPDIRECTDRAWCOLORCONTROL;
 
 #define DDENUMRET_CANCEL	0
 #define DDENUMRET_OK		1
@@ -124,10 +132,17 @@
 #define DDERR_UNSUPPORTEDMODE			MAKE_DDHRESULT( 590 )
 #define DDERR_NOMIPMAPHW			MAKE_DDHRESULT( 591 )
 #define DDERR_INVALIDSURFACETYPE		MAKE_DDHRESULT( 592 )
+#define DDERR_NOOPTIMIZEHW			MAKE_DDHRESULT( 600 )
+#define DDERR_NOTLOADED				MAKE_DDHRESULT( 601 )
+#define DDERR_NOFOCUSWINDOW			MAKE_DDHRESULT( 602 )
 #define DDERR_DCALREADYCREATED			MAKE_DDHRESULT( 620 )
+#define DDERR_NONONLOCALVIDMEM			MAKE_DDHRESULT( 630 )
 #define DDERR_CANTPAGELOCK			MAKE_DDHRESULT( 640 )
 #define DDERR_CANTPAGEUNLOCK			MAKE_DDHRESULT( 660 )
 #define DDERR_NOTPAGELOCKED			MAKE_DDHRESULT( 680 )
+#define DDERR_MOREDATA				MAKE_DDHRESULT( 690 )
+#define DDERR_VIDEONOTACTIVE			MAKE_DDHRESULT( 695 )
+#define DDERR_DEVICEDOESNTOWNSURFACE		MAKE_DDHRESULT( 699 )
 #define DDERR_NOTINITIALIZED			CO_E_NOTINITIALIZED
 
 /* dwFlags for Blt* */
@@ -165,14 +180,17 @@
 #define DDBLTFAST_WAIT				0x00000010
 
 /* dwFlags for Flip */
-#define DDFLIP_WAIT				0x00000001
+#define DDFLIP_WAIT	0x00000001
+#define DDFLIP_EVEN	0x00000002 /* only valid for overlay */
+#define DDFLIP_ODD	0x00000004 /* only valid for overlay */
 
 /* dwFlags for GetBltStatus */
 #define DDGBS_CANBLT				0x00000001
 #define DDGBS_ISBLTDONE				0x00000002
 
-/* 3d capable (no meaning?) */
-#define DDSCAPS_3D			0x00000001
+/* DDSCAPS.dwCaps */
+/* reserved1, was 3d capable */
+#define DDSCAPS_RESERVED1		0x00000001
 /* surface contains alpha information */
 #define DDSCAPS_ALPHA			0x00000002
 /* this surface is a backbuffer */
@@ -217,8 +235,19 @@
 #define DDSCAPS_MODEX			0x00200000
 /* one mipmap surface (1 level) */
 #define DDSCAPS_MIPMAP			0x00400000
+#define DDSCAPS_RESERVED2		0x00800000
 /* memory allocation delayed until Load() */
 #define DDSCAPS_ALLOCONLOAD		0x04000000
+/* Indicates that the surface will recieve data from a video port */
+#define DDSCAPS_VIDEOPORT		0x08000000
+/* surface is in local videomemory */
+#define DDSCAPS_LOCALVIDMEM		0x10000000
+/* surface is in nonlocal videomemory */
+#define DDSCAPS_NONLOCALVIDMEM		0x20000000
+/* surface is a standard VGA mode surface (NOT ModeX) */
+#define DDSCAPS_STANDARDVGAMODE		0x40000000
+/* optimized? surface */
+#define DDSCAPS_OPTIMIZED		0x80000000
 
 typedef struct _DDSCAPS {
 	DWORD	dwCaps;	/* capabilities of surface wanted */
@@ -226,7 +255,7 @@
 
 #define	DD_ROP_SPACE	(256/32)	/* space required to store ROP array */
 
-typedef struct _DDCAPS
+typedef struct _DDCAPS_DX3
 {
     DWORD	dwSize;                 /* size of the DDDRIVERCAPS structure */
     DWORD	dwCaps;                 /* driver specific capabilities */
@@ -279,11 +308,77 @@
     DWORD	dwReserved4;
     DWORD	dwReserved5;
     DWORD	dwReserved6;
+} DDCAPS_DX3,*LPDDCAPS_DX3;
+
+typedef struct _DDCAPS
+{
+/*  0*/ DWORD  dwSize;			/* size of the DDDRIVERCAPS structure */
+/*  4*/ DWORD  dwCaps;			/* driver specific capabilities */
+/*  8*/ DWORD  dwCaps2;			/* more driver specific capabilites */
+/*  c*/ DWORD  dwCKeyCaps;		/* color key capabilities of the surface */
+/* 10*/ DWORD  dwFXCaps;		/* driver specific stretching and effects capabilites */
+/* 14*/ DWORD  dwFXAlphaCaps;		/* alpha driver specific capabilities */
+/* 18*/ DWORD  dwPalCaps;		/* palette capabilities */
+/* 1c*/ DWORD  dwSVCaps;		/* stereo vision capabilities */
+/* 20*/ DWORD  dwAlphaBltConstBitDepths;	/* DDBD_2,4,8 */
+/* 24*/ DWORD  dwAlphaBltPixelBitDepths;	/* DDBD_1,2,4,8 */
+/* 28*/ DWORD  dwAlphaBltSurfaceBitDepths;	/* DDBD_1,2,4,8 */
+/* 2c*/ DWORD  dwAlphaOverlayConstBitDepths;	/* DDBD_2,4,8 */
+/* 30*/ DWORD  dwAlphaOverlayPixelBitDepths;	/* DDBD_1,2,4,8 */
+/* 34*/ DWORD  dwAlphaOverlaySurfaceBitDepths;	/* DDBD_1,2,4,8 */
+/* 38*/ DWORD  dwZBufferBitDepths;		/* DDBD_8,16,24,32 */
+/* 3c*/ DWORD  dwVidMemTotal;		/* total amount of video memory */
+/* 40*/ DWORD  dwVidMemFree;		/* amount of free video memory */
+/* 44*/ DWORD  dwMaxVisibleOverlays;	/* maximum number of visible overlays */
+/* 48*/ DWORD  dwCurrVisibleOverlays;	/* current number of visible overlays */
+/* 4c*/ DWORD  dwNumFourCCCodes;	/* number of four cc codes */
+/* 50*/ DWORD  dwAlignBoundarySrc;	/* source rectangle alignment */
+/* 54*/ DWORD  dwAlignSizeSrc;		/* source rectangle byte size */
+/* 58*/ DWORD  dwAlignBoundaryDest;	/* dest rectangle alignment */
+/* 5c*/ DWORD  dwAlignSizeDest;		/* dest rectangle byte size */
+/* 60*/ DWORD  dwAlignStrideAlign;	/* stride alignment */
+/* 64*/ DWORD  dwRops[DD_ROP_SPACE];	/* ROPS supported */
+/* 84*/ DDSCAPS ddsCaps;		/* DDSCAPS structure has all the general capabilities */
+/* 88*/ DWORD  dwMinOverlayStretch;	/* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+/* 8c*/ DWORD  dwMaxOverlayStretch;	/* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+/* 90*/ DWORD  dwMinLiveVideoStretch;	/* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+/* 94*/ DWORD  dwMaxLiveVideoStretch;	/* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+/* 98*/ DWORD  dwMinHwCodecStretch;	/* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+/* 9c*/ DWORD  dwMaxHwCodecStretch;	/* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */
+/* a0*/ DWORD  dwReserved1;
+/* a4*/ DWORD  dwReserved2;
+/* a8*/ DWORD  dwReserved3;
+/* ac*/ DWORD  dwSVBCaps;	/* driver specific capabilities for System->Vmem blts */
+/* b0*/ DWORD  dwSVBCKeyCaps;	/* driver color key capabilities for System->Vmem blts */
+/* b4*/ DWORD  dwSVBFXCaps;	/* driver FX capabilities for System->Vmem blts */
+/* b8*/ DWORD  dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */
+/* d8*/ DWORD  dwVSBCaps;	/* driver specific capabilities for Vmem->System blts */
+/* dc*/ DWORD  dwVSBCKeyCaps;	/* driver color key capabilities for Vmem->System blts */
+/* e0*/ DWORD  dwVSBFXCaps;	/* driver FX capabilities for Vmem->System blts */
+/* e4*/ DWORD  dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */
+/*104*/ DWORD  dwSSBCaps;	/* driver specific capabilities for System->System blts */
+/*108*/ DWORD  dwSSBCKeyCaps;	/* driver color key capabilities for System->System blts */
+/*10c*/ DWORD  dwSSBFXCaps;	/* driver FX capabilities for System->System blts */
+/*110*/ DWORD  dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */
+#if       DIRECTDRAW_VERSION >= 0x0500
+/*130*/ DWORD  dwMaxVideoPorts;	/* maximum number of usable video ports */
+/*134*/ DWORD  dwCurrVideoPorts;/* current number of video ports used */
+/*138*/ DWORD  dwSVBCaps2;	/* more driver specific capabilities for System->Vmem blts */
+/*13c*/ DWORD  dwNLVBCaps;	/* driver specific capabilities for non-local->local vidmem blts */
+/*140*/ DWORD  dwNLVBCaps2;	/* more driver specific capabilities non-local->local vidmem blts */
+/*144*/ DWORD  dwNLVBCKeyCaps;	/* driver color key capabilities for non-local->local vidmem blts */
+/*148*/ DWORD  dwNLVBFXCaps;	/* driver FX capabilities for non-local->local blts */
+/*14c*/ DWORD  dwNLVBRops[DD_ROP_SPACE];/* ROPS supported for non-local->local blts */
+#else  /* DIRECTDRAW_VERSION >= 0x0500 */
+/*130*/ DWORD  dwReserved4;
+/*134*/ DWORD  dwReserved5;
+/*138*/ DWORD  dwReserved6;
+#endif /* DIRECTDRAW_VERSION >= 0x0500 */
 } DDCAPS,*LPDDCAPS;
 
-/* hw has 3d accel */
+
+/* DDCAPS.dwCaps */
 #define DDCAPS_3D			0x00000001
-/* supports only boundary aligned rectangles */
 #define DDCAPS_ALIGNBOUNDARYDEST	0x00000002
 #define DDCAPS_ALIGNSIZEDEST		0x00000004
 #define DDCAPS_ALIGNBOUNDARYSRC		0x00000008
@@ -316,11 +411,22 @@
 #define DDCAPS_CANCLIPSTRETCHED		0x40000000
 #define DDCAPS_CANBLTSYSMEM		0x80000000
 
-/* dwCaps2 */
-/* driver is certified */
+/* DDCAPS.dwCaps2 */
 #define DDCAPS2_CERTIFIED		0x00000001
-/* no 2d operations in 3d mode */
 #define DDCAPS2_NO2DDURING3DSCENE       0x00000002
+#define DDCAPS2_VIDEOPORT		0x00000004
+#define DDCAPS2_AUTOFLIPOVERLAY		0x00000008
+#define DDCAPS2_CANBOBINTERLEAVED	0x00000010
+#define DDCAPS2_CANBOBNONINTERLEAVED	0x00000020
+#define DDCAPS2_COLORCONTROLOVERLAY	0x00000040
+#define DDCAPS2_COLORCONTROLPRIMARY	0x00000080
+#define DDCAPS2_CANDROPZ16BIT		0x00000100
+#define DDCAPS2_NONLOCALVIDMEM		0x00000200
+#define DDCAPS2_NONLOCALVIDMEMCAPS	0x00000400
+#define DDCAPS2_NOPAGELOCKREQUIRED	0x00000800
+#define DDCAPS2_WIDESURFACES		0x00001000
+#define DDCAPS2_CANFLIPODDEVEN		0x00002000
+#define DDCAPS2_CANBOBHARDWARE		0x00004000
 
 typedef struct _DDCOLORKEY
 {
@@ -354,32 +460,34 @@
 #define DDCKEYCAPS_NOCOSTOVERLAY		0x00040000
 
 typedef struct _DDPIXELFORMAT {
-    DWORD	dwSize;                 /* size of structure */
-    DWORD	dwFlags;                /* pixel format flags */
-    DWORD	dwFourCC;               /* (FOURCC code) */
+    DWORD	dwSize;                 /* 0: size of structure */
+    DWORD	dwFlags;                /* 4: pixel format flags */
+    DWORD	dwFourCC;               /* 8: (FOURCC code) */
     union {
-	DWORD	dwRGBBitCount;          /* how many bits per pixel (BD_4,8,16,24,32)*/
-	DWORD	dwYUVBitCount;          /* how many bits per pixel (BD_4,8,16,24,32)*/
-	DWORD	dwZBufferBitDepth;      /* how many bits for z buffers (BD_8,16,24,32)*/
-	DWORD	dwAlphaBitDepth;        /* how many bits for alpha channels (BD_1,2,4,8)*/
+	DWORD	dwRGBBitCount;          /* C: how many bits per pixel */
+	DWORD	dwYUVBitCount;          /* C: how many bits per pixel */
+	DWORD	dwZBufferBitDepth;      /* C: how many bits for z buffers */
+	DWORD	dwAlphaBitDepth;        /* C: how many bits for alpha channels*/
     } x;
     union {
-	DWORD	dwRBitMask;             /* mask for red bit*/
-	DWORD	dwYBitMask;             /* mask for Y bits*/
+	DWORD	dwRBitMask;             /* 10: mask for red bit*/
+	DWORD	dwYBitMask;             /* 10: mask for Y bits*/
     } y;
     union {
-	DWORD	dwGBitMask;             /* mask for green bits*/
-	DWORD	dwUBitMask;             /* mask for U bits*/
+	DWORD	dwGBitMask;             /* 14: mask for green bits*/
+	DWORD	dwUBitMask;             /* 14: mask for U bits*/
     } z;
     union {
-	DWORD   dwBBitMask;             /* mask for blue bits*/
-	DWORD   dwVBitMask;             /* mask for V bits*/
+	DWORD   dwBBitMask;             /* 18: mask for blue bits*/
+	DWORD   dwVBitMask;             /* 18: mask for V bits*/
     } xx;
     union {
-    	DWORD	dwRGBAlphaBitMask;	/* mask for alpha channel */
-    	DWORD	dwYUVAlphaBitMask;	/* mask for alpha channel */
-
+    	DWORD	dwRGBAlphaBitMask;	/* 1C: mask for alpha channel */
+    	DWORD	dwYUVAlphaBitMask;	/* 1C: mask for alpha channel */
+	DWORD	dwRGBZBitMask;		/* 1C: mask for Z channel */
+	DWORD	dwYUVZBitMask;		/* 1C: mask for Z channel */
     } xy;
+    					/* 20: next structure */
 } DDPIXELFORMAT,*LPDDPIXELFORMAT;
 
 /* DDCAPS.dwFXCaps */
@@ -468,6 +576,7 @@
 #define DDPF_ZBUFFER			0x00000400
 #define DDPF_PALETTEINDEXED1		0x00000800
 #define DDPF_PALETTEINDEXED2		0x00001000
+#define DDPF_ZPIXELS			0x00002000
 
 /* SetCooperativeLevel dwFlags */
 #define DDSCL_FULLSCREEN		0x00000001
@@ -476,40 +585,12 @@
 #define DDSCL_NORMAL			0x00000008
 #define DDSCL_EXCLUSIVE			0x00000010
 #define DDSCL_ALLOWMODEX		0x00000040
+#define DDSCL_SETFOCUSWINDOW		0x00000080
+#define DDSCL_SETDEVICEWINDOW		0x00000100
+#define DDSCL_CREATEDEVICEWINDOW	0x00000200
 
-typedef struct _DDSURFACEDESC
-{
-	DWORD	dwSize;	/* size of the DDSURFACEDESC structure*/
-	DWORD	dwFlags;/* determines what fields are valid*/
-	DWORD	dwHeight;/* height of surface to be created*/
-	DWORD	dwWidth;/* width of input surface*/
-	LONG	lPitch;	/* distance to start of next line (return value only)*/
-	DWORD	dwBackBufferCount;	/* number of back buffers requested*/
-	union {
-		DWORD	dwMipMapCount;	/* number of mip-map levels requested*/
-		DWORD	dwZBufferBitDepth;/* depth of Z buffer requested*/
-		DWORD	dwRefreshRate;	/* refresh rate (used when display mode is described)*/
-	} x;
-	DWORD	dwAlphaBitDepth;        /* depth of alpha buffer requested*/
-	DWORD	dwReserved;             /* reserved*/
-	LPVOID	lpSurface;              /* pointer to the associated surface memory*/
-	DDCOLORKEY	ddckCKDestOverlay;/* color key for destination overlay use*/
-	DDCOLORKEY	ddckCKDestBlt;/* color key for destination blt use*/
-	DDCOLORKEY	ddckCKSrcOverlay;/* color key for source overlay use*/
-	DDCOLORKEY	ddckCKSrcBlt;/* color key for source blt use*/
-	DDPIXELFORMAT	ddpfPixelFormat;/* pixel format description of the surface*/
-	DDSCAPS		ddsCaps;/* direct draw surface capabilities*/
-} DDSURFACEDESC,*LPDDSURFACEDESC;
 
-typedef BOOL32 (CALLBACK * LPDDENUMCALLBACK32A)(GUID *, LPSTR, LPSTR, LPVOID);
-typedef BOOL32 (CALLBACK * LPDDENUMCALLBACK32W)(GUID *, LPWSTR, LPWSTR, LPVOID);
-DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACK)
-
-typedef HRESULT (CALLBACK * LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID);
-typedef HRESULT (CALLBACK * LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID);
-
-/* dwFlags field... which are valid */
-
+/* DDSURFACEDESC.dwFlags */
 #define	DDSD_CAPS		0x00000001
 #define	DDSD_HEIGHT		0x00000002
 #define	DDSD_WIDTH		0x00000004
@@ -517,6 +598,7 @@
 #define	DDSD_BACKBUFFERCOUNT	0x00000020
 #define	DDSD_ZBUFFERBITDEPTH	0x00000040
 #define	DDSD_ALPHABITDEPTH	0x00000080
+#define	DDSD_LPSURFACE		0x00000800
 #define	DDSD_PIXELFORMAT	0x00001000
 #define	DDSD_CKDESTOVERLAY	0x00002000
 #define	DDSD_CKDESTBLT		0x00004000
@@ -524,7 +606,85 @@
 #define	DDSD_CKSRCBLT		0x00010000
 #define	DDSD_MIPMAPCOUNT	0x00020000
 #define	DDSD_REFRESHRATE	0x00040000
-#define	DDSD_ALL		0x0007f9ee
+#define	DDSD_LINEARSIZE		0x00080000
+#define	DDSD_ALL		0x000ff9ee
+
+/* SetDisplayMode flags */
+#define DDSDM_STANDARDVGAMODE	0x00000001
+
+/* EnumDisplayModes flags */
+#define DDEDM_REFRESHRATES	0x00000001
+#define DDEDM_STANDARDVGAMODES	0x00000002
+
+
+typedef struct _DDSURFACEDESC
+{
+	DWORD	dwSize;		/* 0: size of the DDSURFACEDESC structure*/
+	DWORD	dwFlags;	/* 4: determines what fields are valid*/
+	DWORD	dwHeight;	/* 8: height of surface to be created*/
+	DWORD	dwWidth;	/* C: width of input surface*/
+	LONG	lPitch;		/*10: distance to start of next line (return value only)*/
+	DWORD	dwBackBufferCount;/* 14: number of back buffers requested*/
+	union {
+		DWORD	dwMipMapCount;/* 18:number of mip-map levels requested*/
+		DWORD	dwZBufferBitDepth;/*18: depth of Z buffer requested*/
+		DWORD	dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/
+	} x;		
+	DWORD	dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/
+	DWORD	dwReserved;	/* 20:reserved*/
+	union {
+		LPVOID	lpSurface;	/* 24:pointer to the associated surface memory*/
+		DWORD	dwLinearSize;	/* 24:Formless late-allocated optimized surface size*/
+	} y;
+	DDCOLORKEY	ddckCKDestOverlay;/* 28: CK for dest overlay use*/
+	DDCOLORKEY	ddckCKDestBlt;	/* 30: CK for destination blt use*/
+	DDCOLORKEY	ddckCKSrcOverlay;/* 38: CK for source overlay use*/
+	DDCOLORKEY	ddckCKSrcBlt;	/* 40: CK for source blt use*/
+	DDPIXELFORMAT	ddpfPixelFormat;/* 48: pixel format description of the surface*/
+	DDSCAPS		ddsCaps;	/* 68: direct draw surface caps */
+} DDSURFACEDESC,*LPDDSURFACEDESC;
+
+/* DDCOLORCONTROL.dwFlags */
+#define DDCOLOR_BRIGHTNESS	0x00000001
+#define DDCOLOR_CONTRAST	0x00000002
+#define DDCOLOR_HUE		0x00000004
+#define DDCOLOR_SATURATION	0x00000008
+#define DDCOLOR_SHARPNESS	0x00000010
+#define DDCOLOR_GAMMA		0x00000020
+#define DDCOLOR_COLORENABLE	0x00000040
+
+typedef struct {
+	DWORD	dwSize;
+	DWORD	dwFlags;
+	LONG	lBrightness;
+	LONG	lContrast;
+	LONG	lHue;
+	LONG	lSaturation;
+	LONG	lSharpness;
+	LONG	lGamma;
+	LONG	lColorEnable;
+	DWORD	dwReserved1;
+} DDCOLORCONTROL,*LPDDCOLORCONTROL;
+
+typedef BOOL32 (CALLBACK * LPDDENUMCALLBACK32A)(GUID *, LPSTR, LPSTR, LPVOID);
+typedef BOOL32 (CALLBACK * LPDDENUMCALLBACK32W)(GUID *, LPWSTR, LPWSTR, LPVOID);
+DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACK);
+
+typedef HRESULT (CALLBACK * LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID);
+typedef HRESULT (CALLBACK * LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID);
+
+typedef HANDLE32 HMONITOR;
+typedef BOOL32 (CALLBACK * LPDDENUMCALLBACKEX32A)(GUID *, LPSTR, LPSTR, LPVOID, HMONITOR);
+typedef BOOL32 (CALLBACK * LPDDENUMCALLBACKEX32W)(GUID *, LPWSTR, LPWSTR, LPVOID, HMONITOR);
+DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACKEX);
+
+HRESULT WINAPI DirectDrawEnumerateExA( LPDDENUMCALLBACKEX32A lpCallback, LPVOID lpContext, DWORD dwFlags);
+HRESULT WINAPI DirectDrawEnumerateExW( LPDDENUMCALLBACKEX32W lpCallback, LPVOID lpContext, DWORD dwFlags);
+
+/* flags for DirectDrawEnumerateEx */
+#define DDENUM_ATTACHEDSECONDARYDEVICES	0x00000001
+#define DDENUM_DETACHEDSECONDARYDEVICES	0x00000002
+#define DDENUM_NONDISPLAYDEVICES	0x00000004
 
 typedef struct _DDBLTFX
 {
@@ -568,6 +728,7 @@
     {
         DWORD   dwFillColor;                    /* color in RGB or Palettized */
         DWORD   dwFillDepth;                    /* depth value for z-buffer */
+	DWORD   dwFillPixel;			/* pixel val for RGBA or RGBZ */
         LPDIRECTDRAWSURFACE lpDDSPattern;       /* Surface to use as pattern */
     } b;
     DDCOLORKEY  ddckDestColorkey;               /* DestColorkey override */
@@ -631,7 +792,6 @@
 #define STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn)
 #define PURE
 #define FAR
-#define ULONG DWORD
 #define THIS_ THIS ,
 
 #define THIS LPDIRECTDRAWPALETTE this
@@ -704,7 +864,7 @@
     STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE;
     STDMETHOD(RestoreDisplayMode)(THIS) PURE;
     STDMETHOD(SetCooperativeLevel)(THIS_ HWND32, DWORD) PURE;
-    STDMETHOD(SetDisplayMode)(THIS_ DWORD width, DWORD height,DWORD depth) PURE;
+    STDMETHOD(SetDisplayMode)(THIS_ DWORD , DWORD ,DWORD ) PURE;
     STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE32 ) PURE;
 } *LPDIRECTDRAW_VTABLE,IDirectDraw_VTable;
 
@@ -724,28 +884,16 @@
 	DWORD			ref;
 	struct _directdrawdata	d;
 };
+#undef THIS
 
 /* flags for Lock() */
-/* The default.  Set to indicate that Lock should return a valid memory pointer
- * to the top of the specified rectangle.  If no rectangle is specified then a
- * pointer to the top of the surface is returned.
- */
-#define DDLOCK_SURFACEMEMORYPTR	0x00000000L
-/* Set to indicate that Lock should wait until it can obtain a valid memory
- * pointer before returning.  If this bit is set, Lock will never return
- * DDERR_WASSTILLDRAWING.
- */
-#define DDLOCK_WAIT		0x00000001L
-/* Set if an event handle is being passed to Lock.  Lock will trigger the event
- * when it can return the surface memory pointer requested.
- */
-#define DDLOCK_EVENT		0x00000002L
-/* Indicates that the surface being locked will only be read from.  */
-#define DDLOCK_READONLY		0x00000010L
-/* Indicates that the surface being locked will only be written to */
-#define DDLOCK_WRITEONLY	0x00000020L
+#define DDLOCK_SURFACEMEMORYPTR	0x00000000
+#define DDLOCK_WAIT		0x00000001
+#define DDLOCK_EVENT		0x00000002
+#define DDLOCK_READONLY		0x00000010
+#define DDLOCK_WRITEONLY	0x00000020
+#define DDLOCK_NOSYSLOCK	0x00000800
 
-#undef THIS
 
 #define THIS LPDIRECTDRAW2 this
 typedef struct IDirectDraw2_VTable
@@ -775,7 +923,7 @@
     STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE;
     STDMETHOD(RestoreDisplayMode)(THIS) PURE;
     STDMETHOD(SetCooperativeLevel)(THIS_ HWND32, DWORD) PURE;
-    STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD, DWORD, DWORD) PURE;
+    STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD, DWORD, DWORD, DWORD) PURE;
     STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE32 ) PURE;
     /*** Added in the v2 interface ***/
     STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS, LPDWORD, LPDWORD) PURE;
@@ -790,6 +938,14 @@
 #undef THIS
 
 #define THIS LPDIRECTDRAWSURFACE this
+struct _directdrawsurface {
+    LPVOID		surface;
+    LPDIRECTDRAWPALETTE	palette;
+    DWORD		fb_height,lpitch,width,height;
+    LPDIRECTDRAW	ddraw;
+    LPDIRECTDRAWSURFACE	backbuffer;
+};
+
 typedef struct IDirectDrawSurface_VTable {
     /*** IUnknown methods ***/
     STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
@@ -831,13 +987,9 @@
 } *LPDIRECTDRAWSURFACE_VTABLE,IDirectDrawSurface_VTable;
 
 struct IDirectDrawSurface {
-    LPDIRECTDRAWSURFACE_VTABLE lpvtbl;
-    DWORD		ref;
-    LPVOID		surface;
-    LPDIRECTDRAWPALETTE	palette;
-    DWORD		fb_height,lpitch,width,height;
-    LPDIRECTDRAW	ddraw;
-    LPDIRECTDRAWSURFACE	backbuffer;
+    LPDIRECTDRAWSURFACE_VTABLE	lpvtbl;
+    DWORD			ref;
+    struct _directdrawsurface	s;
 };
 #undef THIS
 #define THIS LPDIRECTDRAWSURFACE2 this
@@ -888,12 +1040,79 @@
 
 struct IDirectDrawSurface2 {
     LPDIRECTDRAWSURFACE2_VTABLE	lpvtbl;
-    DWORD		ref;
-    LPVOID		surface;
-    LPDIRECTDRAWPALETTE	palette;
-    DWORD		fb_height,lpitch,width,height;
-    LPDIRECTDRAW	ddraw;
-    LPDIRECTDRAWSURFACE	backbuffer;
+    DWORD			ref;
+    struct _directdrawsurface	s;
+};
+#undef THIS
+#define THIS LPDIRECTDRAWSURFACE3 this
+
+typedef struct IDirectDrawSurface3_VTable {
+    /*** IUnknown methods ***/
+    STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+    STDMETHOD_(ULONG,Release) (THIS) PURE;
+    /*** IDirectDrawSurface methods ***/
+    STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE3) PURE;
+    STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT32) PURE;
+    STDMETHOD(Blt)(THIS_ LPRECT32,LPDIRECTDRAWSURFACE3, LPRECT32,DWORD, LPDDBLTFX) PURE;
+    STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH, DWORD, DWORD ) PURE;
+    STDMETHOD(BltFast)(THIS_ DWORD,DWORD,LPDIRECTDRAWSURFACE3, LPRECT32,DWORD) PURE;
+    STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD,LPDIRECTDRAWSURFACE3) PURE;
+    STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID,LPDDENUMSURFACESCALLBACK) PURE;    STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD,LPVOID,LPDDENUMSURFACESCALLBACK) PURE;
+    STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE3, DWORD) PURE;
+    STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS, LPDIRECTDRAWSURFACE3 FAR *) PURE;
+    STDMETHOD(GetBltStatus)(THIS_ DWORD) PURE;
+    STDMETHOD(GetCaps)(THIS_ LPDDSCAPS) PURE;
+    STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER FAR*) PURE;
+    STDMETHOD(GetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE;
+    STDMETHOD(GetDC)(THIS_ HDC32 FAR *) PURE;
+    STDMETHOD(GetFlipStatus)(THIS_ DWORD) PURE;
+    STDMETHOD(GetOverlayPosition)(THIS_ LPLONG, LPLONG ) PURE;
+    STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE FAR*) PURE;
+    STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT) PURE;
+    STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC) PURE;
+    STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW, LPDDSURFACEDESC) PURE;
+    STDMETHOD(IsLost)(THIS) PURE;
+    STDMETHOD(Lock)(THIS_ LPRECT32,LPDDSURFACEDESC,DWORD,HANDLE32) PURE;
+    STDMETHOD(ReleaseDC)(THIS_ HDC32) PURE;
+    STDMETHOD(Restore)(THIS) PURE;
+    STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER) PURE;
+    STDMETHOD(SetColorKey)(THIS_ DWORD, LPDDCOLORKEY) PURE;
+    STDMETHOD(SetOverlayPosition)(THIS_ LONG, LONG ) PURE;
+    STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE) PURE;
+    STDMETHOD(Unlock)(THIS_ LPVOID) PURE;
+    STDMETHOD(UpdateOverlay)(THIS_ LPRECT32, LPDIRECTDRAWSURFACE3,LPRECT32,DWORD, LPDDOVERLAYFX) PURE;
+    STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD) PURE;
+    STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD, LPDIRECTDRAWSURFACE3) PURE;
+    /*** Added in the v2 interface ***/
+    STDMETHOD(GetDDInterface)(THIS_ LPVOID FAR *) PURE;
+    STDMETHOD(PageLock)(THIS_ DWORD) PURE;
+    STDMETHOD(PageUnlock)(THIS_ DWORD) PURE;
+    /*** Added in the V3 interface ***/
+    STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC, DWORD) PURE;
+} *LPDIRECTDRAWSURFACE3_VTABLE,IDirectDrawSurface3_VTable;
+
+struct IDirectDrawSurface3 {
+    LPDIRECTDRAWSURFACE3_VTABLE	lpvtbl;
+    DWORD			ref;
+    struct _directdrawsurface	s;
+};
+#undef THIS
+
+#define THIS LPDIRECTDRAWCOLORCONTROL this
+typedef struct IDirectDrawColorControl_VTable {
+	/*** IUnknown methods ***/
+	STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
+	STDMETHOD_(ULONG,AddRef) (THIS)  PURE;
+	STDMETHOD_(ULONG,Release) (THIS) PURE;
+	/*** IDirectDrawColorControl methods ***/
+	STDMETHOD(GetColorControls)(THIS_ LPDDCOLORCONTROL) PURE;
+	STDMETHOD(SetColorControls)(THIS_ LPDDCOLORCONTROL) PURE;
+} IDirectDrawColorControl_VTable,*LPDIRECTDRAWCOLORCONTROL_VTABLE;
+
+struct IDirectDrawColorControl  {
+	LPDIRECTDRAWCOLORCONTROL_VTABLE	lpvtbl;
+	DWORD	ref;
 };
 #undef THIS
 
diff --git a/include/debug.h b/include/debug.h
index a34519d..2f35c73 100644
--- a/include/debug.h
+++ b/include/debug.h
@@ -23,10 +23,12 @@
 #undef DEBUG_CURSOR
 #undef DEBUG_DC
 #undef DEBUG_DDE
+#undef DEBUG_DDRAW
 #undef DEBUG_DIALOG
 #undef DEBUG_DLL
 #undef DEBUG_DOSFS
 #undef DEBUG_DRIVER
+#undef DEBUG_DSOUND
 #undef DEBUG_EDIT
 #undef DEBUG_EVENT
 #undef DEBUG_EXEC
@@ -90,6 +92,7 @@
 #undef DEBUG_WIN16DRV
 #undef DEBUG_WIN32
 #undef DEBUG_WINSOCK
+#undef DEBUG_X11
 #endif
 
 #ifdef DEBUG_ALL_EXT
@@ -110,10 +113,12 @@
 #define DEBUG_CURSOR
 #define DEBUG_DC
 #define DEBUG_DDE
+#define DEBUG_DDRAW
 #define DEBUG_DIALOG
 #define DEBUG_DLL
 #define DEBUG_DOSFS
 #define DEBUG_DRIVER
+#define DEBUG_DSOUND
 #define DEBUG_EDIT
 #define DEBUG_EVENT
 #define DEBUG_EXEC
@@ -177,6 +182,7 @@
 #define DEBUG_WIN16DRV
 #define DEBUG_WIN32
 #define DEBUG_WINSOCK
+#define DEBUG_X11
 #endif
 
 #ifdef DEBUG_RUNTIME
@@ -267,6 +273,11 @@
 #else
     0,
 #endif
+#ifdef DEBUG_DDRAW
+    1,
+#else
+    0,
+#endif
 #ifdef DEBUG_DIALOG
     1,
 #else
@@ -287,6 +298,11 @@
 #else
     0,
 #endif
+#ifdef DEBUG_DSOUND
+    1,
+#else
+    0,
+#endif
 #ifdef DEBUG_EDIT
     1,
 #else
@@ -602,6 +618,11 @@
 #else
     0,
 #endif
+#ifdef DEBUG_X11
+    1,
+#else
+    0,
+#endif
     0
 };
 #else
@@ -831,8 +852,21 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dialog if(!debug_msg_enabled[17]) ; else fprintf
-#define debugging_dialog debug_msg_enabled[17]
+#define dprintf_ddraw if(!debug_msg_enabled[17]) ; else fprintf
+#define debugging_ddraw debug_msg_enabled[17]
+#else
+#ifdef DEBUG_DDRAW
+#define dprintf_ddraw fprintf
+#define debugging_ddraw 1
+#else
+#define dprintf_ddraw while(0) fprintf
+#define debugging_ddraw 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_dialog if(!debug_msg_enabled[18]) ; else fprintf
+#define debugging_dialog debug_msg_enabled[18]
 #else
 #ifdef DEBUG_DIALOG
 #define dprintf_dialog fprintf
@@ -844,8 +878,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dll if(!debug_msg_enabled[18]) ; else fprintf
-#define debugging_dll debug_msg_enabled[18]
+#define dprintf_dll if(!debug_msg_enabled[19]) ; else fprintf
+#define debugging_dll debug_msg_enabled[19]
 #else
 #ifdef DEBUG_DLL
 #define dprintf_dll fprintf
@@ -857,8 +891,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_dosfs if(!debug_msg_enabled[19]) ; else fprintf
-#define debugging_dosfs debug_msg_enabled[19]
+#define dprintf_dosfs if(!debug_msg_enabled[20]) ; else fprintf
+#define debugging_dosfs debug_msg_enabled[20]
 #else
 #ifdef DEBUG_DOSFS
 #define dprintf_dosfs fprintf
@@ -870,8 +904,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_driver if(!debug_msg_enabled[20]) ; else fprintf
-#define debugging_driver debug_msg_enabled[20]
+#define dprintf_driver if(!debug_msg_enabled[21]) ; else fprintf
+#define debugging_driver debug_msg_enabled[21]
 #else
 #ifdef DEBUG_DRIVER
 #define dprintf_driver fprintf
@@ -883,8 +917,21 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_edit if(!debug_msg_enabled[21]) ; else fprintf
-#define debugging_edit debug_msg_enabled[21]
+#define dprintf_dsound if(!debug_msg_enabled[22]) ; else fprintf
+#define debugging_dsound debug_msg_enabled[22]
+#else
+#ifdef DEBUG_DSOUND
+#define dprintf_dsound fprintf
+#define debugging_dsound 1
+#else
+#define dprintf_dsound while(0) fprintf
+#define debugging_dsound 0
+#endif
+#endif
+
+#ifdef DEBUG_RUNTIME
+#define dprintf_edit if(!debug_msg_enabled[23]) ; else fprintf
+#define debugging_edit debug_msg_enabled[23]
 #else
 #ifdef DEBUG_EDIT
 #define dprintf_edit fprintf
@@ -896,8 +943,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_event if(!debug_msg_enabled[22]) ; else fprintf
-#define debugging_event debug_msg_enabled[22]
+#define dprintf_event if(!debug_msg_enabled[24]) ; else fprintf
+#define debugging_event debug_msg_enabled[24]
 #else
 #ifdef DEBUG_EVENT
 #define dprintf_event fprintf
@@ -909,8 +956,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_exec if(!debug_msg_enabled[23]) ; else fprintf
-#define debugging_exec debug_msg_enabled[23]
+#define dprintf_exec if(!debug_msg_enabled[25]) ; else fprintf
+#define debugging_exec debug_msg_enabled[25]
 #else
 #ifdef DEBUG_EXEC
 #define dprintf_exec fprintf
@@ -922,8 +969,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_file if(!debug_msg_enabled[24]) ; else fprintf
-#define debugging_file debug_msg_enabled[24]
+#define dprintf_file if(!debug_msg_enabled[26]) ; else fprintf
+#define debugging_file debug_msg_enabled[26]
 #else
 #ifdef DEBUG_FILE
 #define dprintf_file fprintf
@@ -935,8 +982,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_fixup if(!debug_msg_enabled[25]) ; else fprintf
-#define debugging_fixup debug_msg_enabled[25]
+#define dprintf_fixup if(!debug_msg_enabled[27]) ; else fprintf
+#define debugging_fixup debug_msg_enabled[27]
 #else
 #ifdef DEBUG_FIXUP
 #define dprintf_fixup fprintf
@@ -948,8 +995,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_font if(!debug_msg_enabled[26]) ; else fprintf
-#define debugging_font debug_msg_enabled[26]
+#define dprintf_font if(!debug_msg_enabled[28]) ; else fprintf
+#define debugging_font debug_msg_enabled[28]
 #else
 #ifdef DEBUG_FONT
 #define dprintf_font fprintf
@@ -961,8 +1008,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_gdi if(!debug_msg_enabled[27]) ; else fprintf
-#define debugging_gdi debug_msg_enabled[27]
+#define dprintf_gdi if(!debug_msg_enabled[29]) ; else fprintf
+#define debugging_gdi debug_msg_enabled[29]
 #else
 #ifdef DEBUG_GDI
 #define dprintf_gdi fprintf
@@ -974,8 +1021,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_global if(!debug_msg_enabled[28]) ; else fprintf
-#define debugging_global debug_msg_enabled[28]
+#define dprintf_global if(!debug_msg_enabled[30]) ; else fprintf
+#define debugging_global debug_msg_enabled[30]
 #else
 #ifdef DEBUG_GLOBAL
 #define dprintf_global fprintf
@@ -987,8 +1034,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_graphics if(!debug_msg_enabled[29]) ; else fprintf
-#define debugging_graphics debug_msg_enabled[29]
+#define dprintf_graphics if(!debug_msg_enabled[31]) ; else fprintf
+#define debugging_graphics debug_msg_enabled[31]
 #else
 #ifdef DEBUG_GRAPHICS
 #define dprintf_graphics fprintf
@@ -1000,8 +1047,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_heap if(!debug_msg_enabled[30]) ; else fprintf
-#define debugging_heap debug_msg_enabled[30]
+#define dprintf_heap if(!debug_msg_enabled[32]) ; else fprintf
+#define debugging_heap debug_msg_enabled[32]
 #else
 #ifdef DEBUG_HEAP
 #define dprintf_heap fprintf
@@ -1013,8 +1060,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_hook if(!debug_msg_enabled[31]) ; else fprintf
-#define debugging_hook debug_msg_enabled[31]
+#define dprintf_hook if(!debug_msg_enabled[33]) ; else fprintf
+#define debugging_hook debug_msg_enabled[33]
 #else
 #ifdef DEBUG_HOOK
 #define dprintf_hook fprintf
@@ -1026,8 +1073,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_icon if(!debug_msg_enabled[32]) ; else fprintf
-#define debugging_icon debug_msg_enabled[32]
+#define dprintf_icon if(!debug_msg_enabled[34]) ; else fprintf
+#define debugging_icon debug_msg_enabled[34]
 #else
 #ifdef DEBUG_ICON
 #define dprintf_icon fprintf
@@ -1039,8 +1086,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_int if(!debug_msg_enabled[33]) ; else fprintf
-#define debugging_int debug_msg_enabled[33]
+#define dprintf_int if(!debug_msg_enabled[35]) ; else fprintf
+#define debugging_int debug_msg_enabled[35]
 #else
 #ifdef DEBUG_INT
 #define dprintf_int fprintf
@@ -1052,8 +1099,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_key if(!debug_msg_enabled[34]) ; else fprintf
-#define debugging_key debug_msg_enabled[34]
+#define dprintf_key if(!debug_msg_enabled[36]) ; else fprintf
+#define debugging_key debug_msg_enabled[36]
 #else
 #ifdef DEBUG_KEY
 #define dprintf_key fprintf
@@ -1065,8 +1112,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_keyboard if(!debug_msg_enabled[35]) ; else fprintf
-#define debugging_keyboard debug_msg_enabled[35]
+#define dprintf_keyboard if(!debug_msg_enabled[37]) ; else fprintf
+#define debugging_keyboard debug_msg_enabled[37]
 #else
 #ifdef DEBUG_KEYBOARD
 #define dprintf_keyboard fprintf
@@ -1078,8 +1125,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_ldt if(!debug_msg_enabled[36]) ; else fprintf
-#define debugging_ldt debug_msg_enabled[36]
+#define dprintf_ldt if(!debug_msg_enabled[38]) ; else fprintf
+#define debugging_ldt debug_msg_enabled[38]
 #else
 #ifdef DEBUG_LDT
 #define dprintf_ldt fprintf
@@ -1091,8 +1138,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_listbox if(!debug_msg_enabled[37]) ; else fprintf
-#define debugging_listbox debug_msg_enabled[37]
+#define dprintf_listbox if(!debug_msg_enabled[39]) ; else fprintf
+#define debugging_listbox debug_msg_enabled[39]
 #else
 #ifdef DEBUG_LISTBOX
 #define dprintf_listbox fprintf
@@ -1104,8 +1151,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_local if(!debug_msg_enabled[38]) ; else fprintf
-#define debugging_local debug_msg_enabled[38]
+#define dprintf_local if(!debug_msg_enabled[40]) ; else fprintf
+#define debugging_local debug_msg_enabled[40]
 #else
 #ifdef DEBUG_LOCAL
 #define dprintf_local fprintf
@@ -1117,8 +1164,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mci if(!debug_msg_enabled[39]) ; else fprintf
-#define debugging_mci debug_msg_enabled[39]
+#define dprintf_mci if(!debug_msg_enabled[41]) ; else fprintf
+#define debugging_mci debug_msg_enabled[41]
 #else
 #ifdef DEBUG_MCI
 #define dprintf_mci fprintf
@@ -1130,8 +1177,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mcianim if(!debug_msg_enabled[40]) ; else fprintf
-#define debugging_mcianim debug_msg_enabled[40]
+#define dprintf_mcianim if(!debug_msg_enabled[42]) ; else fprintf
+#define debugging_mcianim debug_msg_enabled[42]
 #else
 #ifdef DEBUG_MCIANIM
 #define dprintf_mcianim fprintf
@@ -1143,8 +1190,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mciwave if(!debug_msg_enabled[41]) ; else fprintf
-#define debugging_mciwave debug_msg_enabled[41]
+#define dprintf_mciwave if(!debug_msg_enabled[43]) ; else fprintf
+#define debugging_mciwave debug_msg_enabled[43]
 #else
 #ifdef DEBUG_MCIWAVE
 #define dprintf_mciwave fprintf
@@ -1156,8 +1203,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mdi if(!debug_msg_enabled[42]) ; else fprintf
-#define debugging_mdi debug_msg_enabled[42]
+#define dprintf_mdi if(!debug_msg_enabled[44]) ; else fprintf
+#define debugging_mdi debug_msg_enabled[44]
 #else
 #ifdef DEBUG_MDI
 #define dprintf_mdi fprintf
@@ -1169,8 +1216,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_menu if(!debug_msg_enabled[43]) ; else fprintf
-#define debugging_menu debug_msg_enabled[43]
+#define dprintf_menu if(!debug_msg_enabled[45]) ; else fprintf
+#define debugging_menu debug_msg_enabled[45]
 #else
 #ifdef DEBUG_MENU
 #define dprintf_menu fprintf
@@ -1182,8 +1229,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_message if(!debug_msg_enabled[44]) ; else fprintf
-#define debugging_message debug_msg_enabled[44]
+#define dprintf_message if(!debug_msg_enabled[46]) ; else fprintf
+#define debugging_message debug_msg_enabled[46]
 #else
 #ifdef DEBUG_MESSAGE
 #define dprintf_message fprintf
@@ -1195,8 +1242,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_metafile if(!debug_msg_enabled[45]) ; else fprintf
-#define debugging_metafile debug_msg_enabled[45]
+#define dprintf_metafile if(!debug_msg_enabled[47]) ; else fprintf
+#define debugging_metafile debug_msg_enabled[47]
 #else
 #ifdef DEBUG_METAFILE
 #define dprintf_metafile fprintf
@@ -1208,8 +1255,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_midi if(!debug_msg_enabled[46]) ; else fprintf
-#define debugging_midi debug_msg_enabled[46]
+#define dprintf_midi if(!debug_msg_enabled[48]) ; else fprintf
+#define debugging_midi debug_msg_enabled[48]
 #else
 #ifdef DEBUG_MIDI
 #define dprintf_midi fprintf
@@ -1221,8 +1268,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mmaux if(!debug_msg_enabled[47]) ; else fprintf
-#define debugging_mmaux debug_msg_enabled[47]
+#define dprintf_mmaux if(!debug_msg_enabled[49]) ; else fprintf
+#define debugging_mmaux debug_msg_enabled[49]
 #else
 #ifdef DEBUG_MMAUX
 #define dprintf_mmaux fprintf
@@ -1234,8 +1281,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mmio if(!debug_msg_enabled[48]) ; else fprintf
-#define debugging_mmio debug_msg_enabled[48]
+#define dprintf_mmio if(!debug_msg_enabled[50]) ; else fprintf
+#define debugging_mmio debug_msg_enabled[50]
 #else
 #ifdef DEBUG_MMIO
 #define dprintf_mmio fprintf
@@ -1247,8 +1294,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mmsys if(!debug_msg_enabled[49]) ; else fprintf
-#define debugging_mmsys debug_msg_enabled[49]
+#define dprintf_mmsys if(!debug_msg_enabled[51]) ; else fprintf
+#define debugging_mmsys debug_msg_enabled[51]
 #else
 #ifdef DEBUG_MMSYS
 #define dprintf_mmsys fprintf
@@ -1260,8 +1307,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_mmtime if(!debug_msg_enabled[50]) ; else fprintf
-#define debugging_mmtime debug_msg_enabled[50]
+#define dprintf_mmtime if(!debug_msg_enabled[52]) ; else fprintf
+#define debugging_mmtime debug_msg_enabled[52]
 #else
 #ifdef DEBUG_MMTIME
 #define dprintf_mmtime fprintf
@@ -1273,8 +1320,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_module if(!debug_msg_enabled[51]) ; else fprintf
-#define debugging_module debug_msg_enabled[51]
+#define dprintf_module if(!debug_msg_enabled[53]) ; else fprintf
+#define debugging_module debug_msg_enabled[53]
 #else
 #ifdef DEBUG_MODULE
 #define dprintf_module fprintf
@@ -1286,8 +1333,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_msg if(!debug_msg_enabled[52]) ; else fprintf
-#define debugging_msg debug_msg_enabled[52]
+#define dprintf_msg if(!debug_msg_enabled[54]) ; else fprintf
+#define debugging_msg debug_msg_enabled[54]
 #else
 #ifdef DEBUG_MSG
 #define dprintf_msg fprintf
@@ -1299,8 +1346,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_nonclient if(!debug_msg_enabled[53]) ; else fprintf
-#define debugging_nonclient debug_msg_enabled[53]
+#define dprintf_nonclient if(!debug_msg_enabled[55]) ; else fprintf
+#define debugging_nonclient debug_msg_enabled[55]
 #else
 #ifdef DEBUG_NONCLIENT
 #define dprintf_nonclient fprintf
@@ -1312,8 +1359,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_ole if(!debug_msg_enabled[54]) ; else fprintf
-#define debugging_ole debug_msg_enabled[54]
+#define dprintf_ole if(!debug_msg_enabled[56]) ; else fprintf
+#define debugging_ole debug_msg_enabled[56]
 #else
 #ifdef DEBUG_OLE
 #define dprintf_ole fprintf
@@ -1325,8 +1372,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_palette if(!debug_msg_enabled[55]) ; else fprintf
-#define debugging_palette debug_msg_enabled[55]
+#define dprintf_palette if(!debug_msg_enabled[57]) ; else fprintf
+#define debugging_palette debug_msg_enabled[57]
 #else
 #ifdef DEBUG_PALETTE
 #define dprintf_palette fprintf
@@ -1338,8 +1385,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_profile if(!debug_msg_enabled[56]) ; else fprintf
-#define debugging_profile debug_msg_enabled[56]
+#define dprintf_profile if(!debug_msg_enabled[58]) ; else fprintf
+#define debugging_profile debug_msg_enabled[58]
 #else
 #ifdef DEBUG_PROFILE
 #define dprintf_profile fprintf
@@ -1351,8 +1398,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_progress if(!debug_msg_enabled[57]) ; else fprintf
-#define debugging_progress debug_msg_enabled[57]
+#define dprintf_progress if(!debug_msg_enabled[59]) ; else fprintf
+#define debugging_progress debug_msg_enabled[59]
 #else
 #ifdef DEBUG_PROGRESS
 #define dprintf_progress fprintf
@@ -1364,8 +1411,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_prop if(!debug_msg_enabled[58]) ; else fprintf
-#define debugging_prop debug_msg_enabled[58]
+#define dprintf_prop if(!debug_msg_enabled[60]) ; else fprintf
+#define debugging_prop debug_msg_enabled[60]
 #else
 #ifdef DEBUG_PROP
 #define dprintf_prop fprintf
@@ -1377,8 +1424,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_reg if(!debug_msg_enabled[59]) ; else fprintf
-#define debugging_reg debug_msg_enabled[59]
+#define dprintf_reg if(!debug_msg_enabled[61]) ; else fprintf
+#define debugging_reg debug_msg_enabled[61]
 #else
 #ifdef DEBUG_REG
 #define dprintf_reg fprintf
@@ -1390,8 +1437,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_region if(!debug_msg_enabled[60]) ; else fprintf
-#define debugging_region debug_msg_enabled[60]
+#define dprintf_region if(!debug_msg_enabled[62]) ; else fprintf
+#define debugging_region debug_msg_enabled[62]
 #else
 #ifdef DEBUG_REGION
 #define dprintf_region fprintf
@@ -1403,8 +1450,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_relay if(!debug_msg_enabled[61]) ; else fprintf
-#define debugging_relay debug_msg_enabled[61]
+#define dprintf_relay if(!debug_msg_enabled[63]) ; else fprintf
+#define debugging_relay debug_msg_enabled[63]
 #else
 #ifdef DEBUG_RELAY
 #define dprintf_relay fprintf
@@ -1416,8 +1463,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_resource if(!debug_msg_enabled[62]) ; else fprintf
-#define debugging_resource debug_msg_enabled[62]
+#define dprintf_resource if(!debug_msg_enabled[64]) ; else fprintf
+#define debugging_resource debug_msg_enabled[64]
 #else
 #ifdef DEBUG_RESOURCE
 #define dprintf_resource fprintf
@@ -1429,8 +1476,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_scroll if(!debug_msg_enabled[63]) ; else fprintf
-#define debugging_scroll debug_msg_enabled[63]
+#define dprintf_scroll if(!debug_msg_enabled[65]) ; else fprintf
+#define debugging_scroll debug_msg_enabled[65]
 #else
 #ifdef DEBUG_SCROLL
 #define dprintf_scroll fprintf
@@ -1442,8 +1489,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_selector if(!debug_msg_enabled[64]) ; else fprintf
-#define debugging_selector debug_msg_enabled[64]
+#define dprintf_selector if(!debug_msg_enabled[66]) ; else fprintf
+#define debugging_selector debug_msg_enabled[66]
 #else
 #ifdef DEBUG_SELECTOR
 #define dprintf_selector fprintf
@@ -1455,8 +1502,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_sem if(!debug_msg_enabled[65]) ; else fprintf
-#define debugging_sem debug_msg_enabled[65]
+#define dprintf_sem if(!debug_msg_enabled[67]) ; else fprintf
+#define debugging_sem debug_msg_enabled[67]
 #else
 #ifdef DEBUG_SEM
 #define dprintf_sem fprintf
@@ -1468,8 +1515,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_sendmsg if(!debug_msg_enabled[66]) ; else fprintf
-#define debugging_sendmsg debug_msg_enabled[66]
+#define dprintf_sendmsg if(!debug_msg_enabled[68]) ; else fprintf
+#define debugging_sendmsg debug_msg_enabled[68]
 #else
 #ifdef DEBUG_SENDMSG
 #define dprintf_sendmsg fprintf
@@ -1481,8 +1528,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_shm if(!debug_msg_enabled[67]) ; else fprintf
-#define debugging_shm debug_msg_enabled[67]
+#define dprintf_shm if(!debug_msg_enabled[69]) ; else fprintf
+#define debugging_shm debug_msg_enabled[69]
 #else
 #ifdef DEBUG_SHM
 #define dprintf_shm fprintf
@@ -1494,8 +1541,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_stress if(!debug_msg_enabled[68]) ; else fprintf
-#define debugging_stress debug_msg_enabled[68]
+#define dprintf_stress if(!debug_msg_enabled[70]) ; else fprintf
+#define debugging_stress debug_msg_enabled[70]
 #else
 #ifdef DEBUG_STRESS
 #define dprintf_stress fprintf
@@ -1507,8 +1554,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_string if(!debug_msg_enabled[69]) ; else fprintf
-#define debugging_string debug_msg_enabled[69]
+#define dprintf_string if(!debug_msg_enabled[71]) ; else fprintf
+#define debugging_string debug_msg_enabled[71]
 #else
 #ifdef DEBUG_STRING
 #define dprintf_string fprintf
@@ -1520,8 +1567,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_task if(!debug_msg_enabled[70]) ; else fprintf
-#define debugging_task debug_msg_enabled[70]
+#define dprintf_task if(!debug_msg_enabled[72]) ; else fprintf
+#define debugging_task debug_msg_enabled[72]
 #else
 #ifdef DEBUG_TASK
 #define dprintf_task fprintf
@@ -1533,8 +1580,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_text if(!debug_msg_enabled[71]) ; else fprintf
-#define debugging_text debug_msg_enabled[71]
+#define dprintf_text if(!debug_msg_enabled[73]) ; else fprintf
+#define debugging_text debug_msg_enabled[73]
 #else
 #ifdef DEBUG_TEXT
 #define dprintf_text fprintf
@@ -1546,8 +1593,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_thunk if(!debug_msg_enabled[72]) ; else fprintf
-#define debugging_thunk debug_msg_enabled[72]
+#define dprintf_thunk if(!debug_msg_enabled[74]) ; else fprintf
+#define debugging_thunk debug_msg_enabled[74]
 #else
 #ifdef DEBUG_THUNK
 #define dprintf_thunk fprintf
@@ -1559,8 +1606,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_timer if(!debug_msg_enabled[73]) ; else fprintf
-#define debugging_timer debug_msg_enabled[73]
+#define dprintf_timer if(!debug_msg_enabled[75]) ; else fprintf
+#define debugging_timer debug_msg_enabled[75]
 #else
 #ifdef DEBUG_TIMER
 #define dprintf_timer fprintf
@@ -1572,8 +1619,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_toolhelp if(!debug_msg_enabled[74]) ; else fprintf
-#define debugging_toolhelp debug_msg_enabled[74]
+#define dprintf_toolhelp if(!debug_msg_enabled[76]) ; else fprintf
+#define debugging_toolhelp debug_msg_enabled[76]
 #else
 #ifdef DEBUG_TOOLHELP
 #define dprintf_toolhelp fprintf
@@ -1585,8 +1632,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_tweak if(!debug_msg_enabled[75]) ; else fprintf
-#define debugging_tweak debug_msg_enabled[75]
+#define dprintf_tweak if(!debug_msg_enabled[77]) ; else fprintf
+#define debugging_tweak debug_msg_enabled[77]
 #else
 #ifdef DEBUG_TWEAK
 #define dprintf_tweak fprintf
@@ -1598,8 +1645,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_updown if(!debug_msg_enabled[76]) ; else fprintf
-#define debugging_updown debug_msg_enabled[76]
+#define dprintf_updown if(!debug_msg_enabled[78]) ; else fprintf
+#define debugging_updown debug_msg_enabled[78]
 #else
 #ifdef DEBUG_UPDOWN
 #define dprintf_updown fprintf
@@ -1611,8 +1658,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_ver if(!debug_msg_enabled[77]) ; else fprintf
-#define debugging_ver debug_msg_enabled[77]
+#define dprintf_ver if(!debug_msg_enabled[79]) ; else fprintf
+#define debugging_ver debug_msg_enabled[79]
 #else
 #ifdef DEBUG_VER
 #define dprintf_ver fprintf
@@ -1624,8 +1671,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_virtual if(!debug_msg_enabled[78]) ; else fprintf
-#define debugging_virtual debug_msg_enabled[78]
+#define dprintf_virtual if(!debug_msg_enabled[80]) ; else fprintf
+#define debugging_virtual debug_msg_enabled[80]
 #else
 #ifdef DEBUG_VIRTUAL
 #define dprintf_virtual fprintf
@@ -1637,8 +1684,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_vxd if(!debug_msg_enabled[79]) ; else fprintf
-#define debugging_vxd debug_msg_enabled[79]
+#define dprintf_vxd if(!debug_msg_enabled[81]) ; else fprintf
+#define debugging_vxd debug_msg_enabled[81]
 #else
 #ifdef DEBUG_VXD
 #define dprintf_vxd fprintf
@@ -1650,8 +1697,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_win if(!debug_msg_enabled[80]) ; else fprintf
-#define debugging_win debug_msg_enabled[80]
+#define dprintf_win if(!debug_msg_enabled[82]) ; else fprintf
+#define debugging_win debug_msg_enabled[82]
 #else
 #ifdef DEBUG_WIN
 #define dprintf_win fprintf
@@ -1663,8 +1710,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_win16drv if(!debug_msg_enabled[81]) ; else fprintf
-#define debugging_win16drv debug_msg_enabled[81]
+#define dprintf_win16drv if(!debug_msg_enabled[83]) ; else fprintf
+#define debugging_win16drv debug_msg_enabled[83]
 #else
 #ifdef DEBUG_WIN16DRV
 #define dprintf_win16drv fprintf
@@ -1676,8 +1723,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_win32 if(!debug_msg_enabled[82]) ; else fprintf
-#define debugging_win32 debug_msg_enabled[82]
+#define dprintf_win32 if(!debug_msg_enabled[84]) ; else fprintf
+#define debugging_win32 debug_msg_enabled[84]
 #else
 #ifdef DEBUG_WIN32
 #define dprintf_win32 fprintf
@@ -1689,8 +1736,8 @@
 #endif
 
 #ifdef DEBUG_RUNTIME
-#define dprintf_winsock if(!debug_msg_enabled[83]) ; else fprintf
-#define debugging_winsock debug_msg_enabled[83]
+#define dprintf_winsock if(!debug_msg_enabled[85]) ; else fprintf
+#define debugging_winsock debug_msg_enabled[85]
 #else
 #ifdef DEBUG_WINSOCK
 #define dprintf_winsock fprintf
@@ -1701,6 +1748,19 @@
 #endif
 #endif
 
+#ifdef DEBUG_RUNTIME
+#define dprintf_x11 if(!debug_msg_enabled[86]) ; else fprintf
+#define debugging_x11 debug_msg_enabled[86]
+#else
+#ifdef DEBUG_X11
+#define dprintf_x11 fprintf
+#define debugging_x11 1
+#else
+#define dprintf_x11 while(0) fprintf
+#define debugging_x11 0
+#endif
+#endif
+
 
 #ifdef DEBUG_RUNTIME
 #ifdef DEBUG_DEFINE_VARIABLES
@@ -1722,10 +1782,12 @@
     "cursor",
     "dc",
     "dde",
+    "ddraw",
     "dialog",
     "dll",
     "dosfs",
     "driver",
+    "dsound",
     "edit",
     "event",
     "exec",
@@ -1789,6 +1851,7 @@
     "win16drv",
     "win32",
     "winsock",
+    "x11",
     ""
 };
 #endif
diff --git a/include/dinput.h b/include/dinput.h
new file mode 100644
index 0000000..563c7e1
--- /dev/null
+++ b/include/dinput.h
@@ -0,0 +1,432 @@
+#ifndef _WINE_DINPUT_H
+#define _WINE_DINPUT_H
+
+#define STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn)
+#define STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn)
+#define PURE
+#define FAR
+#define THIS_ THIS,
+
+#define DIRECTINPUT_VERSION	0x0500
+
+/* Classes */
+DEFINE_GUID(CLSID_DirectInput,		0x25E609E0,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(CLSID_DirectInputDevice,	0x25E609E1,0xB259,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+/* Interfaces */
+DEFINE_GUID(IID_IDirectInputA,		0x89521360,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputW,		0x89521361,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInput2A,		0x5944E662,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInput2W,		0x5944E663,0xAA8A,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDeviceA,	0x5944E680,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDeviceW,	0x5944E681,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDevice2A,	0x5944E682,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputDevice2W,	0x5944E683,0xC92E,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(IID_IDirectInputEffect,	0xE7E1F7C0,0x88D2,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+
+/* Predefined object types */
+DEFINE_GUID(GUID_XAxis,	0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_YAxis,	0xA36D02E1,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_ZAxis,	0xA36D02E2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_RxAxis,0xA36D02F4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_RyAxis,0xA36D02F5,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_RzAxis,0xA36D02E3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Slider,0xA36D02E4,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Button,0xA36D02F0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Key,	0x55728220,0xD33C,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_POV,	0xA36D02F2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Unknown,0xA36D02F3,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+/* Predefined product GUIDs */
+DEFINE_GUID(GUID_SysMouse,	0x6F1D2B60,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_SysKeyboard,	0x6F1D2B61,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+DEFINE_GUID(GUID_Joystick,	0x6F1D2B70,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
+
+/* predefined forcefeedback effects */
+DEFINE_GUID(GUID_ConstantForce,	0x13541C20,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_RampForce,	0x13541C21,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Square,	0x13541C22,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Sine,		0x13541C23,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Triangle,	0x13541C24,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_SawtoothUp,	0x13541C25,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_SawtoothDown,	0x13541C26,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Spring,	0x13541C27,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Damper,	0x13541C28,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Inertia,	0x13541C29,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_Friction,	0x13541C2A,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+DEFINE_GUID(GUID_CustomForce,	0x13541C2B,0x8E33,0x11D0,0x9A,0xD0,0x00,0xA0,0xC9,0xA0,0x6E,0x35);
+
+typedef struct IDirectInput32A IDirectInput32A,*LPDIRECTINPUT32A;
+typedef struct IDirectInputDevice32A IDirectInputDevice32A,*LPDIRECTINPUTDEVICE32A;
+
+typedef struct {
+    DWORD	dwSize;
+    GUID	guidType;
+    DWORD	dwOfs;
+    DWORD	dwType;
+    DWORD	dwFlags;
+    CHAR	tszName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+    DWORD	dwFFMaxForce;
+    DWORD	dwFFForceResolution;
+    WORD	wCollectionNumber;
+    WORD	wDesignatorIndex;
+    WORD	wUsagePage;
+    WORD	wUsage;
+    DWORD	dwDimension;
+    WORD	wExponent;
+    WORD	wReserved;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEOBJECTINSTANCE32A, *LPDIDEVICEOBJECTINSTANCE32A,*LPCDIDEVICEOBJECTINSTANCE32A;
+
+typedef struct {
+    DWORD	dwSize;
+    GUID	guidType;
+    DWORD	dwOfs;
+    DWORD	dwType;
+    DWORD	dwFlags;
+    WCHAR	tszName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+    DWORD	dwFFMaxForce;
+    DWORD	dwFFForceResolution;
+    WORD	wCollectionNumber;
+    WORD	wDesignatorIndex;
+    WORD	wUsagePage;
+    WORD	wUsage;
+    DWORD	dwDimension;
+    WORD	wExponent;
+    WORD	wReserved;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEOBJECTINSTANCE32W, *LPDIDEVICEOBJECTINSTANCE32W,*LPCDIDEVICEOBJECTINSTANCE32W;
+DECL_WINELIB_TYPE_AW(LPDIDEVICEOBJECTINSTANCE);
+DECL_WINELIB_TYPE_AW(DIDEVICEOBJECTINSTANCE);
+
+
+typedef struct {
+    DWORD	dwSize;
+    GUID	guidInstance;
+    GUID	guidProduct;
+    DWORD	dwDevType;
+    CHAR	tszInstanceName[MAX_PATH];
+    CHAR	tszProductName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+    GUID	guidFFDriver;
+    WORD	wUsagePage;
+    WORD	wUsage;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEINSTANCE32A, *LPDIDEVICEINSTANCE32A, *LPCDIDEVICEINSTANCE32A;
+
+typedef struct {
+    DWORD	dwSize;
+    GUID	guidInstance;
+    GUID	guidProduct;
+    DWORD	dwDevType;
+    WCHAR	tszInstanceName[MAX_PATH];
+    WCHAR	tszProductName[MAX_PATH];
+#if(DIRECTINPUT_VERSION >= 0x0500)
+    GUID	guidFFDriver;
+    WORD	wUsagePage;
+    WORD	wUsage;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVICEINSTANCE32W, *LPDIDEVICEINSTANCE32W, *LPCDIDEVICEINSTANCE32W;
+DECL_WINELIB_TYPE_AW(DIDEVICEINSTANCE);
+DECL_WINELIB_TYPE_AW(LPDIDEVICEINSTANCE);
+DECL_WINELIB_TYPE_AW(LPCDIDEVICEINSTANCE);
+
+typedef BOOL32 (CALLBACK * LPDIENUMDEVICESCALLBACK32A)(LPCDIDEVICEINSTANCE32A,LPVOID);
+typedef BOOL32 (CALLBACK * LPDIENUMDEVICESCALLBACK32W)(LPCDIDEVICEINSTANCE32W,LPVOID);
+DECL_WINELIB_TYPE_AW(LPDIENUMDEVICESCALLBACK);
+
+typedef BOOL32 (CALLBACK * LPDIENUMDEVICEOBJECTSCALLBACK32A)(LPCDIDEVICEOBJECTINSTANCE32A, LPVOID);
+typedef BOOL32 (CALLBACK * LPDIENUMDEVICEOBJECTSCALLBACK32W)(LPCDIDEVICEOBJECTINSTANCE32W,LPVOID);
+DECL_WINELIB_TYPE_AW(LPDIENUMDEVICEOBJECTSCALLBACK);
+
+#define DIK_ESCAPE          0x01
+#define DIK_1               0x02
+#define DIK_2               0x03
+#define DIK_3               0x04
+#define DIK_4               0x05
+#define DIK_5               0x06
+#define DIK_6               0x07
+#define DIK_7               0x08
+#define DIK_8               0x09
+#define DIK_9               0x0A
+#define DIK_0               0x0B
+#define DIK_MINUS           0x0C    /* - on main keyboard */
+#define DIK_EQUALS          0x0D
+#define DIK_BACK            0x0E    /* backspace */
+#define DIK_TAB             0x0F
+#define DIK_Q               0x10
+#define DIK_W               0x11
+#define DIK_E               0x12
+#define DIK_R               0x13
+#define DIK_T               0x14
+#define DIK_Y               0x15
+#define DIK_U               0x16
+#define DIK_I               0x17
+#define DIK_O               0x18
+#define DIK_P               0x19
+#define DIK_LBRACKET        0x1A
+#define DIK_RBRACKET        0x1B
+#define DIK_RETURN          0x1C    /* Enter on main keyboard */
+#define DIK_LCONTROL        0x1D
+#define DIK_A               0x1E
+#define DIK_S               0x1F
+#define DIK_D               0x20
+#define DIK_F               0x21
+#define DIK_G               0x22
+#define DIK_H               0x23
+#define DIK_J               0x24
+#define DIK_K               0x25
+#define DIK_L               0x26
+#define DIK_SEMICOLON       0x27
+#define DIK_APOSTROPHE      0x28
+#define DIK_GRAVE           0x29    /* accent grave */
+#define DIK_LSHIFT          0x2A
+#define DIK_BACKSLASH       0x2B
+#define DIK_Z               0x2C
+#define DIK_X               0x2D
+#define DIK_C               0x2E
+#define DIK_V               0x2F
+#define DIK_B               0x30
+#define DIK_N               0x31
+#define DIK_M               0x32
+#define DIK_COMMA           0x33
+#define DIK_PERIOD          0x34    /* . on main keyboard */
+#define DIK_SLASH           0x35    /* / on main keyboard */
+#define DIK_RSHIFT          0x36
+#define DIK_MULTIPLY        0x37    /* * on numeric keypad */
+#define DIK_LMENU           0x38    /* left Alt */
+#define DIK_SPACE           0x39
+#define DIK_CAPITAL         0x3A
+#define DIK_F1              0x3B
+#define DIK_F2              0x3C
+#define DIK_F3              0x3D
+#define DIK_F4              0x3E
+#define DIK_F5              0x3F
+#define DIK_F6              0x40
+#define DIK_F7              0x41
+#define DIK_F8              0x42
+#define DIK_F9              0x43
+#define DIK_F10             0x44
+#define DIK_NUMLOCK         0x45
+#define DIK_SCROLL          0x46    /* Scroll Lock */
+#define DIK_NUMPAD7         0x47
+#define DIK_NUMPAD8         0x48
+#define DIK_NUMPAD9         0x49
+#define DIK_SUBTRACT        0x4A    /* - on numeric keypad */
+#define DIK_NUMPAD4         0x4B
+#define DIK_NUMPAD5         0x4C
+#define DIK_NUMPAD6         0x4D
+#define DIK_ADD             0x4E    /* + on numeric keypad */
+#define DIK_NUMPAD1         0x4F
+#define DIK_NUMPAD2         0x50
+#define DIK_NUMPAD3         0x51
+#define DIK_NUMPAD0         0x52
+#define DIK_DECIMAL         0x53    /* . on numeric keypad */
+#define DIK_F11             0x57
+#define DIK_F12             0x58
+#define DIK_F13             0x64    /*                     (NEC PC98) */
+#define DIK_F14             0x65    /*                     (NEC PC98) */
+#define DIK_F15             0x66    /*                     (NEC PC98) */
+#define DIK_KANA            0x70    /* (Japanese keyboard)            */
+#define DIK_CONVERT         0x79    /* (Japanese keyboard)            */
+#define DIK_NOCONVERT       0x7B    /* (Japanese keyboard)            */
+#define DIK_YEN             0x7D    /* (Japanese keyboard)            */
+#define DIK_NUMPADEQUALS    0x8D    /* = on numeric keypad (NEC PC98) */
+#define DIK_CIRCUMFLEX      0x90    /* (Japanese keyboard)            */
+#define DIK_AT              0x91    /*                     (NEC PC98) */
+#define DIK_COLON           0x92    /*                     (NEC PC98) */
+#define DIK_UNDERLINE       0x93    /*                     (NEC PC98) */
+#define DIK_KANJI           0x94    /* (Japanese keyboard)            */
+#define DIK_STOP            0x95    /*                     (NEC PC98) */
+#define DIK_AX              0x96    /*                     (Japan AX) */
+#define DIK_UNLABELED       0x97    /*                        (J3100) */
+#define DIK_NUMPADENTER     0x9C    /* Enter on numeric keypad */
+#define DIK_RCONTROL        0x9D
+#define DIK_NUMPADCOMMA     0xB3    /* , on numeric keypad (NEC PC98) */
+#define DIK_DIVIDE          0xB5    /* / on numeric keypad */
+#define DIK_SYSRQ           0xB7
+#define DIK_RMENU           0xB8    /* right Alt */
+#define DIK_PAUSE           0xC5    /* Pause */
+#define DIK_HOME            0xC7    /* Home on arrow keypad */
+#define DIK_UP              0xC8    /* UpArrow on arrow keypad */
+#define DIK_PRIOR           0xC9    /* PgUp on arrow keypad */
+#define DIK_LEFT            0xCB    /* LeftArrow on arrow keypad */
+#define DIK_RIGHT           0xCD    /* RightArrow on arrow keypad */
+#define DIK_END             0xCF    /* End on arrow keypad */
+#define DIK_DOWN            0xD0    /* DownArrow on arrow keypad */
+#define DIK_NEXT            0xD1    /* PgDn on arrow keypad */
+#define DIK_INSERT          0xD2    /* Insert on arrow keypad */
+#define DIK_DELETE          0xD3    /* Delete on arrow keypad */
+#define DIK_LWIN            0xDB    /* Left Windows key */
+#define DIK_RWIN            0xDC    /* Right Windows key */
+#define DIK_APPS            0xDD    /* AppMenu key */
+#define DIK_POWER           0xDE
+#define DIK_SLEEP           0xDF
+#define DIK_BACKSPACE       DIK_BACK            /* backspace */
+#define DIK_NUMPADSTAR      DIK_MULTIPLY        /* * on numeric keypad */
+#define DIK_LALT            DIK_LMENU           /* left Alt */
+#define DIK_CAPSLOCK        DIK_CAPITAL         /* CapsLock */
+#define DIK_NUMPADMINUS     DIK_SUBTRACT        /* - on numeric keypad */
+#define DIK_NUMPADPLUS      DIK_ADD             /* + on numeric keypad */
+#define DIK_NUMPADPERIOD    DIK_DECIMAL         /* . on numeric keypad */
+#define DIK_NUMPADSLASH     DIK_DIVIDE          /* / on numeric keypad */
+#define DIK_RALT            DIK_RMENU           /* right Alt */
+#define DIK_UPARROW         DIK_UP              /* UpArrow on arrow keypad */
+#define DIK_PGUP            DIK_PRIOR           /* PgUp on arrow keypad */
+#define DIK_LEFTARROW       DIK_LEFT            /* LeftArrow on arrow keypad */
+#define DIK_RIGHTARROW      DIK_RIGHT           /* RightArrow on arrow keypad */
+#define DIK_DOWNARROW       DIK_DOWN            /* DownArrow on arrow keypad */
+#define DIK_PGDN            DIK_NEXT            /* PgDn on arrow keypad */
+
+#define DIDFT_ALL		0x00000000
+#define DIDFT_RELAXIS		0x00000001
+#define DIDFT_ABSAXIS		0x00000002
+#define DIDFT_AXIS		0x00000003
+#define DIDFT_PSHBUTTON		0x00000004
+#define DIDFT_TGLBUTTON		0x00000008
+#define DIDFT_BUTTON		0x0000000C
+#define DIDFT_POV		0x00000010
+#define DIDFT_COLLECTION	0x00000040
+#define DIDFT_NODATA		0x00000080
+#define DIDFT_ANYINSTANCE	0x00FFFF00
+#define DIDFT_INSTANCEMASK	DIDFT_ANYINSTANCE
+#define DIDFT_MAKEINSTANCE(n)	((WORD)(n) << 8)
+#define DIDFT_GETTYPE(n)	LOBYTE(n)
+#define DIDFT_GETINSTANCE(n)	LOWORD((n) >> 8)
+#define DIDFT_FFACTUATOR	0x01000000
+#define DIDFT_FFEFFECTTRIGGER	0x02000000
+#define DIDFT_OUTPUT		0x10000000
+#define DIDFT_ENUMCOLLECTION(n)	((WORD)(n) << 8)
+#define DIDFT_NOCOLLECTION	0x00FFFF00
+#define DIDF_ABSAXIS		0x00000001
+#define DIDF_RELAXIS		0x00000002
+
+typedef struct {
+    DWORD	dwOfs;
+    DWORD	dwData;
+    DWORD	dwTimeStamp;
+    DWORD	dwSequence;
+} DIDEVICEOBJECTDATA,*LPDIDEVICEOBJECTDATA,*LPCDIDEVICEOBJECTDATA;
+
+typedef struct _DIOBJECTDATAFORMAT {
+    const GUID *pguid;
+    DWORD	dwOfs;
+    DWORD	dwType;
+    DWORD	dwFlags;
+} DIOBJECTDATAFORMAT, *LPDIOBJECTDATAFORMAT;
+
+typedef struct {
+    DWORD			dwSize;
+    DWORD			dwObjSize;
+    DWORD			dwFlags;
+    DWORD			dwDataSize;
+    DWORD			dwNumObjs;
+    LPDIOBJECTDATAFORMAT	rgodf;
+} DIDATAFORMAT, *LPDIDATAFORMAT,*LPCDIDATAFORMAT;
+
+typedef struct {
+    DWORD	dwSize;
+    DWORD	dwHeaderSize;
+    DWORD	dwObj;
+    DWORD	dwHow;
+} DIPROPHEADER,*LPDIPROPHEADER,*LPCDIPROPHEADER;
+
+#define DIPH_DEVICE	0
+#define DIPH_BYOFFSET	1
+#define DIPH_BYID	2
+#define DIPH_BYUSAGE	3
+
+typedef struct DIDEVCAPS {
+    DWORD	dwSize;
+    DWORD	dwFlags;
+    DWORD	dwDevType;
+    DWORD	dwAxes;
+    DWORD	dwButtons;
+    DWORD	dwPOVs;
+#if(DIRECTINPUT_VERSION >= 0x0500)
+    DWORD	dwFFSamplePeriod;
+    DWORD	dwFFMinTimeResolution;
+    DWORD	dwFirmwareRevision;
+    DWORD	dwHardwareRevision;
+    DWORD	dwFFDriverVersion;
+#endif /* DIRECTINPUT_VERSION >= 0x0500 */
+} DIDEVCAPS,*LPDIDEVCAPS;
+
+#define DIDC_ATTACHED		0x00000001
+#define DIDC_POLLEDDEVICE	0x00000002
+#define DIDC_EMULATED		0x00000004
+#define DIDC_POLLEDDATAFORMAT	0x00000008
+#define DIDC_FORCEFEEDBACK	0x00000100
+#define DIDC_FFATTACK		0x00000200
+#define DIDC_FFFADE		0x00000400
+#define DIDC_SATURATION		0x00000800
+#define DIDC_POSNEGCOEFFICIENTS	0x00001000
+#define DIDC_POSNEGSATURATION	0x00002000
+#define DIDC_DEADBAND		0x00004000
+
+/* SetCooperativeLevel dwFlags */
+#define DISCL_EXCLUSIVE		0x00000001
+#define DISCL_NONEXCLUSIVE	0x00000002
+#define DISCL_FOREGROUND	0x00000004
+#define DISCL_BACKGROUND	0x00000008
+
+#define THIS LPDIRECTINPUTDEVICE32A this
+typedef struct IDirectInputDeviceA_VTable {
+    /*** IUnknown methods ***/
+    STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+    STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG,Release)(THIS) PURE;
+
+    /*** IDirectInputDeviceA methods ***/
+    STDMETHOD(GetCapabilities)(THIS_ LPDIDEVCAPS) PURE;
+    STDMETHOD(EnumObjects)(THIS_ LPDIENUMDEVICEOBJECTSCALLBACK32A,LPVOID,DWORD) PURE;
+    STDMETHOD(GetProperty)(THIS_ REFGUID,LPDIPROPHEADER) PURE;
+    STDMETHOD(SetProperty)(THIS_ REFGUID,LPCDIPROPHEADER) PURE;
+    STDMETHOD(Acquire)(THIS) PURE;
+    STDMETHOD(Unacquire)(THIS) PURE;
+    STDMETHOD(GetDeviceState)(THIS_ DWORD,LPVOID) PURE;
+    STDMETHOD(GetDeviceData)(THIS_ DWORD,LPDIDEVICEOBJECTDATA,LPDWORD,DWORD) PURE;
+    STDMETHOD(SetDataFormat)(THIS_ LPCDIDATAFORMAT) PURE;
+    STDMETHOD(SetEventNotification)(THIS_ HANDLE32) PURE;
+    STDMETHOD(SetCooperativeLevel)(THIS_ HWND32,DWORD) PURE;
+    STDMETHOD(GetObjectInfo)(THIS_ LPDIDEVICEOBJECTINSTANCE32A,DWORD,DWORD) PURE;
+    STDMETHOD(GetDeviceInfo)(THIS_ LPDIDEVICEINSTANCE32A) PURE;
+    STDMETHOD(RunControlPanel)(THIS_ HWND32,DWORD) PURE;
+    STDMETHOD(Initialize)(THIS_ HINSTANCE32,DWORD,REFGUID) PURE;
+} IDirectInputDeviceA_VTable,*LPDIRECTINPUTDEVICEA_VTABLE;
+
+struct IDirectInputDevice32A {
+	LPDIRECTINPUTDEVICEA_VTABLE	lpvtbl;
+	DWORD				ref;
+	GUID				guid;
+};
+#undef THIS
+
+#define THIS LPDIRECTINPUT32A this
+typedef struct IDirectInputA_VTable {
+	/*** IUnknown methods ***/
+	STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE;
+	STDMETHOD_(ULONG,AddRef)(THIS) PURE;
+	STDMETHOD_(ULONG,Release)(THIS) PURE;
+
+	/*** IDirectInputA methods ***/
+	STDMETHOD(CreateDevice)(THIS_ REFGUID,LPDIRECTINPUTDEVICE32A*,LPUNKNOWN) PURE;
+	STDMETHOD(EnumDevices)(THIS_ DWORD,LPDIENUMDEVICESCALLBACK32A,LPVOID,DWORD) PURE;
+	STDMETHOD(GetDeviceStatus)(THIS_ REFGUID) PURE;
+	STDMETHOD(RunControlPanel)(THIS_ HWND32,DWORD) PURE;
+	STDMETHOD(Initialize)(THIS_ HINSTANCE32,DWORD) PURE;
+} IDirectInputA_VTable,*LPDIRECTINPUTA_VTABLE;
+
+struct IDirectInput32A {
+	LPDIRECTINPUTA_VTABLE	lpvtbl;
+	DWORD			ref;
+};
+#undef THIS
+#undef THIS_
+#undef STDMETHOD(xfn) HRESULT (CALLBACK *fn##xfn)
+#undef STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn)
+#undef PURE
+#undef FAR
+#endif
diff --git a/include/drive.h b/include/drive.h
index 3520a1b..5849e3a 100644
--- a/include/drive.h
+++ b/include/drive.h
@@ -44,5 +44,6 @@
 extern int DRIVE_Disable( int drive  );
 extern int DRIVE_Enable( int drive  );
 extern int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive );
+extern int DRIVE_OpenDevice( int drive, int flags );
 
 #endif  /* __WINE_DRIVE_H */
diff --git a/include/dsound.h b/include/dsound.h
index f4d6801..013f035 100644
--- a/include/dsound.h
+++ b/include/dsound.h
@@ -3,20 +3,27 @@
 
 #include "mmsystem.h"
 
-/* Direct Sound Component GUID    {47D4D946-62E8-11cf-93BC-444553540000} */
-DEFINE_GUID(CLSID_DirectSound,0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
+DEFINE_GUID(CLSID_DirectSound,		0x47d4d946, 0x62e8, 0x11cf, 0x93, 0xbc, 0x44, 0x45, 0x53, 0x54, 0x0, 0x0);
 
-/* DirectSound 279afa83-4981-11ce-a521-0020af0be560 */
-DEFINE_GUID(IID_IDirectSound,0x279AFA83,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60);
-/* DirectSoundBuffer 279afa85-4981-11ce-a521-0020af0be560 */
-DEFINE_GUID(IID_IDirectSoundBuffer,0x279AFA85,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); 
+DEFINE_GUID(IID_IDirectSound,		0x279AFA83,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60);
+DEFINE_GUID(IID_IDirectSoundBuffer,	0x279AFA85,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); 
+DEFINE_GUID(IID_IDirectSoundNotify,	0xB0210783,0x89cd,0x11d0,0xAF,0x08,0x00,0xA0,0xC9,0x25,0xCD,0x16);
+DEFINE_GUID(IID_IDirectSound3DListener,	0x279AFA84,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60);
+DEFINE_GUID(IID_IDirectSound3DBuffer,	0x279AFA86,0x4981,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60); 
+DEFINE_GUID(IID_IDirectSoundCapture,	0xB0210781,0x89CD,0x11D0,0xAF,0x08,0x00,0xA0,0xC9,0x25,0xCD,0x16);
+DEFINE_GUID(IID_IDirectSoundCaptureBuffer,0xB0210782,0x89CD,0x11D0,0xAF,0x08,0x00,0xA0,0xC9,0x25,0xCD,0x16);
+DEFINE_GUID(IID_IKsPropertySet,		0x31EFAC30,0x515C,0x11D0,0xA9,0xAA,0x00,0xAA,0x00,0x61,0xBE,0x93);
+
+
 
 typedef struct IDirectSound IDirectSound,*LPDIRECTSOUND;
+typedef struct IDirectSoundNotify IDirectSoundNotify,*LPDIRECTSOUNDNOTIFY;
 typedef struct IDirectSoundBuffer IDirectSoundBuffer,*LPDIRECTSOUNDBUFFER,**LPLPDIRECTSOUNDBUFFER;
 
 #define	_FACDS		0x878
 #define	MAKE_DSHRESULT(code)		MAKE_HRESULT(1,_FACDS,code)
 
+#define DS_OK				0
 #define DSERR_ALLOCATED			MAKE_DSHRESULT(10)
 #define DSERR_CONTROLUNAVAIL		MAKE_DSHRESULT(30)
 #define DSERR_INVALIDPARAM		E_INVALIDARG
@@ -122,7 +129,13 @@
     LPWAVEFORMATEX	lpwfxFormat;
 } DSBUFFERDESC,*LPDSBUFFERDESC;
 
+typedef struct _DSBPOSITIONNOTIFY
+{
+	DWORD		dwOffset;
+	HANDLE32	hEventNotify;
+} DSBPOSITIONNOTIFY,*LPDSBPOSITIONNOTIFY;
 
+typedef const DSBPOSITIONNOTIFY *LPCDSBPOSITIONNOTIFY;
 
 #define DSSPEAKER_HEADPHONE     1
 #define DSSPEAKER_MONO          2
@@ -131,7 +144,6 @@
 #define DSSPEAKER_SURROUND      5
 
 
-
 typedef LPVOID* LPLPVOID;
 
 typedef BOOL32 (CALLBACK *LPDSENUMCALLBACK32W)(LPGUID,LPWSTR,LPWSTR,LPVOID);
@@ -143,11 +155,9 @@
 #define STDMETHOD_(ret,xfn) ret (CALLBACK *fn##xfn)
 #define PURE
 #define FAR
-#define ULONG DWORD
+#define THIS_ THIS,
 
 #define THIS LPDIRECTSOUND this
-#define THIS_ LPDIRECTSOUND this,
-
 typedef struct tagLPDIRECTSOUND_VTABLE
 {
     /*** IUnknown methods ***/
@@ -171,12 +181,11 @@
 	DWORD			ref;
 	int			nrofbuffers;
 	LPDIRECTSOUNDBUFFER	*buffers;
+	WAVEFORMATEX		wfx; /* current main waveformat */
 };
-
 #undef THIS
-#undef THIS_
+
 #define THIS LPDIRECTSOUNDBUFFER this
-#define THIS_ LPDIRECTSOUNDBUFFER this,
 typedef struct tagLPDIRECTSOUNDBUFFER_VTABLE
 {
     /*** IUnknown methods ***/
@@ -210,8 +219,36 @@
 	WAVEFORMATEX			wfx;
 	DWORD				ref;
 	LPBYTE				buffer;
-	DWORD				playing,playpos,writepos,buflen;
+	DWORD				playflags,playing,playpos,writepos,buflen;
+	LONG				volume,pan;
 	LPDIRECTSOUND			dsound;
+	DSBUFFERDESC			dsbd;
+	LPDSBPOSITIONNOTIFY		notifies;
+	int				nrofnotifies;
 };
+#undef THIS
 
+#define THIS LPDIRECTSOUNDNOTIFY this
+typedef struct IDirectSoundNotify_VTable {
+	/* IUnknown methods */
+	STDMETHOD(QueryInterface)           (THIS_ REFIID, LPVOID *) PURE;
+	STDMETHOD_(ULONG,AddRef)            (THIS) PURE;
+	STDMETHOD_(ULONG,Release)           (THIS) PURE;
+
+	/* IDirectSoundNotify methods */
+	STDMETHOD(SetNotificationPositions) (THIS_ DWORD, LPCDSBPOSITIONNOTIFY) PURE;
+} *LPDIRECTSOUNDNOTIFY_VTABLE,IDirectSoundNotify_VTable;
+
+struct IDirectSoundNotify {
+	LPDIRECTSOUNDNOTIFY_VTABLE	lpvtbl;
+	DWORD				ref;
+	LPDIRECTSOUNDBUFFER		dsb;
+};
+#undef THIS
+
+#undef STDMETHOD
+#undef STDMETHOD_
+#undef PURE
+#undef FAR
+#undef THIS_
 #endif
diff --git a/include/font.h b/include/font.h
index cae411c..7ccc65c 100644
--- a/include/font.h
+++ b/include/font.h
@@ -26,4 +26,16 @@
 extern INT16  FONT_GetObject16( FONTOBJ * font, INT16 count, LPSTR buffer );
 extern INT32  FONT_GetObject32A( FONTOBJ * font, INT32 count, LPSTR buffer );
 
+extern void FONT_LogFont32ATo16( const LOGFONT32A* font32, LPLOGFONT16 font16 );
+extern void FONT_LogFont32WTo16( const LOGFONT32W* font32, LPLOGFONT16 font16 );
+extern void FONT_LogFont16To32A( const LPLOGFONT16 font16, LPLOGFONT32A font32 );
+extern void FONT_LogFont16To32W( const LPLOGFONT16 font16, LPLOGFONT32W font32 );
+extern void FONT_TextMetric32Ato16(const LPTEXTMETRIC32A ptm32, LPTEXTMETRIC16 ptm16 );
+extern void FONT_TextMetric32Wto16(const LPTEXTMETRIC32W ptm32, LPTEXTMETRIC16 ptm16 );
+extern void FONT_TextMetric16to32A(const LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32A ptm32 );
+extern void FONT_TextMetric16to32W(const LPTEXTMETRIC16 ptm16, LPTEXTMETRIC32W ptm32 );
+extern void FONT_TextMetric32Ato32W(const LPTEXTMETRIC32A ptm32A, LPTEXTMETRIC32W ptm32W );
+
+
+
 #endif /* __WINE_FONT_H */
diff --git a/include/gdi.h b/include/gdi.h
index ed90b94..cce4270 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -131,6 +131,11 @@
     INT32         DCOrgY;
     INT32         CursPosX;          /* Current position */
     INT32         CursPosY;
+    INT32         ArcDirection;
+    BOOL32        UseWorldXform;     /* Should we use the world transform? */
+                                     /* (i.e. is it not equal to the       */
+				     /* identity transformation?)          */
+    XFORM         WorldXform;        /* World transform */
 } WIN_DC_INFO;
 
 typedef X11DRV_PDEVICE X_DC_INFO;  /* Temporary */
@@ -286,6 +291,16 @@
 #define YLPTODP(dc,y) \
     (((y)-(dc)->wndOrgY) * (dc)->vportExtY / (dc)->wndExtY+(dc)->vportOrgY)
 
+  /* Device <-> logical size conversion */
+
+#define XDSTOLS(dc,x) \
+    ((x) * (dc)->wndExtX / (dc)->vportExtX)
+#define YDSTOLS(dc,y) \
+    ((y) * (dc)->wndExtY / (dc)->vportExtY)
+#define XLSTODS(dc,x) \
+    ((x) * (dc)->vportExtX / (dc)->wndExtX)
+#define YLSTODS(dc,y) \
+    ((y) * (dc)->vportExtY / (dc)->wndExtY)
 
   /* GDI local heap */
 
diff --git a/include/module.h b/include/module.h
index 2737501..7e7a743 100644
--- a/include/module.h
+++ b/include/module.h
@@ -129,7 +129,7 @@
 extern BOOL16 MODULE_SetEntryPoint( HMODULE32 hModule, WORD ordinal,
                                     WORD offset );
 extern FARPROC16 MODULE_GetWndProcEntry16( const char *name );
-extern FARPROC16 WIN32_GetProcAddress16( HMODULE32 hmodule, LPSTR name );
+extern FARPROC16 WINAPI WIN32_GetProcAddress16( HMODULE32 hmodule, LPSTR name );
 
 /* builtin.c */
 extern BOOL32 BUILTIN_Init(void);
@@ -147,4 +147,7 @@
 extern void NE_FixupPrologs( NE_MODULE *pModule );
 extern void NE_InitializeDLLs( HMODULE16 hModule );
 
+/* relay32/builtin.c */
+extern HMODULE32 BUILTIN32_LoadModule( LPCSTR name, BOOL32 force );
+
 #endif  /* __WINE_MODULE_H */
diff --git a/include/ole.h b/include/ole.h
index 0d90960..71c1659 100644
--- a/include/ole.h
+++ b/include/ole.h
@@ -7,10 +7,15 @@
 
 #include "windows.h"
 
+typedef CHAR	OLE_CHAR,OLECHAR;
 typedef LPCSTR	OLE_LPCSTR;
 typedef LPSTR	LPOLESTR;
 typedef LPCSTR	LPCOLESTR;
 
+typedef unsigned short VARTYPE;
+typedef LONG DISPID;
+
+
 /* object types */
 #define OT_LINK		1
 #define OT_EMBEDDED	2
@@ -260,4 +265,39 @@
 OLESTATUS WINAPI OleRevokeClientDoc(LHCLIENTDOC);
 OLESTATUS WINAPI OleRevokeServer(LHSERVER);
 
+typedef enum tagCALLCONV {
+    CC_CDECL		= 1,
+    CC_MSCPASCAL	= CC_CDECL + 1,
+    CC_PASCAL		= CC_MSCPASCAL,
+    CC_MACPASCAL	= CC_PASCAL + 1,
+    CC_STDCALL		= CC_MACPASCAL + 1,
+    CC_RESERVED		= CC_STDCALL + 1,
+    CC_SYSCALL		= CC_RESERVED + 1,
+    CC_MPWCDECL		= CC_SYSCALL + 1,
+    CC_MPWPASCAL	= CC_MPWCDECL + 1,
+    CC_MAX 		= CC_MPWPASCAL + 1
+} CALLCONV;
+
+typedef struct tagPARAMDATA {
+    OLECHAR * szName;    /* parameter name */
+    VARTYPE vt;         /* parameter type */
+} PARAMDATA, * LPPARAMDATA;
+
+typedef struct tagMETHODDATA {
+    OLECHAR * szName;    /* method name */
+    PARAMDATA * ppdata;  /* pointer to an array of PARAMDATAs */
+    DISPID dispid;      /* method ID */
+    UINT16 iMeth;         /* method index */
+    CALLCONV cc;        /* calling convention */
+    UINT16 cArgs;         /* count of arguments */
+    WORD wFlags;        /* same wFlags as on IDispatch::Invoke() */
+    VARTYPE vtReturn;
+} METHODDATA, * LPMETHODDATA;
+
+typedef struct tagINTERFACEDATA {
+    METHODDATA * pmethdata;  /* pointer to an array of METHODDATAs */
+    UINT16 cMembers;      /* count of members */
+} INTERFACEDATA, * LPINTERFACEDATA;
+
+
 #endif  /* __WINE_OLE_H */
diff --git a/include/options.h b/include/options.h
index 784614c..2b9fceb 100644
--- a/include/options.h
+++ b/include/options.h
@@ -25,7 +25,9 @@
     LANG_Ko,  /* Korean */
     LANG_Hu,  /* Hungarian */
     LANG_Pl,  /* Polish */
-    LANG_Po   /* Portuguese */
+    LANG_Po,  /* Portuguese */
+    LANG_Sw,  /* Swedish */
+    LANG_Ca   /* Catalan */
 } WINE_LANGUAGE;
 
 typedef struct
diff --git a/include/path.h b/include/path.h
index fbf00e1..4ddfc28 100644
--- a/include/path.h
+++ b/include/path.h
@@ -1,7 +1,7 @@
 /*
  * Graphics paths (BeginPath, EndPath etc.)
  *
- * Copyright 1997 Martin Boehme
+ * Copyright 1997, 1998 Martin Boehme
  */
 
 #ifndef __WINE_PATH_H
@@ -39,7 +39,12 @@
 extern void   PATH_DestroyGdiPath(GdiPath *pPath);
 extern BOOL32 PATH_AssignGdiPath(GdiPath *pPathDest,
    const GdiPath *pPathSrc);
+
 extern BOOL32 PATH_MoveTo(HDC32 hdc);
 extern BOOL32 PATH_LineTo(HDC32 hdc, INT32 x, INT32 y);
+extern BOOL32 PATH_Ellipse(HDC32 hdc, INT32 x1, INT32 y1,
+   INT32 x2, INT32 y2);
+extern BOOL32 PATH_Arc(HDC32 hdc, INT32 x1, INT32 y1, INT32 x2, INT32 y2,
+   INT32 xStart, INT32 yStart, INT32 xEnd, INT32 yEnd);
 
 #endif /* __WINE_PATH_H */
diff --git a/include/pe_image.h b/include/pe_image.h
index b6876e9..aafab14 100644
--- a/include/pe_image.h
+++ b/include/pe_image.h
@@ -20,8 +20,12 @@
 #define PE_MODREF_PROCESS_ATTACHED	0x00000001
 #define PE_MODREF_NO_DLL_CALLS		0x00000002
 #define PE_MODREF_RELOCS_DONE		0x00000004
+#define PE_MODREF_TLS_ALLOCED		0x00000008
+	int				tlsindex;
 };
 
+struct _PDB32;
+
 typedef struct pe_modref PE_MODREF;
 
 extern int PE_unloadImage(HMODULE32 hModule);
@@ -35,11 +39,13 @@
 extern BOOL32 PE_EnumResourceLanguages32W(HMODULE32,LPCWSTR,LPCWSTR,ENUMRESLANGPROC32W,LONG);
 extern HRSRC32 PE_FindResourceEx32W(HINSTANCE32,LPCWSTR,LPCWSTR,WORD);
 extern DWORD PE_SizeofResource32(HINSTANCE32,HRSRC32);
-extern HMODULE32 PE_LoadLibraryEx32A(LPCSTR,HFILE32,DWORD);
+extern HMODULE32 PE_LoadLibraryEx32A(LPCSTR,struct _PDB32*,HFILE32,DWORD);
 extern HGLOBAL32 PE_LoadResource32(HINSTANCE32,HRSRC32);
 
 struct _PDB32; /* forward definition */
+struct _THDB; /* forward definition */
 extern void PE_InitializeDLLs(struct _PDB32*,DWORD,LPVOID);
+extern void PE_InitTls(struct _THDB*);
 
 extern LPIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(LPIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD,BOOL32);
 
diff --git a/include/process.h b/include/process.h
index 21893db..848f775 100644
--- a/include/process.h
+++ b/include/process.h
@@ -98,6 +98,11 @@
     LCID             locale;           /* c4 Locale to be queried by GetThreadLocale (NT) */
 } PDB32;
 
+/* PDB <-> Process id conversion macros */
+#define PROCESS_OBFUSCATOR     ((DWORD)0xdeadbeef)
+#define PROCESS_ID_TO_PDB(id)  ((PDB32 *)((id) ^ PROCESS_OBFUSCATOR))
+#define PDB_TO_PROCESS_ID(pdb) ((DWORD)(pdb) ^ PROCESS_OBFUSCATOR)
+
 /* scheduler/process.c */
 extern PDB32 *PROCESS_Current(void);
 extern PDB32 *PROCESS_IdToPDB( DWORD id );
diff --git a/include/stackframe.h b/include/stackframe.h
index 1435bbb..5394c05 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -10,6 +10,7 @@
 #include <string.h>
 #include "windows.h"
 #include "ldt.h"
+#include "thread.h"
 
 #pragma pack(1)
 
@@ -46,11 +47,9 @@
 
 #pragma pack(4)
 
-  /* Saved 16-bit stack for current process (Win16 only) */
-extern DWORD IF1632_Saved16_ss_sp;
-
-#define CURRENT_STACK16 ((STACK16FRAME *)PTR_SEG_TO_LIN(IF1632_Saved16_ss_sp))
-#define CURRENT_DS      (CURRENT_STACK16->ds)
+#define THREAD_STACK16(thdb) ((STACK16FRAME*)PTR_SEG_TO_LIN((thdb)->cur_stack))
+#define CURRENT_STACK16      (THREAD_STACK16(THREAD_Current()))
+#define CURRENT_DS           (CURRENT_STACK16->ds)
 
 /* varargs lists on the 16-bit stack */
 
@@ -64,15 +63,19 @@
      *((type *)(void *)((char *)(list) - __VA_ROUNDED16(type))))
 #define VA_END16(list) ((void)0)
 
-/* Push bytes on the 16-bit stack; return a segptr to the first pushed byte */
-#define STACK16_PUSH(size) \
- (memmove((char*)CURRENT_STACK16-(size),CURRENT_STACK16,sizeof(STACK16FRAME)),\
-  IF1632_Saved16_ss_sp -= (size), \
-  (SEGPTR)(IF1632_Saved16_ss_sp + sizeof(STACK16FRAME)))
+/* Push bytes on the 16-bit stack of a thread;
+ * return a segptr to the first pushed byte
+ */
+#define STACK16_PUSH(thdb,size) \
+ (memmove((char*)THREAD_STACK16(thdb)-(size),THREAD_STACK16(thdb), \
+          sizeof(STACK16FRAME)), \
+  (thdb)->cur_stack -= (size), \
+  (SEGPTR)((thdb)->cur_stack + sizeof(STACK16FRAME)))
 
-/* Pop bytes from the 16-bit stack */
-#define STACK16_POP(size) \
- (memmove((char*)CURRENT_STACK16+(size),CURRENT_STACK16,sizeof(STACK16FRAME)),\
-  IF1632_Saved16_ss_sp += (size))
+/* Pop bytes from the 16-bit stack of a thread */
+#define STACK16_POP(thdb,size) \
+ (memmove((char*)THREAD_STACK16(thdb)+(size),THREAD_STACK16(thdb), \
+          sizeof(STACK16FRAME)), \
+  (thdb)->cur_stack += (size))
 
 #endif /* __WINE_STACKFRAME_H */
diff --git a/include/stddebug.h b/include/stddebug.h
index 0f51994..71c6092 100644
--- a/include/stddebug.h
+++ b/include/stddebug.h
@@ -93,10 +93,12 @@
 #undef DEBUG_CURSOR
 #undef DEBUG_DC
 #undef DEBUG_DDE
+#undef DEBUG_DDRAW
 #undef DEBUG_DIALOG
 #undef DEBUG_DLL
 #undef DEBUG_DOSFS
 #undef DEBUG_DRIVER
+#undef DEBUG_DSOUND
 #undef DEBUG_EDIT
 #undef DEBUG_EVENT
 #undef DEBUG_EXEC
@@ -160,6 +162,7 @@
 #undef DEBUG_WIN16DRV
 #undef DEBUG_WIN32
 #undef DEBUG_WINSOCK
+#undef DEBUG_X11
 #endif
 
 #ifdef DEBUG_ALL
@@ -180,10 +183,12 @@
 #define DEBUG_CURSOR
 #define DEBUG_DC
 #define DEBUG_DDE
+#define DEBUG_DDRAW
 #define DEBUG_DIALOG
 #define DEBUG_DLL
 #define DEBUG_DOSFS
 #define DEBUG_DRIVER
+#define DEBUG_DSOUND
 #define DEBUG_EDIT
 #define DEBUG_EVENT
 #define DEBUG_EXEC
@@ -247,4 +252,5 @@
 #define DEBUG_WIN16DRV
 #define DEBUG_WIN32
 #define DEBUG_WINSOCK
+#define DEBUG_X11
 #endif
diff --git a/include/thread.h b/include/thread.h
index 361d165..c17349c 100644
--- a/include/thread.h
+++ b/include/thread.h
@@ -50,7 +50,7 @@
     struct _PDB32 *process;        /*  08 Process owning this thread */
     K32OBJ        *event;          /*  0c Thread event */
     TEB            teb;            /*  10 Thread exception block */
-    struct _PDB32 *process2;       /*  40 Same as offset 08 (?) */
+    DWORD          cur_stack;      /*  40 Current stack (was: process2) */
     DWORD          flags;          /*  44 Flags */
     DWORD          exit_code;      /*  48 Termination status */
     WORD           teb_sel;        /*  4c Selector to TEB */
diff --git a/include/ts_xlib.h b/include/ts_xlib.h
new file mode 100644
index 0000000..69f9a5e
--- /dev/null
+++ b/include/ts_xlib.h
@@ -0,0 +1,129 @@
+/*
+ * Thread safe wrappers around Xlib calls.
+ * Always include this file instead of <X11/Xlib.h>.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#ifndef __WINE_TSXLIB_H
+#define __WINE_TSXLIB_H
+
+#include <X11/Xlib.h>
+
+extern XFontStruct * TSXLoadQueryFont(Display*, const  char*);
+extern XModifierKeymap	* TSXGetModifierMapping(Display*);
+extern XImage * TSXCreateImage(Display*, Visual*, unsigned int, int, int, char*, unsigned int, unsigned int, int, int);
+extern XImage * TSXGetImage(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int);
+extern Display * TSXOpenDisplay(const  char*);
+extern void  TSXrmInitialize(void);
+extern char * TSXGetAtomName(Display*, Atom);
+extern char * TSXKeysymToString(KeySym);
+extern Atom  TSXInternAtom(Display*, const  char*, int);
+extern Colormap  TSXCreateColormap(Display*, Window, Visual*, int);
+extern Cursor  TSXCreatePixmapCursor(Display*, Pixmap, Pixmap, XColor*, XColor*, unsigned int, unsigned int);
+extern Cursor  TSXCreateFontCursor(Display*, unsigned int);
+extern GC  TSXCreateGC(Display*, Drawable, unsigned long, XGCValues*);
+extern Pixmap  TSXCreatePixmap(Display*, Drawable, unsigned int, unsigned int, unsigned int);
+extern Pixmap  TSXCreateBitmapFromData(Display*, Drawable, const  char*, unsigned int, unsigned int);
+extern Window  TSXGetSelectionOwner(Display*, Atom);
+extern Window  TSXCreateWindow(Display*, Window, int, int, unsigned int, unsigned int, unsigned int, int, unsigned int, Visual*, unsigned long, XSetWindowAttributes*);
+extern char ** TSXListFonts(Display*, const  char*, int, int*);
+extern KeySym  TSXKeycodeToKeysym(Display*, unsigned int, int);
+extern KeySym  TSXLookupKeysym(XKeyEvent*, int);
+extern KeySym * TSXGetKeyboardMapping(Display*, unsigned int, int, int*);
+extern char * TSXResourceManagerString(Display*);
+extern int   TSXInitThreads(void);
+extern int * TSXListDepths(Display*, int, int*);
+extern int   TSXReconfigureWMWindow(Display*, Window, int, unsigned int, XWindowChanges*);
+extern int   TSXSetWMProtocols(Display*, Window, Atom*, int);
+extern int  TSXSetTransientForHint(Display*, Window, Window);
+extern int  TSXActivateScreenSaver(Display*);
+extern int   TSXAllocColor(Display*, Colormap, XColor*);
+extern int   TSXAllocColorCells(Display*, Colormap, int, unsigned long*, unsigned int, unsigned long*, unsigned int);
+extern int  TSXBell(Display*, int);
+extern int  TSXChangeGC(Display*, GC, unsigned long, XGCValues*);
+extern int  TSXChangeKeyboardControl(Display*, unsigned long, XKeyboardControl*);
+extern int  TSXChangeProperty(Display*, Window, Atom, Atom, int, int, const  unsigned char*, int);
+extern int  TSXChangeWindowAttributes(Display*, Window, unsigned long, XSetWindowAttributes*);
+extern int   TSXCheckTypedWindowEvent(Display*, Window, int, XEvent*);
+extern int   TSXCheckWindowEvent(Display*, Window, long, XEvent*);
+extern int  TSXConvertSelection(Display*, Atom, Atom, Atom, Window, Time);
+extern int  TSXCopyArea(Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int);
+extern int  TSXCopyPlane(Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int, unsigned long);
+extern int  TSXDefineCursor(Display*, Window, Cursor);
+extern int  TSXDestroyWindow(Display*, Window);
+extern int  TSXDisplayKeycodes(Display*, int*, int*);
+extern int  TSXDrawArc(Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int);
+extern int  TSXDrawLine(Display*, Drawable, GC, int, int, int, int);
+extern int  TSXDrawLines(Display*, Drawable, GC, XPoint*, int, int);
+extern int  TSXDrawPoint(Display*, Drawable, GC, int, int);
+extern int  TSXDrawRectangle(Display*, Drawable, GC, int, int, unsigned int, unsigned int);
+extern int  TSXDrawSegments(Display*, Drawable, GC, XSegment*, int);
+extern int  TSXDrawString(Display*, Drawable, GC, int, int, const  char*, int);
+extern int  TSXDrawText(Display*, Drawable, GC, int, int, XTextItem*, int);
+extern int  TSXFillArc(Display*, Drawable, GC, int, int, unsigned int, unsigned int, int, int);
+extern int  TSXFillPolygon(Display*, Drawable, GC, XPoint*, int, int, int);
+extern int  TSXFillRectangle(Display*, Drawable, GC, int, int, unsigned int, unsigned int);
+extern int  TSXFlush(Display*);
+extern int  TSXFree(void*);
+extern int  TSXFreeColors(Display*, Colormap, unsigned long*, int, unsigned long);
+extern int  TSXFreeCursor(Display*, Cursor);
+extern int  TSXFreeFont(Display*, XFontStruct*);
+extern int  TSXFreeFontNames(char**);
+extern int  TSXFreeGC(Display*, GC);
+extern int  TSXFreeModifiermap(XModifierKeymap*);
+extern int  TSXFreePixmap(Display*, Pixmap);
+extern int   TSXGetFontProperty(XFontStruct*, Atom, unsigned long*);
+extern int   TSXGetGeometry(Display*, Drawable, Window*, int*, int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*);
+extern int  TSXGetInputFocus(Display*, Window*, int*);
+extern int  TSXGetKeyboardControl(Display*, XKeyboardState*);
+extern int  TSXGetScreenSaver(Display*, int*, int*, int*, int*);
+extern int  TSXGetWindowProperty(Display*, Window, Atom, long, long, int, Atom, Atom*, int*, unsigned long*, unsigned long*, unsigned char**);
+extern int   TSXGetWindowAttributes(Display*, Window, XWindowAttributes*);
+extern int  TSXGrabPointer(Display*, Window, int, unsigned int, int, int, Window, Cursor, Time);
+extern int  TSXGrabServer(Display*);
+extern int  TSXInstallColormap(Display*, Colormap);
+extern KeyCode  TSXKeysymToKeycode(Display*, KeySym);
+extern int  TSXMapWindow(Display*, Window);
+extern int  TSXNextEvent(Display*, XEvent*);
+extern int  TSXParseGeometry(const  char*, int*, int*, unsigned int*, unsigned int*);
+extern int  TSXPending(Display*);
+extern int  TSXPutBackEvent(Display*, XEvent*);
+extern int  TSXPutImage(Display*, Drawable, GC, XImage*, int, int, int, int, unsigned int, unsigned int);
+extern int  TSXQueryColor(Display*, Colormap, XColor*);
+extern int   TSXQueryPointer(Display*, Window, Window*, Window*, int*, int*, int*, int*, unsigned int*);
+extern int   TSXQueryTree(Display*, Window, Window*, Window*, Window**, unsigned int*);
+extern int  TSXResetScreenSaver(Display*);
+extern int  TSXRestackWindows(Display*, Window*, int);
+extern int   TSXSendEvent(Display*, Window, int, long, XEvent*);
+extern int  TSXSetArcMode(Display*, GC, int);
+extern int  TSXSetBackground(Display*, GC, unsigned long);
+extern int  TSXSetClipMask(Display*, GC, Pixmap);
+extern int  TSXSetClipOrigin(Display*, GC, int, int);
+extern int  TSXSetClipRectangles(Display*, GC, int, int, XRectangle*, int, int);
+extern int  TSXSetDashes(Display*, GC, int, const  char*, int);
+extern int  TSXSetFillStyle(Display*, GC, int);
+extern int  TSXSetForeground(Display*, GC, unsigned long);
+extern int  TSXSetFunction(Display*, GC, int);
+extern int  TSXSetGraphicsExposures(Display*, GC, int);
+extern int  TSXSetIconName(Display*, Window, const  char*);
+extern int  TSXSetInputFocus(Display*, Window, int, Time);
+extern int  TSXSetLineAttributes(Display*, GC, unsigned int, int, int, int);
+extern int  TSXSetScreenSaver(Display*, int, int, int, int);
+extern int  TSXSetSelectionOwner(Display*, Atom, Window, Time);
+extern int  TSXSetSubwindowMode(Display*, GC, int);
+extern int  TSXStoreColor(Display*, Colormap, XColor*);
+extern int  TSXStoreName(Display*, Window, const  char*);
+extern int  TSXSync(Display*, int);
+extern int  TSXTextExtents(XFontStruct*, const  char*, int, int*, int*, int*, XCharStruct*);
+extern int  TSXTextWidth(XFontStruct*, const  char*, int);
+extern int  TSXUngrabPointer(Display*, Time);
+extern int  TSXUngrabServer(Display*);
+extern int  TSXUninstallColormap(Display*, Colormap);
+extern int  TSXUnmapWindow(Display*, Window);
+extern int  TSXWarpPointer(Display*, Window, Window, int, int, unsigned int, unsigned int, int, int);
+extern int (*TSXSynchronize(Display *, Bool))(Display *);
+extern void TS_XInitImageFuncPtrs(XImage *);
+
+#endif /* __WINE_TSXLIB_H */
diff --git a/include/ts_xpm.h b/include/ts_xpm.h
new file mode 100644
index 0000000..05aeef3
--- /dev/null
+++ b/include/ts_xpm.h
@@ -0,0 +1,17 @@
+/*
+ * Thread safe wrappers around xpm calls.
+ * Always include this file instead of <X11/xpm.h>.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#ifndef __WINE_TSXPM_H
+#define __WINE_TSXPM_H
+
+#include <X11/xpm.h>
+
+extern int TSXpmCreatePixmapFromData(Display *, Drawable, char **, Pixmap *, Pixmap *, XpmAttributes *);
+extern int TSXpmAttributesSize(void);
+
+#endif /* __WINE_TSXPM_H */
diff --git a/include/ts_xresource.h b/include/ts_xresource.h
new file mode 100644
index 0000000..ddacdd1
--- /dev/null
+++ b/include/ts_xresource.h
@@ -0,0 +1,22 @@
+/*
+ * Thread safe wrappers around Xresource calls.
+ * Always include this file instead of <X11/Xresource.h>.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#ifndef __WINE_TSXRESOURCE_H
+#define __WINE_TSXRESOURCE_H
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+
+extern XrmQuark  TSXrmUniqueQuark(void);
+extern int   TSXrmGetResource(XrmDatabase, const  char*, const  char*, char**, XrmValue*);
+extern XrmDatabase  TSXrmGetFileDatabase(const  char*);
+extern XrmDatabase  TSXrmGetStringDatabase(const  char*);
+extern void  TSXrmMergeDatabases(XrmDatabase, XrmDatabase*);
+extern void  TSXrmParseCommand(XrmDatabase*, XrmOptionDescList, int, const  char*, int*, char**);
+
+#endif /* __WINE_TSXRESOURCE_H */
diff --git a/include/ts_xshm.h b/include/ts_xshm.h
new file mode 100644
index 0000000..01a2b51
--- /dev/null
+++ b/include/ts_xshm.h
@@ -0,0 +1,20 @@
+/*
+ * Thread safe wrappers around XShm calls.
+ * Always include this file instead of <X11/XShm.h>.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#ifndef __WINE_TSXSHM_H
+#define __WINE_TSXSHM_H
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+
+extern Bool TSXShmQueryExtension(Display *);
+extern int TSXShmPixmapFormat(Display *);
+extern Status TSXShmDetach(Display *, XShmSegmentInfo *);
+extern Status TSXShmAttach(Display *, XShmSegmentInfo *);
+
+#endif /* __WINE_TSXSHM_H */
diff --git a/include/ts_xutil.h b/include/ts_xutil.h
new file mode 100644
index 0000000..253f212
--- /dev/null
+++ b/include/ts_xutil.h
@@ -0,0 +1,50 @@
+/*
+ * Thread safe wrappers around Xutil calls.
+ * Always include this file instead of <X11/Xutil.h>.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#ifndef __WINE_TSXUTIL_H
+#define __WINE_TSXUTIL_H
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+
+extern XClassHint * TSXAllocClassHint(void);
+extern XSizeHints * TSXAllocSizeHints(void);
+extern XWMHints * TSXAllocWMHints(void);
+extern int  TSXClipBox(Region, XRectangle*);
+extern Region  TSXCreateRegion(void);
+extern int  TSXDeleteContext(Display*, XID, XContext);
+extern int  TSXDestroyRegion(Region);
+extern int  TSXEmptyRegion(Region);
+extern int  TSXEqualRegion(Region, Region);
+extern int  TSXFindContext(Display*, XID, XContext, XPointer*);
+extern int   TSXGetWMSizeHints(Display*, Window, XSizeHints*, long*, Atom);
+extern int  TSXIntersectRegion(Region, Region, Region);
+extern int  TSXLookupString(XKeyEvent*, char*, int, KeySym*, XComposeStatus*);
+extern int  TSXOffsetRegion(Region, int, int);
+extern int   TSXPointInRegion(Region, int, int);
+extern Region  TSXPolygonRegion(XPoint*, int, int);
+extern int  TSXRectInRegion(Region, int, int, unsigned int, unsigned int);
+extern int  TSXSaveContext(Display*, XID, XContext, const  char*);
+extern void  TSXSetWMProperties(Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*);
+extern void  TSXSetWMSizeHints(Display*, Window, XSizeHints*, Atom);
+extern int  TSXSetRegion(Display*, GC, Region);
+extern int  TSXShrinkRegion(Region, int, int);
+extern int   TSXStringListToTextProperty(char**, int, XTextProperty*);
+extern int  TSXSubtractRegion(Region, Region, Region);
+extern int  TSXUnionRectWithRegion(XRectangle*, Region, Region);
+extern int  TSXUnionRegion(Region, Region, Region);
+extern int  TSXXorRegion(Region, Region, Region);
+extern int TSXDestroyImage(struct _XImage *);
+extern unsigned long TSXGetPixel(struct _XImage *, int, int);
+extern int TSXPutPixel(struct _XImage *, int, int, unsigned long);
+extern struct _XImage * TSXSubImage(struct _XImage *, int, int, unsigned int, unsigned int);
+extern int TSXAddPixel(struct _XImage *, long);
+extern XContext TSXUniqueContext(void);
+
+#endif /* __WINE_TSXUTIL_H */
diff --git a/include/tsx11defs.h b/include/tsx11defs.h
new file mode 100644
index 0000000..87396a7
--- /dev/null
+++ b/include/tsx11defs.h
@@ -0,0 +1,22 @@
+/*
+ * Thread safe wrappers around X11 calls
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#ifndef __WINE_TSX11DEFS_H
+#define __WINE_TSX11DEFS_H
+
+#include "winbase.h"
+
+extern CRITICAL_SECTION *TSX11_SectionPtr;
+
+extern int TSX11_Init(void);
+
+#define X11_LOCK() \
+    (TSX11_SectionPtr ? EnterCriticalSection(TSX11_SectionPtr) : 0)
+
+#define X11_UNLOCK() \
+    (TSX11_SectionPtr ? LeaveCriticalSection(TSX11_SectionPtr) : 0)
+
+#endif  /* __WINE_TSX11DEFS_H */
diff --git a/include/version.h b/include/version.h
index 686a913..0581786 100644
--- a/include/version.h
+++ b/include/version.h
@@ -1 +1 @@
-#define WINE_RELEASE_INFO "Wine release 980118"
+#define WINE_RELEASE_INFO "Wine release 980201"
diff --git a/include/win.h b/include/win.h
index 5a57b43..c1f9186 100644
--- a/include/win.h
+++ b/include/win.h
@@ -7,7 +7,7 @@
 #ifndef __WINE_WIN_H
 #define __WINE_WIN_H
 
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 
 #include "ldt.h"
 #include "class.h"
diff --git a/include/win16drv.h b/include/win16drv.h
index d219358..d34e173 100644
--- a/include/win16drv.h
+++ b/include/win16drv.h
@@ -95,12 +95,6 @@
     TOTAL_PRINTER_DRIVER_FUNCTIONS /* insert functions before here */
 };
 
-typedef struct PRINTER_FONTS_INFO
-{
-    LOGFONT16		lf;			/* LogFont infomation */
-    TEXTMETRIC16	tm;			/* Text metrics infomation */
-} PRINTER_FONTS_INFO;
-
 typedef struct
 {
     LPSTR 	szDriver;		/* Driver name eg EPSON */
@@ -108,8 +102,6 @@
     WORD	ds_reg;			/* DS of driver */
     FARPROC16 	fn[TOTAL_PRINTER_DRIVER_FUNCTIONS];	/* Printer functions */
     int		nUsageCount;		/* Usage count, unload == 0 */
-    int		nPrinterFonts;		/* Number of printer fonts */
-    PRINTER_FONTS_INFO *paPrinterFonts; /* array of printer fonts */
     int		nIndex;			/* Index in global driver array */
 } LOADED_PRINTER_DRIVER;
 
@@ -143,10 +135,8 @@
 
 typedef struct WINE_ENUM_PRINTER_FONT_CALLBACK
 {
-    DWORD	magic;			/* magic number */
-    int 	nMode;			/* Mode 0=count, 1=store */
-    int 	nCount;			/* Callback count */
-    LOADED_PRINTER_DRIVER *pLPD;    	/* Printer driver info */
+    int (*proc)(LPENUMLOGFONT16, LPNEWTEXTMETRIC16, UINT16, LPARAM);
+    LPARAM lp;
 } WEPFC;
 
 #define DRVOBJ_PEN 	1       
@@ -160,9 +150,9 @@
     SEGPTR		segptrPDEVICE;	/* PDEVICE used by 16 bit printer drivers */
     LOGFONT16		lf;		/* Current font details */
     TEXTMETRIC16	tm;		/* Current font metrics */
-    SEGPTR		segptrFontInfo; /* Current font realized by printer driver */
-    SEGPTR		segptrBrushInfo; /* Current brush realized by printer driver */
-    SEGPTR		segptrPenInfo;   /* Current pen realized by printer driver */
+    LPFONTINFO16       	FontInfo;       /* Current font realized by printer driver */
+    LPLOGBRUSH16	BrushInfo;      /* Current brush realized by printer driver */
+    LPLOGPEN16		PenInfo;        /* Current pen realized by printer driver */
 } WIN16DRV_PDEVICE;
 
 /*
@@ -183,10 +173,33 @@
 extern BOOL16 PRTDRV_EnumObj(LPPDEVICE lpDestDev, WORD iStyle, FARPROC16 lpfn, LPVOID lpb);
 extern DWORD PRTDRV_ExtTextOut(LPPDEVICE lpDestDev, WORD wDestXOrg, WORD wDestYOrg,
 			       RECT16 *lpClipRect, LPCSTR lpString, WORD wCount, 
-			       SEGPTR lpFontInfo,SEGPTR lpDrawMode, 
+			       LPFONTINFO16 lpFontInfo, SEGPTR lpDrawMode, 
 			       SEGPTR lpTextXForm, SHORT *lpCharWidths,
 			       RECT16 *     lpOpaqueRect, WORD wOptions);
 
+extern WORD PRTDRV_Output(LPPDEVICE 	 lpDestDev,
+			  WORD 	 wStyle, 
+			  WORD 	 wCount,
+			  POINT16       *points, 
+			  LPLOGPEN16 	 lpPen,
+			  LPLOGBRUSH16	 lpBrush,
+			  SEGPTR	 lpDrawMode,
+			  HRGN32 	 hClipRgn);
+
+DWORD PRTDRV_StretchBlt(LPPDEVICE lpDestDev,
+                        WORD wDestX, WORD wDestY,
+                        WORD wDestXext, WORD wDestYext, 
+                        LPPDEVICE lpSrcDev,
+                        WORD wSrcX, WORD wSrcY,
+                        WORD wSrcXext, WORD wSrcYext, 
+                        DWORD Rop3,
+                        LPLOGBRUSH16 lpBrush,
+                        SEGPTR lpDrawMode,
+                        RECT16 *lpClipRect);
+
+extern WORD PRTDRV_GetCharWidth(LPPDEVICE lpDestDev, LPINT32 lpBuffer, 
+		      WORD wFirstChar, WORD wLastChar, LPFONTINFO16 lpFontInfo,
+		      SEGPTR lpDrawMode, SEGPTR lpTextXForm );
 
 /* Wine driver functions */
 
@@ -203,11 +216,14 @@
 extern BOOL32 WIN16DRV_LineTo( DC *dc, INT32 x, INT32 y );
 extern BOOL32 WIN16DRV_MoveToEx(DC *dc,INT32 x,INT32 y,LPPOINT32 pt);
 extern BOOL32 WIN16DRV_Polygon(DC *dc, LPPOINT32 pt, INT32 count );
+extern BOOL32 WIN16DRV_Polyline(DC *dc, LPPOINT32 pt, INT32 count );
 extern BOOL32 WIN16DRV_Rectangle(DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom);
 extern HGDIOBJ32 WIN16DRV_SelectObject( DC *dc, HGDIOBJ32 handle );
 extern BOOL32 WIN16DRV_PatBlt( struct tagDC *dc, INT32 left, INT32 top,
                                INT32 width, INT32 height, DWORD rop );
-
+extern BOOL32 WIN16DRV_Ellipse(DC *dc, INT32 left, INT32 top, INT32 right, INT32 bottom);
+extern BOOL32 WIN16DRV_EnumDeviceFonts( DC* dc, LPLOGFONT16 plf, 
+				        DEVICEFONTENUMPROC proc, LPARAM lp );
 
 
 /*
diff --git a/include/wincon.h b/include/wincon.h
index 0eb84a9..b7c46e5 100644
--- a/include/wincon.h
+++ b/include/wincon.h
@@ -54,5 +54,64 @@
     COORD       dwMaximumWindowSize;
 } CONSOLE_SCREEN_BUFFER_INFO,*LPCONSOLE_SCREEN_BUFFER_INFO;
 
+typedef struct tagCHAR_INFO
+{
+    union
+	{
+	WCHAR UnicodeChar;
+	CHAR AsciiChar;
+	} Char;
+    WORD	Attributes;
+} CHAR_INFO,*LPCHAR_INFO;
+
+typedef struct tagKEY_EVENT_RECORD
+{
+    BOOL32	bKeyDown;
+    WORD	wRepeatCount;
+    WORD	wVirtualKeyCode;
+    WORD	wVirtualScanCode;
+    union
+	{
+	WCHAR UniCodeChar;
+	CHAR AsciiChar;
+	} uChar;
+    DWORD	dwControlKeyState;
+} KEY_EVENT_RECORD,*LPKEY_EVENT_RECORD;
+
+typedef struct tagMOUSE_EVENT_RECORD
+{
+    COORD	dwMousePosition;
+    DWORD	dwButtonState;
+    DWORD	dwControlKeyState;
+    DWORD	dwEventFlags;
+} MOUSE_EVENT_RECORD,*LPMOUSE_EVENT_RECORD;
+
+typedef struct tagWINDOW_BUFFER_SIZE_RECORD
+{
+    COORD	dwSize;
+} WINDOW_BUFFER_SIZE_RECORD,*LPWINDOW_BUFFER_SIZE_RECORD;
+
+typedef struct tagMENU_EVENT_RECORD
+{
+    UINT32	dwCommandId; /* perhaps UINT16 ??? */
+} MENU_EVENT_RECORD,*LPMENU_EVENT_RECORD;
+
+typedef struct tagFOCUS_EVENT_RECORD
+{
+    BOOL32      bSetFocus; /* perhaps BOOL16 ??? */
+} FOCUS_EVENT_RECORD,*LPFOCUS_EVENT_RECORD;
+
+typedef struct tagINPUT_RECORD
+{
+    WORD		EventType;
+    union
+	{
+	KEY_EVENT_RECORD KeyEvent;
+	MOUSE_EVENT_RECORD MouseEvent;
+	WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
+	MENU_EVENT_RECORD MenuEvent;
+	FOCUS_EVENT_RECORD FocusEvent;
+	} Event;
+} INPUT_RECORD,*LPINPUT_RECORD;
 
 #endif  /* __WINE_WINCON_H */
diff --git a/include/windows.h b/include/windows.h
index 43a00b8..11f7d6c 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -305,6 +305,12 @@
 #define RDW_FRAME            0x0400
 #define RDW_NOFRAME          0x0800
 
+/* debug flags */
+#define DBGFILL_ALLOC  0xfd
+#define DBGFILL_FREE   0xfb
+#define DBGFILL_BUFFER 0xf9
+#define DBGFILL_STACK  0xf7
+
   /* WM_WINDOWPOSCHANGING/CHANGED struct */
 typedef struct
 {
@@ -1168,16 +1174,16 @@
     CHAR  dfUnderline;
     CHAR  dfStrikeOut;
     INT16 dfWeight;
-    CHAR  dfCHARSet;
+    CHAR  dfCharSet;
     INT16 dfPixWidth;
     INT16 dfPixHeight;
     CHAR  dfPitchAndFamily;
     INT16 dfAvgWidth;
     INT16 dfMaxWidth;
-    CHAR  dfFirstCHAR;
-    CHAR  dfLastCHAR;
-    CHAR  dfDefaultCHAR;
-    CHAR  dfBreakCHAR;
+    CHAR  dfFirstChar;
+    CHAR  dfLastChar;
+    CHAR  dfDefaultChar;
+    CHAR  dfBreakChar;
     INT16 dfWidthBytes;
     LONG  dfDevice;
     LONG  dfFace;
@@ -1659,6 +1665,10 @@
 #define GM_ADVANCED       2
 #define GM_LAST           2
 
+  /* Arc direction modes */
+#define AD_COUNTERCLOCKWISE 1
+#define AD_CLOCKWISE        2
+
   /* Map modes */
 #define MM_TEXT		  1
 #define MM_LOMETRIC	  2
@@ -5466,6 +5476,31 @@
 DECL_WINELIB_TYPE_AW(MSGBOXPARAMS);
 DECL_WINELIB_TYPE_AW(LPMSGBOXPARAMS);
 
+/* for WOWHandle{16,32} */
+typedef enum _WOW_HANDLE_TYPE { /* WOW */
+    WOW_TYPE_HWND,
+    WOW_TYPE_HMENU,
+    WOW_TYPE_HDWP,
+    WOW_TYPE_HDROP,
+    WOW_TYPE_HDC,
+    WOW_TYPE_HFONT,
+    WOW_TYPE_HMETAFILE,
+    WOW_TYPE_HRGN,
+    WOW_TYPE_HBITMAP,
+    WOW_TYPE_HBRUSH,
+    WOW_TYPE_HPALETTE,
+    WOW_TYPE_HPEN,
+    WOW_TYPE_HACCEL,
+    WOW_TYPE_HTASK,
+    WOW_TYPE_FULLHWND
+} WOW_HANDLE_TYPE;
+
+/* WOWCallback16Ex defines */
+#define WCB16_MAX_CBARGS	16
+/* ... dwFlags */
+#define WCB16_PASCAL		0x0
+#define WCB16_CDECL		0x1
+
 #pragma pack(4)
 
 /* Declarations for functions that exist only in Win16 */
@@ -5545,6 +5580,7 @@
 DWORD       WINAPI GlobalDOSAlloc(DWORD);
 WORD        WINAPI GlobalDOSFree(WORD);
 void        WINAPI GlobalFreeAll(HGLOBAL16);
+DWORD       WINAPI GlobalHandleNoRIP(WORD);
 HGLOBAL16   WINAPI GlobalLRUNewest(HGLOBAL16);
 HGLOBAL16   WINAPI GlobalLRUOldest(HGLOBAL16);
 VOID        WINAPI GlobalNotify(FARPROC16);
@@ -5657,6 +5693,7 @@
 HANDLE32    WINAPI CreateSemaphore32A(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR);
 HANDLE32    WINAPI CreateSemaphore32W(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR);
 #define     CreateSemaphore WINELIB_NAME_AW(CreateSemaphore)
+HANDLE32    WINAPI CreateThread(LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD);
 BOOL32      WINAPI DestroyAcceleratorTable(HACCEL32);
 BOOL32      WINAPI DisableThreadLibraryCalls(HMODULE32);
 BOOL32      WINAPI DosDateTimeToFileTime(WORD,WORD,LPFILETIME);
@@ -5738,6 +5775,7 @@
 DWORD       WINAPI GetFullPathName32A(LPCSTR,DWORD,LPSTR,LPSTR*);
 DWORD       WINAPI GetFullPathName32W(LPCWSTR,DWORD,LPWSTR,LPWSTR*);
 #define     GetFullPathName WINELIB_NAME_AW(GetFullPathName)
+INT32       WINAPI GetGraphicsMode(HDC32);
 DWORD       WINAPI GetLargestConsoleWindowSize(HANDLE32);
 VOID        WINAPI GetLocalTime(LPSYSTEMTIME);
 DWORD       WINAPI GetLogicalDrives(void);
@@ -5776,6 +5814,7 @@
 BOOL32      WINAPI GetUserName32W(LPWSTR,LPDWORD);
 #define     GetUserName WINELIB_NAME_AW(GetUserName)
 DWORD       WINAPI GetWindowThreadProcessId(HWND32,LPDWORD);
+BOOL32      WINAPI GetWorldTransform(HDC32,LPXFORM);
 VOID        WINAPI GlobalMemoryStatus(LPMEMORYSTATUS);
 LPVOID      WINAPI HeapAlloc(HANDLE32,DWORD,DWORD);
 DWORD       WINAPI HeapCompact(HANDLE32,DWORD);
@@ -5877,6 +5916,7 @@
 DWORD       WINAPI SetFilePointer(HFILE32,LONG,LPLONG,DWORD);
 BOOL32      WINAPI SetFileTime(HFILE32,const FILETIME*,const FILETIME*,
                                const FILETIME*);
+INT32       WINAPI SetGraphicsMode(HDC32,INT32);
 VOID        WINAPI SetLastErrorEx(DWORD,DWORD);
 BOOL32      WINAPI SetMenuItemInfo32A(HMENU32,UINT32,BOOL32,const MENUITEMINFO32A*);
 BOOL32      WINAPI SetMenuItemInfo32W(HMENU32,UINT32,BOOL32,const MENUITEMINFO32W*);
@@ -5887,6 +5927,7 @@
 BOOL32      WINAPI SetSystemTime(const SYSTEMTIME*);
 BOOL32      WINAPI SetThreadPriority(HANDLE32,INT32);
 BOOL32      WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION);
+BOOL32      WINAPI SetWorldTransform(HDC32,const XFORM*);
 VOID        WINAPI Sleep(DWORD);
 BOOL32      WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME);
 BOOL32      WINAPI TrackPopupMenuEx(HMENU32,UINT32,INT32,INT32,HWND32,
@@ -5910,12 +5951,16 @@
 DWORD       WINAPI WaitForMultipleObjectsEx(DWORD,const HANDLE32*,BOOL32,DWORD,BOOL32);
 DWORD       WINAPI WaitForSingleObject(HANDLE32,DWORD);
 DWORD       WINAPI WaitForSingleObjectEx(HANDLE32,DWORD,BOOL32);
+SEGPTR      WINAPI WOWGlobalAllocLock16(DWORD,DWORD,HGLOBAL16*);
+DWORD       WINAPI WOWCallback16(FARPROC16,DWORD);
+BOOL32      WINAPI WOWCallback16Ex(FARPROC16,DWORD,DWORD,LPVOID,LPDWORD);
+HANDLE32    WINAPI WOWHandle32(WORD,WOW_HANDLE_TYPE);
+WORD        WINAPI WOWHandle16(HANDLE32,WOW_HANDLE_TYPE);
 BOOL32      WINAPI WriteConsole32A(HANDLE32,LPCVOID,DWORD,LPDWORD,LPVOID);
 BOOL32      WINAPI WriteConsole32W(HANDLE32,LPCVOID,DWORD,LPDWORD,LPVOID);
 #define     WriteConsole WINELIB_NAME_AW(WriteConsole)
 BOOL32      WINAPI WriteFile(HFILE32,LPVOID,DWORD,LPDWORD,LPOVERLAPPED);
 
-
 /* Declarations for functions that are the same in Win16 and Win32 */
 
 VOID        WINAPI CloseSound(VOID);
@@ -6634,6 +6679,9 @@
 DWORD       WINAPI GetAppCompatFlags16(HTASK16);
 DWORD       WINAPI GetAppCompatFlags32(HTASK32);
 #define     GetAppCompatFlags WINELIB_NAME(GetAppCompatFlags)
+INT16       WINAPI GetArcDirection16(HDC16);
+INT32       WINAPI GetArcDirection32(HDC32);
+#define     GetArcDirection WINELIB_NAME(GetArcDirection)
 WORD        WINAPI GetAsyncKeyState16(INT16);
 WORD        WINAPI GetAsyncKeyState32(INT32);
 #define     GetAsyncKeyState WINELIB_NAME(GetAsyncKeyState)
@@ -7314,6 +7362,10 @@
 HICON32     WINAPI LoadIcon32A(HINSTANCE32,LPCSTR);
 HICON32     WINAPI LoadIcon32W(HINSTANCE32,LPCWSTR);
 #define     LoadIcon WINELIB_NAME_AW(LoadIcon)
+HANDLE16    WINAPI LoadImage16(HINSTANCE16,LPCSTR,UINT16,INT16,INT16,UINT16);
+HANDLE32    WINAPI LoadImage32A(HINSTANCE32,LPCSTR,UINT32,INT32,INT32,UINT32);
+HANDLE32    WINAPI LoadImage32W(HINSTANCE32,LPCWSTR,UINT32,INT32,INT32,UINT32);
+#define     LoadImage WINELIB_NAME_AW(LoadImage)
 HINSTANCE16 WINAPI LoadLibrary16(LPCSTR);
 HMODULE32   WINAPI LoadLibrary32A(LPCSTR);
 HMODULE32   WINAPI LoadLibrary32W(LPCWSTR);
@@ -7697,6 +7749,9 @@
 HWND16      WINAPI SetActiveWindow16(HWND16);
 HWND32      WINAPI SetActiveWindow32(HWND32);
 #define     SetActiveWindow WINELIB_NAME(SetActiveWindow)
+INT16       WINAPI SetArcDirection16(HDC16,INT16);
+INT32       WINAPI SetArcDirection32(HDC32,INT32);
+#define     SetArcDirection WINELIB_NAME(SetArcDirection)
 LONG        WINAPI SetBitmapBits16(HBITMAP16,LONG,LPCVOID);
 LONG        WINAPI SetBitmapBits32(HBITMAP32,LONG,LPCVOID);
 #define     SetBitmapBits WINELIB_NAME(SetBitmapBits)
diff --git a/include/winnt.h b/include/winnt.h
index be00784..e18eeb3 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -25,10 +25,13 @@
 #define HEAP_WINE_CODESEG               0x02000000  /* Not a Win32 flag */
 
 /* Processor feature flags.  */
-#define PF_FLOATING_POINT_PRECISION_ERRATA    0
-#define PF_FLOATING_POINT_EMULATED            1
-#define PF_COMPARE_EXCHANGE_DOUBLE            2
-#define PF_MMX_INSTRUCTIONS_AVAILABLE         3
+#define PF_FLOATING_POINT_PRECISION_ERRATA	0
+#define PF_FLOATING_POINT_EMULATED		1
+#define PF_COMPARE_EXCHANGE_DOUBLE		2
+#define PF_MMX_INSTRUCTIONS_AVAILABLE		3
+#define PF_PPC_MOVEMEM_64BIT_OK			4
+#define PF_ALPHA_BYTE_INSTRUCTIONS		5
+
 
 /* The Win32 register context */
 
diff --git a/include/winsock.h b/include/winsock.h
index ca7357c..63a1878 100644
--- a/include/winsock.h
+++ b/include/winsock.h
@@ -475,8 +475,8 @@
 
 /* ws_... struct conversion flags */
 
-#define WS_DUP_LINEAR		0x0000
-#define WS_DUP_NATIVE           0x0001		/* native structure format (not ws_..) */
+#define WS_DUP_LINEAR		0x0001
+#define WS_DUP_NATIVE           0x0000		/* not used anymore */
 #define WS_DUP_OFFSET           0x0002		/* internal pointers are offsets */
 #define WS_DUP_SEGPTR           0x0004		/* internal pointers are SEGPTRs */
 						/* by default, internal pointers are linear */
@@ -537,7 +537,7 @@
   ws_select_op*	psop;
 } ws_socket;
 
-#define WS_MAX_SOCKETS_PER_THREAD       16
+#define WS_MAX_SOCKETS_PER_PROCESS      16
 #define WS_MAX_UDP_DATAGRAM             1024
 
 #define WSI_BLOCKINGCALL	0x00000001	/* per-thread info flags */
@@ -556,7 +556,7 @@
   char*			buffer;			/* allocated from SEGPTR heap */
   char*			dbuffer;		/* buffer for dummies (32 bytes) */
 
-  ws_socket		sock[WS_MAX_SOCKETS_PER_THREAD];
+  ws_socket		sock[WS_MAX_SOCKETS_PER_PROCESS];
   DWORD			blocking_hook;
   HTASK16               tid;    		/* owning task id - process might be better */
 } WSINFO, *LPWSINFO;
@@ -579,7 +579,7 @@
 
 void WINSOCK_cancel_task_aops(HTASK16, void (*__memfree)(void*) );
 
-BOOL32 WINSOCK_HandleIO(int* fd_max, int num_pending, fd_set io_set[3] );
+BOOL32 WINSOCK_HandleIO(int* fd_max, int num_pending, fd_set pending_set[3], fd_set master_set[3] );
 void   WINSOCK_Shutdown(void);
 UINT16 wsaErrno(void);
 UINT16 wsaHerrno(void);
diff --git a/include/wnet.h b/include/wnet.h
new file mode 100644
index 0000000..6f6b951
--- /dev/null
+++ b/include/wnet.h
@@ -0,0 +1,120 @@
+/* Definitions for windows network service
+ * 
+ * Copyright 1997 Andreas Mohr
+ */
+#ifndef __WINE_WNET_H
+#define __WINE_WNET_H
+
+#define WN_SUCCESS                              0x0000
+#define WN_NOT_SUPPORTED                        0x0001
+#define WN_NET_ERROR                            0x0002
+#define WN_MORE_DATA                            0x0003
+#define WN_BAD_POINTER                          0x0004
+#define WN_BAD_VALUE                            0x0005
+#define WN_BAD_PASSWORD                         0x0006
+#define WN_ACCESS_DENIED                        0x0007
+#define WN_FUNCTION_BUSY                        0x0008
+#define WN_WINDOWS_ERROR                        0x0009
+#define WN_BAD_USER                             0x000A
+#define WN_OUT_OF_MEMORY                        0x000B
+#define WN_CANCEL                               0x000C
+#define WN_CONTINUE                             0x000D
+#define WN_NOT_CONNECTED                        0x0030
+#define WN_OPEN_FILES                           0x0031
+#define WN_BAD_NETNAME                          0x0032
+#define WN_BAD_LOCALNAME                        0x0033
+#define WN_ALREADY_CONNECTED                    0x0034
+#define WN_DEVICE_ERROR                         0x0035
+#define WN_CONNECTION_CLOSED                    0x0036
+#define WN_NO_NETWORK                           ERROR_NO_NETWORK
+
+#define WNNC_SPEC_VERSION                       0x01
+#define WNNC_NET_TYPE                           0x02
+#define WNNC_DRIVER_VERSION                     0x03
+#define WNNC_USER                               0x04
+/*#define WNNC_5                                0x05*/
+#define WNNC_CONNECTION                         0x06
+#define WNNC_PRINTING                           0x07
+#define WNNC_DIALOG                             0x08
+#define WNNC_ADMIN                              0x09
+#define WNNC_ERROR                              0x0a
+#define WNNC_PRINTMGREXT                        0x0b
+
+#define WNNC_NET_NONE                           0x0
+#define WNNC_NET_MSNet                          0x1
+#define WNNC_NET_LanMan                         0x2
+#define WNNC_NET_NetWare                        0x3
+#define WNNC_NET_Vines                          0x4
+#define WNNC_NET_10NET                          0x5
+#define WNNC_NET_Locus                          0x6
+#define WNNC_NET_SUN_PC_NFS                     0x7
+#define WNNC_NET_LANstep                        0x8
+#define WNNC_NET_9TILES                         0x9
+#define WNNC_NET_LANtastic                      0xa
+#define WNNC_NET_AS400                          0xb
+#define WNNC_NET_FTP_NFS                        0xc
+#define WNNC_NET_PATHWORKS                      0xd
+#define WNNC_NET_LifeNet                        0xe
+#define WNNC_NET_POWERLan                       0xf
+#define WNNC_NET_MultiNet                       0x8000
+
+#define WNNC_SUBNET_NONE                        0x00
+#define WNNC_SUBNET_MSNet                       0x01
+#define WNNC_SUBNET_LanMan                      0x02
+#define WNNC_SUBNET_WinWorkgroups               0x04
+#define WNNC_SUBNET_NetWare                     0x08
+#define WNNC_SUBNET_Vines                       0x10
+#define WNNC_SUBNET_Other                       0x80
+
+#define WNNC_CON_AddConnection                  0x0001
+#define WNNC_CON_CancelConnection               0x0002
+#define WNNC_CON_GetConnections                 0x0004
+#define WNNC_CON_AutoConnect                    0x0008
+#define WNNC_CON_BrowseDialog                   0x0010
+#define WNNC_CON_RestoreConnection              0x0020
+
+#define WNNC_PRT_OpenJob                        0x0002
+#define WNNC_PRT_CloseJob                       0x0004
+#define WNNC_PRT_HoldJob                        0x0010
+#define WNNC_PRT_ReleaseJob                     0x0020
+#define WNNC_PRT_CancelJob                      0x0040
+#define WNNC_PRT_SetJobCopies                   0x0080
+#define WNNC_PRT_WatchQueue                     0x0100
+#define WNNC_PRT_UnwatchQueue                   0x0200
+#define WNNC_PRT_LockQueueData                  0x0400
+#define WNNC_PRT_UnlockQueueData                0x0800
+#define WNNC_PRT_ChangeMsg                      0x1000
+#define WNNC_PRT_AbortJob                       0x2000
+#define WNNC_PRT_NoArbitraryLock                0x4000
+#define WNNC_PRT_WriteJob                       0x8000
+
+#define WNNC_DLG_DeviceMode                     0x0001
+#define WNNC_DLG_BrowseDialog                   0x0002
+#define WNNC_DLG_ConnectDialog                  0x0004
+#define WNNC_DLG_DisconnectDialog               0x0008
+#define WNNC_DLG_ViewQueueDialog                0x0010
+#define WNNC_DLG_PropertyDialog                 0x0020
+#define WNNC_DLG_ConnectionDialog               0x0040
+#define WNNC_DLG_PrinterConnectDialog           0x0080
+#define WNNC_DLG_SharesDialog                   0x0100
+#define WNNC_DLG_ShareAsDialog                  0x0200
+
+#define WNNC_ADM_GetDirectoryType               0x0001
+#define WNNC_ADM_DirectoryNotify                0x0002
+#define WNNC_ADM_LongNames                      0x0004
+#define WNNC_ADM_SetDefaultDrive                0x0008
+
+#define WNNC_ERR_GetError                       0x0001
+#define WNNC_ERR_GetErrorText                   0x0002
+
+#define WIN30X                                  0x0
+#define WIN31X                                  0x1
+#define WIN311X                                 0x2
+#define WIN95X                                  0x3
+#define WINNTX                                  0x4
+#define WINOTHERX                               0x5
+#define WIN32X                                  0x6
+
+typedef LPVOID  LPNETRESOURCE16;
+
+#endif	/* __WINE_WNET_H */
diff --git a/include/x11drv.h b/include/x11drv.h
index 0db6b86..885a595 100644
--- a/include/x11drv.h
+++ b/include/x11drv.h
@@ -5,8 +5,9 @@
 #ifndef __WINE_X11DRV_H
 #define __WINE_X11DRV_H
 
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xutil.h"
+#include "tsx11defs.h"
 
 #include "windows.h"
 
diff --git a/ipc/dde_proc.c b/ipc/dde_proc.c
index d9fc256..57142b1 100644
--- a/ipc/dde_proc.c
+++ b/ipc/dde_proc.c
@@ -231,7 +231,7 @@
      dprintf_msg(stddeb,"DDE_DoOneMessage: "
 		 "Trying to get acknowledgment from msg queue=%d\n",
 		 proc->msg);
-     Yield();			/* force task switch, and */
+     Yield16();			/* force task switch, and */
 				/* acknowledgment sending */
      if (get_ack()) {
 	return TRUE;
diff --git a/library/winestub.c b/library/winestub.c
index 789c7bf..e39b7be 100644
--- a/library/winestub.c
+++ b/library/winestub.c
@@ -1,13 +1,16 @@
 /* Sample winestub.c file for compiling programs with libwine.so. */
 
 #include <string.h>
+#include <stdio.h>
 #include "windows.h"
 #include "xmalloc.h"
 
 /* Stub needed for linking with Winelib */
 /* FIXME: this should not be necessary */
-HMODULE32 BUILTIN_LoadModule( LPCSTR name, BOOL32 force ) { return 0; }
-
+HMODULE32 BUILTIN_LoadModule( LPCSTR name, BOOL32 force ) { 
+	fprintf(stderr,"BUILTIN_LoadModule(%s,%d) called in a library!\n",name,force);
+	return 0;
+}
 
 extern int PASCAL WinMain(HINSTANCE32,HINSTANCE32,LPSTR,int);
 extern int MAIN_WinelibInit(void);
diff --git a/libtest/Makefile.in b/libtest/Makefile.in
index 11deeea..f68cd12 100644
--- a/libtest/Makefile.in
+++ b/libtest/Makefile.in
@@ -4,7 +4,7 @@
 VPATH     = @srcdir@
 MODULE    = none
 RCFLAGS   = -w16 -h
-PROGRAMS  = expand hello hello2 hello3 hello4 new rolex
+PROGRAMS  = expand hello hello2 hello3 hello4 hello5 new rolex
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 
 C_SRCS = \
@@ -13,6 +13,7 @@
 	hello2.c \
 	hello3.c \
 	hello4.c \
+	hello5.c \
 	new.c \
 	rolex.c
 
@@ -42,6 +43,9 @@
 hello4: hello4.o
 	$(CC) -o hello4 hello4.o $(LDOPTIONS) $(ALL_LIBS)
 
+hello5: hello5.o
+	$(CC) -o hello5 hello5.o $(LDOPTIONS) $(ALL_LIBS)
+
 new: new.o
 	$(CC) -o new new.o $(LDOPTIONS) $(ALL_LIBS)
 
diff --git a/libtest/hello5.c b/libtest/hello5.c
new file mode 100644
index 0000000..39d1ad0
--- /dev/null
+++ b/libtest/hello5.c
@@ -0,0 +1,36 @@
+/*
+ * This example demonstrates dynamical loading of (internal) Win32 DLLS.
+ */
+#include <windows.h>
+#include <stdio.h>
+
+int PASCAL WinMain (HANDLE inst, HANDLE prev, LPSTR cmdline, int show)
+{
+	SYSTEM_INFO	si;
+	void (CALLBACK *fnGetSystemInfo)(LPSYSTEM_INFO si);
+	HMODULE32	kernel32;
+
+	kernel32 = LoadLibrary("KERNEL32");
+	if (kernel32<32) {
+		fprintf(stderr,"FATAL: could not load KERNEL32!\n");
+		return 0;
+	}
+	fnGetSystemInfo = (void (CALLBACK*)(LPSYSTEM_INFO))GetProcAddress(kernel32,"GetSystemInfo");
+	if (!fnGetSystemInfo) {
+		fprintf(stderr,"FATAL: could not find GetSystemInfo!\n");
+		return 0;
+	}
+	fnGetSystemInfo(&si);
+	fprintf(stderr,"QuerySystemInfo returns:\n");
+	fprintf(stderr,"	wProcessorArchitecture: %d\n",si.u.x.wProcessorArchitecture);
+	fprintf(stderr,"	dwPageSize: %ld\n",si.dwPageSize);
+	fprintf(stderr,"	lpMinimumApplicationAddress: %p\n",si.lpMinimumApplicationAddress);
+	fprintf(stderr,"	lpMaximumApplicationAddress: %p\n",si.lpMaximumApplicationAddress);
+	fprintf(stderr,"	dwActiveProcessorMask: %ld\n",si.dwActiveProcessorMask);
+	fprintf(stderr,"	dwNumberOfProcessors: %ld\n",si.dwNumberOfProcessors);
+	fprintf(stderr,"	dwProcessorType: %ld\n",si.dwProcessorType);
+	fprintf(stderr,"	dwAllocationGranularity: %ld\n",si.dwAllocationGranularity);
+	fprintf(stderr,"	wProcessorLevel: %d\n",si.wProcessorLevel);
+	fprintf(stderr,"	wProcessorRevision: %d\n",si.wProcessorRevision);
+	return 0;
+}
diff --git a/loader/module.c b/loader/module.c
index 831a001..35134fd 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -1418,7 +1418,7 @@
                                        DWORD flags )
 {
     fprintf(stderr,"LoadLibraryEx32W(%s,%d,%08lx)\n",libname,hf,flags);
-    return LoadLibraryEx32A(libname,hf,flags);
+    return LoadLibraryEx32A(libname, hf,flags);
 }
 
 /***********************************************************************
@@ -1428,13 +1428,13 @@
 {
     HMODULE32 hmod;
     
-    hmod = PE_LoadLibraryEx32A(libname,hfile,flags);
+    hmod = PE_LoadLibraryEx32A(libname,PROCESS_Current(),hfile,flags);
     if (hmod <= 32) {
 	char buffer[256];
 
 	strcpy( buffer, libname );
 	strcat( buffer, ".dll" );
-	hmod = PE_LoadLibraryEx32A(buffer,hfile,flags);
+	hmod = PE_LoadLibraryEx32A(buffer,PROCESS_Current(),hfile,flags);
     }
     /* initialize all DLLs, which haven't been initialized yet. */
     PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, NULL);
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 14278c8..d092b3d 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -69,15 +69,16 @@
         STACK16FRAME *stack16Top;
         DWORD oldstack;
  	WORD oldselector, newselector;
+        THDB *thdb = THREAD_Current();
         HFILE32 hf = FILE_DupUnixHandle( fd );
 
  	selfloadheader = (SELFLOADHEADER *)
  		PTR_SEG_OFF_TO_LIN(pSegTable->selector,0);
- 	oldstack = IF1632_Saved16_ss_sp;
+ 	oldstack = thdb->cur_stack;
  	oldselector = pSeg->selector;
- 	IF1632_Saved16_ss_sp = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
+ 	thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
                                                  0xff00 - sizeof(*stack16Top));
-        stack16Top = CURRENT_STACK16;
+        stack16Top = (STACK16FRAME *)PTR_SEG_TO_LIN(thdb->cur_stack);
         stack16Top->frame32 = 0;
         stack16Top->ds = stack16Top->es = pModule->self_loading_sel;
         stack16Top->entry_point = 0;
@@ -107,7 +108,7 @@
  	  }
  	} 
  	
- 	IF1632_Saved16_ss_sp = oldstack;
+ 	thdb->cur_stack = oldstack;
     }
     else if (!(pSeg->flags & NE_SEGFLAGS_ITERATED))
       read(fd, mem, size);
@@ -368,6 +369,7 @@
         SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule);
         SELFLOADHEADER *selfloadheader;
         STACK16FRAME *stack16Top;
+        THDB *thdb = THREAD_Current();
         HMODULE16 hselfload = GetModuleHandle16("WPROCS");
         DWORD oldstack;
         WORD saved_dgroup = pSegTable[pModule->dgroup - 1].selector;
@@ -382,10 +384,10 @@
         selfloadheader->MyAlloc  = MODULE_GetEntryPoint(hselfload,28);
         selfloadheader->SetOwner = MODULE_GetEntryPoint(GetModuleHandle16("KERNEL"),403);
         pModule->self_loading_sel = GlobalHandleToSel(GLOBAL_Alloc(GMEM_ZEROINIT, 0xFF00, pModule->self, FALSE, FALSE, FALSE));
-        oldstack = IF1632_Saved16_ss_sp;
-        IF1632_Saved16_ss_sp = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
+        oldstack = thdb->cur_stack;
+        thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR(pModule->self_loading_sel,
                                                 0xff00 - sizeof(*stack16Top) );
-        stack16Top = CURRENT_STACK16;
+        stack16Top = (STACK16FRAME *)PTR_SEG_TO_LIN(thdb->cur_stack);
         stack16Top->frame32 = 0;
         stack16Top->ebp = 0;
         stack16Top->ds = stack16Top->es = pModule->self_loading_sel;
@@ -401,7 +403,7 @@
         _lclose32(hf);
         /* some BootApp procs overwrite the selector of dgroup */
         pSegTable[pModule->dgroup - 1].selector = saved_dgroup;
-        IF1632_Saved16_ss_sp = oldstack;
+        thdb->cur_stack = oldstack;
         for (i = 2; i <= pModule->seg_count; i++)
             if (!NE_LoadSegment( pModule, i )) return FALSE;
     }
@@ -622,7 +624,7 @@
 
     CS_reg(&context)  = pSegTable[pModule->cs-1].selector;
     EIP_reg(&context) = pModule->ip;
-    EBP_reg(&context) = OFFSETOF(IF1632_Saved16_ss_sp)
+    EBP_reg(&context) = OFFSETOF(THREAD_Current()->cur_stack)
                           + (WORD)&((STACK16FRAME*)0)->bp;
     EDI_reg(&context) = DS_reg(&context) ? DS_reg(&context) : hModule;
 
diff --git a/loader/pe_image.c b/loader/pe_image.c
index e3f31d4..acc8a66 100644
--- a/loader/pe_image.c
+++ b/loader/pe_image.c
@@ -26,6 +26,7 @@
 #include "neexe.h"
 #include "peexe.h"
 #include "process.h"
+#include "thread.h"
 #include "pe_image.h"
 #include "module.h"
 #include "global.h"
@@ -166,8 +167,7 @@
 	return NULL;
 }
 
-void 
-fixup_imports (PDB32 *process,PE_MODREF *pem,HMODULE32 hModule)
+DWORD fixup_imports (PDB32 *process,PE_MODREF *pem,HMODULE32 hModule)
 {
     IMAGE_IMPORT_DESCRIPTOR	*pe_imp;
     int	fixup_failed		= 0;
@@ -205,7 +205,7 @@
  	char *name = (char *) RVA(pe_imp->Name);
 
 	/* don't use MODULE_Load, Win32 creates new task differently */
-	res = PE_LoadLibraryEx32A( name, 0, 0 );
+	res = PE_LoadLibraryEx32A( name, process, 0, 0 );
 	if (res <= (HMODULE32) 32) {
 	    char *p, buffer[1024];
 
@@ -214,11 +214,11 @@
 	    if (!(p = strrchr (buffer, '\\')))
 		p = buffer;
 	    strcpy (p + 1, name);
-	    res = PE_LoadLibraryEx32A( buffer, 0, 0 );
+	    res = PE_LoadLibraryEx32A( buffer, process, 0, 0 );
 	}
 	if (res <= (HMODULE32) 32) {
 	    fprintf (stderr, "Module %s not found\n", name);
-	    exit (0);
+	    return res;
 	}
 	res = MODULE_HANDLEtoHMODULE32(res);
 	xpem = pem->next;
@@ -328,7 +328,8 @@
 	}
 	pe_imp++;
     }
-    if (fixup_failed) exit(1);
+    if (fixup_failed) return 22;
+    return 0;
 }
 
 static int calc_vma_size( HMODULE32 hModule )
@@ -629,10 +630,6 @@
 		dprintf_win32(stdnimp,"Global Pointer (MIPS) ignored\n");
 
 	if(nt_header->OptionalHeader.DataDirectory
-		[IMAGE_DIRECTORY_ENTRY_TLS].Size)
-		 fprintf(stdnimp,"Thread local storage ignored\n");
-
-	if(nt_header->OptionalHeader.DataDirectory
 		[IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG].Size)
 		dprintf_win32(stdnimp,"Load Configuration directory ignored\n");
 
@@ -652,7 +649,28 @@
 
 	if(pem->pe_reloc)	do_relocations(pem);
 	if(pem->pe_export)	dump_exports(pem->module);
-	if(pem->pe_import)	fixup_imports(process,pem,hModule);
+	if(pem->pe_import)	{
+		if (fixup_imports(process,pem,hModule)) {
+			PE_MODREF	**xpem;
+
+			/* remove entry from modref chain */
+			xpem = &(process->modref_list);
+			while (*xpem) {
+				if (*xpem==pem) {
+					*xpem = pem->next;
+					break;
+				}
+				xpem = &((*xpem)->next);
+			}
+			/* FIXME: there are several more dangling references
+			 * left. Including dlls loaded by this dll before the
+			 * failed one. Unrolling is rather difficult with the
+			 * current structure and we can leave it them lying
+			 * around with no problems, so we don't care
+			 */
+			return 0;
+		}
+	}
   		
 	if (pem->pe_export)
 		modname = (char*)RVA(pem->pe_export->Name);
@@ -678,9 +696,11 @@
  * FIXME: handle the flags.
  *        internal module handling should be made better here (and in builtin.c)
  */
-HMODULE32 PE_LoadLibraryEx32A (LPCSTR name, HFILE32 hFile, DWORD flags) {
+HMODULE32 PE_LoadLibraryEx32A (LPCSTR name, PDB32 *process,
+                               HFILE32 hFile, DWORD flags)
+{
 	OFSTRUCT	ofs;
-	HMODULE32	hModule;
+	HMODULE32	hModule,ret;
 	NE_MODULE	*pModule;
 	PE_MODREF	*pem;
 
@@ -690,14 +710,13 @@
 		if (!HIWORD(hModule)) /* internal (or bad) */
 			return hModule;
 		/* check if this module is already mapped */
-		pem 	= PROCESS_Current()->modref_list;
+		pem 	= process->modref_list;
 		while (pem) {
 			if (pem->module == hModule) return hModule;
 			pem = pem->next;
 		}
 		pModule = MODULE_GetPtr(hModule);
 		if (pModule->flags & NE_FFLAGS_BUILTIN) {
-			PDB32	*process = PROCESS_Current();
 			IMAGE_DOS_HEADER	*dh;
 			IMAGE_NT_HEADERS	*nh;
 			IMAGE_SECTION_HEADER	*sh;
@@ -720,13 +739,13 @@
 	} else {
 
 		/* try to load builtin, enabled modules first */
-		if ((hModule = BUILTIN_LoadModule( name, FALSE )))
+		if ((hModule = BUILTIN32_LoadModule( name, FALSE )))
                     return MODULE_HANDLEtoHMODULE32( hModule );
 
 		/* try to open the specified file */
 		if (HFILE_ERROR32==(hFile=OpenFile32(name,&ofs,OF_READ))) {
 			/* Now try the built-in even if disabled */
-			if ((hModule = BUILTIN_LoadModule( name, TRUE ))) {
+			if ((hModule = BUILTIN32_LoadModule( name, TRUE ))) {
 				fprintf( stderr, "Warning: could not load Windows DLL '%s', using built-in module.\n", name );
                                 return MODULE_HANDLEtoHMODULE32( hModule );
 			}
@@ -743,9 +762,13 @@
 		if (pModule->module32 < 32) return 21;
 	}
 	/* recurse */
-	pModule->module32 = PE_MapImage( pModule->module32, PROCESS_Current(),
-                                         &ofs,flags);
-	return pModule->module32;
+	ret = PE_MapImage( pModule->module32, process, &ofs,flags);
+	if (!ret) {
+		/* should free this module and the already referenced ones */
+		return 0;
+	}
+	pModule->module32 = ret;
+	return ret;
 }
 
 /*****************************************************************************
@@ -756,10 +779,11 @@
 HINSTANCE16 PE_LoadModule( HFILE32 hFile, OFSTRUCT *ofs, LOADPARAMS* params )
 {
     HMODULE16 hModule16;
-    HMODULE32 hModule32;
+    HMODULE32 hModule32, ret;
     HINSTANCE16 hInstance;
     NE_MODULE *pModule;
-
+    THDB *thdb = THREAD_Current();
+    
     if ((hModule16 = MODULE_CreateDummyModule( ofs )) < 32) return hModule16;
     pModule = (NE_MODULE *)GlobalLock16( hModule16 );
     pModule->flags = NE_FFLAGS_WIN32;
@@ -771,12 +795,21 @@
     hInstance = MODULE_CreateInstance( hModule16, params );
     if (!(PE_HEADER(hModule32)->FileHeader.Characteristics & IMAGE_FILE_DLL))
     {
-        TASK_CreateTask( hModule16, hInstance, 0,
-                         params->hEnvironment,
-                         (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
-                         *((WORD*)PTR_SEG_TO_LIN(params->showCmd) + 1) );
+        HTASK16 hTask = TASK_CreateTask( hModule16, hInstance, 0,
+                                         params->hEnvironment,
+                                      (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
+                               *((WORD*)PTR_SEG_TO_LIN(params->showCmd) + 1) );
+        TDB *pTask = (TDB *)GlobalLock16( hTask );
+        thdb = pTask->thdb;
     }
-    pModule->module32 = PE_MapImage( hModule32, PROCESS_Current(), ofs, 0 );
+    if (!(ret = PE_MapImage( hModule32, thdb->process, ofs, 0 )))
+    {
+     	/* FIXME: should destroy the task created ... */
+        return 0;
+    }
+    pModule->module32 = ret;
+    /* yuck. but there is no other good place to do that... */
+    PE_InitTls( thdb );
     return hInstance;
 }
 
@@ -840,14 +873,15 @@
 	}
 }
 
-void PE_InitTls(PDB32 *pdb)
+void PE_InitTls(THDB *thdb)
 {
 	/* FIXME: tls callbacks ??? */
 	PE_MODREF		*pem;
 	IMAGE_NT_HEADERS	*peh;
-	DWORD			size,datasize,index;
+	DWORD			size,datasize;
 	LPVOID			mem;
 	LPIMAGE_TLS_DIRECTORY	pdir;
+	PDB32			*pdb = thdb->process;
 
 	pem = pdb->modref_list;
 	while (pem) {
@@ -858,13 +892,18 @@
 		}
 		pdir = (LPVOID)(pem->module + peh->OptionalHeader.
 			DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress);
-		index	= TlsAlloc();
+		
+		if (!(pem->flags & PE_MODREF_TLS_ALLOCED)) {
+			pem->tlsindex = TlsAlloc();
+			*(pdir->AddressOfIndex)=pem->tlsindex;   
+		}
+		pem->flags |= PE_MODREF_TLS_ALLOCED;
 		datasize= pdir->EndAddressOfRawData-pdir->StartAddressOfRawData;
 		size	= datasize + pdir->SizeOfZeroFill;
 		mem=VirtualAlloc(0,size,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
 		memcpy(mem,(LPVOID) pdir->StartAddressOfRawData, datasize);
-		TlsSetValue(index,mem);
-		*(pdir->AddressOfIndex)=index;   
+		/* don't use TlsSetValue, we are in the wrong thread */
+		thdb->tls_array[pem->tlsindex] = mem;
 		pem=pem->next;
 	}
 }
diff --git a/loader/task.c b/loader/task.c
index 7c31fae..eeeaeb0 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -38,10 +38,6 @@
 
 extern INT32 WINSOCK_DeleteTaskWSI( TDB* pTask, struct _WSINFO* );
 extern BOOL32 MODULE_FreeModule( HMODULE16 hModule, TDB* ptaskContext );
-extern void PE_InitTls( PDB32 *pdb32 );
-
-  /* Saved 16-bit stack for current process (Win16 only) */
-DWORD IF1632_Saved16_ss_sp = 0;
 
   /* Pointer to function to switch to a larger stack */
 int (*IF1632_CallLargeStack)( int (*func)(), void *arg ) = NULL;
@@ -337,19 +333,19 @@
     NE_MODULE *pModule = MODULE_GetPtr( pTask->hModule );
     SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule );
 
-    IF1632_Saved16_ss_sp = pTask->ss_sp;
-    /* Terminate the stack frame */
-    CURRENT_STACK16->frame32 = NULL;
     SET_CUR_THREAD( pTask->thdb );
+    /* Terminate the stack frame */
+    THREAD_STACK16(pTask->thdb)->frame32 = NULL;
     if (pModule->flags & NE_FFLAGS_WIN32)
     {
         /* FIXME: all this is an ugly hack */
 
-        extern void InitTask( CONTEXT *context );
-
         FARPROC32 entry = (FARPROC32)RVA_PTR( PROCESS_Current()->exe_modref->module, OptionalHeader.AddressOfEntryPoint );
 
-        InitTask( NULL );
+        pTask->userhandler = (USERSIGNALPROC)&USER_SignalProc;
+        if (pModule->heap_size)
+            LocalInit( pTask->hInstance, 0, pModule->heap_size );
+
         InitApp( pTask->hModule );
         PE_InitializeDLLs( PROCESS_Current(), DLL_PROCESS_ATTACH, (LPVOID)-1 );
         dprintf_relay( stddeb, "CallTo32(entryproc=%p)\n", entry );
@@ -383,8 +379,8 @@
 
         dprintf_task( stddeb, "Starting main program: cs:ip=%04lx:%04x ds=%04lx ss:sp=%04x:%04x\n",
                       CS_reg(&context), IP_reg(&context), DS_reg(&context),
-                      SELECTOROF(IF1632_Saved16_ss_sp),
-                      OFFSETOF(IF1632_Saved16_ss_sp) );
+                      SELECTOROF(pTask->thdb->cur_stack),
+                      OFFSETOF(pTask->thdb->cur_stack) );
 
         Callbacks->CallRegisterShortProc( &context, 0 );
         /* This should never return */
@@ -528,19 +524,31 @@
         pTask->thdb = THREAD_Create( pdb32,
           PE_HEADER(pModule->module32)->OptionalHeader.SizeOfStackReserve,
                                      NULL, NULL );
-        /* FIXME: should not be done here */
-        PE_InitTls( pdb32 );
     }
     else
         pTask->thdb = THREAD_Create( pdb32, 0, NULL, NULL );
-
     /* FIXME: check for pTask->thdb == NULL.  */
-    SET_CUR_THREAD( pTask->thdb );
+
+    /* Create the 16-bit stack frame */
+
+    if (!(sp = pModule->sp))
+        sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
+    sp &= ~1;
+    pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
+    pTask->thdb->cur_stack -= sizeof(STACK16FRAME) + sizeof(STACK32FRAME *);
+    frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
+    frame16->ebp = sp + (int)&((STACK16FRAME *)0)->bp;
+    frame16->bp = LOWORD(frame16->ebp);
+    frame16->ds = frame16->es = pTask->hInstance;
+    frame16->entry_point = 0;
+    frame16->entry_cs = 0;
+    /* The remaining fields will be initialized in TASK_Reschedule */
 
     /* Create the 32-bit stack frame */
 
     stack32Top = (char*)pTask->thdb->teb.stack_top;
-    frame32 = (STACK32FRAME *)stack32Top - 1;
+    frame16->frame32 = frame32 = (STACK32FRAME *)stack32Top - 1;
+    frame32->frame16 = pTask->thdb->cur_stack + sizeof(STACK16FRAME);
     frame32->edi     = 0;
     frame32->esi     = 0;
     frame32->edx     = 0;
@@ -549,29 +557,10 @@
     frame32->retaddr = (DWORD)TASK_CallToStart;
     /* The remaining fields will be initialized in TASK_Reschedule */
 
-    /* Create the 16-bit stack frame */
+    if (!THREAD_Current()->cur_stack)
+        THREAD_Current()->cur_stack = pTask->thdb->cur_stack;
 
-    if (!(sp = pModule->sp))
-        sp = pSegTable[pModule->ss-1].minsize + pModule->stack_size;
-    sp &= ~1;
-    pTask->ss_sp = PTR_SEG_OFF_TO_SEGPTR( hInstance, sp );
-    pTask->ss_sp -= sizeof(STACK16FRAME);
-    frame16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->ss_sp );
-    frame16->frame32 = frame32;
-    frame16->ebp = sp + (int)&((STACK16FRAME *)0)->bp;
-    frame16->bp = LOWORD(frame16->ebp);
-    frame16->ds = frame16->es = pTask->hInstance;
-    frame16->entry_point = 0;
-    frame16->entry_cs = 0;
-    /* The remaining fields will be initialized in TASK_Reschedule */
-
-      /* If there's no 16-bit stack yet, use a part of the new task stack */
-      /* This is only needed to have a stack to switch from on the first  */
-      /* call to DirectedYield(). */
-
-    if (!IF1632_Saved16_ss_sp) IF1632_Saved16_ss_sp = pTask->ss_sp;
-
-      /* Add the task to the linked list */
+    /* Add the task to the linked list */
 
     TASK_LinkTask( hTask );
 
@@ -593,6 +582,8 @@
     if (!(pTask = (TDB *)GlobalLock16( hTask ))) return;
     hPDB = pTask->hPDB;
 
+    pTask->magic = 0xdead; /* invalidate signature */
+
     /* Delete the Win32 part of the task */
 
     K32OBJ_DecCount( &pTask->thdb->process->header );
@@ -756,10 +747,6 @@
     dprintf_task( stddeb, "Switching to task %04x (%.8s)\n",
                   hTask, pNewTask->module_name );
 
-      /* Save the stack of the previous task (if any) */
-
-    if (pOldTask) pOldTask->ss_sp = IF1632_Saved16_ss_sp;
-
      /* Make the task the last in the linked list (round-robin scheduling) */
 
     pNewTask->priority++;
@@ -769,7 +756,7 @@
 
     /* Finish initializing the new task stack if necessary */
 
-    newframe16 = (STACK16FRAME *)PTR_SEG_TO_LIN( pNewTask->ss_sp );
+    newframe16 = THREAD_STACK16( pNewTask->thdb );
     if (!newframe16->entry_cs)
     {
         STACK16FRAME *oldframe16 = CURRENT_STACK16;
@@ -788,7 +775,7 @@
 
     hCurrentTask = hTask;
     SET_CUR_THREAD( pNewTask->thdb );
-    IF1632_Saved16_ss_sp = pNewTask->ss_sp;
+    pNewTask->ss_sp = pNewTask->thdb->cur_stack;
 }
 
 
@@ -875,7 +862,7 @@
     pinstance = (INSTANCEDATA *)PTR_SEG_OFF_TO_LIN(CURRENT_DS, 0);
     pinstance->stackbottom = stackhi; /* yup, that's right. Confused me too. */
     pinstance->stacktop    = stacklow; 
-    pinstance->stackmin    = OFFSETOF(IF1632_Saved16_ss_sp);
+    pinstance->stackmin    = OFFSETOF( pTask->thdb->cur_stack );
 }
 
 
@@ -1133,13 +1120,12 @@
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
     if (!(pData = (INSTANCEDATA *)GlobalLock16( seg ))) return;
     dprintf_task( stddeb, "SwitchStackTo: old=%04x:%04x new=%04x:%04x\n",
-                  SELECTOROF(IF1632_Saved16_ss_sp),
-                  OFFSETOF(IF1632_Saved16_ss_sp), seg, ptr );
+                  SELECTOROF( pTask->thdb->cur_stack ),
+                  OFFSETOF( pTask->thdb->cur_stack ), seg, ptr );
 
     /* Save the old stack */
 
-    oldFrame           = CURRENT_STACK16;
-    pData->old_ss_sp   = IF1632_Saved16_ss_sp;
+    pData->old_ss_sp   = pTask->thdb->cur_stack;
     pData->stacktop    = top;
     pData->stackmin    = ptr;
     pData->stackbottom = ptr;
@@ -1149,9 +1135,10 @@
     /* Note: we need to take the 3 arguments into account; otherwise,
      * the stack will underflow upon return from this function.
      */
-    IF1632_Saved16_ss_sp = PTR_SEG_OFF_TO_SEGPTR( seg,
+    oldFrame = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
+    pTask->thdb->cur_stack = PTR_SEG_OFF_TO_SEGPTR( seg,
                              ptr - sizeof(STACK16FRAME) - 3 * sizeof(WORD) );
-    newFrame = CURRENT_STACK16;
+    newFrame = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
 
     /* Copy the stack frame and the local variables to the new stack */
 
@@ -1174,7 +1161,7 @@
     INSTANCEDATA *pData;
 
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
-    if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(IF1632_Saved16_ss_sp))))
+    if (!(pData = (INSTANCEDATA *)GlobalLock16(SELECTOROF(pTask->thdb->cur_stack))))
         return;
     if (!pData->old_ss_sp)
     {
@@ -1184,16 +1171,16 @@
     dprintf_task( stddeb, "SwitchStackBack: restoring stack %04x:%04x\n",
                   SELECTOROF(pData->old_ss_sp), OFFSETOF(pData->old_ss_sp) );
 
-    oldFrame = CURRENT_STACK16;
+    oldFrame = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
 
     /* Switch back to the old stack */
 
-    IF1632_Saved16_ss_sp = pData->old_ss_sp;
+    pTask->thdb->cur_stack = pData->old_ss_sp;
     pData->old_ss_sp = 0;
 
     /* Build a stack frame for the return */
 
-    newFrame = CURRENT_STACK16;
+    newFrame = (STACK16FRAME *)PTR_SEG_TO_LIN( pTask->thdb->cur_stack );
     newFrame->frame32 = oldFrame->frame32;
     if (debugging_relay)
     {
@@ -1469,8 +1456,8 @@
     lpte->hTaskParent   = pTask->hParent;
     lpte->hInst         = pTask->hInstance;
     lpte->hModule       = pTask->hModule;
-    lpte->wSS           = SELECTOROF( pTask->ss_sp );
-    lpte->wSP           = OFFSETOF( pTask->ss_sp );
+    lpte->wSS           = SELECTOROF( pTask->thdb->cur_stack );
+    lpte->wSP           = OFFSETOF( pTask->thdb->cur_stack );
     lpte->wStackTop     = pInstData->stacktop;
     lpte->wStackMinimum = pInstData->stackmin;
     lpte->wStackBottom  = pInstData->stackbottom;
diff --git a/memory/global.c b/memory/global.c
index ecb6c95..ad9d600 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -482,6 +482,18 @@
     return MAKELONG( GET_ARENA_PTR(sel)->handle, GlobalHandleToSel(sel) );
 }
 
+/***********************************************************************
+ *           GlobalHandleNoRIP   (KERNEL.159)
+ */
+DWORD WINAPI GlobalHandleNoRIP( WORD sel )
+{
+    int i;
+    for (i = globalArenaSize-1 ; i>=0 ; i--) {
+        if (pGlobalArena[i].size!=0 && pGlobalArena[i].handle == sel)
+		return MAKELONG( GET_ARENA_PTR(sel)->handle, GlobalHandleToSel(sel) );
+    }
+    return 0;
+}
 
 /***********************************************************************
  *           GlobalFlags16   (KERNEL.22)
@@ -832,6 +844,16 @@
     return TRUE;
 }
 
+/***********************************************************************
+ *           GetFreeMemInfo   (KERNEL.316)
+ */
+DWORD WINAPI GetFreeMemInfo(void)
+{
+    MEMMANINFO info;
+    MemManInfo( &info );
+    return MAKELONG( info.dwTotalLinearSpace, info.dwMaxPagesAvailable );
+}
+
 /*
  * Win32 Global heap functions (GlobalXXX).
  * These functions included in Win32 for compatibility with 16 bit Windows
@@ -970,7 +992,10 @@
  */
 HGLOBAL32 WINAPI GlobalHandle32(LPCVOID pmem)
 {
-    HGLOBAL32 handle = POINTER_TO_HANDLE(pmem);
+    HGLOBAL32 handle;
+
+    if (!HEAP_IsInsideHeap( GetProcessHeap(), 0, pmem )) goto error;
+    handle = POINTER_TO_HANDLE(pmem);
     if (HEAP_IsInsideHeap( GetProcessHeap(), 0, (LPCVOID)handle ))
     {
         if (HANDLE_TO_INTERN(handle)->Magic == MAGIC_GLOBAL_USED)
@@ -980,6 +1005,7 @@
     if (HeapValidate( GetProcessHeap(), 0, pmem ))
         return (HGLOBAL32)pmem;  /* valid fixed block */
 
+error:
     SetLastError( ERROR_INVALID_HANDLE );
     return 0;
 }
diff --git a/memory/selector.c b/memory/selector.c
index 28c8a61..db7ca70 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -633,7 +633,6 @@
 LPVOID WINAPI WOWGetVDMPointer(DWORD vp,DWORD nrofbytes,BOOL32 protected)
 {
     /* FIXME: add size check too */
-    fprintf(stdnimp,"WOWGetVDMPointer(%08lx,%ld,%d)\n",vp,nrofbytes,protected);
     if (protected)
 	return PTR_SEG_TO_LIN(vp);
     else
@@ -655,7 +654,6 @@
 LPVOID WINAPI WOWGetVDMPointerFix(DWORD vp,DWORD nrofbytes,BOOL32 protected)
 {
     /* FIXME: fix heapsegment */
-    fprintf(stdnimp,"WOWGetVDMPointerFix(%08lx,%ld,%d)\n",vp,nrofbytes,protected);
     return WOWGetVDMPointer(vp,nrofbytes,protected);
 }
 
@@ -664,7 +662,6 @@
  */
 void WINAPI WOWGetVDMPointerUnfix(DWORD vp)
 {
-    fprintf(stdnimp,"WOWGetVDMPointerUnfix(%08lx), STUB\n",vp);
     /* FIXME: unfix heapsegment */
 }
 
diff --git a/memory/string.c b/memory/string.c
index 969aeee..fb94859 100644
--- a/memory/string.c
+++ b/memory/string.c
@@ -80,6 +80,7 @@
 {
     dprintf_string(stddeb,"strcat: Append %s to %s\n",
 		   debugstr_a (src), debugstr_a (dst));
+    /* Windows does not check for NULL pointers here, so we don't either */
     strcat( dst, src );
     return dst;
 }
@@ -93,6 +94,7 @@
     register LPWSTR p = dst;
     dprintf_string(stddeb,"strcat: Append L%s to L%s\n",
 		   debugstr_w (src), debugstr_w (dst));
+    /* Windows does not check for NULL pointers here, so we don't either */
     while (*p) p++;
     while ((*p++ = *src++));
     return dst;
@@ -255,7 +257,7 @@
 LPSTR WINAPI lstrcpy32A( LPSTR dst, LPCSTR src )
 {
     dprintf_string(stddeb,"strcpy %s\n", debugstr_a (src));
-    if (!src || !dst) return NULL;
+    /* Windows does not check for NULL pointers here, so we don't either */
     strcpy( dst, src );
     return dst;
 }
@@ -268,6 +270,7 @@
 {
     register LPWSTR p = dst;
     dprintf_string(stddeb,"strcpy L%s\n", debugstr_w (src));
+    /* Windows does not check for NULL pointers here, so we don't either */
     while ((*p++ = *src++));
     return dst;
 }
@@ -291,6 +294,7 @@
     LPSTR p = dst;
     dprintf_string(stddeb,"strcpyn %s for %d chars\n",
 		   debugstr_an (src,n), n);
+    /* Windows does not check for NULL pointers here, so we don't either */
     while ((n-- > 1) && *src) *p++ = *src++;
     if (n >= 0) *p = 0;
     return dst;
@@ -305,6 +309,7 @@
     LPWSTR p = dst;
     dprintf_string(stddeb,"strcpyn L%s for %d chars\n",
 		   debugstr_wn (src,n), n);
+    /* Windows does not check for NULL pointers here, so we don't either */
     while ((n-- > 1) && *src) *p++ = *src++;
     if (n >= 0) *p = 0;
     return dst;
diff --git a/memory/virtual.c b/memory/virtual.c
index 65f17d4..bc75762 100644
--- a/memory/virtual.c
+++ b/memory/virtual.c
@@ -281,9 +281,11 @@
  */
 static void VIRTUAL_GetWin32Prot( BYTE vprot, DWORD *protect, DWORD *state )
 {
-    *protect = VIRTUAL_Win32Flags[vprot & 0x0f];
-    if (vprot & VPROT_GUARD) *protect |= PAGE_GUARD;
-    if (vprot & VPROT_NOCACHE) *protect |= PAGE_NOCACHE;
+    if (protect) {
+    	*protect = VIRTUAL_Win32Flags[vprot & 0x0f];
+    	if (vprot & VPROT_GUARD) *protect |= PAGE_GUARD;
+    	if (vprot & VPROT_NOCACHE) *protect |= PAGE_NOCACHE;
+    }
 
     if (state) *state = (vprot & VPROT_COMMITTED) ? MEM_COMMIT : MEM_RESERVE;
 }
diff --git a/misc/aspi.c b/misc/aspi.c
index fe453a9..993cd4a 100644
--- a/misc/aspi.c
+++ b/misc/aspi.c
@@ -384,8 +384,7 @@
  *             GetASPISupportInfo16   (WINASPI.1)
  */
 
-WORD
-GetASPISupportInfo16()
+WORD WINAPI GetASPISupportInfo16()
 {
 #ifdef linux
     dprintf_aspi(stddeb, "GETASPISupportInfo\n");
@@ -403,8 +402,7 @@
  *             SendASPICommand16   (WINASPI.2)
  */
 
-WORD
-SendASPICommand16(SEGPTR segptr_srb)
+WORD WINAPI SendASPICommand16(SEGPTR segptr_srb)
 {
 #ifdef linux
   LPSRB16 lpSRB = PTR_SEG_TO_LIN(segptr_srb);
@@ -430,3 +428,16 @@
   return SS_INVALID_SRB;
 #endif
 }
+
+/***********************************************************************
+ *             GetASPIDLLVersion   (WINASPI.4)
+ */
+
+DWORD WINAPI GetASPIDLLVersion()
+{
+#ifdef linux
+	return (DWORD)2;
+#else
+	return (DWORD)0;
+#endif
+}
diff --git a/misc/callback.c b/misc/callback.c
index 34e5f02..84354d5 100644
--- a/misc/callback.c
+++ b/misc/callback.c
@@ -6,6 +6,7 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include "windows.h"
 #include "callback.h"
 #include "task.h"
 
@@ -134,6 +135,92 @@
 }
 
 /**********************************************************************
+ *	     CALLBACK_CallWOWCallback16Ex
+ *
+ * WCB16_MAX_CBARGS (16) is the maximum number of args.
+ *
+ * Can call functions using CDECL or PASCAL calling conventions. The CDECL
+ * ones are reversed (not 100% sure about that).
+ */
+static BOOL32 WINAPI CALLBACK_CallWOWCallback16Ex( 
+	FARPROC16 proc, DWORD dwFlags, DWORD cbArgs, LPVOID xargs,LPDWORD pdwret
+) {
+    LPDWORD	args = (LPDWORD)xargs;
+    DWORD	ret,i;
+
+    if (dwFlags == WCB16_CDECL) {
+    	/* swap the arguments */
+    	args = HeapAlloc(GetProcessHeap(),0,cbArgs*sizeof(DWORD));
+	for (i=0;i<cbArgs;i++)
+		args[i] = ((DWORD*)xargs)[cbArgs-i-1];
+    }
+    switch (cbArgs) {
+    case 0: ret = proc();break;
+    case 1: ret = proc(args[0]);break;
+    case 2: ret = proc(args[0],args[1]);break;
+    case 3: ret = proc(args[0],args[1],args[2]);break;
+    case 4: ret = proc(args[0],args[1],args[2],args[3]);break;
+    case 5: ret = proc(args[0],args[1],args[2],args[3],args[4]);break;
+    case 6: ret = proc(args[0],args[1],args[2],args[3],args[4],args[5]);
+	    break;
+    case 7: ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6]
+	    );
+	    break;
+    case 8: ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6],args[7]
+	    );
+	    break;
+    case 9: ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6],args[7],args[8]
+	    );
+	    break;
+    case 10:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6],args[7],args[8],args[9]
+	    );
+	    break;
+    case 11:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6],args[7],args[8],args[9],args[10]
+	    );
+	    break;
+    case 12:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6],args[7],args[8],args[9],args[10],args[11]
+	    );
+	    break;
+    case 13:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6],args[7],args[8],args[9],args[10],args[11],
+		    args[12]
+	    );
+	    break;
+    case 14:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6],args[7],args[8],args[9],args[10],args[11],
+		    args[12],args[13]
+	    );
+	    break;
+    case 15:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6],args[7],args[8],args[9],args[10],args[11],
+		    args[12],args[13],args[14]
+	    );
+	    break;
+    case 16:ret = proc(args[0],args[1],args[2],args[3],args[4],args[5],
+		    args[6],args[7],args[8],args[9],args[10],args[11],
+		    args[12],args[13],args[14],args[15]
+	    );
+	    break;
+    default:
+	    fprintf(stderr,"CALLBACK_CallWOWCallback16Ex(), %ld arguments not supported.!n",cbArgs);
+	    if (dwFlags == WCB16_CDECL)
+		HeapFree(GetProcessHeap(),0,args);
+	    return FALSE;
+    }
+    if (dwFlags == WCB16_CDECL)
+    	HeapFree(GetProcessHeap(),0,args);
+    if (pdwret) 
+    	*pdwret = ret;
+    return TRUE;
+}
+
+/**********************************************************************
  *	     CALLBACK_WinelibTable
  *
  * The callbacks function table for Winelib
@@ -154,6 +241,7 @@
     CALLBACK_CallLoadAppSegProc,   /* CallLoadAppSegProc */
     CALLBACK_CallSystemTimerProc,  /* CallSystemTimerProc */
     CALLBACK_CallWOWCallbackProc,  /* CallWOWCallbackProc */
+    CALLBACK_CallWOWCallback16Ex,  /* CallWOWCallback16Ex */
     CALLBACK_CallASPIPostProc,     /* CallASPIPostProc */
     /* The graphics driver callbacks are never used in Winelib */
     NULL,                          /* CallDrvControlProc */
@@ -163,7 +251,10 @@
     NULL,                          /* CallDrvOutputProc */
     NULL,                          /* CallDrvRealizeProc */
     NULL,                          /* CallDrvStretchBltProc */
-    NULL                           /* CallDrvExtTextOutProc */
+    NULL,                          /* CallDrvExtTextOutProc */
+    NULL                           /* CallDrvGetCharWidth */
 };
 
 const CALLBACKS_TABLE *Callbacks = &CALLBACK_WinelibTable;
+
+
diff --git a/misc/commdlg.c b/misc/commdlg.c
index d422c87..f81c7b1 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -3224,3 +3224,11 @@
 
 GET_XXX_FILENAME(GetOpenFileName)
 GET_XXX_FILENAME(GetSaveFileName)
+
+/***********************************************************************
+ *           ChooseFontA   (COMDLG32.3)
+ */
+DWORD WINAPI ChooseFont32A(CHOOSEFONT pChoosefont)
+{
+	return NULL;
+}
diff --git a/misc/cpu.c b/misc/cpu.c
index 6a79097..9265986 100644
--- a/misc/cpu.c
+++ b/misc/cpu.c
@@ -11,6 +11,8 @@
 #include "windows.h"
 #include "winnt.h"
 
+static BYTE PF[64] = {0,};
+
 /***********************************************************************
  * 			GetSystemInfo            	[KERNELL32.404]
  */
@@ -23,6 +25,7 @@
 		memcpy(si,&cachedsi,sizeof(*si));
 		return;
 	}
+	memset(PF,0,sizeof(PF));
 
 	/* choose sensible defaults ...
 	 * FIXME: perhaps overrideable with precompiler flags?
@@ -43,43 +46,87 @@
 	cache = 1; /* even if there is no more info, we now have a cacheentry */
 	memcpy(si,&cachedsi,sizeof(*si));
 
+	/* hmm, reasonable processor feature defaults? */
+
 #ifdef linux
 	{
-	char line[200],info[200],value[200],junk[200];
+	char line[200];
 	FILE *f = fopen ("/proc/cpuinfo", "r");
 
 	if (!f)
 		return;
 	while (fgets(line,200,f)!=NULL) {
-		if (sscanf(line,"%s%[ \t:]%s",info,junk,value)!=3)
+		char	*s,*value;
+
+		/* NOTE: the ':' is the only character we can rely on */
+		if (!(value = strchr(line,':')))
 			continue;
-		if (!lstrncmpi32A(line, "cpu",3)) {
-			if (	isdigit (value[0]) && value[1] == '8' && 
-				value[2] == '6' && value[3] == 0
-			) {
+		/* terminate the valuename */
+		*value++ = '\0';
+		/* skip any leading spaces */
+		while (*value==' ') value++;
+		if ((s=strchr(value,'\n')))
+			*s='\0';
+
+		/* 2.1 method */
+		if (!lstrncmpi32A(line, "cpu family",strlen("cpu family"))) {
+			if (isdigit (value[0])) {
 				switch (value[0] - '0') {
-				case 3:
-					cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
+				case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
 					cachedsi.wProcessorLevel= 3;
 					break;
-				case 4:
-					cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
+				case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
 					cachedsi.wProcessorLevel= 4;
 					break;
-				case 5:
-					cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+				case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
 					cachedsi.wProcessorLevel= 5;
 					break;
-				case 6: /* FIXME does the PPro have a special type? */
-					cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+				case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
 					cachedsi.wProcessorLevel= 5;
 					break;
 				default:
 					break;
 				}
 			}
+			continue;
 		}
-		if (!lstrncmpi32A(info,"processor",9)) {
+		/* old 2.0 method */
+		if (!lstrncmpi32A(line, "cpu",strlen("cpu"))) {
+			if (	isdigit (value[0]) && value[1] == '8' && 
+				value[2] == '6' && value[3] == 0
+			) {
+				switch (value[0] - '0') {
+				case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
+					cachedsi.wProcessorLevel= 3;
+					break;
+				case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
+					cachedsi.wProcessorLevel= 4;
+					break;
+				case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+					cachedsi.wProcessorLevel= 5;
+					break;
+				case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
+					cachedsi.wProcessorLevel= 5;
+					break;
+				default:
+					break;
+				}
+			}
+			continue;
+		}
+		if (!lstrncmpi32A(line,"fdiv_bug",strlen("fdiv_bug"))) {
+			if (!lstrncmpi32A(value,"yes",3))
+				PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
+
+			continue;
+		}
+		if (!lstrncmpi32A(line,"fpu",strlen("fpu"))) {
+			if (!lstrncmpi32A(value,"no",2))
+				PF[PF_FLOATING_POINT_EMULATED] = TRUE;
+
+			continue;
+		}
+		if (!lstrncmpi32A(line,"processor",strlen("processor"))) {
 			/* processor number counts up...*/
 			int	x;
 
@@ -87,12 +134,19 @@
 				if (x+1>cachedsi.dwNumberOfProcessors)
 					cachedsi.dwNumberOfProcessors=x+1;
 		}
-		if (!lstrncmpi32A(info,"stepping",8)) {
+		if (!lstrncmpi32A(line,"stepping",strlen("stepping"))) {
 			int	x;
 
 			if (sscanf(value,"%d",&x))
 				cachedsi.wProcessorRevision = x;
 		}
+		if (!lstrncmpi32A(line,"flags",strlen("flags"))) {
+			if (strstr(value,"cx8"))
+				PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
+			if (strstr(value,"mmx"))
+				PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
+
+		}
 	}
 	fclose (f);
 	}
@@ -105,48 +159,15 @@
 }
 
 /***********************************************************************
- *          CPU_TestProcessorFeature
- */
-static BOOL32 CPU_TestProcessorFeature(const char* query_info, const char* query_value)
-{
-    BOOL32 flag=FALSE;
-#ifdef linux
-    char line[200],info[200],value[200],junk[200];
-    FILE *f = fopen ("/proc/cpuinfo", "r");
-    
-    if (!f)
-      return 0;
-    while (fgets(line,200,f)!=NULL) {
-      if (sscanf(line,"%s%[ \t:]%s",info,junk,value)!=3)
-	continue;
-      if (strcmp(info,query_info)==0)
-	flag = strstr(value,query_value)!=NULL;
-    }
-    fclose (f);
-#else  /* linux */
-    /* FIXME: how do we do this on other systems? */
-#endif  /* linux */
-    return flag;
-}
-
-/***********************************************************************
  * 			IsProcessorFeaturePresent	[KERNELL32.880]
  */
 BOOL32 WINAPI IsProcessorFeaturePresent (DWORD feature)
 {
   SYSTEM_INFO si;
-  GetSystemInfo (&si);
-  switch (feature)
-    {
-    case PF_FLOATING_POINT_PRECISION_ERRATA: 
-      return si.wProcessorLevel == 5;
-    case PF_FLOATING_POINT_EMULATED:
-      return CPU_TestProcessorFeature("fpu","no"); break;
-    case PF_COMPARE_EXCHANGE_DOUBLE:
-      return si.wProcessorLevel >= 5;
-    case PF_MMX_INSTRUCTIONS_AVAILABLE:
-      return CPU_TestProcessorFeature("flags","mmx"); break;
-    default:
-      return FALSE;
-    }
+  GetSystemInfo (&si); /* to ensure the information is loaded and cached */
+
+  if (feature < 64)
+    return PF[feature];
+  else
+    return FALSE;
 }
diff --git a/misc/main.c b/misc/main.c
index ca68de1..2fffd0b 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -13,9 +13,9 @@
 #ifdef MALLOC_DEBUGGING
 #include <malloc.h>
 #endif
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xresource.h"
+#include "ts_xutil.h"
 #include <X11/Xlocale.h>
 #include <X11/cursorfont.h>
 #include "winsock.h"
@@ -52,6 +52,8 @@
     {"Hu",0x0436},	/* LANG_Hu */
     {"Pl",0x0415},      /* LANG_Pl */
     {"Po",0x0416},      /* LANG_Po */
+    {"Sw",0x0417},      /* LANG_Sw */
+    {"Ca",     0},      /* LANG_Ca */ /* FIXME languageid */
     {NULL,0}
 };
 
@@ -129,7 +131,7 @@
   "    -failreadonly   Read only files may not be opened in write mode\n" \
   "    -fixedmap       Use a \"standard\" color map\n" \
   "    -iconic         Start as an icon\n" \
-  "    -language xx    Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz,Eo,It,Ko,\n                    Hu,Pl,Po)\n" \
+  "    -language xx    Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz,Eo,It,Ko,\n                    Hu,Pl,Po,Sw,Ca)\n" \
   "    -managed        Allow the window manager to manage created windows\n" \
   "    -mode mode      Start Wine in a particular mode (standard or enhanced)\n" \
   "    -name name      Set the application name\n" \
@@ -191,7 +193,7 @@
     strcat( buff_instance, name );
     strcpy( buff_class, WINE_CLASS );
     strcat( buff_class, name );
-    retval = XrmGetResource( db, buff_instance, buff_class, &dummy, value );
+    retval = TSXrmGetResource( db, buff_instance, buff_class, &dummy, value );
     free( buff_instance );
     free( buff_class );
     return retval;
@@ -300,7 +302,7 @@
 {
     char *display_name = NULL;
     XrmValue value;
-    XrmDatabase db = XrmGetFileDatabase(WINE_APP_DEFAULTS);
+    XrmDatabase db = TSXrmGetFileDatabase(WINE_APP_DEFAULTS);
     int i;
     char *xrm_string;
 
@@ -323,7 +325,7 @@
     if (display_name == NULL &&
 	MAIN_GetResource( db, ".display", &value )) display_name = value.addr;
 
-    if (!(display = XOpenDisplay( display_name )))
+    if (!(display = TSXOpenDisplay( display_name )))
     {
 	fprintf( stderr, "%s: Can't open display: %s\n",
 		 argv[0], display_name ? display_name : "(none specified)" );
@@ -331,14 +333,14 @@
     }
 
       /* Merge file and screen databases */
-    if ((xrm_string = XResourceManagerString( display )) != NULL)
+    if ((xrm_string = TSXResourceManagerString( display )) != NULL)
     {
-        XrmDatabase display_db = XrmGetStringDatabase( xrm_string );
-        XrmMergeDatabases( display_db, &db );
+        XrmDatabase display_db = TSXrmGetStringDatabase( xrm_string );
+        TSXrmMergeDatabases( display_db, &db );
     }
 
       /* Parse command line */
-    XrmParseCommand( &db, optionsTable, NB_OPTIONS,
+    TSXrmParseCommand( &db, optionsTable, NB_OPTIONS,
 		     Options.programName, argc, argv );
 
       /* Get all options */
@@ -430,7 +432,7 @@
     XTextProperty window_name;
     Atom XA_WM_DELETE_WINDOW;
 
-    flags = XParseGeometry( Options.desktopGeometry, &x, &y, &width, &height );
+    flags = TSXParseGeometry( Options.desktopGeometry, &x, &y, &width, &height );
     screenWidth  = width;
     screenHeight = height;
 
@@ -439,18 +441,18 @@
     win_attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask |
 	                 PointerMotionMask | ButtonPressMask |
 			 ButtonReleaseMask | EnterWindowMask;
-    win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
+    win_attr.cursor = TSXCreateFontCursor( display, XC_top_left_arrow );
 
-    rootWindow = XCreateWindow( display, DefaultRootWindow(display),
+    rootWindow = TSXCreateWindow( display, DefaultRootWindow(display),
 			        x, y, width, height, 0,
 			        CopyFromParent, InputOutput, CopyFromParent,
 			        CWEventMask | CWCursor, &win_attr );
 
       /* Set window manager properties */
 
-    size_hints  = XAllocSizeHints();
-    wm_hints    = XAllocWMHints();
-    class_hints = XAllocClassHint();
+    size_hints  = TSXAllocSizeHints();
+    wm_hints    = TSXAllocWMHints();
+    class_hints = TSXAllocClassHint();
     if (!size_hints || !wm_hints || !class_hints)
     {
         fprintf( stderr, "Not enough memory for window manager hints.\n" );
@@ -469,18 +471,18 @@
     class_hints->res_name = argv[0];
     class_hints->res_class = "Wine";
 
-    XStringListToTextProperty( &name, 1, &window_name );
-    XSetWMProperties( display, rootWindow, &window_name, &window_name,
+    TSXStringListToTextProperty( &name, 1, &window_name );
+    TSXSetWMProperties( display, rootWindow, &window_name, &window_name,
                       argv, argc, size_hints, wm_hints, class_hints );
-    XA_WM_DELETE_WINDOW = XInternAtom( display, "WM_DELETE_WINDOW", False );
-    XSetWMProtocols( display, rootWindow, &XA_WM_DELETE_WINDOW, 1 );
-    XFree( size_hints );
-    XFree( wm_hints );
-    XFree( class_hints );
+    XA_WM_DELETE_WINDOW = TSXInternAtom( display, "WM_DELETE_WINDOW", False );
+    TSXSetWMProtocols( display, rootWindow, &XA_WM_DELETE_WINDOW, 1 );
+    TSXFree( size_hints );
+    TSXFree( wm_hints );
+    TSXFree( class_hints );
 
       /* Map window */
 
-    XMapWindow( display, rootWindow );
+    TSXMapWindow( display, rootWindow );
 }
 
 
@@ -491,7 +493,7 @@
  */
 static void MAIN_SaveSetup(void)
 {
-    XGetKeyboardControl(display, &keyboard_state);
+    TSXGetKeyboardControl(display, &keyboard_state);
 }
 
 /***********************************************************************
@@ -507,7 +509,7 @@
     keyboard_value.bell_duration	= keyboard_state.bell_duration;
     keyboard_value.auto_repeat_mode	= keyboard_state.global_auto_repeat;
 
-    XChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent | 
+    TSXChangeKeyboardControl(display, KBKeyClickPercent | KBBellPercent | 
     	KBBellPitch | KBBellDuration | KBAutoRepeatMode, &keyboard_value);
 }
 
@@ -554,7 +556,7 @@
     gettimeofday( &tv, NULL);
     MSG_WineStartTicks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
 
-    XrmInitialize();
+    TSXrmInitialize();
 
     putenv("XKB_DISABLE="); /* Disable XKB extension if present. */
 
@@ -572,10 +574,10 @@
     screenHeight = HeightOfScreen( screen );
     if (screenDepth)  /* -depth option specified */
     {
-	depth_list = XListDepths(display,DefaultScreen(display),&depth_count);
+	depth_list = TSXListDepths(display,DefaultScreen(display),&depth_count);
 	for (i = 0; i < depth_count; i++)
 	    if (depth_list[i] == screenDepth) break;
-	XFree( depth_list );
+	TSXFree( depth_list );
 	if (i >= depth_count)
 	{
 	    fprintf( stderr, "%s: Depth %d not supported on this screen.\n",
@@ -584,7 +586,7 @@
 	}
     }
     else screenDepth  = DefaultDepthOfScreen( screen );
-    if (Options.synchronous) XSynchronize( display, True );
+    if (Options.synchronous) TSXSynchronize( display, True );
     if (Options.desktopGeometry) MAIN_CreateDesktop( *argc, argv );
     else rootWindow = DefaultRootWindow( display );
 
@@ -608,7 +610,7 @@
  */
 BOOL32 WINAPI MessageBeep32( UINT32 i )
 {
-    XBell( display, 0 );
+    TSXBell( display, 0 );
     return TRUE;
 }
 
@@ -619,7 +621,7 @@
 BOOL32 WINAPI Beep( DWORD dwFreq, DWORD dwDur )
 {
     /* dwFreq and dwDur are ignored by Win95 */
-    XBell(display, 0);
+    TSXBell(display, 0);
     return TRUE;
 }
 
@@ -643,7 +645,7 @@
 
 	switch (uAction) {
 	case SPI_GETBEEP:
-		XGetKeyboardControl(display, &keyboard_state);
+		TSXGetKeyboardControl(display, &keyboard_state);
 		if (keyboard_state.bell_percent == 0)
 			*(BOOL32 *) lpvParam = FALSE;
 		else
@@ -690,7 +692,7 @@
 
 	case SPI_GETSCREENSAVETIMEOUT:
 	/* FIXME GetProfileInt( "windows", "ScreenSaveTimeout", 300 ); */
-		XGetScreenSaver(display, &timeout, &temp,&temp,&temp);
+		TSXGetScreenSaver(display, &timeout, &temp,&temp,&temp);
 		*(INT32 *) lpvParam = timeout * 1000;
 		break;
 
@@ -779,7 +781,7 @@
 	switch (uAction)
         {
 		case SPI_GETBEEP:
-			XGetKeyboardControl(display, &keyboard_state);
+			TSXGetKeyboardControl(display, &keyboard_state);
 			if (keyboard_state.bell_percent == 0)
 				*(BOOL16 *) lpvParam = FALSE;
 			else
@@ -833,7 +835,7 @@
 
 		case SPI_GETSCREENSAVETIMEOUT:
 			/* FIXME GetProfileInt( "windows", "ScreenSaveTimeout", 300 ); */
-			XGetScreenSaver(display, &timeout, &temp,&temp,&temp);
+			TSXGetScreenSaver(display, &timeout, &temp,&temp,&temp);
 			*(INT16 *) lpvParam = timeout * 1000;
 			break;
 
@@ -858,19 +860,19 @@
 				keyboard_value.bell_percent = -1;
 			else
 				keyboard_value.bell_percent = 0;			
-   			XChangeKeyboardControl(display, KBBellPercent, 
+   			TSXChangeKeyboardControl(display, KBBellPercent, 
    							&keyboard_value);
 			break;
 
 		case SPI_SETSCREENSAVEACTIVE:
 			if (uParam == TRUE)
-				XActivateScreenSaver(display);
+				TSXActivateScreenSaver(display);
 			else
-				XResetScreenSaver(display);
+				TSXResetScreenSaver(display);
 			break;
 
 		case SPI_SETSCREENSAVETIMEOUT:
-			XSetScreenSaver(display, uParam, 60, DefaultBlanking, 
+			TSXSetScreenSaver(display, uParam, 60, DefaultBlanking, 
 							DefaultExposures);
 			break;
 
diff --git a/misc/network.c b/misc/network.c
index 58b8cbd..601ca07 100644
--- a/misc/network.c
+++ b/misc/network.c
@@ -8,32 +8,7 @@
 #include "windows.h"
 #include "winerror.h"
 #include "drive.h"
-
-#define WN_SUCCESS       			0x0000
-#define WN_NOT_SUPPORTED 			0x0001
-#define WN_NET_ERROR     			0x0002
-#define WN_MORE_DATA     			0x0003
-#define WN_BAD_POINTER   			0x0004
-#define WN_BAD_VALUE     			0x0005
-#define WN_BAD_PASSWORD  			0x0006
-#define WN_ACCESS_DENIED 			0x0007
-#define WN_FUNCTION_BUSY 			0x0008
-#define WN_WINDOWS_ERROR 			0x0009
-#define WN_BAD_USER      			0x000A
-#define WN_OUT_OF_MEMORY 			0x000B
-#define WN_CANCEL        			0x000C
-#define WN_CONTINUE      			0x000D
-#define WN_NOT_CONNECTED 			0x0030
-#define WN_OPEN_FILES    			0x0031
-#define WN_BAD_NETNAME   			0x0032
-#define WN_BAD_LOCALNAME 			0x0033
-#define WN_ALREADY_CONNECTED		0x0034
-#define WN_DEVICE_ERROR     		0x0035
-#define WN_CONNECTION_CLOSED		0x0036
-#define WN_NO_NETWORK				ERROR_NO_NETWORK
-
-
-typedef LPVOID	LPNETRESOURCE16;
+#include "wnet.h"
 
 /**************************************************************************
  *              WNetErrorText       [USER.499]
@@ -192,7 +167,70 @@
  */
 int WINAPI WNetGetCaps(WORD capability)
 {
-	return 0;
+	switch (capability) {
+		case WNNC_SPEC_VERSION:
+		{
+			return 0x30a; /* WfW 3.11 (and apparently other 3.1x) */
+		}
+		case WNNC_NET_TYPE:
+		/* hi byte = network type, lo byte = network vendor (Netware = 0x03) [15 types] */
+		return WNNC_NET_MultiNet | WNNC_SUBNET_WinWorkgroups;
+
+		case WNNC_DRIVER_VERSION:
+		/* driver version of vendor */
+		return 0x100; /* WfW 3.11 */
+
+		case WNNC_USER:
+		/* 1 = WNetGetUser is supported */
+		return 1;
+
+		case WNNC_CONNECTION:
+		/* returns mask of the supported connection functions */
+		return	WNNC_CON_AddConnection|WNNC_CON_CancelConnection
+			|WNNC_CON_GetConnections/*|WNNC_CON_AutoConnect*/
+			|WNNC_CON_BrowseDialog|WNNC_CON_RestoreConnection;
+
+		case WNNC_PRINTING:
+		/* returns mask of the supported printing functions */
+		return	WNNC_PRT_OpenJob|WNNC_PRT_CloseJob|WNNC_PRT_HoldJob
+			|WNNC_PRT_ReleaseJob|WNNC_PRT_CancelJob
+			|WNNC_PRT_SetJobCopies|WNNC_PRT_WatchQueue
+			|WNNC_PRT_UnwatchQueue|WNNC_PRT_LockQueueData
+			|WNNC_PRT_UnlockQueueData|WNNC_PRT_AbortJob
+			|WNNC_PRT_WriteJob;
+
+		case WNNC_DIALOG:
+		/* returns mask of the supported dialog functions */
+		return	WNNC_DLG_DeviceMode|WNNC_DLG_BrowseDialog
+			|WNNC_DLG_ConnectDialog|WNNC_DLG_DisconnectDialog
+			|WNNC_DLG_ViewQueueDialog|WNNC_DLG_PropertyDialog
+			|WNNC_DLG_ConnectionDialog
+			/*|WNNC_DLG_PrinterConnectDialog
+			|WNNC_DLG_SharesDialog|WNNC_DLG_ShareAsDialog*/;
+
+		case WNNC_ADMIN:
+		/* returns mask of the supported administration functions */
+		/* not sure if long file names is a good idea */
+		return	WNNC_ADM_GetDirectoryType|WNNC_ADM_DirectoryNotify
+			|WNNC_ADM_LongNames/*|WNNC_ADM_SetDefaultDrive*/;
+
+		case WNNC_ERROR:
+		/* returns mask of the supported error functions */
+		return	WNNC_ERR_GetError|WNNC_ERR_GetErrorText;
+
+		case WNNC_PRINTMGREXT:
+		/* returns the Print Manager version in major and minor format if Print Manager functions are available */
+		return 0x30e; /* printman version of WfW 3.11 */
+
+		case 0xffff:
+		/* Win 3.11 returns HMODULE of network driver here
+		FIXME: what should we return ?
+		logonoff.exe needs it, msmail crashes with wrong value */
+		return 0;
+
+	default:
+		return 0;
+	}
 }
 
 /**************************************************************************
diff --git a/misc/registry.c b/misc/registry.c
index 9aa04ce..1343fb4 100644
--- a/misc/registry.c
+++ b/misc/registry.c
@@ -925,9 +925,9 @@
  *      0x20 ... offset_of_RGDB_part: Disk Key Entry structures
  *
  *   Disk Key Entry Structure:
- *	00: DWORD	- unknown
- *	04: DWORD	- unknown
- *	08: DWORD	- unknown, but usually 0xFFFFFFFF on win95 systems
+ *	00: DWORD	- Free entry indicator(?)
+ *	04: DWORD	- Hash = sum of bytes of keyname
+ *	08: DWORD	- Root key indicator? unknown, but usually 0xFFFFFFFF on win95 systems
  *	0C: DWORD	- disk address of PreviousLevel Key.
  *	10: DWORD	- disk address of Next Sublevel Key.
  *	14: DWORD	- disk address of Next Key (on same level).
@@ -938,15 +938,15 @@
  * of the referenced key. Don't ask me why, or even if I got this correct
  * from staring at 1kg of hexdumps. (DKEP)
  *
- * The number of the entry is the low byte of the Low Significant Part ored
- * with 0x100 * (low byte of the High Significant part)
- * (C expression : nr = (nrLS & 0xFF) | ((nrHS &0xFF)<<8))
+ * The High significant part of the structure seems to equal the number
+ * of the RGDB section. The low significant part is a unique ID within
+ * that RGDB section
  *
  * There are two minor corrections to the position of that structure.
  * 1. If the address is xxx014 or xxx018 it will be aligned to xxx01c AND 
  *    the DKE reread from there.
  * 2. If the address is xxxFFx it will be aligned to (xxx+1)000.
- * (FIXME: slightly better explanation needed here)
+ * CPS - I have not experienced the above phenomenon in my registry files
  *
  * RGDB_section:
  * 	00:		"RGDB"	- magic
@@ -1003,149 +1003,38 @@
 	char			*name;
 	int			nrofvals;
 	struct	_w95keyvalue	*values;
-	unsigned long		dkeaddr;
-	unsigned long 		x1;
-	unsigned long 		x2;
-	unsigned long 		x3;
-	unsigned long 		xx1;
 	struct _w95key		*prevlvl;
 	struct _w95key		*nextsub;
 	struct _w95key		*next;
 };
 
-/* fast lookup table dkeaddr->nr */
-struct 	_w95nr2da {
-	unsigned long		dkeaddr;
-	unsigned long		nr;
-	struct _w95key		*key;
+
+struct _w95_info {
+  char *rgknbuffer;
+  int  rgknsize;
+  char *rgdbbuffer;
+  int  rgdbsize;
+  int  depth;
+  int  lastmodified;
 };
 
+LPWSTR strcvtA2W(LPCSTR src, int nchars)
 
-static void
-_w95_walk_tree(LPKEYSTRUCT lpkey,struct _w95key *key) {
-	int		i;
-	LPKEYSTRUCT	lpxkey;
-	LPWSTR		name;
+{
+   LPWSTR dest = xmalloc (2 * nchars + 2);
 
-	while (key) {
-		if (key->name == NULL) {
-			fprintf(stderr,"_w95_walk_tree:Please report: key with dkeaddr %lx not loaded, skipping hierarchy\n",
-				key->dkeaddr
-			);
-			return;
-		}
-		lpxkey=_find_or_add_key(lpkey,strdupA2W(key->name));
-
-		if (key->nrofvals<0) {
-			/* shouldn't happen */
-			fprintf(stderr,"key %s already processed!\n",key->name);
-			key = key->next;
-			continue;
-		}
-		for (i=0;i<key->nrofvals;i++) {
-			LPBYTE	data;
-			int	len;
-
-			name = strdupA2W(key->values[i].name);
-			if (!*name) {
-				free(name);
-				name = NULL;
-			}
-			free(key->values[i].name);
-
-			len	= key->values[i].datalen;
-			data	= key->values[i].data;
-			if ((1<<key->values[i].type) & UNICONVMASK) {
-				data = (BYTE*)strdupA2W(data);
-				len  = lstrlen32W((LPWSTR)data)*2+2;
-				free(key->values[i].data);
-			}
-			_find_or_add_value(
-				lpxkey,
-				name,
-				key->values[i].type,
-				data,
-				len,
-				key->values[i].lastmodified
-			);
-		}
-		if (key->values) {
-			free(key->values);
-			key->values = NULL;
-		}
-		key->nrofvals=-key->nrofvals-1;
-		_w95_walk_tree(lpxkey,key->nextsub);
-		key=key->next;
-	}
+   lstrcpynAtoW(dest,src, nchars);
+   dest[nchars] = 0;
+   return dest;
 }
 
-/* small helper function to adjust address offset (dkeaddrs) */
-static unsigned long
-_w95_adj_da(unsigned long dkeaddr) {
-	if ((dkeaddr&0xFFF)<0x018) {
-		int	diff;
+static LPKEYSTRUCT _w95_processKey ( LPKEYSTRUCT lpkey, 
+                                   int nrLS, int nrMS, struct _w95_info *info )
 
-		diff=0x1C-(dkeaddr&0xFFF);
-		return dkeaddr+diff;
-	}
-	if (((dkeaddr+0x1C)&0xFFF)<0x1C) {
-		/* readjust to 0x000,
-		 * but ONLY if we are >0x1000 already
-		 */
-		if (dkeaddr & ~0xFFF)
-			return dkeaddr & ~0xFFF;
-	}
-	return dkeaddr;
-}
-
-static int
-_w95dkecomp(struct _w95nr2da *a,struct _w95nr2da *b){return a->dkeaddr-b->dkeaddr;}
-
-static struct _w95key*
-_w95dkelookup(unsigned long dkeaddr,int n,struct _w95nr2da *nr2da,struct _w95key *keys) {
-int	i;
-int left, right;
-
-	if (dkeaddr == 0xFFFFFFFF)
-		return NULL;
-	if (dkeaddr<0x20)
-		return NULL;
-	dkeaddr=_w95_adj_da(dkeaddr+0x1c);
-	left=0;
-	right=n-1;
-	while(left<=right)
-	{
-		i=(left+right)/2;
-
-		if(nr2da[i].dkeaddr == dkeaddr)
-			return nr2da[i].key;
-		else if(nr2da[i].dkeaddr < dkeaddr)
-			left=i+1;
-		else
-			right=i-1;
-	}
-	/* 0x3C happens often, just report unusual values */
-	if (dkeaddr!=0x3c)
-		dprintf_reg(stddeb,"search hasn't found dkeaddr %lx?\n",dkeaddr);
-	return NULL;
-}
-
-static void
-_w95_loadreg(char* fn,LPKEYSTRUCT lpkey) {
-	/* Disk Key Entry structure (RGKN part) */
-	struct	dke {
-		unsigned long		x1;
-		unsigned long		x2;
-		unsigned long		x3;/*usually 0xFFFFFFFF */
-		unsigned long		prevlvl;
-		unsigned long		nextsub;
-		unsigned long		next;
-		unsigned short		nrLS;
-		unsigned short		nrMS;
-	};
-	/* Disk Key Header structure (RGDB part) */
-	struct	dkh {
-		unsigned long		nextkeyoff; 
+{
+  /* Disk Key Header structure (RGDB part) */
+  struct	dkh {
+                unsigned long		nextkeyoff; 
 		unsigned short		nrLS;
 		unsigned short		nrMS;
 		unsigned long		bytesused;
@@ -1163,15 +1052,145 @@
 		unsigned short		valdatalen;
 		/* valname, valdata */
 	};
-    struct  _w95nr2da   *nr2da;
 
+	
+	struct	dkh dkh;
+	int	bytesread = 0;
+	char    *rgdbdata = info->rgdbbuffer;
+	int     nbytes = info->rgdbsize;
+	char    *curdata = rgdbdata;
+	char    *end = rgdbdata + nbytes;
+	int     off_next_rgdb;
+	char    *next = rgdbdata;
+	int     nrgdb, i;
+	LPKEYSTRUCT	lpxkey;
+	
+	do {
+	  curdata = next;
+	  if (strncmp(curdata, "RGDB", 4)) return (NULL);
+	    
+	  memcpy(&off_next_rgdb,curdata+4,4);
+	  next = curdata + off_next_rgdb;
+	  nrgdb = (int) *((short *)curdata + 7);
+
+	} while (nrgdb != nrMS && (next < end));
+
+	/* curdata now points to the start of the right RGDB section */
+	curdata += 0x20;
+
+#define XREAD(whereto,len) \
+	if ((curdata + len) <end) {\
+		memcpy(whereto,curdata,len);\
+		curdata+=len;\
+		bytesread+=len;\
+	}
+
+	do {
+	  XREAD(&dkh, sizeof (dkh));
+	  if (dkh.nrLS == nrLS) break;
+
+	  curdata += dkh.nextkeyoff - sizeof(dkh);
+	} while (curdata < next);
+
+	if (dkh.nrLS != nrLS) return (NULL);
+
+	if (nrgdb != dkh.nrMS) {
+	  return (NULL);
+	}
+
+	lpxkey=_find_or_add_key(lpkey,strcvtA2W(curdata, dkh.keynamelen));
+	curdata += dkh.keynamelen;
+
+	for (i=0;i< dkh.values; i++) {
+	  struct dkv dkv;
+	  LPBYTE data;
+	  int len;
+	  LPWSTR name;
+
+	  XREAD(&dkv,sizeof(dkv));
+
+	  name = strcvtA2W(curdata, dkv.valnamelen);
+	  curdata += dkv.valnamelen;
+
+	  if ((1 << dkv.type) & UNICONVMASK) {
+	    data = (LPBYTE) strcvtA2W(curdata, dkv.valdatalen);
+	    len = dkv.valdatalen + 1;
+	  } else {
+	    /* I don't think we want to NULL terminate all data */
+	    data = xmalloc(dkv.valdatalen);
+	    memcpy (data, curdata, dkv.valdatalen);
+	    len = dkv.valdatalen;
+	  }
+
+	  curdata += dkv.valdatalen;
+	  
+	  _find_or_add_value(
+			     lpxkey,
+			     name,
+			     dkv.type,
+			     data,
+			     len,
+			     info->lastmodified
+			     );
+
+	}
+
+	return (lpxkey);
+}
+
+static void
+_w95_walkrgkn(LPKEYSTRUCT prevkey, char *off, struct _w95_info *info)
+
+{
+  /* Disk Key Entry structure (RGKN part) */
+  struct	dke {
+    unsigned long		x1;
+    unsigned long		x2;
+    unsigned long		x3;/*usually 0xFFFFFFFF */
+    unsigned long		prevlvl;
+    unsigned long		nextsub;
+    unsigned long		next;
+    unsigned short		nrLS;
+    unsigned short		nrMS;
+  } *dke = (struct dke *)off;
+  LPKEYSTRUCT  lpxkey;
+
+  if (dke == NULL) {
+    dke = (struct dke *) ((char *)info->rgknbuffer);
+  }
+
+  lpxkey = _w95_processKey(prevkey, dke->nrLS, dke->nrMS, info);
+  /* XXX <-- This is a hack*/
+  if (!lpxkey) {
+    lpxkey = prevkey;
+  }
+
+  if (dke->nextsub != -1 && 
+      ((dke->nextsub - 0x20) < info->rgknsize) 
+      && (dke->nextsub > 0x20)) {
+    
+    _w95_walkrgkn(lpxkey, 
+		  info->rgknbuffer + dke->nextsub - 0x20, 
+		  info);
+  }
+  
+  if (dke->next != -1 && 
+      ((dke->next - 0x20) < info->rgknsize) && 
+      (dke->next > 0x20)) {
+    _w95_walkrgkn(prevkey,  
+		  info->rgknbuffer + dke->next - 0x20,
+		  info);
+  }
+
+  return;
+}
+
+static void
+_w95_loadreg(char* fn,LPKEYSTRUCT lpkey) {
 	HFILE32		hfd;
-	int		lastmodified;
 	char		magic[5];
-	unsigned long	nr,pos,i,j,where,version,rgdbsection,end,off_next_rgdb;
-	struct	_w95key	*keys,*key;
-	int		nrofdkes;
-	unsigned char	*data,*curdata,*nextrgdb;
+	unsigned long	where,version,rgdbsection,end;
+	struct          _w95_info info;
 	OFSTRUCT	ofs;
 	BY_HANDLE_FILE_INFORMATION hfdinfo;
 
@@ -1205,232 +1224,31 @@
 	where	= 0x40;
 	end	= rgdbsection;
 
-	/* I removed the '+100' that was here. The adjustments to dkeaddr   */
-	/* imply alignments to the data in 'data' which would mean it is    */
-	/* larger than the number of dke entries it holds therefore nrofdkes*/
-	/* would be equal to or larger than it needs to be without the need */
-	/* for the +100 - kc                                                */
-	nrofdkes = (end-where)/sizeof(struct dke);
-
-	data = (char*)xmalloc(end-where);
-	if ((end-where)!=_lread32(hfd,data,end-where))
+	info.rgknsize = end - where;
+	info.rgknbuffer = (char*)xmalloc(info.rgknsize);
+	if (info.rgknsize != _lread32(hfd,info.rgknbuffer,info.rgknsize))
 		return;
-	curdata = data;
 
-	keys = (struct _w95key*)xmalloc(nrofdkes * sizeof(struct _w95key));
-	memset(keys,'\0',nrofdkes*sizeof(struct _w95key));
-    nr2da= (struct _w95nr2da*)xmalloc(nrofdkes * sizeof(struct _w95nr2da));
-    memset(nr2da,'\0',nrofdkes*sizeof(struct _w95nr2da));
-
-#if DEBUG_W95_LOADREG
-	dprintf_reg(stddeb,"nrofdkes = %d\n", nrofdkes);
-#endif
-	for (i=0;i<nrofdkes;i++) {
-		struct	dke	dke;
-		unsigned long 	dkeaddr;
-
-		pos=curdata-data+0x40;
-		memcpy(&dke,curdata,sizeof(dke));
-		curdata+=sizeof(dke);
-		nr = dke.nrLS + (dke.nrMS<<8);
-#if DEBUG_W95_LOADREG
-		dprintf_reg(stddeb,"%ld: nr = %ld, nrMS:nrLS = %04X:%X\n",
-					i,nr,dke.nrMS,dke.nrLS);
-#endif
-		dkeaddr=pos-4;
-		if ((dkeaddr&0xFFF)<0x018) {
-			int	diff;
-
-			diff=0x1C-(dkeaddr&0xFFF);
-			dkeaddr+=diff;
-			curdata+=diff-sizeof(dke);
-			memcpy(&dke,curdata,sizeof(dke));
-			nr = dke.nrLS + (dke.nrMS<<8);
-#if DEBUG_W95_LOADREG
-			dprintf_reg(stddeb,"> nr = %lu, nrMS:nrLS = %04X:%X\n",
-						nr,dke.nrMS,dke.nrLS);
-#endif
-			curdata+=sizeof(dke);
-		}
-		if (((dkeaddr+0x1C)&0xFFF)<0x1C) {
-			/* readjust to 0x000,
-			 * but ONLY if we are >0x1000 already
-			 */
-			if (dkeaddr & ~0xFFF)
-				dkeaddr &= ~0xFFF;
-		}
-		/* For the time being we will assume that all values of */
-		/* nr are valid unless the following condition is true. */
-		/* This value is obtained when dke.nrLS and dke.nrMS are*/
-		/* both FFFF as dke.nrMS is only shifted by 8 before the*/
-		/* add and not 16. -kc                                  */
-		if (nr==0x0100FEFF)
-			continue;
-		for (j = 0; j < i; ++j) {
-			if (nr2da[j].nr == nr)
-				break;
-		}
-		if (j < i) {
-			key = nr2da[j].key;
-			if (key && key->dkeaddr) {
-				int	x;
-
-				for (x=sizeof(dke);x--;)
-					if (((char*)&dke)[x])
-						break;
-				if (x==-1)
-					break;	/* finished reading if we got only 0 */
-				if (nr) {
-					if ((dke.next!=(long)key->next) ||
-						(dke.nextsub!=(long)key->nextsub) ||
-						(dke.prevlvl!=(long)key->prevlvl) 
-					)
-						dprintf_reg(stddeb,"key doubled? nr=%lu,key->dkeaddr=%lx,dkeaddr=%lx\n",nr,key->dkeaddr,dkeaddr);
-				}
-				continue;
-			}
-		}
-#if DEBUG_W95_LOADREG
-		dprintf_reg(stddeb,"- nr=%lu,dkeaddr=%lx\n",nr,dkeaddr);
-#endif
-		nr2da[i].nr = nr;
-		nr2da[i].dkeaddr = dkeaddr;
-		nr2da[i].key = &keys[i];
-
-		keys[i].dkeaddr = dkeaddr;
-		keys[i].x1 = dke.x1;
-		keys[i].x2 = dke.x2;
-		keys[i].x3 = dke.x3;
-		keys[i].prevlvl= (struct _w95key*)dke.prevlvl;
-		keys[i].nextsub= (struct _w95key*)dke.nextsub;
-		keys[i].next 	= (struct _w95key*)dke.next;
-	}
-	free(data);
-
-	nrofdkes = i;	/* This is the real number of dke entries */
-#if DEBUG_W95_LOADREG
-	dprintf_reg(stddeb,"nrofdkes = %d\n", nrofdkes);
-#endif
-
-	qsort(nr2da,nrofdkes,sizeof(nr2da[0]),
-              (int(*)(const void *,const void *))_w95dkecomp);
-
-	/* STEP 2: keydata & values */
 	if (!GetFileInformationByHandle(hfd,&hfdinfo))
 		return;
+
 	end = hfdinfo.nFileSizeLow;
-	lastmodified = DOSFS_FileTimeToUnixTime(&hfdinfo.ftLastWriteTime,NULL);
+	info.lastmodified = DOSFS_FileTimeToUnixTime(&hfdinfo.ftLastWriteTime,NULL);
 
 	if (-1==_llseek32(hfd,rgdbsection,SEEK_SET))
 		return;
-	data = (char*)xmalloc(end-rgdbsection);
-	if ((end-rgdbsection)!=_lread32(hfd,data,end-rgdbsection))
+
+	info.rgdbbuffer = (char*)xmalloc(end-rgdbsection);
+	info.rgdbsize = end - rgdbsection;
+
+	if (info.rgdbsize !=_lread32(hfd,info.rgdbbuffer,info.rgdbsize))
 		return;
 	_lclose32(hfd);
-	curdata = data;
-	memcpy(magic,curdata,4);
-	memcpy(&off_next_rgdb,curdata+4,4);
-	nextrgdb = curdata+off_next_rgdb;
-	if (strcmp(magic,"RGDB")) {
-		dprintf_reg(stddeb,"third IFF header not RGDB, but %s\n",magic);
-		return;
-	}
 
-	curdata=data+0x20;
-	while (1) {
-		struct	dkh dkh;
-		int		bytesread;
-		struct	_w95key	xkey;	/* Used inside second main loop */
+	_w95_walkrgkn(lpkey, NULL, &info);
 
-		bytesread = 0;
-		if (curdata>=nextrgdb) {
-			curdata = nextrgdb;
-			if (!strncmp(curdata,"RGDB",4)) {
-				memcpy(&off_next_rgdb,curdata+4,4);
-				nextrgdb = curdata+off_next_rgdb;
-				curdata+=0x20;
-			} else {
-				dprintf_reg(stddeb,"at end of RGDB section, but no next header (%x of %lx). Breaking.\n",curdata-data,end-rgdbsection);
-				break;
-			}
-		}
-#define XREAD(whereto,len) \
-	if ((curdata-data+len)<end) {\
-		memcpy(whereto,curdata,len);\
-		curdata+=len;\
-		bytesread+=len;\
-	}
-
-		XREAD(&dkh,sizeof(dkh));
-		nr = dkh.nrLS + (dkh.nrMS<<8);
-		if (dkh.nrLS == 0xFFFF) {
-				/* skip over key using nextkeyoff */
- 				curdata+=dkh.nextkeyoff-sizeof(struct dkh);
-				continue;
-		} 
-		for (i = 0; i < nrofdkes; ++i) {
-			if (nr2da[i].nr == nr && nr2da[i].dkeaddr) {
-				key = nr2da[i].key;
-				break;
-			}
-		}
-		if (i >= nrofdkes) {
-			/* Move the next statement to just before the previous for */
-			/* loop to prevent the compiler from issuing a warning -kc */
-			key = &xkey;
-			memset(key,'\0',sizeof(xkey));
-			dprintf_reg(stddeb,"haven't found nr %lu.\n",nr);
-		} else {
-			if (!key->dkeaddr)
-				dprintf_reg(stddeb,"key with nr=%lu has no dkeaddr?\n",nr);
-		}
-		key->nrofvals	= dkh.values;
-		key->name	= (char*)xmalloc(dkh.keynamelen+1);
-		key->xx1	= dkh.xx1;
-		XREAD(key->name,dkh.keynamelen);
-		key->name[dkh.keynamelen]=0;
-		if (key->nrofvals) {
-			key->values = (struct _w95keyvalue*)xmalloc(
-				sizeof(struct _w95keyvalue)*key->nrofvals
-			);
-			for (i=0;i<key->nrofvals;i++) {
-				struct	dkv	dkv;
-
-				XREAD(&dkv,sizeof(dkv));
-				key->values[i].type = dkv.type;
-				key->values[i].name = (char*)xmalloc(
-					dkv.valnamelen+1
-				);
-				key->values[i].datalen = dkv.valdatalen;
-				key->values[i].data = (unsigned char*)xmalloc(
-					dkv.valdatalen+1
-				);
-				key->values[i].x1   = dkv.x1;
-				XREAD(key->values[i].name,dkv.valnamelen);
-				XREAD(key->values[i].data,dkv.valdatalen);
-				key->values[i].data[dkv.valdatalen]=0;
-				key->values[i].name[dkv.valnamelen]=0;
-				key->values[i].lastmodified=lastmodified;
-			}
-		}
-		if (bytesread != dkh.nextkeyoff) {
-			if (dkh.bytesused != bytesread)
-				dprintf_reg(stddeb,
-					"read has difference in read bytes (%d) and nextoffset (%lu) (bytesused=%lu)\n",bytesread,dkh.nextkeyoff,
-					dkh.bytesused
-				);
-			curdata += dkh.nextkeyoff-bytesread;
-		}
-		key->prevlvl	= _w95dkelookup((long)key->prevlvl,nrofdkes,nr2da,keys);
-		key->nextsub	= _w95dkelookup((long)key->nextsub,nrofdkes,nr2da,keys);
-		key->next	= _w95dkelookup((long)key->next,nrofdkes,nr2da,keys);
-		if (!bytesread)
-			break;
-	}
-	free(data);
-	_w95_walk_tree(lpkey,keys);
-	free(nr2da);
-	free(keys);
+	free (info.rgdbbuffer);
+	free (info.rgknbuffer);
 }
 
 /* WINDOWS 31 REGISTRY LOADER, supplied by Tor Sjøwall, tor@sn.no */
diff --git a/misc/shell.c b/misc/shell.c
index d0bd6ba..02a24d2 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -802,7 +802,7 @@
 	return IMAGE_NT_SIGNATURE;
   if (*(WORD*)magic == IMAGE_OS2_SIGNATURE) {
   	IMAGE_OS2_HEADER	ne_header;
-  	LPBYTE			pTypeInfo = NULL;
+  	LPBYTE			pTypeInfo = (LPBYTE)-1;
 
   	if (_lread32(hFile,&ne_header,sizeof(ne_header))!=sizeof(ne_header))
 		return 0;
diff --git a/misc/toolhelp.c b/misc/toolhelp.c
index afbdc46..51074b9 100644
--- a/misc/toolhelp.c
+++ b/misc/toolhelp.c
@@ -28,6 +28,8 @@
 
 static int nrofnotifys = 0;
 
+static FARPROC16 HookNotify = NULL;
+
 BOOL16 WINAPI NotifyRegister( HTASK16 htask, FARPROC16 lpfnCallback,
                               WORD wFlags )
 {
@@ -85,3 +87,16 @@
 {
     return TRUE;
 }
+
+/***********************************************************************
+ *           ToolHelpHook                             (KERNEL.341)
+ *	see "Undocumented Windows"
+ */
+FARPROC16 WINAPI ToolHelpHook(FARPROC16 lpfnNotifyHandler)
+{
+FARPROC16 tmp;
+	tmp = HookNotify;
+	HookNotify = lpfnNotifyHandler;
+	/* just return previously installed notification function */
+	return tmp;
+}
diff --git a/misc/tweak.c b/misc/tweak.c
index 3fa2782..53d7f42 100644
--- a/misc/tweak.c
+++ b/misc/tweak.c
@@ -26,7 +26,7 @@
 
 #include <stdio.h>
 #include <malloc.h>
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 #include <string.h>
 #include "dc.h"
 #include "debug.h"
@@ -296,32 +296,32 @@
 	/* Draw the top/left lines first */
 	prevpen = SelectObject32(hdc, TWEAK_PenE095);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
 		  rect->right - 1, rect->top);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
 		  rect->left, rect->bottom - 1);
 
 	SelectObject32(hdc, TWEAK_PenFF95);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
 		  rect->top + 1, rect->right - 2, rect->top + 1);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
 		  rect->top + 1, rect->left + 1, rect->bottom - 2);
 
 
 	/* Now the bottom/right lines */
 	SelectObject32(hdc, TWEAK_Pen0095);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left,
 		  rect->bottom - 1, rect->right - 1, rect->bottom - 1);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1,
 		  rect->top, rect->right - 1, rect->bottom - 1);
 
 	SelectObject32(hdc, TWEAK_Pen8095);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
 		  rect->bottom - 2, rect->right - 2, rect->bottom - 2);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2,
 		  rect->top + 1, rect->right - 2, rect->bottom - 2);
 	
 	SelectObject32(hdc, prevpen);
@@ -365,32 +365,32 @@
 	/* Draw the top/left lines first */
 	prevpen = SelectObject32(hdc, TWEAK_Pen8095);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
 		  rect->right - 1, rect->top);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left, rect->top,
 		  rect->left, rect->bottom - 1);
 
 	SelectObject32(hdc, TWEAK_Pen0095);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
 		  rect->top + 1, rect->right - 2, rect->top + 1);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
 		  rect->top + 1, rect->left + 1, rect->bottom - 2);
 
 
 	/* Now the bottom/right lines */
 	SelectObject32(hdc, TWEAK_PenFF95);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left,
 		  rect->bottom - 1, rect->right - 1, rect->bottom - 1);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 1,
 		  rect->top, rect->right - 1, rect->bottom - 1);
 
 	SelectObject32(hdc, TWEAK_PenE095);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->left + 1,
 		  rect->bottom - 2, rect->right - 2, rect->bottom - 2);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, rect->right - 2,
 		  rect->top + 1, rect->right - 2, rect->bottom - 2);
 	
 	SelectObject32(hdc, prevpen);
@@ -436,13 +436,13 @@
 	/* Draw the top line */
 	prevpen = SelectObject32(hdc, TWEAK_Pen8095);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc - 1, xc2,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc - 1, xc2,
 		  yc - 1);
 
 	/* And the bottom line */
 	SelectObject32(hdc, TWEAK_PenFF95);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc, xc2, yc);
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc1, yc, xc2, yc);
 
 	SelectObject32(hdc, prevpen);
     }
@@ -484,13 +484,13 @@
 	/* Draw the top line */
 	prevpen = SelectObject32(hdc, TWEAK_Pen8095);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc, yc1, xc,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc, yc1, xc,
 		  yc2);
 
 	/* And the bottom line */
 	SelectObject32(hdc, TWEAK_PenFF95);
 	DC_SetupGCForPen(dc);
-	XDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc + 1, yc1, xc + 1,
+	TSXDrawLine(display, dc->u.x.drawable, dc->u.x.gc, xc + 1, yc1, xc + 1,
 		  yc2);
 
 	SelectObject32(hdc, prevpen);
diff --git a/misc/version.c b/misc/version.c
index e62438e..c07d013 100644
--- a/misc/version.c
+++ b/misc/version.c
@@ -264,3 +264,35 @@
     /* Constants: WDI_OPTIONS WDI_FILTER WDI_ALLOCBREAK */
     return 0;
 }
+
+
+/***********************************************************************
+ *           DebugFillBuffer                    (KERNEL.329)
+ *
+ * TODO:
+ * Should fill lpBuffer only if DBO_BUFFERFILL has been set by SetWinDebugInfo()
+ */
+void WINAPI DebugFillBuffer(LPSTR lpBuffer, WORD wBytes)
+{
+	memset(lpBuffer, DBGFILL_BUFFER, wBytes);
+}
+
+/***********************************************************************
+ *           DiagQuery                          (KERNEL.339)
+ *
+ * returns TRUE if Win called with "/b" (bootlog.txt)
+ */
+BOOL16 WINAPI DiagQuery()
+{
+	/* perhaps implement a Wine "/b" command line flag sometime ? */
+	return FALSE;
+}
+
+/***********************************************************************
+ *           DiagOutput                         (KERNEL.340)
+ *
+ * writes a debug string into <windir>\bootlog.txt
+ */
+void WINAPI DiagOutput()
+{
+}
diff --git a/misc/w32scomb.c b/misc/w32scomb.c
index 9d2ac9e..3005fae 100644
--- a/misc/w32scomb.c
+++ b/misc/w32scomb.c
@@ -11,13 +11,26 @@
 #include "windows.h"
 #include "module.h"
 #include "ldt.h"
+#include "selectors.h"
+#include "winbase.h"
+#include "heap.h"
 
 /***********************************************************************
  *           Get16DLLAddress       (KERNEL32)
  *
- * rough guesswork, but seems to work
+ * This function is used by a Win32s DLL if it wants to call a Win16 function.
+ * A 16:16 segmented pointer to the function is returned.
+ * Written without any docu.
  */
-FARPROC16 WINAPI Get16DLLAddress(HMODULE16 handle, LPSTR name) {
-        if (!handle) handle=GetModuleHandle16("WIN32S16");
-        return (FARPROC16)WIN32_GetProcAddress16(handle, name);
+FARPROC16 WINAPI Get16DLLAddress(HMODULE32 handle, LPSTR func_name) {
+       if ( (strcasecmp(func_name, "StackLinearToSegmented"))
+        && (strcasecmp(func_name, "CoThkCommon")) ) {
+               fprintf(stderr, "Get16DLLAddress() called for function %s(). Please report to Andreas Mohr.\n", func_name);
+       }
+        if (!handle) {
+               handle = (HMODULE32)LoadLibrary16("WIN32S16");
+               FreeLibrary16(handle);
+       }
+       return WIN32_GetProcAddress16(handle,func_name);
 }
+
diff --git a/misc/win32s16.c b/misc/win32s16.c
index 382e146..ecf61b0 100644
--- a/misc/win32s16.c
+++ b/misc/win32s16.c
@@ -14,3 +14,14 @@
 {
 	fprintf(stderr, "BootTask(): should only be used by WIN32S.EXE.\n");
 }
+
+/***********************************************************************
+ *           StackLinearToSegmented       (WIN32S16.43)
+ *
+ * Written without any docu.
+ */
+SEGPTR WINAPI StackLinearToSegmented()
+{
+	fprintf(stderr, "StackLinearToSegmented(), stub !\n");
+	return (SEGPTR)NULL;
+}
diff --git a/misc/windebug.c b/misc/windebug.c
index 30f4d2c..5f73299 100644
--- a/misc/windebug.c
+++ b/misc/windebug.c
@@ -14,7 +14,28 @@
  *           WinNotify       (WINDEBUG.1)
  *  written without _any_ docu
  */
-DWORD WinNotify() {
-	fprintf(stderr, "WinNotify(): stub !\n");
-	return NULL;
+void WinNotify(CONTEXT *context)
+{
+	fprintf(stderr, "WinNotify(AX=%04x): stub !\n", AX_reg(context));
+	switch (AX_reg(context))
+	{
+		case 0x000D:
+		case 0x000E:	/* __asm__("pushl $0x0\n\t"); ??? */
+				break;
+		case 0x0060:	/* do nothing */
+				break;
+		case 0x0063:	/* do something complicated */
+				break;
+		case 0x0064:	/* do something complicated */
+				break;
+		case 0x0065:	/* do something complicated */
+				break;
+		case 0x0050:	/* do something complicated, now just return error */
+				SET_CFLAG(context);
+				break;
+		case 0x0052:	/* do something complicated */
+				break;
+		default:
+				break;
+	}	
 }
diff --git a/misc/winsock.c b/misc/winsock.c
index 88c740c..ff3dba3 100644
--- a/misc/winsock.c
+++ b/misc/winsock.c
@@ -4,6 +4,10 @@
  * 
  * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
  *
+ * NOTE: If you make any changes to fix a particular app, make sure 
+ * they don't break something else like Netscape or telnet and ftp 
+ * clients and servers (www.winsite.com got a lot of those).
+ *
  */
  
 #include <stdio.h>
@@ -26,6 +30,7 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <ctype.h>
 #include <fcntl.h>
 #include <errno.h>
 #include <netdb.h>
@@ -82,8 +87,8 @@
          SO_LINGER, SO_OOBINLINE, SO_SNDBUF, SO_RCVBUF, SO_ERROR, SO_TYPE,
 	 SO_LINGER };
 
-static int _check_ws(LPWSINFO pwsi, ws_socket* pws);
-static int _check_buffer(LPWSINFO pwsi, int size);
+static int   _check_ws(LPWSINFO pwsi, ws_socket* pws);
+static char* _check_buffer(LPWSINFO pwsi, int size);
 
 extern void EVENT_AddIO( int fd, unsigned flag );
 extern void EVENT_DeleteIO( int fd, unsigned flag );
@@ -147,6 +152,23 @@
     return NULL;
 }
 
+static int wsi_strtolo(LPWSINFO pwsi, const char* name, const char* opt)
+{
+    /* Stuff a lowercase copy of the string into the local buffer */
+
+    int i = strlen(name) + 2;
+    char* p = _check_buffer(pwsi, i + ((opt)?strlen(opt):0));
+
+    if( p )
+    {
+	do *p++ = tolower(*name); while(*name++);
+	i = (p - (char*)(pwsi->buffer));
+	if( opt ) do *p++ = tolower(*opt); while(*opt++);
+	return i;
+    }
+    return 0;
+}
+
 static fd_set* fd_set_import( fd_set* fds, LPWSINFO pwsi, void* wsfds, int* highfd, BOOL32 b32 )
 {
     /* translate Winsock fd set into local fd set */
@@ -159,7 +181,8 @@
 	int i, count;
 
 	FD_ZERO(fds);
-	count = (b32) ? wsfds32->fd_count : wsfds16->fd_count;
+	count = b32 ? wsfds32->fd_count : wsfds16->fd_count;
+
 	for( i = 0; i < count; i++ )
 	{
 	     pws = (b32) ? (ws_socket*)WS_HANDLE2PTR(wsfds32->fd_array[i])
@@ -170,10 +193,6 @@
 		    FD_SET(pws->fd, fds);
 	     }
 	}
-	if (b32)
-	     wsfds32->fd_count = 0;
-	else
-	     wsfds16->fd_count = 0;
 #undef wsfds32
 #undef wsfds16
 	return fds;
@@ -208,20 +227,22 @@
 	{
 	    ws_socket *pws = (b32) ? (ws_socket*)WS_HANDLE2PTR(wsfds32->fd_array[i])
 				   : (ws_socket*)WS_HANDLE2PTR(wsfds16->fd_array[i]);
-	    int fd = pws->fd;
-
-	    if( _check_ws(pwsi, pws) && FD_ISSET(fd, fds) )
+	    if( _check_ws(pwsi, pws) )
 	    {
-		if ( exceptfds && sock_error_p(fd) )
+		int fd = pws->fd;
+
+		if( FD_ISSET(fd, fds) )
 		{
-		    FD_SET(fd, exceptfds);
-		    num_err++;
+		    if ( exceptfds && sock_error_p(fd) )
+		    {
+			FD_SET(fd, exceptfds);
+			num_err++;
+		    }
+		    else if( b32 )
+			     wsfds32->fd_array[j++] = wsfds32->fd_array[i];
+			 else
+			     wsfds16->fd_array[j++] = wsfds16->fd_array[i];
 		}
-		else
-		    if( b32 )
-			wsfds32->fd_array[j++] = wsfds32->fd_array[i];
-		    else
-			wsfds16->fd_array[j++] = wsfds16->fd_array[i];
 	    }
 	}
 
@@ -278,7 +299,7 @@
                         #else
                                 "Unknown",
                         #endif
-			   WS_MAX_SOCKETS_PER_THREAD,
+			   WS_MAX_SOCKETS_PER_PROCESS,
 			   WS_MAX_UDP_DATAGRAM, (SEGPTR)NULL };
     HTASK16             tid = GetCurrentTask();
     LPWSINFO            pwsi;
@@ -314,12 +335,12 @@
 	{
 	    int i = 0;
 	    pwsi->tid = tid;
-	    for( i = 0; i < WS_MAX_SOCKETS_PER_THREAD; i++ )
+	    for( i = 0; i < WS_MAX_SOCKETS_PER_PROCESS; i++ )
 	    {
 		pwsi->sock[i].fd = -1; 
 		pwsi->sock[i].flags = i + 1; 
 	    }
-	    pwsi->sock[WS_MAX_SOCKETS_PER_THREAD - 1].flags = -1;
+	    pwsi->sock[WS_MAX_SOCKETS_PER_PROCESS - 1].flags = -1;
 	}
 	else return WSASYSNOTREADY;
 
@@ -400,7 +421,7 @@
  *	  dprintf_winsock(stddeb,"\thave %i outstanding async ops!\n", pwsi->num_async_rq );
  */
 
-    for(i = 0, j = 0, n = 0; i < WS_MAX_SOCKETS_PER_THREAD; i++)
+    for(i = 0, j = 0, n = 0; i < WS_MAX_SOCKETS_PER_PROCESS; i++)
 	if( pwsi->sock[i].fd != -1 )
 	{
 	    if( pwsi->sock[i].psop )
@@ -485,13 +506,13 @@
     return 0;
 }
 
-int _check_buffer(LPWSINFO pwsi, int size)
+char* _check_buffer(LPWSINFO pwsi, int size)
 {
-    if( pwsi->buffer && pwsi->buflen >= size ) return 1;
+    if( pwsi->buffer && pwsi->buflen >= size ) return pwsi->buffer;
     else SEGPTR_FREE(pwsi->buffer);
 
     pwsi->buffer = (char*)SEGPTR_ALLOC((pwsi->buflen = size)); 
-    return (pwsi->buffer != NULL);
+    return pwsi->buffer;
 }
 
 /* ----------------------------------- i/o APIs */
@@ -558,9 +579,9 @@
 
     dprintf_winsock(stddeb, "WS_BIND(%08x): socket %04x, ptr %8x, length %d\n", 
 			   (unsigned)pwsi, s, (int) name, namelen);
-/* #if DEBUG_SOCKADDR */
+#if DEBUG_SOCKADDR
     dump_sockaddr(name);
-/* #endif */
+#endif
 
     if ( _check_ws(pwsi, pws) )
       if ( namelen >= sizeof(*name) ) 
@@ -936,7 +957,7 @@
 		if( !(fd_flags & O_NONBLOCK) ) pws->flags |= WS_FD_ACCEPT;
 	    }
 	    pws->flags |= WS_FD_LISTENING;
-	    pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECTED); /* just in case */
+	    pws->flags &= ~(WS_FD_INACTIVE | WS_FD_CONNECT | WS_FD_CONNECTED); /* just in case */
 	    return 0;
 	}
 	pwsi->err = wsaErrno();
@@ -1065,42 +1086,44 @@
 	p_write = fd_set_import(&writefds, pwsi, ws_writefds, &highfd, b32);
 	p_except = fd_set_import(&exceptfds, pwsi, ws_exceptfds, &highfd, b32);
 
-	if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeout)) >= 0 )
+	if( (highfd = select(highfd + 1, p_read, p_write, p_except, timeout)) > 0 )
 	{
-	    if( highfd )
-	    {
-		fd_set_export(pwsi, &readfds, p_except, ws_readfds, b32);
-		fd_set_export(pwsi, &writefds, p_except, ws_writefds, b32);
+	    fd_set_export(pwsi, &readfds, p_except, ws_readfds, b32);
+	    fd_set_export(pwsi, &writefds, p_except, ws_writefds, b32);
 
-		if (p_except && ws_exceptfds)
-		{
+	    if (p_except && ws_exceptfds)
+	    {
 #define wsfds16 ((ws_fd_set16*)ws_exceptfds)
 #define wsfds32 ((ws_fd_set32*)ws_exceptfds)
-		    int i, j, count = (b32) ? wsfds32->fd_count : wsfds16->fd_count;
+		int i, j, count = (b32) ? wsfds32->fd_count : wsfds16->fd_count;
 
-		    for (i = j = 0; i < count; i++)
+		for (i = j = 0; i < count; i++)
+		{
+		    ws_socket *pws = (b32) ? (ws_socket *)WS_HANDLE2PTR(wsfds32->fd_array[i])
+					   : (ws_socket *)WS_HANDLE2PTR(wsfds16->fd_array[i]);
+		    if( _check_ws(pwsi, pws) && FD_ISSET(pws->fd, &exceptfds) )
 		    {
-			ws_socket *pws = (b32) ? (ws_socket *)WS_HANDLE2PTR(wsfds32->fd_array[i])
-					       : (ws_socket *)WS_HANDLE2PTR(wsfds16->fd_array[i]);
-			if( _check_ws(pwsi, pws) && FD_ISSET(pws->fd, &exceptfds) )
-			{
-			    if( b32 )
+			if( b32 )
 				wsfds32->fd_array[j++] = wsfds32->fd_array[i];
-			    else
+			else
 				wsfds16->fd_array[j++] = wsfds16->fd_array[i];
-			}
 		    }
-		    if( b32 )
-			wsfds32->fd_count = j;
-		    else
-			wsfds16->fd_count = j;
+		}
+		if( b32 )
+		    wsfds32->fd_count = j;
+		else
+		    wsfds16->fd_count = j;
 #undef wsfds32
 #undef wsfds16
-		}
 	    }
 	    return highfd; 
 	}
-        pwsi->err = wsaErrno();
+	if( ws_readfds ) ((ws_fd_set32*)ws_readfds)->fd_count = 0;
+	if( ws_writefds ) ((ws_fd_set32*)ws_writefds)->fd_count = 0;
+	if( ws_exceptfds ) ((ws_fd_set32*)ws_exceptfds)->fd_count = 0;
+
+        if( highfd == 0 ) return 0;
+	pwsi->err = wsaErrno();
     } 
     return SOCKET_ERROR;
 }
@@ -1253,15 +1276,24 @@
 			if( pws->flags & (WS_FD_READ | WS_FD_CLOSE) )
 			    EVENT_DeleteIO( pws->fd, EVENT_IO_READ );
 			pws->flags &= ~(WS_FD_READ | WS_FD_CLOSE);
+#ifdef SHUT_RD
+			how = SHUT_RD;
+#endif
 			break;
 
 		case 1: /* drop sends */
 			if( pws->flags & WS_FD_WRITE )
 			    EVENT_DeleteIO( pws->fd, EVENT_IO_WRITE );
 			pws->flags &= ~WS_FD_WRITE;
+#ifdef SHUT_WR
+			how = SHUT_WR;
+#endif
 			break;
 
 		case 2: /* drop all */
+#ifdef SHUT_RDWR
+			how = SHUT_RDWR;
+#endif
 		default:
 			WSAAsyncSelect32( s, 0, 0, 0 );
 			break;
@@ -1342,9 +1374,13 @@
     {
         ws_socket*      pnew = wsi_alloc_socket(pwsi, sock);
 
-	dprintf_winsock(stddeb,"\tcreated %04x (handle %i)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
+	dprintf_winsock(stddeb,"\tcreated %i (handle %04x)\n", sock, (UINT16)WS_PTR2HANDLE(pnew));
 
-        if( pnew ) return (SOCKET16)WS_PTR2HANDLE(pnew);
+        if( pnew ) 
+	{
+	    pnew->flags |= WS_FD_INACTIVE;
+	    return (SOCKET16)WS_PTR2HANDLE(pnew);
+	}
 	
         close(sock);
         pwsi->err = WSAENOBUFS;
@@ -1375,7 +1411,8 @@
  *
  * IMPORTANT: 16-bit API structures have SEGPTR pointers inside them.
  * Also, we have to use wsock32 stubs to convert structures and
- * error codes from Unix to WSA, hence no direct mapping in if1632/wsock32.spec.
+ * error codes from Unix to WSA, hence there is no direct mapping in 
+ * the relay32/wsock32.spec.
  */
 
 static char*	NULL_STRING = "NULL";
@@ -1530,11 +1567,15 @@
     if( pwsi )
     {
 	struct servent*     serv;
-	if( (serv = getservbyname(name, proto)) != NULL )
-	    if( WS_dup_se(pwsi, serv, dup_flag) )
-		return (struct WIN_servent*)(pwsi->buffer);
-	    else pwsi->err = WSAENOBUFS;
-	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+	int i = wsi_strtolo( pwsi, name, proto );
+
+	if( i )
+	    if( (serv = getservbyname(pwsi->buffer, pwsi->buffer + i)) != NULL )
+		if( WS_dup_se(pwsi, serv, dup_flag) )
+		    return (struct WIN_servent*)(pwsi->buffer);
+		else pwsi->err = WSAENOBUFS;
+	    else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+	else pwsi->err = WSAENOBUFS;
     }
     return NULL;
 }
@@ -1566,11 +1607,15 @@
     if( pwsi )
     {
 	struct servent*     serv;
-	if( (serv = getservbyport(port, proto)) != NULL )
-	    if( WS_dup_se(pwsi, serv, dup_flag) )
-		return (struct WIN_servent*)(pwsi->buffer);
-	    else pwsi->err = WSAENOBUFS;
-	else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+	int i = wsi_strtolo( pwsi, proto, NULL );
+
+	if( i )
+	    if( (serv = getservbyport(port, pwsi->buffer)) != NULL )
+		if( WS_dup_se(pwsi, serv, dup_flag) )
+		    return (struct WIN_servent*)(pwsi->buffer);
+		else pwsi->err = WSAENOBUFS;
+	    else pwsi->err = (h_errno < 0) ? wsaErrno() : wsaHerrno();
+	else pwsi->err = WSAENOBUFS;
     }
     return NULL;
 }
@@ -1781,8 +1826,13 @@
                    (unsigned)pwsi, hWnd, uMsg, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING );
 
   if( pwsi )
-    return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
-                            proto, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME );
+  {
+      int i = wsi_strtolo( pwsi, name, proto );
+
+      if( i )
+          return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, pwsi->buffer, 0,
+                    pwsi->buffer + i, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME );
+  }
   return 0;
 }
 
@@ -1797,8 +1847,13 @@
   dprintf_winsock(stddeb, "WS_AsyncGetServByName32(%08x): hwnd %04x, msg %08x, name %s, proto %s\n",
            (unsigned)pwsi, (HWND16)hWnd, uMsg, (name)?name:NULL_STRING, (proto)?proto:NULL_STRING );
   if( pwsi )
-    return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, name, 0,
-                            proto, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME | WSMSG_ASYNC_WIN32);
+  {
+      int i = wsi_strtolo( pwsi, name, proto );
+
+      if( i )
+          return __WSAsyncDBQuery(pwsi, hWnd, uMsg, 0, pwsi->buffer, 0,
+                 pwsi->buffer + i, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYNAME | WSMSG_ASYNC_WIN32);
+  }
   return 0;
 }
 
@@ -1815,8 +1870,13 @@
                            (unsigned)pwsi, hWnd, uMsg, port, (proto)?proto:NULL_STRING );
 
   if( pwsi )
-      return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, proto, 0,
-                              NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT );
+  {
+      int i = wsi_strtolo( pwsi, proto, NULL );
+
+      if( i )
+	  return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, pwsi->buffer, 0,
+		NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT );
+  }
   return 0;
 }
 
@@ -1832,8 +1892,13 @@
                            (unsigned)pwsi, (HWND16)hWnd, uMsg, port, (proto)?proto:NULL_STRING );
 
   if( pwsi )
-      return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, proto, 0,
-             NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT | WSMSG_ASYNC_WIN32);
+  {
+      int i = wsi_strtolo( pwsi, proto, NULL );
+
+      if( i )
+	  return __WSAsyncDBQuery(pwsi, hWnd, uMsg, port, pwsi->buffer, 0,
+		 NULL, (void*)sbuf, buflen, WSMSG_ASYNC_SERVBYPORT | WSMSG_ASYNC_WIN32);
+  }
   return 0;
 }
 
@@ -1875,10 +1940,12 @@
 
 static ws_select_op* __ws_select_list = NULL;
 
-BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, fd_set io_set[3] )
+BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, 
+			 fd_set pending_set[3], fd_set event_set[3] )
 {
     /* This function is called by the event dispatcher
-     * with io_set containing the result of select() */
+     * with the pending_set[] containing the result of select() and
+     * the event_set[] containing all fd that are being watched */
 
     ws_select_op*	psop = __ws_select_list;
     BOOL32		bPost = FALSE;
@@ -1894,9 +1961,9 @@
 	int		r, w, e;
 
 	w = 0;
-	if( (r = FD_ISSET( fd, &io_set[EVENT_IO_READ] )) ||
-	    (w = FD_ISSET( fd, &io_set[EVENT_IO_WRITE] )) ||
-	    (e = FD_ISSET( fd, &io_set[EVENT_IO_EXCEPT] )) )
+	if( (r = FD_ISSET( fd, &pending_set[EVENT_IO_READ] )) ||
+	    (w = FD_ISSET( fd, &pending_set[EVENT_IO_WRITE] )) ||
+	    (e = FD_ISSET( fd, &pending_set[EVENT_IO_EXCEPT] )) )
 	{
 	    /* This code removes WS_FD flags on one-shot events (WS_FD_CLOSE, 
 	     * WS_FD_CONNECT), otherwise it clears descriptors in the io_set.
@@ -1918,10 +1985,10 @@
 		/* WS_FD_ACCEPT is valid only if the socket is in the
 		 * listening state */
 
-		FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+		FD_CLR( fd, &event_set[EVENT_IO_WRITE] );
 		if( r )
 		{
-		    FD_CLR( fd, &io_set[EVENT_IO_READ] ); /* reenabled by the next accept() */
+		    FD_CLR( fd, &event_set[EVENT_IO_READ] ); /* reenabled by the next accept() */
 		    dwEvent = WSAMAKESELECTREPLY( WS_FD_ACCEPT, 0 );
 		    bPost = TRUE;
 		} 
@@ -1931,22 +1998,27 @@
 	    {
 		/* connecting socket */
 
-		if( w || (w = FD_ISSET( fd, &io_set[EVENT_IO_WRITE] )) )
+		if( w || (w = FD_ISSET( fd, &pending_set[EVENT_IO_WRITE] )) )
 		{
-		    /* ready to write means that socket is connected */
+		    /* ready to write means that socket is connected 
+		     *
+		     * FIXME: Netscape calls AsyncSelect( s, ... WS_FD_CONNECT .. )
+		     * right after s = socket() and somehow "s" becomes writeable 
+		     * before it goes through connect()!?!?
+		     */
 
 		    psop->pws->flags |= WS_FD_CONNECTED;
 		    psop->pws->flags &= ~(WS_FD_CONNECT | WS_FD_INACTIVE);
 		    dwEvent = WSAMAKESELECTREPLY( WS_FD_CONNECT, 0 );
 
 		    if( flags & (WS_FD_READ | WS_FD_CLOSE))
-			FD_SET( fd, &io_set[EVENT_IO_READ] );
+			FD_SET( fd, &event_set[EVENT_IO_READ] );
 		    else 
-			FD_CLR( fd, &io_set[EVENT_IO_READ] );
+			FD_CLR( fd, &event_set[EVENT_IO_READ] );
 		    if( flags & WS_FD_WRITE ) 
-			FD_SET( fd, &io_set[EVENT_IO_WRITE] );
+			FD_SET( fd, &event_set[EVENT_IO_WRITE] );
 		    else 
-			FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+			FD_CLR( fd, &event_set[EVENT_IO_WRITE] );
 		    bPost = TRUE;
 		}
 		else if( r )
@@ -1959,16 +2031,14 @@
 			bPost = TRUE;
 		    }
 		}
-		/* otherwise bPost stays FALSE */
+		/* otherwise bPost stays FALSE, should probably clear event_set  */
 	    }
 	    else 
 	    {
-		/* connected socket --
-		 * removed WS_FD_OOB code for now.
-		 */
+		/* connected socket, no WS_FD_OOB code for now. */
 
 		if( flags & WS_FD_WRITE &&
-		   (w || (w = FD_ISSET( fd, &io_set[EVENT_IO_WRITE] ))) )
+		   (w || (w = FD_ISSET( fd, &pending_set[EVENT_IO_WRITE] ))) )
 		{
 		    /* this will be reenabled when send() or sendto() fail with
 		     * WSAEWOULDBLOCK */
@@ -1978,7 +2048,7 @@
 		    {
 			dprintf_winsock(stddeb, "\t    hwnd %04x - %04x, %08x\n",
                                 psop->hWnd, psop->uMsg, (unsigned)MAKELONG(WS_FD_WRITE, 0) );
-			FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+			FD_CLR( fd, &event_set[EVENT_IO_WRITE] );
 			num_posted++;
 		    }
 		}
@@ -2000,7 +2070,7 @@
 		    {
 			/* got pending data, will be reenabled by recv() or recvfrom() */
 
-			FD_CLR( fd, &io_set[EVENT_IO_READ] );
+			FD_CLR( fd, &event_set[EVENT_IO_READ] );
 			dwEvent = WSAMAKESELECTREPLY( WS_FD_READ, 0 );
 		    }
 		    else
@@ -2028,8 +2098,8 @@
 			/* this is it, this socket is closed */
 
 			psop->pws->flags &= ~(WS_FD_READ | WS_FD_CLOSE | WS_FD_WRITE);
-			FD_CLR( fd, &io_set[EVENT_IO_READ] );
-			FD_CLR( fd, &io_set[EVENT_IO_WRITE] );
+			FD_CLR( fd, &event_set[EVENT_IO_READ] );
+			FD_CLR( fd, &event_set[EVENT_IO_WRITE] );
 
 			if( *max_fd == (fd + 1) ) (*max_fd)--;
 		    }
@@ -2107,7 +2177,7 @@
 		psop->uMsg = uMsg;
 
 		pws->psop = psop;
-		pws->flags |= (0x0000FFFF &lEvent);
+		pws->flags |= (0x0000FFFF & lEvent);
 		getsockopt(pws->fd, SOL_SOCKET, SO_TYPE, &sock_type, &bytes);
 		if( sock_type == SOCK_RAW ) pws->flags |= WS_FD_RAW;
 
@@ -2143,7 +2213,7 @@
 {
   int i = set->fd_count;
   
-  dprintf_winsock(stddeb, "__WSAFDIsSet16(%d,%8lx)\n", s,(unsigned long)set);
+  dprintf_winsock(stddeb, "__WSAFDIsSet16(%d,%8lx(%i))\n", s,(unsigned long)set, i);
     
   while (i--)
       if (set->fd_array[i] == s) return 1;
@@ -2157,7 +2227,7 @@
 {
   int i = set->fd_count;
 
-  dprintf_winsock(stddeb, "__WSAFDIsSet32(%d,%8lx)\n", s,(unsigned long)set);
+  dprintf_winsock(stddeb, "__WSAFDIsSet32(%d,%8lx(%i))\n", s,(unsigned long)set, i);
 
   while (i--)
       if (set->fd_array[i] == s) return 1;
@@ -2171,7 +2241,7 @@
 {
   /* By default WinSock should set all its sockets to non-blocking mode
    * and poll in PeekMessage loop when processing "blocking" ones. This 
-   * function is supposed to tell if program is in this loop. Our 
+   * function is supposed to tell if the program is in this loop. Our 
    * blocking calls are truly blocking so we always return FALSE.
    *
    * Note: It is allowed to call this function without prior WSAStartup().
@@ -2332,7 +2402,7 @@
  *
  * TODO: Merge WS_dup_..() stuff into one function that
  * would operate with a generic structure containing internal
- * pointers (via some sort of a template).
+ * pointers (via a template of some kind).
  */
 
 static int list_size(char** l, int item_size)
@@ -2378,7 +2448,7 @@
 
 int WS_dup_he(LPWSINFO pwsi, struct hostent* p_he, int flag)
 {
-   /* Duplicate hostent structure and flatten data (with its pointers)
+   /* Convert hostent structure into ws_hostent so that the data fits 
     * into pwsi->buffer. Internal pointers can be linear, SEGPTR, or 
     * relative to pwsi->buffer depending on "flag" value. Returns size
     * of the data copied (also in the pwsi->buflen).
@@ -2479,7 +2549,7 @@
      p = pwsi->buffer;
      p_base = (flag & WS_DUP_OFFSET) ? NULL 
 				     : ((flag & WS_DUP_SEGPTR) ? (char*)SEGPTR_GET(p) : p);
-     p += (flag & WS_DUP_NATIVE)? sizeof(struct servent) : sizeof(struct ws_servent);
+     p += sizeof(struct ws_servent);
      p_name = p;
      strcpy(p, p_se->s_name); p += strlen(p) + 1;
      p_proto = p;
diff --git a/misc/winsock_dns.c b/misc/winsock_dns.c
index 94224de..4150b9c 100644
--- a/misc/winsock_dns.c
+++ b/misc/winsock_dns.c
@@ -337,20 +337,23 @@
 
 	    WINSOCK_link_async_op( async_ctl.ws_aop );
 
+	    EVENT_AddIO( async_ctl.ws_aop->fd[0], EVENT_IO_READ );
+	    pwsi->num_async_rq++;
+
 	    async_ctl.ws_aop->pid = fork();
 	    if( async_ctl.ws_aop->pid )
 	    {
+		dprintf_winsock(stddeb, "\tasync_op = %04x (child %i)\n", 
+				handle, async_ctl.ws_aop->pid);
+
 		close(async_ctl.ws_aop->fd[1]);  /* write endpoint */
-		dprintf_winsock(stddeb, "\tasync_op = %04x (child %i)\n",
-					handle, async_ctl.ws_aop->pid);
 		if( async_ctl.ws_aop->pid > 0 )
-		{
-		    EVENT_AddIO( async_ctl.ws_aop->fd[0], EVENT_IO_READ );
-		    pwsi->num_async_rq++;
 		    return __ws_gethandle(async_ctl.ws_aop);
-		}
 
 		/* fork() failed */
+
+	        pwsi->num_async_rq--;
+		EVENT_DeleteIO( async_ctl.ws_aop->fd[0], EVENT_IO_READ );
 		close(async_ctl.ws_aop->fd[0]);
 		pwsi->err = WSAEWOULDBLOCK;
 	    }
@@ -518,7 +521,7 @@
  * NOTE: It is possible to exploit the fact that fork() doesn't 
  * change the buffer address by storing fixed up pointers right 
  * in the handler. However, this will get in the way if we ever 
- * get to implementing DNS helper daemon a-la Netscape.
+ * get around to implementing DNS helper daemon a-la Netscape.
  */
 
 void fixup_wshe(struct ws_hostent* p_wshe, void* base)
diff --git a/msdos/Makefile.in b/msdos/Makefile.in
index 398fb34..a30b251 100644
--- a/msdos/Makefile.in
+++ b/msdos/Makefile.in
@@ -14,6 +14,7 @@
 	int13.c \
 	int15.c \
 	int1a.c \
+	int20.c \
 	int21.c \
 	int25.c \
 	int26.c \
diff --git a/msdos/dpmi.c b/msdos/dpmi.c
index 0a5feb4..0352d01 100644
--- a/msdos/dpmi.c
+++ b/msdos/dpmi.c
@@ -427,6 +427,15 @@
         }
         break;
 
+    case 0x0304:  /* Free Real Mode Callback Address */
+	{
+	    fprintf(stdnimp,
+		    "FreeRMCB: callback address: %04x:%04x\n",
+		    CX_reg(context), DX_reg(context));
+	    SET_CFLAG(context);
+	}
+	break;
+
     case 0x0400:  /* Get DPMI version */
     	{
 	    SYSTEM_INFO si;
diff --git a/msdos/int13.c b/msdos/int13.c
index 1e86258..b46b6a2 100644
--- a/msdos/int13.c
+++ b/msdos/int13.c
@@ -4,11 +4,19 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#ifdef linux
+#include <linux/fd.h>
+#endif
 #include "miscemu.h"
 #include "stddebug.h"
 /* #define DEBUG_INT */
 #include "debug.h"
-
+#include "drive.h"
 
 /**********************************************************************
  *	    INT_Int13Handler
@@ -27,14 +35,86 @@
 	case 0x05:                                     /* FORMAT TRACK */
         case 0x06:             /* FORMAT TRACK AND SET BAD SECTOR FLAGS */
         case 0x07:             /* FORMAT DRIVE STARTING AT GIVEN TRACK  */
-       /* despite of what Ralf Brown says, 0x06 and 0x07 seem to set CFLAG, too (at least my BIOS does that) */
-		AH_reg(context) = 0x0c;
-                SET_CFLAG(context);
-		break;
+            /* despite what Ralf Brown says, 0x06 and 0x07 seem to
+             * set CFLAG, too (at least my BIOS does that) */
+            AH_reg(context) = 0x0c;
+            SET_CFLAG(context);
+            break;
 
 	case 0x08:                              /* GET DRIVE PARAMETERS  */
-		AH_reg(context) = (DL_reg(context) & 0x80) ? 0x07 : 0x01;
-                SET_CFLAG(context);
+		if (DL_reg(context) & 0x80) { /* hard disk ? */
+			AH_reg(context) = 0x07;
+			SET_CFLAG(context);
+		}
+		else { /* floppy disk */
+#ifdef linux
+			unsigned int i, nr_of_drives = 0;			
+			BYTE drive_nr = DL_reg(context);
+                        int floppy_fd;
+                        struct floppy_drive_params floppy_parm;
+
+                        AH_reg(context) = 0x00; /* success */
+
+                        for (i = 0; i < MAX_DOS_DRIVES; i++)
+                        if (DRIVE_GetType(i) == TYPE_FLOPPY) nr_of_drives++;
+                        DL_reg(context) = nr_of_drives;
+
+			if (drive_nr > 1) { /* invalid drive ? */
+				BX_reg(context) = 0;
+				CX_reg(context) = 0;
+				DH_reg(context) = 0;
+				break;
+			}
+
+                        if ( (floppy_fd = DRIVE_OpenDevice( drive_nr, O_NONBLOCK)) == -1)
+                        {
+                                fprintf(stderr, "INT 0x13 (GET DRIVE PARAMETERS): can't determine floppy geometry !\n");
+                                BX_reg(context) = 0;
+                                CX_reg(context) = 0;
+                                DH_reg(context) = 0;
+                                break;
+                        }
+                        ioctl(floppy_fd, FDGETDRVPRM, &floppy_parm);
+                        close(floppy_fd);
+
+			BL_reg(context) = floppy_parm.cmos;
+
+			/* CH = low eight bits of max cyl
+			   CL = max sec nr (bits 5-0),
+			   hi two bits of max cyl (bits 7-6)
+			   DH = max head nr */ 
+			DH_reg(context) = 0x01;
+			switch (BL_reg(context))
+			{
+			    case 0: /* no drive */
+				CX_reg(context) = 0x0;
+				DX_reg(context) = 0x0;
+				break;
+			    case 1: /* 360 K */
+				CX_reg(context) = 0x2709;
+				break;
+			    case 2: /* 1.2 M */
+				CX_reg(context) = 0x4f0f;
+				break;
+			    case 3: /* 720 K */
+				CX_reg(context) = 0x4f09;
+				break;
+			    case 4: /* 1.44 M */
+				CX_reg(context) = 0x4f12;
+				break;
+			    case 5:
+			    case 6: /* 2.88 M */
+				CX_reg(context) = 0x4f24;
+				break;
+			}
+			ES_reg(context) = 0x0000; /* FIXME: drive parameter table */
+			DI_reg(context) = 0x0000;
+#else
+                	AH_reg(context) = 0x01;
+                	SET_CFLAG(context);
+                	break;
+#endif
+		}
 		break;
 
         case 0x09:         /* INITIALIZE CONTROLLER WITH DRIVE PARAMETERS */
diff --git a/msdos/int20.c b/msdos/int20.c
new file mode 100644
index 0000000..a84a4d7
--- /dev/null
+++ b/msdos/int20.c
@@ -0,0 +1,21 @@
+/*
+ * DOS interrupt 20h handler (TERMINATE PROGRAM)
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "miscemu.h"
+#include "stddebug.h"
+/* #define DEBUG_INT */
+#include "debug.h"
+#include "task.h"
+
+/**********************************************************************
+ *	    INT_Int20Handler
+ *
+ * Handler for int 20h.
+ */
+void WINAPI INT_Int20Handler( CONTEXT *context )
+{
+        TASK_KillCurrentTask( 0 );
+}
diff --git a/msdos/int21.c b/msdos/int21.c
index ae03308..0fa7a21 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -595,6 +595,10 @@
     char *name = PTR_SEG_OFF_TO_LIN( DS_reg(context), DX_reg(context) );
     char *p = name + strlen(name);
 
+    /* despite what Ralf Brown says, some programs seem to call without 
+     * ending backslash (DOS accepts that, so we accept it too) */
+    if ((p == name) || (p[-1] != '\\')) *p++ = '\\';
+
     for (;;)
     {
         sprintf( p, "wine%04x.%03d", (int)getpid(), counter );
@@ -1271,6 +1275,7 @@
             AX_reg(context) = ER_NoMoreFiles;
             SET_CFLAG(context);
         }
+        else AX_reg(context) = 0;  /* OK */
         break;
 
     case 0x51: /* GET PSP ADDRESS */
@@ -1610,3 +1615,8 @@
                  EFL_reg(context));
 }
 
+FARPROC16 WINAPI GetSetKernelDOSProc(FARPROC16 DosProc)
+{
+	fprintf(stderr, "GetSetKernelDOSProc(DosProc: %08x);\n", (UINT32)DosProc);
+	return NULL;
+}
diff --git a/msdos/int25.c b/msdos/int25.c
index 8e99609..2fd6d73 100644
--- a/msdos/int25.c
+++ b/msdos/int25.c
@@ -5,6 +5,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include "msdos.h"
 #include "ldt.h"
 #include "miscemu.h"
@@ -22,6 +24,7 @@
 {
     BYTE *dataptr = PTR_SEG_OFF_TO_LIN( DS_reg(context), BX_reg(context) );
     DWORD begin, length;
+    int fd;
 
     if (!DRIVE_IsValid(AL_reg(context)))
     {
@@ -45,11 +48,18 @@
                  "count %ld, buffer %d\n",
                  AL_reg(context), begin, length, (int) dataptr);
 
-    memset(dataptr, 0, length * 512);
-
-    if (begin == 0 && length > 1) *(dataptr + 512) = 0xf8;
-
-    if (begin == 1) *dataptr = 0xf8;
-
+    if ((fd = DRIVE_OpenDevice( AL_reg(context), O_RDONLY )) != -1)
+    {
+        lseek( fd, begin * 512, SEEK_SET );
+        /* FIXME: check errors */
+        read( fd, dataptr, length * 512 );
+        close( fd );
+    }
+    else
+    {
+        memset(dataptr, 0, length * 512);
+        if (begin == 0 && length > 1) *(dataptr + 512) = 0xf8;
+        if (begin == 1) *dataptr = 0xf8;
+    }
     RESET_CFLAG(context);
 }
diff --git a/msdos/int26.c b/msdos/int26.c
index 4a58a5c..c24f1a9 100644
--- a/msdos/int26.c
+++ b/msdos/int26.c
@@ -4,6 +4,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include "msdos.h"
 #include "ldt.h"
 #include "miscemu.h"
@@ -21,6 +23,7 @@
 {
     BYTE *dataptr = PTR_SEG_OFF_TO_LIN( DS_reg(context), BX_reg(context) );
     DWORD begin, length;
+    int fd;
 
     if (!DRIVE_IsValid(AL_reg(context)))
     {
@@ -45,5 +48,13 @@
                  "count %ld, buffer %d\n",
                  AL_reg(context), begin, length, (int) dataptr );
 
+    if ((fd = DRIVE_OpenDevice( AL_reg(context), O_WRONLY )) != -1)
+    {
+        lseek( fd, begin * 512, SEEK_SET );
+        /* FIXME: check errors */
+        write( fd, dataptr, length * 512 );
+        close( fd );
+    }
+
     RESET_CFLAG(context);
 }
diff --git a/multimedia/dsound.c b/multimedia/dsound.c
index fafa959..118a97e 100644
--- a/multimedia/dsound.c
+++ b/multimedia/dsound.c
@@ -10,14 +10,29 @@
  * FIXME: This file is full of race conditions and unlocked variable access
  * from two threads. But we usually don't need to bother.
  *
+ * Tested with a Soundblaster clone and a Gravis UltraSound Classic.
+ *
+ * Status:
+ * - Wing Commander 4/W95:
+ *   The intromovie plays without problems. Nearly lipsynchron.
+ * - DiscWorld 2
+ *   The sound works, but noticeable chunks are left out (from the sound and
+ *   the animation). Don't know why yet.
+ * - Diablo:
+ *   Sound works, but slows down the movieplayer.
+ * - XvT: 
+ *   Doesn't sound yet.
+ * - Monkey Island 3:
+ *   The background sound of the startscreen works ;)
+ * - WingCommander Prophecy Demo:
+ *   Sound works for the intromovie.
  */
 
 #include <stdio.h>
 #include <assert.h>
 #include <sys/types.h>
-#include <sys/mman.h>
+#include <sys/time.h>
 #include <sys/fcntl.h>
-#include <sys/signal.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
@@ -26,15 +41,26 @@
 #include "interfaces.h"
 #include "mmsystem.h"
 #include "dsound.h"
+#include "thread.h"
+#include "stddebug.h"
+#include "debug.h"
 
 #ifdef HAVE_OSS
 #include <sys/ioctl.h>
 #include <sys/soundcard.h>
-static int audiofd = 0;
+
+static int audiofd = -1;
+static int current_buffered_frags = 4;
 static LPDIRECTSOUND	dsound = NULL;
+
+static short playbuf[2048];
+
 #endif
 
 HRESULT WINAPI DirectSoundEnumerate32A(LPDSENUMCALLBACK32A enumcb,LPVOID context) {
+#ifdef HAVE_OSS
+	enumcb(NULL,"WINE DirectSound using Open Sound System","sound",context);
+#endif
 	return 0;
 }
 
@@ -64,72 +90,100 @@
 			fprintf(stderr,"%s ",flags[i].name);
 }
 
+/*******************************************************************************
+ *		IDirectSoundNotify
+ */
+static HRESULT WINAPI IDirectSoundNotify_QueryInterface(
+	LPDIRECTSOUNDNOTIFY this,REFIID riid,LPVOID *ppobj
+) {
+	char xbuf[50];
+
+	StringFromCLSID(riid,xbuf);
+	fprintf(stderr,"IDirectSound(%p)->QueryInterface(%s,%p)\n",this,xbuf,ppobj);
+	return E_FAIL;
+}
+
+static ULONG WINAPI IDirectSoundNotify_AddRef(LPDIRECTSOUNDNOTIFY this) {
+	return ++(this->ref);
+}
+
+static ULONG WINAPI IDirectSoundNotify_Release(LPDIRECTSOUNDNOTIFY this) {
+	this->ref--;
+	if (!this->ref) {
+		this->dsb->lpvtbl->fnRelease(this->dsb);
+		HeapFree(GetProcessHeap(),0,this);
+		return 0;
+	}
+	return this->ref;
+}
+
+static int _sort_notifies(const void *a,const void *b) {
+	LPDSBPOSITIONNOTIFY	na = (LPDSBPOSITIONNOTIFY)a;
+	LPDSBPOSITIONNOTIFY	nb = (LPDSBPOSITIONNOTIFY)b;
+
+	return na->dwOffset-nb->dwOffset;
+}
+
+static HRESULT WINAPI IDirectSoundNotify_SetNotificationPositions(
+	LPDIRECTSOUNDNOTIFY this,DWORD howmuch,LPCDSBPOSITIONNOTIFY notify
+) {
+	int	i;
+
+	fprintf(stderr,"IDirectSoundNotify(%p)->SetNotificationPositions(0x%08lx,%p),stub!\n",this,howmuch,notify);
+	for (i=0;i<howmuch;i++)
+		fprintf(stderr,"	notify at %ld to 0x%08lx\n",notify[i].dwOffset,notify[i].hEventNotify);
+	this->dsb->notifies = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,this->dsb->notifies,(this->dsb->nrofnotifies+howmuch)*sizeof(DSBPOSITIONNOTIFY));
+	memcpy(	this->dsb->notifies+this->dsb->nrofnotifies,
+		notify,
+		howmuch*sizeof(DSBPOSITIONNOTIFY)
+	);
+	this->dsb->nrofnotifies+=howmuch;
+	qsort(this->dsb->notifies,this->dsb->nrofnotifies,sizeof(DSBPOSITIONNOTIFY),_sort_notifies);
+	for (i=0;i<this->dsb->nrofnotifies;i++)
+		fprintf(stderr,"	notify at %ld to 0x%08lx\n",this->dsb->notifies[i].dwOffset,this->dsb->notifies[i].hEventNotify);
+	return 0;
+}
+
+IDirectSoundNotify_VTable dsnvt = {
+	IDirectSoundNotify_QueryInterface,
+	IDirectSoundNotify_AddRef,
+	IDirectSoundNotify_Release,
+	IDirectSoundNotify_SetNotificationPositions,
+};
+
+/*******************************************************************************
+ *		IDirectSoundBuffer
+ */
 static HRESULT WINAPI IDirectSoundBuffer_SetFormat(
 	LPDIRECTSOUNDBUFFER this,LPWAVEFORMATEX wfex
 ) {
-	int	xx,channels,speed,format,nformat;
 
-	fprintf(stderr,"IDirectSoundBuffer(%p)->SetFormat(%p),stub!\n",this,wfex);
 	memcpy(&(this->wfx),wfex,sizeof(this->wfx));
-	fprintf(stderr,"	[formattag=0x%04x,",wfex->wFormatTag);
-	fprintf(stderr,"chans=%d,",wfex->nChannels);
-	fprintf(stderr,"samplerate=%ld,",wfex->nSamplesPerSec);
-	fprintf(stderr,"bytespersec=%ld,",wfex->nAvgBytesPerSec);
-	fprintf(stderr,"blockalign=%d,",wfex->nBlockAlign);
-	fprintf(stderr,"bitspersamp=%d,",wfex->wBitsPerSample);
-	fprintf(stderr,"cbSize=%d]\n",wfex->cbSize);
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->SetFormat(%p),stub!\n",this,wfex);
+	dprintf_dsound(stderr,"	[formattag=0x%04x,",wfex->wFormatTag);
+	dprintf_dsound(stderr,"chans=%d,",wfex->nChannels);
+	dprintf_dsound(stderr,"samplerate=%ld,",wfex->nSamplesPerSec);
+	dprintf_dsound(stderr,"bytespersec=%ld,",wfex->nAvgBytesPerSec);
+	dprintf_dsound(stderr,"blockalign=%d,",wfex->nBlockAlign);
+	dprintf_dsound(stderr,"bitspersamp=%d,",wfex->wBitsPerSample);
+	dprintf_dsound(stderr,"cbSize=%d]\n",wfex->cbSize);
 
-	switch (wfex->wFormatTag) {
-	default:
-		fprintf(stderr,"unknown WAVE_FORMAT tag %d\n",wfex->wFormatTag);
-		return DSERR_BADFORMAT;
-	case WAVE_FORMAT_PCM:
-		format = AFMT_S16_LE;
-		break;
-	}
-	if (-1==ioctl(audiofd,SNDCTL_DSP_GETFMTS,&xx)) {
-		perror("ioctl SNDCTL_DSP_GETFMTS");
-		return DSERR_BADFORMAT;
-	}
-	if ((xx&format)!=format) {/* format unsupported */
-		fprintf(stderr,"SNDCTL_DSP_GETFMTS: format not supported\n"); 
-		return DSERR_BADFORMAT;
-	}
-	nformat = format;
-	if (-1==ioctl(audiofd,SNDCTL_DSP_SETFMT,&nformat)) {
-		perror("ioctl SNDCTL_DSP_SETFMT");
-		return DSERR_BADFORMAT;
-	}
-	if (nformat!=format) {/* didn't work */
-		fprintf(stderr,"SNDCTL_DSP_GETFMTS: format not set\n"); 
-		return DSERR_BADFORMAT;
-	}
-
-	channels = wfex->nChannels-1;
-	if (-1==ioctl(audiofd,SNDCTL_DSP_STEREO,&channels)) {
-		perror("ioctl SNDCTL_DSP_STEREO");
-		return DSERR_BADFORMAT;
-	}
-	speed = wfex->nSamplesPerSec;
-	if (-1==ioctl(audiofd,SNDCTL_DSP_SPEED,&speed)) {
-		perror("ioctl SNDCTL_DSP_SPEED");
-		return DSERR_BADFORMAT;
-	}
 	return 0;
 }
 
 static HRESULT WINAPI IDirectSoundBuffer_SetVolume(
 	LPDIRECTSOUNDBUFFER this,LONG vol
 ) {
-	fprintf(stderr,"IDirectSoundBuffer(%p)->SetVolume(%08lx),stub!\n",this,vol);
+	fprintf(stderr,"IDirectSoundBuffer(%p)->SetVolume(%ld),stub!\n",this,vol);
+	this->volume = vol;
 	return 0;
 }
 
 static HRESULT WINAPI IDirectSoundBuffer_GetVolume(
 	LPDIRECTSOUNDBUFFER this,LPLONG vol
 ) {
-	fprintf(stderr,"IDirectSoundBuffer(%p)->GetVolume(%p),stub!\n",this,vol);
-	*vol = 100;
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->GetVolume(%p),stub!\n",this,vol);
+	*vol = this->volume;
 	return 0;
 }
 
@@ -143,17 +197,19 @@
 static HRESULT WINAPI IDirectSoundBuffer_Play(
 	LPDIRECTSOUNDBUFFER this,DWORD reserved1,DWORD reserved2,DWORD flags
 ) {
-
-	fprintf(stderr,"IDirectSoundBuffer(%p)->Play(%08lx,%08lx,%08lx),stub!\n",
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->Play(%08lx,%08lx,%08lx),stub!\n",
 		this,reserved1,reserved2,flags
 	);
+	this->playpos = 0;
+	this->playflags = flags;
 	this->playing = 1;
 	return 0;
 }
 
 static HRESULT WINAPI IDirectSoundBuffer_Stop(LPDIRECTSOUNDBUFFER this) {
-	/*fprintf(stderr,"IDirectSoundBuffer(%p)->Stop()\n",this);*/
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->Stop()\n",this);
 	this->playing = 0;
+	this->writepos = 0; /* hmm */
 	return 0;
 }
 
@@ -165,7 +221,6 @@
 
 	if (--this->ref)
 		return this->ref;
-	fprintf(stderr,"	-> IDirectSoundBuffer(%p) freed.\n",this);
 	for (i=0;i<this->dsound->nrofbuffers;i++)
 		if (this->dsound->buffers[i] == this)
 			break;
@@ -186,28 +241,28 @@
 static HRESULT WINAPI IDirectSoundBuffer_GetCurrentPosition(
 	LPDIRECTSOUNDBUFFER this,LPDWORD playpos,LPDWORD writepos
 ) {
-/*	fprintf(stderr,"IDirectSoundBuffer(%p)->GetCurrentPosition(%p,%p),stub!\n",this,playpos,writepos);*/
-
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->GetCurrentPosition(%p,%p),stub!\n",this,playpos,writepos);
 	if (playpos) *playpos = this->playpos;
-	this->writepos = (this->playpos+512) % this->buflen;
-	if (writepos) *writepos = this->writepos; /* hmm */
+	if (writepos) *writepos = this->writepos;
 	return 0;
 }
 
 static HRESULT WINAPI IDirectSoundBuffer_GetStatus(
 	LPDIRECTSOUNDBUFFER this,LPDWORD status
 ) {
-	fprintf(stderr,"IDirectSoundBuffer(%p)->GetStatus(%p),stub!\n",this,status);
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->GetStatus(%p)\n",this,status);
+	*status = 0;
 	if (this->playing)
-		*status = DSBSTATUS_PLAYING;
-	*status |= DSBSTATUS_LOOPING; /* FIXME */
+		*status |= DSBSTATUS_PLAYING;
+	if (this->playflags & DSBPLAY_LOOPING)
+		*status |= DSBSTATUS_LOOPING;
 	return 0;
 }
 
 static HRESULT WINAPI IDirectSoundBuffer_GetFormat(
 	LPDIRECTSOUNDBUFFER this,LPWAVEFORMATEX lpwf,DWORD wfsize,LPDWORD wfwritten
 ) {
-	fprintf(stderr,"IDirectSoundBuffer(%p)->GetFormat(%p,0x%08lx,%p),stub!\n",this,lpwf,wfsize,wfwritten);
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->GetFormat(%p,%ld,%p)\n",this,lpwf,wfsize,wfwritten);
 	if (wfsize>sizeof(this->wfx)) wfsize = sizeof(this->wfx);
 	memcpy(lpwf,&(this->wfx),wfsize);
 	if (wfwritten) *wfwritten = wfsize;
@@ -218,8 +273,7 @@
 	LPDIRECTSOUNDBUFFER this,DWORD writecursor,DWORD writebytes,LPVOID lplpaudioptr1,LPDWORD audiobytes1,LPVOID lplpaudioptr2,LPDWORD audiobytes2,DWORD flags
 ) {
 
-/*
-	fprintf(stderr,"IDirectSoundBuffer(%p)->Lock(%ld,%ld,%p,%p,%p,%p,0x%08lx),stub!\n",
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->Lock(%ld,%ld,%p,%p,%p,%p,0x%08lx)\n",
 		this,
 		writecursor,
 		writebytes,
@@ -229,17 +283,18 @@
 		audiobytes2,
 		flags
 	);
-*/
 	if (flags & DSBLOCK_FROMWRITECURSOR)
 		writecursor = this->writepos;
-
-	if (writecursor+writebytes < this->buflen) {
+	assert(audiobytes1!=audiobytes2);
+	assert(lplpaudioptr1!=lplpaudioptr2);
+	if (writecursor+writebytes <= this->buflen) {
 		*(LPBYTE*)lplpaudioptr1 = this->buffer+writecursor;
 		*audiobytes1 = writebytes;
 		if (lplpaudioptr2)
 			*(LPBYTE*)lplpaudioptr2 = NULL;
 		if (audiobytes2)
 			*audiobytes2 = 0;
+		dprintf_dsound(stderr,"->%ld.0\n",writebytes);
 	} else {
 		*(LPBYTE*)lplpaudioptr1 = this->buffer+writecursor;
 		*audiobytes1 = this->buflen-writecursor;
@@ -247,6 +302,7 @@
 			*(LPBYTE*)lplpaudioptr2 = this->buffer;
 		if (audiobytes2)
 			*audiobytes2 = writebytes-(this->buflen-writecursor);
+		dprintf_dsound(stderr,"->%ld.%ld\n",*audiobytes1,audiobytes2?*audiobytes2:0);
 	}
 	this->writepos=(writecursor+writebytes)%this->buflen;
 	return 0;
@@ -255,7 +311,7 @@
 static HRESULT WINAPI IDirectSoundBuffer_SetCurrentPosition(
 	LPDIRECTSOUNDBUFFER this,DWORD newpos
 ) {
-	fprintf(stderr,"IDirectSoundBuffer(%p)->SetCurrentPosition(%ld)\n",this,newpos);
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->SetCurrentPosition(%ld)\n",this,newpos);
 	this->playpos = newpos;
 	return 0;
 }
@@ -263,33 +319,89 @@
 static HRESULT WINAPI IDirectSoundBuffer_SetPan(
 	LPDIRECTSOUNDBUFFER this,LONG newpan
 ) {
-	fprintf(stderr,"IDirectSoundBuffer(%p)->SetPan(%ld),stub!\n",this,newpan);
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->SetPan(%ld),stub!\n",this,newpan);
+	this->pan = newpan;
+	return 0;
+}
+
+static HRESULT WINAPI IDirectSoundBuffer_GetPan(
+	LPDIRECTSOUNDBUFFER this,LPLONG pan
+) {
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->GetPan(%p),stub!\n",this,pan);
+	*pan = this->pan;
 	return 0;
 }
 
 static HRESULT WINAPI IDirectSoundBuffer_Unlock(
 	LPDIRECTSOUNDBUFFER this,LPVOID p1,DWORD x1,LPVOID p2,DWORD x2
 ) {
-	struct count_info	ci;
-/*
-	fprintf(stderr,"IDirectSoundBuffer(%p)->Unlock(%p,%ld,%p,%ld),stub!\n",this,p1,x1,p2,x2);
- */
- 	fprintf(stderr,"u%ld.%ld,",x1,x2);
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->Unlock(%p,%ld,%p,%ld)\n",
+		this,p1,x1,p2,x2
+	);
 	return 0;
 }
 
+static HRESULT WINAPI IDirectSoundBuffer_GetFrequency(
+	LPDIRECTSOUNDBUFFER this,LPDWORD freq
+) {
+	dprintf_dsound(stderr,"IDirectSoundBuffer(%p)->GetFrequency(%p)\n",
+		this,freq
+	);
+	*freq = this->wfx.nSamplesPerSec;
+	return 0;
+}
+
+static HRESULT WINAPI IDirectSoundBuffer_Initialize(
+	LPDIRECTSOUNDBUFFER this,LPDIRECTSOUND dsound,LPDSBUFFERDESC dbsd
+) {
+	fprintf(stderr,"IDirectSoundBuffer(%p)->Initialize(%p,%p),stub!\n",this,dsound,dbsd);
+	return DSERR_ALREADYINITIALIZED;
+}
+
+static HRESULT WINAPI IDirectSoundBuffer_GetCaps(
+	LPDIRECTSOUNDBUFFER this,LPDSBCAPS caps
+) {
+	caps->dwSize = sizeof(*caps);
+	caps->dwFlags = DSBCAPS_PRIMARYBUFFER|DSBCAPS_STATIC|DSBCAPS_CTRLALL|DSBCAPS_LOCSOFTWARE;
+	caps->dwBufferBytes = 0;
+	caps->dwUnlockTransferRate = 0;
+	caps->dwPlayCpuOverhead = 0;
+	return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundBuffer_QueryInterface(
+	LPDIRECTSOUNDBUFFER this,REFIID riid,LPVOID *ppobj
+) {
+	char	xbuf[50];
+
+	if (!memcmp(&IID_IDirectSoundNotify,riid,sizeof(*riid))) {
+		IDirectSoundNotify	*dsn;
+
+		dsn = (LPDIRECTSOUNDNOTIFY)HeapAlloc(GetProcessHeap(),0,sizeof(*dsn));
+		dsn->ref = 1;
+		dsn->dsb = this;
+		this->lpvtbl->fnAddRef(this);
+		dsn->lpvtbl = &dsnvt;
+		*ppobj = (LPVOID)dsn;
+		return 0;
+	}
+	StringFromCLSID(riid,xbuf);
+	fprintf(stderr,"IDirectSoundBuffer(%p)->QueryInterface(%s,%p)\n",this,xbuf,ppobj);
+	return E_FAIL;
+}
+
 static struct tagLPDIRECTSOUNDBUFFER_VTABLE dsbvt = {
-	(void *)1,
+	IDirectSoundBuffer_QueryInterface,
 	IDirectSoundBuffer_AddRef,
 	IDirectSoundBuffer_Release,
-	(void *)4,
+	IDirectSoundBuffer_GetCaps,
 	IDirectSoundBuffer_GetCurrentPosition,
 	IDirectSoundBuffer_GetFormat,
 	IDirectSoundBuffer_GetVolume,
-	(void *)8,
-        (void *)9,
+	IDirectSoundBuffer_GetPan,
+        IDirectSoundBuffer_GetFrequency,
 	IDirectSoundBuffer_GetStatus,
-	(void *)11,
+	IDirectSoundBuffer_Initialize,
 	IDirectSoundBuffer_Lock,
 	IDirectSoundBuffer_Play,
 	IDirectSoundBuffer_SetCurrentPosition,
@@ -301,12 +413,14 @@
 	IDirectSoundBuffer_Unlock
 };
 
-
+/*******************************************************************************
+ *		IDirectSound
+ */
 
 static HRESULT WINAPI IDirectSound_SetCooperativeLevel(
 	LPDIRECTSOUND this,HWND32 hwnd,DWORD level
 ) {
-	fprintf(stderr,"IDirectSound(%p)->SetCooperativeLevel(%08lx,%ld),stub!\n",
+	dprintf_dsound(stderr,"IDirectSound(%p)->SetCooperativeLevel(%08lx,%ld)\n",
 		this,(DWORD)hwnd,level
 	);
 	return 0;
@@ -316,13 +430,15 @@
 static HRESULT WINAPI IDirectSound_CreateSoundBuffer(
 	LPDIRECTSOUND this,LPDSBUFFERDESC dsbd,LPLPDIRECTSOUNDBUFFER ppdsb,LPUNKNOWN lpunk
 ) {
-	fprintf(stderr,"IDirectSound(%p)->CreateSoundBuffer(%p,%p,%p),stub!\n",this,dsbd,ppdsb,lpunk);
-	fprintf(stderr,"[size=%ld,",dsbd->dwSize);
-	fprintf(stderr,"flags = 0x%08lx,",dsbd->dwFlags);
-	_dump_DSBCAPS(dsbd->dwFlags);
-	fprintf(stderr,"bufferbytes = %ld,",dsbd->dwBufferBytes);
-	fprintf(stderr,"lpwfxFormat = %p]\n",dsbd->lpwfxFormat);
-	*ppdsb = (LPDIRECTSOUNDBUFFER)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBuffer));
+	if (debugging_dsound) {
+		fprintf(stderr,"IDirectSound(%p)->CreateSoundBuffer(%p,%p,%p),stub!\n",this,dsbd,ppdsb,lpunk);
+		fprintf(stderr,"[size=%ld,",dsbd->dwSize);
+		fprintf(stderr,"flags = 0x%08lx,",dsbd->dwFlags);
+		_dump_DSBCAPS(dsbd->dwFlags);
+		fprintf(stderr,"bufferbytes = %ld,",dsbd->dwBufferBytes);
+		fprintf(stderr,"lpwfxFormat = %p]\n",dsbd->lpwfxFormat);
+	}
+	*ppdsb = (LPDIRECTSOUNDBUFFER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundBuffer));
 	(*ppdsb)->ref =1;
 	(*ppdsb)->buffer = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsbd->dwBufferBytes);
 	(*ppdsb)->buflen = dsbd->dwBufferBytes;
@@ -331,6 +447,7 @@
 	(*ppdsb)->lpvtbl = &dsbvt;
 	(*ppdsb)->dsound = this;
 	(*ppdsb)->playing = 0;
+	memcpy(&((*ppdsb)->dsbd),dsbd,sizeof(*dsbd));
 
 	/* register buffer */
 	this->buffers = (LPDIRECTSOUNDBUFFER*)HeapReAlloc(GetProcessHeap(),0,this->buffers,sizeof(LPDIRECTSOUNDBUFFER)*(this->nrofbuffers+1));
@@ -347,9 +464,10 @@
 ) {
 	fprintf(stderr,"IDirectSound(%p)->DuplicateSoundBuffer(%p,%p),stub!\n",this,pdsb,ppdsb);
 
-	*ppdsb = (LPDIRECTSOUNDBUFFER)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBuffer));
+	*ppdsb = (LPDIRECTSOUNDBUFFER)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundBuffer));
 	(*ppdsb)->ref =1;
 	(*ppdsb)->buffer = (LPBYTE)HeapAlloc(GetProcessHeap(),0,pdsb->buflen);
+	memcpy((*ppdsb)->buffer,pdsb->buffer,pdsb->buflen);
 	(*ppdsb)->buflen = pdsb->buflen;
 	(*ppdsb)->playpos = 0;
 	(*ppdsb)->writepos = 0;
@@ -365,9 +483,17 @@
 }
 
 
-static HRESULT WINAPI IDirectSound_GetCaps(LPDIRECTSOUND this,LPDSCAPS dscaps) {
-	fprintf(stderr,"IDirectSound(%p)->GetCaps(%p),stub!\n",this,dscaps);
-	fprintf(stderr,"	flags = 0x%08lx\n",dscaps->dwFlags);
+static HRESULT WINAPI IDirectSound_GetCaps(LPDIRECTSOUND this,LPDSCAPS caps) {
+	fprintf(stderr,"IDirectSound(%p)->GetCaps(%p),stub!\n",this,caps);
+	fprintf(stderr,"	flags = 0x%08lx\n",caps->dwFlags);
+
+	caps->dwSize = sizeof(*caps);
+	caps->dwFlags = DSCAPS_PRIMARYSTEREO|DSCAPS_PRIMARY16BIT|DSCAPS_EMULDRIVER|DSCAPS_SECONDARYSTEREO|DSCAPS_SECONDARY16BIT;
+	/* FIXME: query OSS */
+	caps->dwMinSecondarySampleRate = 22050;
+	caps->dwMaxSecondarySampleRate = 48000;
+	caps->dwPrimaryBuffers = 1;
+	/* FIXME: set the rest... hmm */
 	return 0;
 }
 
@@ -378,15 +504,32 @@
 static ULONG WINAPI IDirectSound_Release(LPDIRECTSOUND this) {
 	if (!--(this->ref)) {
 		HeapFree(GetProcessHeap(),0,this);
-		fprintf(stderr,"	IDIrectSound(%p) freed!\n",this);
 		dsound = NULL;
+		close(audiofd);audiofd = -1;
 		return 0;
 	}
 	return this->ref;
 }
 
+static HRESULT WINAPI IDirectSound_SetSpeakerConfig(
+	LPDIRECTSOUND this,DWORD config
+) {
+	fprintf(stderr,"IDirectSound(%p)->SetSpeakerConfig(0x%08lx)\n",this,config);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectSound_QueryInterface(
+	LPDIRECTSOUND this,REFIID riid,LPVOID *ppobj
+) {
+	char xbuf[50];
+
+	StringFromCLSID(riid,xbuf);
+	fprintf(stderr,"IDirectSound(%p)->QueryInterface(%s,%p)\n",this,xbuf,ppobj);
+	return E_FAIL;
+}
+
 static struct tagLPDIRECTSOUND_VTABLE dsvt = {
-	(void *)1,
+	IDirectSound_QueryInterface,
 	IDirectSound_AddRef,
 	IDirectSound_Release,
 	IDirectSound_CreateSoundBuffer,
@@ -395,68 +538,228 @@
 	IDirectSound_SetCooperativeLevel,
 	(void *)8,
         (void *)9,
-        (void *)10,
+        IDirectSound_SetSpeakerConfig,
         (void *)11
 };
 
-void
-DSOUND_thread(void) {
-	int	res,i,j,curleft,playing;
-	short	buf[512];
+static int
+DSOUND_setformat(LPWAVEFORMATEX wfex) {
+	int	xx,channels,speed,format,nformat;
 
+	switch (wfex->wFormatTag) {
+	default:
+		fprintf(stderr,"unknown WAVE_FORMAT tag %d\n",wfex->wFormatTag);
+		return DSERR_BADFORMAT;
+	case WAVE_FORMAT_PCM:
+		format = AFMT_S16_LE;
+		break;
+	}
+	if (-1==ioctl(audiofd,SNDCTL_DSP_GETFMTS,&xx)) {
+		perror("ioctl SNDCTL_DSP_GETFMTS");
+		return -1;
+	}
+	if ((xx&format)!=format) {/* format unsupported */
+		fprintf(stderr,"SNDCTL_DSP_GETFMTS: format not supported\n"); 
+		return -1;
+	}
+	nformat = format;
+	if (-1==ioctl(audiofd,SNDCTL_DSP_SETFMT,&nformat)) {
+		perror("ioctl SNDCTL_DSP_SETFMT");
+		return -1;
+	}
+	if (nformat!=format) {/* didn't work */
+		fprintf(stderr,"SNDCTL_DSP_GETFMTS: format not set\n"); 
+		return -1;
+	}
+
+	channels = wfex->nChannels-1;
+	if (-1==ioctl(audiofd,SNDCTL_DSP_STEREO,&channels)) {
+		perror("ioctl SNDCTL_DSP_STEREO");
+		return -1;
+	}
+	speed = wfex->nSamplesPerSec;
+	if (-1==ioctl(audiofd,SNDCTL_DSP_SPEED,&speed)) {
+		perror("ioctl SNDCTL_DSP_SPEED");
+		return -1;
+	}
+	return 0;
+}
+
+static LPDSBPOSITIONNOTIFY
+DSOUND_nextevent(IDirectSoundBuffer *dsb) {
+	int	i;
+
+	if (dsb->nrofnotifies) {
+		for (i=0;i<dsb->nrofnotifies;i++) {
+			if (dsb->playpos<dsb->notifies[i].dwOffset)
+				break;
+		}
+		if (i==dsb->nrofnotifies)
+			i=0;
+		return dsb->notifies+i;
+	}
+	return NULL;
+}
+
+#define CHECK_EVENT							\
+	if (nextevent && (dsb->playpos == nextevent->dwOffset)) {	\
+		SetEvent(nextevent->hEventNotify);			\
+		fprintf(stderr,"signalled event %d\n",nextevent->hEventNotify);\
+		nextevent = DSOUND_nextevent(dsb);			\
+	}
+		
+
+static void 
+DSOUND_MixInBuffer(IDirectSoundBuffer *dsb) {
+	int	i,j,buflen = dsb->buflen;
+	LPDSBPOSITIONNOTIFY	nextevent;
+
+	if (dsb->wfx.nSamplesPerSec != dsound->wfx.nSamplesPerSec) {
+		fprintf(stderr,"mixing in buffer of different frequency, argh!\n");
+	}
+	nextevent = DSOUND_nextevent(dsb);
+
+	if (dsb->wfx.wBitsPerSample == 8) {
+		unsigned char	*xbuf = (unsigned char*)(dsb->buffer);
+		if (dsb->wfx.nChannels == 1) {
+			for (j=0;j<sizeof(playbuf)/sizeof(playbuf[0])/2;j++) {
+				dsb->playpos=(dsb->playpos+1)%buflen;
+				if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
+					dsb->playing = 0;
+					dsb->playpos = buflen;
+					return;
+				}
+				/* FIXME: pan,volume */
+				playbuf[(j<<1)  ]+=xbuf[dsb->playpos]<<8;
+				playbuf[(j<<1)+1]+=xbuf[dsb->playpos]<<8;
+				CHECK_EVENT
+			}
+		} else {
+			for (j=0;j<sizeof(playbuf)/sizeof(playbuf[0]);j++) {
+				dsb->playpos=(dsb->playpos+1)%buflen;
+				if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
+					dsb->playing = 0;
+					dsb->playpos = buflen;
+					return;
+				}
+				/* FIXME: pan,volume */
+				playbuf[j]+=xbuf[dsb->playpos]<<8;
+				CHECK_EVENT
+			}
+		}
+	} else { /* 16 */
+		short	*xbuf = (short*)(dsb->buffer);
+		if (dsb->wfx.nChannels == 1) {
+			for (j=0;j<sizeof(playbuf)/sizeof(playbuf[0])/2;j++) {
+				dsb->playpos=(dsb->playpos+2)%buflen;
+				if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
+					dsb->playing = 0;
+					dsb->playpos = buflen;
+					return;
+				}
+				/* FIXME: pan,volume */
+				playbuf[(j<<1)  ]+=xbuf[dsb->playpos>>1];
+				playbuf[(j<<1)+1]+=xbuf[dsb->playpos>>1];
+				CHECK_EVENT
+			}
+		} else {
+			for (j=0;j<sizeof(playbuf)/sizeof(playbuf[0]);j++) {
+				dsb->playpos=(dsb->playpos+2)%buflen;
+				if (!dsb->playpos && !(dsb->playflags&DSBPLAY_LOOPING)) {
+					dsb->playing = 0;
+					dsb->playpos = buflen;
+					return;
+				}
+				/* FIXME: pan,volume */
+				playbuf[j]+=xbuf[dsb->playpos>>1];
+				CHECK_EVENT
+			}
+		}
+	}
+}
+
+static DWORD
+DSOUND_thread(LPVOID arg) {
+	int	fragsdiff,res,i,curleft,playing;
+	struct audio_buf_info	abi;
+
+	fprintf(stderr,"dsound is at pid %d\n",getpid());
+	ioctl(audiofd,SNDCTL_DSP_GETOSPACE,&abi);
+	fragsdiff = abi.fragstotal-abi.fragments;
 	while (1) {
 		if (!dsound) {
-			fprintf(stderr,"DSOUND thread killed\n");
-			kill(getpid(),SIGTERM);
-			return;
+			fprintf(stderr,"DSOUND thread giving up.\n");
+			ExitThread(0);
 		}
+		/* RACE: dsound could be deleted */
 		dsound->lpvtbl->fnAddRef(dsound);
-		memset(buf,0,sizeof(buf));
-		/* FIXME: assumes 16 bit and same format on all buffers
-		 * which must not be the case
-		 */
+		if (!dsound->nrofbuffers) {
+			/* no soundbuffer yet... wait. */
+			Sleep(1000);
+			continue;
+		}
+		memset(playbuf,0,sizeof(playbuf));
+		/* empty in memory soundbuffers */
+		while (1) {
+			ioctl(audiofd,SNDCTL_DSP_GETOSPACE,&abi);
+			if (abi.fragstotal-abi.fragments<=fragsdiff+current_buffered_frags)
+				break;
+			Sleep(1);
+		}
 		playing = 0;
+		dsound->lpvtbl->fnAddRef(dsound); 
 		for (i=dsound->nrofbuffers;i--;) {
+			IDirectSoundBuffer	*dsb = dsound->buffers[i];
 
-			dsound->buffers[i]->lpvtbl->fnAddRef(dsound->buffers[i]);
-			if (	dsound->buffers[i]->buflen &&
-				dsound->buffers[i]->playing
-			) {
-				int	playpos = dsound->buffers[i]->playpos/sizeof(short);
-				int	buflen = dsound->buffers[i]->buflen/sizeof(short);
-				short	*xbuf = (short*)(dsound->buffers[i]->buffer);
-
-				playing++;
-				dsound->buffers[i]->playpos = (sizeof(buf)+(playpos<<1))%(buflen<<1);
-				for (j=0;j<sizeof(buf)/sizeof(short);j++)
-					buf[j]+=xbuf[(j+playpos)%buflen];
+			dsb->lpvtbl->fnAddRef(dsb);
+			if (dsb->dsbd.dwFlags & DSBCAPS_PRIMARYBUFFER) {
+				if (memcmp(&dsound->wfx,&(dsb->wfx),sizeof(dsound->wfx))) {
+					DSOUND_setformat(&(dsb->wfx));
+					memcpy(&dsound->wfx,&(dsb->wfx),sizeof(dsb->wfx));
+				}
 			}
-			dsound->buffers[i]->lpvtbl->fnRelease(dsound->buffers[i]);
+			dsb->lpvtbl->fnRelease(dsb);
+		}
+		for (i=dsound->nrofbuffers;i--;) {
+			IDirectSoundBuffer	*dsb = dsound->buffers[i];
+
+			dsb->lpvtbl->fnAddRef(dsb);
+			if (dsb->buflen && dsb->playing) {
+				playing++;
+				DSOUND_MixInBuffer(dsb);
+			}
+			dsb->lpvtbl->fnRelease(dsb);
 		}
 		dsound->lpvtbl->fnRelease(dsound);
+
 		/*fputc('0'+playing,stderr);*/
 		curleft = 0;
-		while (curleft < sizeof(buf)) {
-			res = write(audiofd,(LPBYTE)buf+curleft,sizeof(buf)-curleft);
+		ioctl(audiofd,SNDCTL_DSP_GETOSPACE,&abi);
+		if ((abi.fragstotal-abi.fragments)<=1+fragsdiff) {
+			current_buffered_frags++;
+		} else if ((abi.fragstotal-abi.fragments)>2+fragsdiff) {
+			current_buffered_frags--;
+		}
+		while (curleft < sizeof(playbuf)) {
+			res = write(audiofd,(LPBYTE)playbuf+curleft,sizeof(playbuf)-curleft);
 			if (res==-1) {
 				perror("write audiofd");
-				fprintf(stderr,"buf is %p, curleft is %d\n",buf,curleft);
-				kill(getpid(),SIGTERM);
+				ExitThread(0);
 				break;
 			}
 			curleft+=res;
 		}
 	}
+	ExitThread(0);
 }
 
 #endif /* HAVE_OSS */
 
 HRESULT WINAPI DirectSoundCreate(LPGUID lpGUID,LPDIRECTSOUND *ppDS,IUnknown *pUnkOuter ) {
+	if (lpGUID)
+		fprintf(stderr,"DirectSoundCreate(%p,%p,%p)\n",lpGUID,ppDS,pUnkOuter);
 #ifdef HAVE_OSS
-	int	xx;
-
-	fprintf(stderr,"DirectSoundCreate(%p,%p,%p)\n",lpGUID,ppDS,pUnkOuter);
-	if (audiofd)
+	if (audiofd>=0)
 		return DSERR_ALLOCATED;
 	audiofd = open("/dev/audio",O_WRONLY);
 	if (audiofd==-1) {
@@ -464,33 +767,37 @@
 		audiofd=0;
 		return DSERR_NODRIVER;
 	}
-	/* make it nonblocking */
-	if (-1==ioctl(audiofd,SNDCTL_DSP_NONBLOCK,NULL)) {
-		perror("ioctl SNDCTL_DSP_NONBLOCK");
-		close(audiofd);
-		audiofd=0;
-		return DSERR_NODRIVER;
-	}
-	if (-1==ioctl(audiofd,SNDCTL_DSP_GETCAPS,&xx)) {
-		perror("ioctl SNDCTL_DSP_GETCAPS");
-		close(audiofd);
-		audiofd=0;
-		return DSERR_NODRIVER;
-	}
-	fprintf(stderr,"SNDCTL_DSP_GETCAPS returned %x\n",xx);
+	/*
+	xx=0x0004000c;
+	if (-1==ioctl(audiofd,SNDCTL_DSP_SETFRAGMENT,&xx))
+		perror("ioctl SETFRAGMENT");
+	*/
+
 	*ppDS = (LPDIRECTSOUND)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSound));
 	(*ppDS)->ref		= 1;
 	(*ppDS)->lpvtbl		= &dsvt;
 	(*ppDS)->buffers	= NULL;
 	(*ppDS)->nrofbuffers	= 0;
 
+	(*ppDS)->wfx.wFormatTag		= 1;
+	(*ppDS)->wfx.nChannels		= 2;
+	(*ppDS)->wfx.nSamplesPerSec	= 22050;
+	(*ppDS)->wfx.nAvgBytesPerSec	= 44100;
+	(*ppDS)->wfx.nBlockAlign	= 2;
+	(*ppDS)->wfx.wBitsPerSample	= 8;
+
+	DSOUND_setformat(&((*ppDS)->wfx));
+
 	if (!dsound) {
+		HANDLE32	hnd;
+		DWORD		xid;
+
 		dsound = (*ppDS);
-/*		THREAD_CreateSysThread(0,DSOUND_thread); FIXME */
+		hnd = CreateThread(NULL,NULL,DSOUND_thread,0,0,&xid);
 	}
 	return 0;
 #else
 	MessageBox32A(0,"DirectSound needs the Open Sound System Driver, which has not been found by ./configure.","WINE DirectSound",MB_OK|MB_ICONSTOP);
-	return DSERR_NODRIVER; /* check */
+	return DSERR_NODRIVER;
 #endif
 }
diff --git a/multimedia/joystick.c b/multimedia/joystick.c
index e59ef65..a1580b3 100644
--- a/multimedia/joystick.c
+++ b/multimedia/joystick.c
@@ -19,6 +19,7 @@
 #include <string.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#include <sys/errno.h>
 #include "windows.h"
 #include "ldt.h"
 #include "user.h"
@@ -27,14 +28,16 @@
 #include "stddebug.h"
 #include "debug.h"
 
-static int count_use[4] = {0, 0, 0, 0};
+#define MAXJOYDRIVERS	4
+
+static int count_use[MAXJOYDRIVERS] = {0, 0, 0, 0};
 static int dev_stat;
 static int joy_nr_open = 0;
 static BOOL16 joyCaptured = FALSE;
-static HWND16 CaptureWnd[2] = {0, 0};
-static int joy_dev[2] = {-1, -1};
-static JOYINFO16 joyCapData[2];
-static unsigned int joy_threshold[2] = {0, 0};
+static HWND16 CaptureWnd[MAXJOYDRIVERS] = {0, 0};
+static int joy_dev[MAXJOYDRIVERS] = {-1, -1,-1,-1};
+static JOYINFO16 joyCapData[MAXJOYDRIVERS];
+static unsigned int joy_threshold[MAXJOYDRIVERS] = {0, 0, 0, 0};
 
 struct js_status
 {
@@ -49,15 +52,16 @@
  */
 BOOL16 joyOpenDriver(WORD wID)
 {
-	char dev_name[] = "/dev/jsx";
+	char dev_name[] = "/dev/js%d";
+	char	buf[20];
 
 	if (joy_dev[wID] >= 0) return TRUE;
-        dev_name[strlen(dev_name)-1]=(char) wID+0x30;
-        if ((joy_dev[wID] = open(dev_name, O_RDONLY)) >= 0) {
+        sprintf(buf,dev_name,wID);
+        if ((joy_dev[wID] = open(buf, O_RDONLY)) >= 0) {
 		joy_nr_open++;
 		return TRUE;
-	}
-	else return FALSE;
+	} else
+		return FALSE;
 }
 
 /**************************************************************************
@@ -81,18 +85,18 @@
         struct js_status js;
 
 	if (joy_nr_open)
-	for (joy=0; joy < 4; joy++) 
-	if (joy_dev[joy] >= 0) {
-		if (count_use[joy] > 250) {
-			joyCloseDriver(joy);
-			count_use[joy] = 0;
-		}
-		count_use[joy]++;
-	}
-	else return;
+	for (joy=0; joy < MAXJOYDRIVERS; joy++) 
+		if (joy_dev[joy] >= 0) {
+			if (count_use[joy] > 250) {
+				joyCloseDriver(joy);
+				count_use[joy] = 0;
+			}
+			count_use[joy]++;
+		} else
+			return;
         if (joyCaptured == FALSE) return;
 	dprintf_mmsys(stddeb, "JoySendMessages()\n");
-        for (joy=0; joy < 4; joy++) {
+        for (joy=0; joy < MAXJOYDRIVERS; joy++) {
 		if (joyOpenDriver(joy) == FALSE) continue;
                 dev_stat = read(joy_dev[joy], &js, sizeof(js));
                 if (dev_stat == sizeof(js)) {
@@ -135,7 +139,7 @@
     UINT16 joy_cnt = 0;
 
     dprintf_mmsys(stddeb, "JoyGetNumDevs: ");
-    for (joy=0; joy<4; joy++)
+    for (joy=0; joy<MAXJOYDRIVERS; joy++)
 	if (joyOpenDriver(joy) == TRUE) {		
 		joyCloseDriver(joy);
 		joy_cnt++;
@@ -325,7 +329,7 @@
 MMRESULT16 WINAPI joyGetThreshold16(UINT16 wID, LPUINT16 lpThreshold)
 {
     dprintf_mmsys(stderr, "JoyGetThreshold(%04X, %p);\n", wID, lpThreshold);
-    if (wID > 3) return JOYERR_PARMS;
+    if (wID >= MAXJOYDRIVERS) return JOYERR_PARMS;
     *lpThreshold = joy_threshold[wID];
     return JOYERR_NOERROR;
 }
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 4f1e47c..1ee0023 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -1544,10 +1544,21 @@
 DWORD WINAPI mciSendCommand32A(UINT32 wDevID, UINT32 wMsg, DWORD dwParam1,
                             DWORD dwParam2)
 {
-	fprintf(stderr,"mciSendCommand32A(%08x,%08x,%08lx,%08lx),stub!\n",
-		wDevID,wMsg,dwParam1,dwParam2
+    fprintf(stderr,"mciSendCommand32A(%08x,%s,%08lx,%08lx),stub!\n",
+	    wDevID,_mciCommandToString(wMsg),dwParam1,dwParam2
+    );
+    switch (wMsg) {
+    case MCI_OPEN: {
+    	LPMCI_OPEN_PARMS32A	lpmop = (LPMCI_OPEN_PARMS32A)dwParam2;
+    	fprintf(stderr,"	MCI_OPEN(%s,%s,%s)\n",
+		(dwParam1&MCI_OPEN_TYPE)   ?lpmop->lpstrDeviceType:"<null>",
+		(dwParam1&MCI_OPEN_ELEMENT)?lpmop->lpstrElementName:"<null>",
+		(dwParam1&MCI_OPEN_ALIAS)  ?lpmop->lpstrAlias:"<null>"
 	);
-	return 0; /* ok */
+	break;
+    }
+    }
+    return 0x1; /* !ok */
 }
 /**************************************************************************
  * 				mciSendCommand			[MMSYSTEM.701]
diff --git a/multimedia/time.c b/multimedia/time.c
index 7a4eb6d..5a6d267 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -34,6 +34,7 @@
     UINT32	wCurTime;
     UINT32	iswin32;
     struct tagTIMERENTRY *Next;
+    DWORD	triggertime;
 } TIMERENTRY, *LPTIMERENTRY;
 
 static LPTIMERENTRY lpTimerList = NULL;
@@ -42,11 +43,53 @@
  * FIXME
  * is this the minimum resolution ? 
  */
-#define MMSYSTIME_MININTERVAL (33)
+/*#define MMSYSTIME_MININTERVAL (33)*/
+#define MMSYSTIME_MININTERVAL (31)
 #define MMSYSTIME_MAXINTERVAL (65535)
 
 
 /**************************************************************************
+ *           check_MMtimers
+ */
+static VOID check_MMtimers()
+{
+    LPTIMERENTRY lpTimer = lpTimerList;
+    DWORD	curtick = GetTickCount();
+
+    while (lpTimer != NULL) {
+    	if (lpTimer->triggertime <= curtick) {
+	    lpTimer->wCurTime = lpTimer->wDelay;
+
+	    if (lpTimer->lpFunc != (FARPROC16) NULL) {
+		dprintf_mmtime(stddeb, "MMSysTimeCallback // before CallBack16 !\n");
+		dprintf_mmtime(stddeb, "MMSysTimeCallback // lpFunc=%p wTimerID=%04X dwUser=%08lX !\n",
+			lpTimer->lpFunc, lpTimer->wTimerID, lpTimer->dwUser);
+		dprintf_mmtime(stddeb, "MMSysTimeCallback // hInstance=%04X !\n", lpTimer->hInstance);
+
+
+/*        - TimeProc callback that is called here is something strange, under Windows 3.1x it is called 
+ *          during interrupt time,  is allowed to execute very limited number of API calls (like
+ *	    PostMessage), and must reside in DLL (therefore uses stack of active application). So I 
+ *          guess current implementation via SetTimer has to be improved upon.		
+ */
+ 		if (lpTimer->iswin32)
+			lpTimer->lpFunc(lpTimer->wTimerID,0,lpTimer->dwUser,0,0);
+		else
+			Callbacks->CallTimeFuncProc(lpTimer->lpFunc,
+						    lpTimer->wTimerID,0,
+						    lpTimer->dwUser,0,0
+			);
+
+		dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
+	    }
+	    if (lpTimer->wFlags & TIME_ONESHOT)
+		timeKillEvent32(lpTimer->wTimerID);
+	}
+	lpTimer = lpTimer->Next;
+    }
+}
+
+/**************************************************************************
  *           TIME_MMSysTimeCallback
  */
 static VOID TIME_MMSysTimeCallback( HWND32 hwnd, UINT32 msg,
@@ -170,6 +213,7 @@
     lpTimerList = lpNewTimer;
     lpNewTimer->wTimerID = wNewID + 1;
     lpNewTimer->wCurTime = wDelay;
+    lpNewTimer->triggertime = wDelay+GetTickCount();
     lpNewTimer->wDelay = wDelay;
     lpNewTimer->wResol = wResol;
     lpNewTimer->lpFunc = (FARPROC16) lpFunc;
@@ -210,6 +254,7 @@
     lpNewTimer->wTimerID = wNewID + 1;
     lpNewTimer->wCurTime = wDelay;
     lpNewTimer->wDelay = wDelay;
+    lpNewTimer->triggertime = wDelay+GetTickCount();
     lpNewTimer->wResol = wResol;
     lpNewTimer->lpFunc = (FARPROC16) lpFunc;
     lpNewTimer->iswin32 = 0;
@@ -334,7 +379,11 @@
 	StartMMTime();
     newtick = GetTickCount();
     mmSysTimeMS.u.ms+=newtick-lasttick; /* FIXME: faked timer */
+    if (newtick!=lasttick)
+    	check_MMtimers();
     lasttick = newtick;
     dprintf_mmtime(stddeb, "timeGetTime() // Time = %ld\n",mmSysTimeMS.u.ms);
+
+
     return mmSysTimeMS.u.ms;
 }
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 3290ae7..fc59250 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -7,8 +7,8 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xutil.h"
 #include "gdi.h"
 #include "callback.h"
 #include "dc.h"
@@ -42,7 +42,7 @@
 
 static int XPutImage_wrapper( const struct XPutImage_descr *descr )
 {
-    return XPutImage( display, descr->bmp->pixmap, BITMAP_GC(descr->bmp),
+    return TSXPutImage( display, descr->bmp->pixmap, BITMAP_GC(descr->bmp),
                       descr->image, 0, 0, 0, 0, descr->width, descr->height );
 }
 
@@ -168,7 +168,7 @@
     bmpObjPtr->bitmap.bmBits = NULL;
 
       /* Create the pixmap */
-    bmpObjPtr->pixmap = XCreatePixmap(display, rootWindow, width, height, bpp);
+    bmpObjPtr->pixmap = TSXCreatePixmap(display, rootWindow, width, height, bpp);
     if (!bmpObjPtr->pixmap)
     {
 	GDI_HEAP_FREE( hbitmap );
@@ -235,7 +235,7 @@
  */
 XImage *BITMAP_GetXImage( const BITMAPOBJ *bmp )
 {
-    return XGetImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
+    return TSXGetImage( display, bmp->pixmap, 0, 0, bmp->bitmap.bmWidth,
                       bmp->bitmap.bmHeight, AllPlanes, ZPixmap );
 }
 
@@ -304,7 +304,7 @@
             {
                 if ((w%8) == 0)
                     *tbuf = 0;
-                *tbuf |= XGetPixel(image,w,h)<<(7-(w&7));
+                *tbuf |= TSXGetPixel(image,w,h)<<(7-(w&7));
                 if ((w&7) == 7) ++tbuf;
             }
             tbuf += pad;
@@ -315,8 +315,8 @@
         {
             for (w=0;w<bmp->bitmap.bmWidth;w++)
             {
-                if (!(w & 1)) *tbuf = XGetPixel( image, w, h) << 4;
-	    	else *tbuf++ |= XGetPixel( image, w, h) & 0x0f;
+                if (!(w & 1)) *tbuf = TSXGetPixel( image, w, h) << 4;
+	    	else *tbuf++ |= TSXGetPixel( image, w, h) & 0x0f;
             }
             tbuf += pad;
         }
@@ -325,7 +325,7 @@
         for (h=0;h<height;h++)
         {
             for (w=0;w<bmp->bitmap.bmWidth;w++)
-                *tbuf++ = XGetPixel(image,w,h);
+                *tbuf++ = TSXGetPixel(image,w,h);
             tbuf += pad;
         }
         break;
@@ -335,7 +335,7 @@
         {
             for (w=0;w<bmp->bitmap.bmWidth;w++)
             {
-	    	long pixel = XGetPixel(image,w,h);
+	    	long pixel = TSXGetPixel(image,w,h);
 
 		*tbuf++ = pixel & 0xff;
 		*tbuf++ = (pixel>>8) & 0xff;
@@ -347,7 +347,7 @@
         {
             for (w=0;w<bmp->bitmap.bmWidth;w++)
             {
-	    	long pixel = XGetPixel(image,w,h);
+	    	long pixel = TSXGetPixel(image,w,h);
 
 		*tbuf++ = pixel & 0xff;
 		*tbuf++ = (pixel>> 8) & 0xff;
@@ -356,7 +356,7 @@
             tbuf += pad;
 	}
     }
-    XDestroyImage( image );
+    TSXDestroyImage( image );
     GDI_HEAP_UNLOCK( hbitmap );
     return height * bmp->bitmap.bmWidthBytes;
 }
@@ -411,7 +411,7 @@
 
     widthbytes	= DIB_GetXImageWidthBytes(bmp->bitmap.bmWidth,bmp->bitmap.bmBitsPixel);
     tmpbuffer	= (LPBYTE)xmalloc(widthbytes*height);
-    image = XCreateImage( display, DefaultVisualOfScreen(screen),
+    image = TSXCreateImage( display, DefaultVisualOfScreen(screen),
 		  bmp->bitmap.bmBitsPixel, ZPixmap, 0, tmpbuffer,
 		  bmp->bitmap.bmWidth,height,32,widthbytes
     );
@@ -425,7 +425,7 @@
         {
             for (w=0;w<bmp->bitmap.bmWidth;w++)
             {
-                XPutPixel(image,w,h,(sbuf[0]>>(7-(w&7))) & 1);
+                TSXPutPixel(image,w,h,(sbuf[0]>>(7-(w&7))) & 1);
                 if ((w&7) == 7)
                     sbuf++;
             }
@@ -437,8 +437,8 @@
         {
             for (w=0;w<bmp->bitmap.bmWidth;w++)
             {
-                if (!(w & 1)) XPutPixel( image, w, h, *sbuf >> 4 );
-                else XPutPixel( image, w, h, *sbuf++ & 0xf );
+                if (!(w & 1)) TSXPutPixel( image, w, h, *sbuf >> 4 );
+                else TSXPutPixel( image, w, h, *sbuf++ & 0xf );
             }
             sbuf += pad;
         }
@@ -447,7 +447,7 @@
         for (h=0;h<height;h++)
         {
             for (w=0;w<bmp->bitmap.bmWidth;w++)
-                XPutPixel(image,w,h,*sbuf++);
+                TSXPutPixel(image,w,h,*sbuf++);
             sbuf += pad;
         }
         break;
@@ -457,7 +457,7 @@
         {
             for (w=0;w<bmp->bitmap.bmWidth;w++)
             {
-                XPutPixel(image,w,h,sbuf[1]*256+sbuf[0]);
+                TSXPutPixel(image,w,h,sbuf[1]*256+sbuf[0]);
                 sbuf+=2;
             }
         }
@@ -467,7 +467,7 @@
         {
             for (w=0;w<bmp->bitmap.bmWidth;w++)
             {
-                XPutPixel(image,w,h,(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]);
+                TSXPutPixel(image,w,h,(sbuf[2]<<16)+(sbuf[1]<<8)+sbuf[0]);
                 sbuf += 3;
             }
             sbuf += pad;
@@ -481,7 +481,7 @@
     descr.height = height;
     CALL_LARGE_STACK( XPutImage_wrapper, &descr );
 
-    XDestroyImage( image ); /* frees tmpbuffer too */
+    TSXDestroyImage( image ); /* frees tmpbuffer too */
     GDI_HEAP_UNLOCK( hbitmap );
     return height * bmp->bitmap.bmWidthBytes;
 }
@@ -510,7 +510,7 @@
 	
 }
 /**********************************************************************
- *	    LoadImageA    (USER32.364)
+ *	    LoadImage32A    (USER32.364)
  * FIXME: implementation still lacks nearly all features, see LR_*
  * defines in windows.h
  */
@@ -699,10 +699,10 @@
 {
 #ifdef PRELIMINARY_WING16_SUPPORT
     if( bmp->bitmap.bmBits )
- 	XShmDetach( display, (XShmSegmentInfo*)bmp->bitmap.bmBits );
+ 	TSXShmDetach( display, (XShmSegmentInfo*)bmp->bitmap.bmBits );
 #endif
 
-    XFreePixmap( display, bmp->pixmap );
+    TSXFreePixmap( display, bmp->pixmap );
 #ifdef PRELIMINARY_WING16_SUPPORT
     if( bmp->bitmap.bmBits )
     {
diff --git a/objects/brush.c b/objects/brush.c
index 184eeea..88a232b 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -102,7 +102,7 @@
       GDI_HEAP_UNLOCK( hbitmap );
       return 0;
     }
-    XCopyArea( display, bmp->pixmap, newbmp->pixmap, BITMAP_GC(bmp),
+    TSXCopyArea( display, bmp->pixmap, newbmp->pixmap, BITMAP_GC(bmp),
 	       0, 0, bmp->bitmap.bmWidth, bmp->bitmap.bmHeight, 0, 0 );
     GDI_HEAP_UNLOCK( hbitmap );
     GDI_HEAP_UNLOCK( logbrush.lbHatch );
diff --git a/objects/color.c b/objects/color.c
index b07b790..5476a75 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -6,7 +6,7 @@
  */
 
 #include <stdlib.h>
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 #include <stdio.h>
 #include <string.h>
 #include "windows.h"
@@ -237,7 +237,7 @@
 			    COLOR_sysPal[idx].peGreen << 8,
 			    COLOR_sysPal[idx].peGreen << 8,
 			    (DoRed | DoGreen | DoBlue) };
-	   XStoreColor(display, cSpace.colorMap, &color);
+	   TSXStoreColor(display, cSpace.colorMap, &color);
 	 }
 
 	 idx = COLOR_freeList[idx];
@@ -258,11 +258,11 @@
 	{
 	  xc.pixel = i;
 
-	  XQueryColor(display, cSpace.colorMap, &xc);
+	  TSXQueryColor(display, cSpace.colorMap, &xc);
 	  r = xc.red>>8; g = xc.green>>8; b = xc.blue>>8;
 
 	  if( xc.pixel < 256 && COLOR_CheckSysColor(RGB(r, g, b)) &&
-	      XAllocColor(display, cSpace.colorMap, &xc) )
+	      TSXAllocColor(display, cSpace.colorMap, &xc) )
 	  {
 	     COLOR_PixelToPalette[xc.pixel] = idx;
 	     COLOR_PaletteToPixel[idx] = xc.pixel;
@@ -313,7 +313,7 @@
 
        color.flags = DoRed | DoGreen | DoBlue;
        color.pixel = i;
-       XStoreColor(display, cs->colorMap, &color);
+       TSXStoreColor(display, cs->colorMap, &color);
 
        /* Set EGA mapping if color is from the first or last eight */
 
@@ -359,7 +359,7 @@
         color.blue  = __sysPalTemplate[i].peBlue * 65535 / 255;
         color.flags = DoRed | DoGreen | DoBlue;
 
-        if (!XAllocColor( display, cSpace.colorMap, &color ))
+        if (!TSXAllocColor( display, cSpace.colorMap, &color ))
         { 
 	     XColor	best, c;
 	     
@@ -388,7 +388,7 @@
 	     best.pixel = best.red = best.green = best.blue = 0;
 	     for( c.pixel = 0, diff = 0x7fffffff; c.pixel < max; c.pixel += step )
 	     {
-		XQueryColor(display, cSpace.colorMap, &c);
+		TSXQueryColor(display, cSpace.colorMap, &c);
 		r = (c.red - color.red)>>8; 
 		g = (c.green - color.green)>>8; 
 		b = (c.blue - color.blue)>>8;
@@ -396,7 +396,7 @@
 		if( r < diff ) { best = c; diff = r; }
 	     }
 
-	     if( XAllocColor(display, cSpace.colorMap, &best) )
+	     if( TSXAllocColor(display, cSpace.colorMap, &best) )
 		 color.pixel = best.pixel;
 	     else color.pixel = (i < NB_RESERVED_COLORS/2)? bp : wp;
         }
@@ -424,7 +424,7 @@
 
 	/* comment this out if you want to debug palette init */
 
-	XGrabServer(display);
+	TSXGrabServer(display);
 
 	/* let's become the first client that actually follows 
 	 * X guidelines and does binary search...
@@ -435,12 +435,12 @@
           {
              c_val = (c_max + c_min)/2 + (c_max + c_min)%2;
 
-             if( !XAllocColorCells(display, cs->colorMap, False,
+             if( !TSXAllocColorCells(display, cs->colorMap, False,
                                    plane_masks, 0, pixDynMapping, c_val) )
                  c_max = c_val - 1;
              else
                {
-                 XFreeColors(display, cs->colorMap, pixDynMapping, c_val, 0);
+                 TSXFreeColors(display, cs->colorMap, pixDynMapping, c_val, 0);
                  c_min = c_val;
                }
           }
@@ -451,7 +451,7 @@
 	c_min = (c_min/2) + (c_min/2);		/* need even set for split palette */
 
 	if( c_min > 0 )
-	  if( !XAllocColorCells(display, cs->colorMap, False,
+	  if( !TSXAllocColorCells(display, cs->colorMap, False,
                                 plane_masks, 0, pixDynMapping, c_min) )
 	    {
 	      fprintf(stderr,"Inexplicable failure during colorcell allocation.\n");
@@ -460,7 +460,7 @@
 
         cs->size = c_min + NB_RESERVED_COLORS;
 
-	XUngrabServer(display);
+	TSXUngrabServer(display);
 
 	dprintf_palette(stddeb,"adjusted size %i colorcells\n", cs->size);
      }
@@ -595,7 +595,7 @@
 	{
 	    XSetWindowAttributes win_attr;
 
-	    cSpace.colorMap = XCreateColormap( display, rootWindow,
+	    cSpace.colorMap = TSXCreateColormap( display, rootWindow,
 						 visual, AllocAll );
 	    if (cSpace.colorMap)
 	    {
@@ -608,7 +608,7 @@
 	        if( rootWindow != DefaultRootWindow(display) )
 	        {
 		    win_attr.colormap = cSpace.colorMap;
-		    XChangeWindowAttributes( display, rootWindow,
+		    TSXChangeWindowAttributes( display, rootWindow,
 					 CWColormap, &win_attr );
 		}
 		break;
@@ -630,17 +630,17 @@
 	/* FIXME: hack to detect XFree32 XF_VGA16 ... We just have
 	 * depths 1 and 4
 	 */
-	depths=XListDepths(display,DefaultScreen(display),&nrofdepths);
+	depths=TSXListDepths(display,DefaultScreen(display),&nrofdepths);
 	if ((nrofdepths==2) && ((depths[0]==4) || depths[1]==4)) {
 	    cSpace.monoPlane = 1;
 	    for( white = cSpace.size - 1; !(white & 1); white >>= 1 )
 	        cSpace.monoPlane++;
     	    cSpace.flags = (white & mask) ? COLOR_WHITESET : 0;
 	    cSpace.colorMap = DefaultColormapOfScreen( screen );
-	    XFree(depths);
+	    TSXFree(depths);
 	    break;
 	}
-	XFree(depths);
+	TSXFree(depths);
         cSpace.colorMap = DefaultColormapOfScreen( screen );
         cSpace.flags |= COLOR_FIXED;
         COLOR_Computeshifts(visual->red_mask, &COLOR_Redshift, &COLOR_Redmax);
@@ -678,7 +678,7 @@
 void COLOR_Cleanup(void)
 {
   if( COLOR_gapFilled )
-      XFreeColors(display, cSpace.colorMap, 
+      TSXFreeColors(display, cSpace.colorMap, 
 		  (unsigned long*)(COLOR_PaletteToPixel + COLOR_gapStart), 
 		  COLOR_gapFilled, 0);
 }
@@ -842,7 +842,7 @@
 		   ((COLOR_PixelToPalette)?COLOR_PixelToPalette[pixel]:pixel)) ) & 0x00ffffff;
 
     color.pixel = pixel;
-    XQueryColor(display, cSpace.colorMap, &color);
+    TSXQueryColor(display, cSpace.colorMap, &color);
     return RGB(color.red >> 8, color.green >> 8, color.blue >> 8);
 }
 
@@ -1048,7 +1048,7 @@
                     color.green = palPtr->logpalette.palPalEntry[uStart].peGreen << 8;
                     color.blue = palPtr->logpalette.palPalEntry[uStart].peBlue << 8;
                     color.flags = DoRed | DoGreen | DoBlue;
-                    XStoreColor(display, cSpace.colorMap, &color);
+                    TSXStoreColor(display, cSpace.colorMap, &color);
 
                     COLOR_sysPal[index] = palPtr->logpalette.palPalEntry[uStart];
                     COLOR_sysPal[index].peFlags = flag;
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index a7e77c4..e2a183a 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -981,12 +981,12 @@
         static const char data[] = { 0 };
 
         bg.red = bg.green = bg.blue = 0x0000;
-        pixmapBits = XCreateBitmapFromData( display, rootWindow, data, 1, 1 );
+        pixmapBits = TSXCreateBitmapFromData( display, rootWindow, data, 1, 1 );
         if (pixmapBits)
         {
-            cursor = XCreatePixmapCursor( display, pixmapBits, pixmapBits,
+            cursor = TSXCreatePixmapCursor( display, pixmapBits, pixmapBits,
                                           &bg, &bg, 0, 0 );
-            XFreePixmap( display, pixmapBits );
+            TSXFreePixmap( display, pixmapBits );
         }
     }
     else  /* Create the X cursor from the bits */
@@ -1008,30 +1008,29 @@
 	 *	 as the Windows cursor data). Perhaps use a more generic
 	 *	 algorithm here.
 	 */
-        pixmapAll = XCreatePixmap( display, rootWindow,
+        pixmapAll = TSXCreatePixmap( display, rootWindow,
                                    ptr->nWidth, ptr->nHeight * 2, 1 );
-        image = XCreateImage( display, DefaultVisualOfScreen(screen),
+        image = TSXCreateImage( display, DefaultVisualOfScreen(screen),
                               1, ZPixmap, 0, (char *)(ptr + 1), ptr->nWidth,
                               ptr->nHeight * 2, 16, ptr->nWidthBytes);
         if (image)
         {
-            extern void _XInitImageFuncPtrs( XImage* );
             image->byte_order = MSBFirst;
             image->bitmap_bit_order = MSBFirst;
             image->bitmap_unit = 16;
-            _XInitImageFuncPtrs(image);
+            TS_XInitImageFuncPtrs(image);
             if (pixmapAll)
-                XPutImage( display, pixmapAll, BITMAP_monoGC, image,
+                TSXPutImage( display, pixmapAll, BITMAP_monoGC, image,
                            0, 0, 0, 0, ptr->nWidth, ptr->nHeight * 2 );
             image->data = NULL;
-            XDestroyImage( image );
+            TSXDestroyImage( image );
         }
 
         /* Now create the 2 pixmaps for bits and mask */
 
-        pixmapBits = XCreatePixmap( display, rootWindow,
+        pixmapBits = TSXCreatePixmap( display, rootWindow,
                                     ptr->nWidth, ptr->nHeight, 1 );
-        pixmapMask = XCreatePixmap( display, rootWindow,
+        pixmapMask = TSXCreatePixmap( display, rootWindow,
                                     ptr->nWidth, ptr->nHeight, 1 );
 
         /* Make sure everything went OK so far */
@@ -1060,39 +1059,39 @@
              * I don't know if it's correct per the X spec, but maybe
              * we ought to take advantage of it.  -- AJ
              */
-            XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC,
+            TSXCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC,
                        0, 0, ptr->nWidth, ptr->nHeight, 0, 0 );
-            XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC,
+            TSXCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC,
                        0, 0, ptr->nWidth, ptr->nHeight, 0, 0 );
-            XSetFunction( display, BITMAP_monoGC, GXandReverse );
-            XCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC,
+            TSXSetFunction( display, BITMAP_monoGC, GXandReverse );
+            TSXCopyArea( display, pixmapAll, pixmapBits, BITMAP_monoGC,
                        0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 );
-            XSetFunction( display, BITMAP_monoGC, GXorReverse );
-            XCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC,
+            TSXSetFunction( display, BITMAP_monoGC, GXorReverse );
+            TSXCopyArea( display, pixmapAll, pixmapMask, BITMAP_monoGC,
                        0, ptr->nHeight, ptr->nWidth, ptr->nHeight, 0, 0 );
-            XSetFunction( display, BITMAP_monoGC, GXcopy );
+            TSXSetFunction( display, BITMAP_monoGC, GXcopy );
             fg.red = fg.green = fg.blue = 0xffff;
             bg.red = bg.green = bg.blue = 0x0000;
-            cursor = XCreatePixmapCursor( display, pixmapBits, pixmapMask,
+            cursor = TSXCreatePixmapCursor( display, pixmapBits, pixmapMask,
                                 &fg, &bg, ptr->ptHotSpot.x, ptr->ptHotSpot.y );
         }
 
         /* Now free everything */
 
-        if (pixmapAll) XFreePixmap( display, pixmapAll );
-        if (pixmapBits) XFreePixmap( display, pixmapBits );
-        if (pixmapMask) XFreePixmap( display, pixmapMask );
+        if (pixmapAll) TSXFreePixmap( display, pixmapAll );
+        if (pixmapBits) TSXFreePixmap( display, pixmapBits );
+        if (pixmapMask) TSXFreePixmap( display, pixmapMask );
         GlobalUnlock16( hCursor );
     }
 
     if (cursor == None) return FALSE;
-    if (CURSORICON_XCursor != None) XFreeCursor( display, CURSORICON_XCursor );
+    if (CURSORICON_XCursor != None) TSXFreeCursor( display, CURSORICON_XCursor );
     CURSORICON_XCursor = cursor;
 
     if (rootWindow != DefaultRootWindow(display))
     {
         /* Set the cursor on the desktop window */
-        XDefineCursor( display, rootWindow, cursor );
+        TSXDefineCursor( display, rootWindow, cursor );
     }
     else
     {
@@ -1101,7 +1100,7 @@
         while(hwnd)
         {
             Window win = WIN_GetXWindow( hwnd );
-            if (win) XDefineCursor( display, win, cursor );
+            if (win) TSXDefineCursor( display, win, cursor );
             hwnd = GetWindow32( hwnd, GW_HWNDNEXT );
         }
     }
@@ -1151,7 +1150,7 @@
 BOOL32 WINAPI SetCursorPos32( INT32 x, INT32 y )
 {
     dprintf_cursor( stddeb, "SetCursorPos: x=%d y=%d\n", x, y );
-    XWarpPointer( display, rootWindow, rootWindow, 0, 0, 0, 0, x, y );
+    TSXWarpPointer( display, rootWindow, rootWindow, 0, 0, 0, 0, x, y );
     return TRUE;
 }
 
@@ -1237,7 +1236,7 @@
     unsigned int mousebut;
 
     if (!pt) return;
-    if (!XQueryPointer( display, rootWindow, &root, &child,
+    if (!TSXQueryPointer( display, rootWindow, &root, &child,
 		        &rootX, &rootY, &childX, &childY, &mousebut ))
 	pt->x = pt->y = 0;
     else
diff --git a/objects/dc.c b/objects/dc.c
index 7ff616d..b2041ef 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -14,6 +14,7 @@
 #include "color.h"
 #include "debug.h"
 #include "font.h"
+#include "winerror.h"
 #include "x11font.h"
 
 extern void CLIPPING_UpdateGCRegion( DC * dc );     /* objects/clipping.c */
@@ -136,6 +137,14 @@
     win_dc_info->DCOrgY          = 0;
     win_dc_info->CursPosX        = 0;
     win_dc_info->CursPosY        = 0;
+    win_dc_info->ArcDirection    = AD_COUNTERCLOCKWISE;
+    win_dc_info->UseWorldXform   = FALSE;
+    win_dc_info->WorldXform.eM11 = 1.0f;
+    win_dc_info->WorldXform.eM12 = 0.0f;
+    win_dc_info->WorldXform.eM21 = 0.0f;
+    win_dc_info->WorldXform.eM22 = 1.0f;
+    win_dc_info->WorldXform.eDx  = 0.0f;
+    win_dc_info->WorldXform.eDy  = 0.0f;
 
     PATH_InitGdiPath(&win_dc_info->path);
 }
@@ -267,15 +276,15 @@
         {
             register int x, y;
             XImage *image;
-            pixmap = XCreatePixmap( display, rootWindow, 8, 8, screenDepth );
-            image = XGetImage( display, dc->u.x.brush.pixmap, 0, 0, 8, 8,
+            pixmap = TSXCreatePixmap( display, rootWindow, 8, 8, screenDepth );
+            image = TSXGetImage( display, dc->u.x.brush.pixmap, 0, 0, 8, 8,
                                AllPlanes, ZPixmap );
             for (y = 0; y < 8; y++)
                 for (x = 0; x < 8; x++)
-                    XPutPixel( image, x, y,
-                               COLOR_PixelToPalette[XGetPixel( image, x, y)] );
-            XPutImage( display, pixmap, gc, image, 0, 0, 0, 0, 8, 8 );
-            XDestroyImage( image );
+                    TSXPutPixel( image, x, y,
+                               COLOR_PixelToPalette[TSXGetPixel( image, x, y)] );
+            TSXPutImage( display, pixmap, gc, image, 0, 0, 0, 0, 8, 8 );
+            TSXDestroyImage( image );
             val.tile = pixmap;
         }
         else val.tile = dc->u.x.brush.pixmap;
@@ -289,11 +298,11 @@
     val.ts_x_origin = dc->w.DCOrgX + dc->w.brushOrgX;
     val.ts_y_origin = dc->w.DCOrgY + dc->w.brushOrgY;
     val.fill_rule = (dc->w.polyFillMode==WINDING) ? WindingRule : EvenOddRule;
-    XChangeGC( display, gc, 
+    TSXChangeGC( display, gc, 
 	       GCFunction | GCForeground | GCBackground | GCFillStyle |
 	       GCFillRule | GCTileStipXOrigin | GCTileStipYOrigin | mask,
 	       &val );
-    if (pixmap) XFreePixmap( display, pixmap );
+    if (pixmap) TSXFreePixmap( display, pixmap );
     return TRUE;
 }
 
@@ -351,7 +360,7 @@
     val.fill_style = FillSolid;
     if ((dc->u.x.pen.style!=PS_SOLID) && (dc->u.x.pen.style!=PS_INSIDEFRAME))
     {
-	XSetDashes( display, dc->u.x.gc, 0,
+	TSXSetDashes( display, dc->u.x.gc, 0,
 		    dc->u.x.pen.dashes, dc->u.x.pen.dash_len );
 	val.line_style = (dc->w.backgroundMode == OPAQUE) ?
 	                      LineDoubleDash : LineOnOffDash;
@@ -384,7 +393,7 @@
     default:
 	val.join_style = JoinRound;
     }
-    XChangeGC( display, dc->u.x.gc, 
+    TSXChangeGC( display, dc->u.x.gc, 
 	       GCFunction | GCForeground | GCBackground | GCLineWidth |
 	       GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle, &val );
     return TRUE;
@@ -413,7 +422,7 @@
 	val.fill_style = FillSolid;
 	val.font       = xfs->fid;
 
-	XChangeGC( display, dc->u.x.gc,
+	TSXChangeGC( display, dc->u.x.gc,
 		   GCFunction | GCForeground | GCBackground | GCFillStyle |
 		   GCFont, &val );
 	return TRUE;
@@ -470,10 +479,14 @@
     newdc->w.breakExtra      = dc->w.breakExtra;
     newdc->w.breakRem        = dc->w.breakRem;
     newdc->w.MapMode         = dc->w.MapMode;
+    newdc->w.GraphicsMode    = dc->w.GraphicsMode;
     newdc->w.DCOrgX          = dc->w.DCOrgX;
     newdc->w.DCOrgY          = dc->w.DCOrgY;
     newdc->w.CursPosX        = dc->w.CursPosX;
     newdc->w.CursPosY        = dc->w.CursPosY;
+    newdc->w.ArcDirection    = dc->w.ArcDirection;
+    newdc->w.UseWorldXform   = dc->w.UseWorldXform;
+    newdc->w.WorldXform      = dc->w.WorldXform;
     newdc->wndOrgX           = dc->wndOrgX;
     newdc->wndOrgY           = dc->wndOrgY;
     newdc->wndExtX           = dc->wndExtX;
@@ -547,10 +560,14 @@
     dc->w.breakExtra      = dcs->w.breakExtra;
     dc->w.breakRem        = dcs->w.breakRem;
     dc->w.MapMode         = dcs->w.MapMode;
+    dc->w.GraphicsMode    = dcs->w.GraphicsMode;
     dc->w.DCOrgX          = dcs->w.DCOrgX;
     dc->w.DCOrgY          = dcs->w.DCOrgY;
     dc->w.CursPosX        = dcs->w.CursPosX;
     dc->w.CursPosY        = dcs->w.CursPosY;
+    dc->w.ArcDirection    = dcs->w.ArcDirection;
+    dc->w.UseWorldXform   = dcs->w.UseWorldXform;
+    dc->w.WorldXform      = dcs->w.WorldXform;
 
     dc->wndOrgX           = dcs->wndOrgX;
     dc->wndOrgY           = dcs->wndOrgY;
@@ -1061,7 +1078,7 @@
        Window root;
        int w, h, border, depth;
        /* FIXME: this is not correct for managed windows */
-       XGetGeometry( display, dc->u.x.drawable, &root,
+       TSXGetGeometry( display, dc->u.x.drawable, &root,
                     &lpp->x, &lpp->y, &w, &h, &border, &depth );
     }
     else lpp->x = lpp->y = 0;
@@ -1117,6 +1134,13 @@
 {
     INT32 ret;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+
+    /* One would think that setting the graphics mode to GM_COMPATIBLE
+     * would also reset the world transformation matrix to the unity
+     * matrix. However, in Windows, this is not the case. This doesn't
+     * make a lot of sense to me, but that's the way it is.
+     */
+    
     if (!dc) return 0;
     if ((mode <= 0) || (mode > GM_LAST)) return 0;
     ret = dc->w.GraphicsMode;
@@ -1126,12 +1150,113 @@
 
 
 /***********************************************************************
+ *           GetArcDirection16    (GDI.524)
+ */
+INT16 WINAPI GetArcDirection16( HDC16 hdc )
+{
+    return GetArcDirection32( (HDC32)hdc );
+}
+
+
+/***********************************************************************
+ *           GetArcDirection32    (GDI32.141)
+ */
+INT32 WINAPI GetArcDirection32( HDC32 hdc )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    
+    if (!dc)
+        return 0;
+
+    return dc->w.ArcDirection;
+}
+
+
+/***********************************************************************
+ *           SetArcDirection16    (GDI.525)
+ */
+INT16 WINAPI SetArcDirection16( HDC16 hdc, INT16 nDirection )
+{
+    return SetArcDirection32( (HDC32)hdc, (INT32)nDirection );
+}
+
+
+/***********************************************************************
+ *           SetArcDirection32    (GDI32.302)
+ */
+INT32 WINAPI SetArcDirection32( HDC32 hdc, INT32 nDirection )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    INT32 nOldDirection;
+    
+    if (!dc)
+        return 0;
+
+    if (nDirection!=AD_COUNTERCLOCKWISE && nDirection!=AD_CLOCKWISE)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+	return 0;
+    }
+
+    nOldDirection = dc->w.ArcDirection;
+    dc->w.ArcDirection = nDirection;
+
+    return nOldDirection;
+}
+
+
+/***********************************************************************
  *           GetWorldTransform    (GDI32.244)
  */
 BOOL32 WINAPI GetWorldTransform( HDC32 hdc, LPXFORM xform )
+/* FIXME: Check that SetLastError is being called correctly */
 {
-    fprintf( stdnimp, "GetWorldTransform: empty stub\n" );
-    return FALSE;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    
+    if (!dc)
+        /* FIXME: Call SetLastError? */
+        return FALSE;
+    if (!xform)
+        /* FIXME: Call SetLastError? */
+	return FALSE;
+
+    *xform = dc->w.WorldXform;
+    
+    return TRUE;
+}
+
+
+/***********************************************************************
+ *           SetWorldTransform    (GDI32.346)
+ */
+BOOL32 WINAPI SetWorldTransform( HDC32 hdc, const XFORM *xform )
+{
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    
+    if (!dc)
+    {
+        SetLastError( ERROR_INVALID_HANDLE );
+        return FALSE;
+    }
+
+    if (!xform)
+	return FALSE;
+    
+    /* Check that graphics mode is GM_ADVANCED */
+    if (dc->w.GraphicsMode!=GM_ADVANCED)
+       return FALSE;
+
+    dc->w.WorldXform = *xform;
+
+    /* We only have to use the new world transform if it's not the
+     * identity transformation
+     */
+    dc->w.UseWorldXform=
+       (xform->eM11!=1.0f || xform->eM12!=0.0f ||
+        xform->eM21!=0.0f || xform->eM22!=1.0f ||
+        xform->eDx!=0.0f  || xform->eDy!=0.0f);
+    
+    return TRUE;
 }
 
 
diff --git a/objects/dib.c b/objects/dib.c
index 8955624..f802f14 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -6,8 +6,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xutil.h"
 #include "dc.h"
 #include "bitmap.h"
 #include "callback.h"
@@ -54,11 +54,11 @@
 
     for( i = 0; bitmapDepthTable[i]; i++ )
     {
-	 testimage = XCreateImage(display, DefaultVisualOfScreen(screen),
+	 testimage = TSXCreateImage(display, DefaultVisualOfScreen(screen),
 			 bitmapDepthTable[i], ZPixmap, 0, NULL, 1, 1, 32, 20 );
 	 if( testimage ) ximageDepthTable[i] = testimage->bits_per_pixel;
 	 else return FALSE;
-	 XDestroyImage(testimage);
+	 TSXDestroyImage(testimage);
     }
     return TRUE;
 }
@@ -252,25 +252,25 @@
     for (i = dstwidth/8, x = left&~7; (i > 0); i--)
     {
 	pix = *bits++;
-	XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
-	XPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
-	XPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
-	XPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
-	XPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
-	XPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
-	XPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
-	XPutPixel( bmpImage, x++, h, colors[pix & 1] );
+	TSXPutPixel( bmpImage, x++, h, colors[pix >> 7] );
+	TSXPutPixel( bmpImage, x++, h, colors[(pix >> 6) & 1] );
+	TSXPutPixel( bmpImage, x++, h, colors[(pix >> 5) & 1] );
+	TSXPutPixel( bmpImage, x++, h, colors[(pix >> 4) & 1] );
+	TSXPutPixel( bmpImage, x++, h, colors[(pix >> 3) & 1] );
+	TSXPutPixel( bmpImage, x++, h, colors[(pix >> 2) & 1] );
+	TSXPutPixel( bmpImage, x++, h, colors[(pix >> 1) & 1] );
+	TSXPutPixel( bmpImage, x++, h, colors[pix & 1] );
     }
     pix = *bits;
     switch(dstwidth & 7)
     {
-    case 7: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
-    case 6: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
-    case 5: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
-    case 4: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
-    case 3: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
-    case 2: XPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
-    case 1: XPutPixel( bmpImage, x++, h, colors[pix >> 7] );
+    case 7: TSXPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 6: TSXPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 5: TSXPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 4: TSXPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 3: TSXPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 2: TSXPutPixel( bmpImage, x++, h, colors[pix >> 7] ); pix <<= 1;
+    case 1: TSXPutPixel( bmpImage, x++, h, colors[pix >> 7] );
     }
 }
 
@@ -326,10 +326,10 @@
 	for (h = lines-1; h >= 0; h--) {
 	    for (i = dstwidth/2, x = left&~1; i > 0; i--) {
 		BYTE pix = *bits++;
-		XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
-		XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
+		TSXPutPixel( bmpImage, x++, h, colors[pix >> 4] );
+		TSXPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
 	    }
-	    if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
+	    if (dstwidth & 1) TSXPutPixel( bmpImage, x, h, colors[*bits >> 4] );
 	    srcbits += linebytes;
 	    bits	 = srcbits + (left >> 1);
 	}
@@ -338,10 +338,10 @@
 	for (h = 0; h < lines; h++) {
 	    for (i = dstwidth/2, x = left&~1; i > 0; i--) {
 		BYTE pix = *bits++;
-		XPutPixel( bmpImage, x++, h, colors[pix >> 4] );
-		XPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
+		TSXPutPixel( bmpImage, x++, h, colors[pix >> 4] );
+		TSXPutPixel( bmpImage, x++, h, colors[pix & 0x0f] );
 	    }
-	    if (dstwidth & 1) XPutPixel( bmpImage, x, h, colors[*bits >> 4] );
+	    if (dstwidth & 1) TSXPutPixel( bmpImage, x, h, colors[*bits >> 4] );
 	    srcbits += linebytes;
 	    bits	 = srcbits + (left >> 1);
 	}
@@ -375,11 +375,11 @@
 		if (length) {	/* encoded */
 			c = *bits++;
 			while (length--) {
-				XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
+				TSXPutPixel(bmpImage, x++, lines, colors[c >> 4]);
 				check_xy(x, y);
 				if (length) {
 					length--;
-					XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
+					TSXPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
 					check_xy(x, y);
 				}
 			}
@@ -402,11 +402,11 @@
 				default: /* absolute */
 					while (length--) {
 						c = *bits++;
-						XPutPixel(bmpImage, x++, lines, colors[c >> 4]);
+						TSXPutPixel(bmpImage, x++, lines, colors[c >> 4]);
 						check_xy(x, y);
 						if (length) {
 							length--;
-							XPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
+							TSXPutPixel(bmpImage, x++, lines, colors[c & 0xf]);
 							check_xy(x, y);
 						}
 					}
@@ -438,7 +438,7 @@
     if (lines > 0) {
 	for (h = lines - 1; h >= 0; h--) {
 	    for (x = left; x < dstwidth; x++, bits++) {
-		XPutPixel( bmpImage, x, h, colors[*bits] );
+		TSXPutPixel( bmpImage, x, h, colors[*bits] );
 	    }
 	    bits = (srcbits += linebytes) + left;
 	}
@@ -446,7 +446,7 @@
 	lines = -lines;
 	for (h = 0; h < lines; h++) {
 	    for (x = left; x < dstwidth; x++, bits++) {
-		XPutPixel( bmpImage, x, h, colors[*bits] );
+		TSXPutPixel( bmpImage, x, h, colors[*bits] );
 	    }
 	    bits = (srcbits += linebytes) + left;
 	}
@@ -530,7 +530,7 @@
 		color = colors[color_index];
 
 		while(length--)
-		  XPutPixel(bmpImage, x++, line, color);
+		  TSXPutPixel(bmpImage, x++, line, color);
 	    }
 	  else 
 	    {    
@@ -595,7 +595,7 @@
 			  while(length--)
 			    {
 				color_index = (*pIn++);
-				XPutPixel(bmpImage, x++, line, 
+				TSXPutPixel(bmpImage, x++, line, 
 					  colors[color_index]);
 			    }
 			  
@@ -662,7 +662,7 @@
 		r = (BYTE) ((val & 0x7c00) >> 7);
 		g = (BYTE) ((val & 0x03e0) >> 2);
 		b = (BYTE) ((val & 0x001f) << 3);
-		XPutPixel( bmpImage, x, h,
+		TSXPutPixel( bmpImage, x, h,
 			   COLOR_ToPhysical(dc, RGB(r,g,b)) );
 	    }
 	    ptr = (LPWORD) (srcbits += linebytes) + left;
@@ -675,7 +675,7 @@
 		r = (BYTE) ((val & 0x7c00) >> 7);
 		g = (BYTE) ((val & 0x03e0) >> 2);
 		b = (BYTE) ((val & 0x001f) << 3);
-		XPutPixel( bmpImage, x, h,
+		TSXPutPixel( bmpImage, x, h,
 			   COLOR_ToPhysical(dc, RGB(r,g,b)) );
 	    }
 	    ptr = (LPWORD) (srcbits += linebytes) + left;
@@ -707,7 +707,7 @@
     if (lines > 0) {
 	for (h = lines - 1; h >= 0; h--) {
 	    for (x = left; x < dstwidth; x++, bits += 3) {
-		XPutPixel( bmpImage, x, h, 
+		TSXPutPixel( bmpImage, x, h, 
 			   COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
 	    }
 	    bits = (srcbits += linebytes) + left * 3;
@@ -716,7 +716,7 @@
 	lines = -lines;
 	for (h = 0; h < lines; h++) {
 	    for (x = left; x < dstwidth; x++, bits += 3) {
-		XPutPixel( bmpImage, x, h,
+		TSXPutPixel( bmpImage, x, h,
 			   COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
 	    }
 	    bits = (srcbits += linebytes) + left * 3;
@@ -745,7 +745,7 @@
     if (lines > 0) {
 	for (h = lines - 1; h >= 0; h--) {
 	    for (x = left; x < dstwidth; x++, bits += 4) {
-		XPutPixel( bmpImage, x, h, 
+		TSXPutPixel( bmpImage, x, h, 
 			   COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
 	    }
 	    bits = (srcbits += linebytes) + left * 4;
@@ -754,7 +754,7 @@
 	lines = -lines;
 	for (h = 0; h < lines; h++) {
 	    for (x = left; x < dstwidth; x++, bits += 4) {
-		XPutPixel( bmpImage, x, h,
+		TSXPutPixel( bmpImage, x, h,
 			   COLOR_ToPhysical(dc, RGB(bits[2],bits[1],bits[0])));
 	    }
 	    bits = (srcbits += linebytes) + left * 4;
@@ -831,10 +831,10 @@
         break;
     }
     if (colorMapping) HeapFree( GetProcessHeap(), 0, colorMapping );
-    XPutImage( display, descr->drawable, descr->gc, bmpImage,
+    TSXPutImage( display, descr->drawable, descr->gc, bmpImage,
                descr->xSrc, descr->ySrc, descr->xDest, descr->yDest,
                descr->width, descr->height );
-    XDestroyImage( bmpImage );
+    TSXDestroyImage( bmpImage );
     return lines;
 }
 
@@ -1000,7 +1000,7 @@
     if (!cx || !cy) return 0;
 
     DC_SetupGCForText( dc );  /* To have the correct colors */
-    XSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
+    TSXSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
 
     descr.dc        = dc;
     descr.bits      = bits;
@@ -1209,7 +1209,7 @@
 		for( y = yend - 1; (int)y >= (int)startscan; y-- )
 		{
 		   for( x = 0; x < xend; x++ )
-			*bbits++ = XGetPixel( bmpImage, x, y );
+			*bbits++ = TSXGetPixel( bmpImage, x, y );
 		   bbits += pad;
 		}
 		break;
@@ -1220,7 +1220,7 @@
 		   *bbits = 0;
 		   for( x = 0; x < xend; x++ ) {
 		   	
-			*bbits |= XGetPixel( bmpImage, x, y)<<(7-(x&7));
+			*bbits |= TSXGetPixel( bmpImage, x, y)<<(7-(x&7));
 			if ((x&7)==7) {
 			    bbits++;
 			    *bbits=0;
@@ -1236,7 +1236,7 @@
 		   *bbits = 0;
 		   for( x = 0; x < xend; x++ ) {
 		   	
-			*bbits |= XGetPixel( bmpImage, x, y)<<(4*(1-(x&1)));
+			*bbits |= TSXGetPixel( bmpImage, x, y)<<(4*(1-(x&1)));
 			if ((x&1)==1) {
 			    bbits++;
 			    *bbits=0;
@@ -1252,7 +1252,7 @@
 		{
 		   *bbits = 0;
 		   for( x = 0; x < xend; x++ ) {
-		   	unsigned long pixel=XGetPixel( bmpImage, x, y);
+		   	unsigned long pixel=TSXGetPixel( bmpImage, x, y);
 			*bbits++ = pixel & 0xff;
 			*bbits++ = (pixel >> 8) & 0xff;
 		   }
@@ -1265,7 +1265,7 @@
 		{
 		   *bbits = 0;
 		   for( x = 0; x < xend; x++ ) {
-		   	unsigned long pixel=XGetPixel( bmpImage, x, y);
+		   	unsigned long pixel=TSXGetPixel( bmpImage, x, y);
 			*bbits++ = (pixel >>16) & 0xff;
 			*bbits++ = (pixel >> 8) & 0xff;
 			*bbits++ =  pixel       & 0xff;
@@ -1278,7 +1278,7 @@
 		{
 		   *bbits = 0;
 		   for( x = 0; x < xend; x++ ) {
-		   	unsigned long pixel=XGetPixel( bmpImage, x, y);
+		   	unsigned long pixel=TSXGetPixel( bmpImage, x, y);
 			*bbits++ = (pixel >>16) & 0xff;
 			*bbits++ = (pixel >> 8) & 0xff;
 			*bbits++ =  pixel       & 0xff;
@@ -1292,7 +1292,7 @@
 	   	break;
 	}
 
-	XDestroyImage( bmpImage );
+	TSXDestroyImage( bmpImage );
 
 	info->bmiHeader.biCompression = 0;
     }
@@ -1432,8 +1432,8 @@
             /* FIXME: this is wrong! (bmBits is always NULL) */
             if (bits) *bits = bmp.bmBits;
 	    /* hmpf */
-	    fprintf(stderr,"allocating %d bytes of memory\n",bmi->bmiHeader.biWidth*bmi->bmiHeader.biHeight*4);
-	    if (bits) *bits = (LPBYTE)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,bmi->bmiHeader.biWidth*bmi->bmiHeader.biHeight*4);
+	    fprintf(stderr,"allocating %ld bytes of memory\n",bmi->bmiHeader.biWidth*bmi->bmiHeader.biHeight*4);
+	    if (bits) *bits = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,bmi->bmiHeader.biWidth*bmi->bmiHeader.biHeight*4);
             return res;
 	}
     }
diff --git a/objects/metafile.c b/objects/metafile.c
index 9fabc7c..b390b04 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -56,7 +56,7 @@
 
 
 /******************************************************************
- *         GetMetafile16   (GDI.124)
+ *         GetMetaFile16   (GDI.124)
  */
 HMETAFILE16 WINAPI GetMetaFile16( LPCSTR lpFilename )
 {
@@ -65,9 +65,14 @@
 
 
 /******************************************************************
- *         GetMetafile32A   (GDI32.197)
+ *         GetMetaFile32A   (GDI32.197)
+ *
+ *  Read a metafile from a file. Returns handle to a disk-based metafile.
  */
-HMETAFILE32 WINAPI GetMetaFile32A( LPCSTR lpFilename )
+HMETAFILE32 WINAPI GetMetaFile32A( 
+				  LPCSTR lpFilename 
+		      /* pointer to string containing filename to read */
+)
 {
   HMETAFILE16 hmf;
   METAHEADER *mh;
@@ -136,7 +141,7 @@
 
 
 /******************************************************************
- *         GetMetafile32W   (GDI32.199)
+ *         GetMetaFile32W   (GDI32.199)
  */
 HMETAFILE32 WINAPI GetMetaFile32W( LPCWSTR lpFilename )
 {
@@ -159,8 +164,25 @@
 
 /******************************************************************
  *         CopyMetaFile32A   (GDI32.23)
+ *
+ *  Copies the metafile corresponding to hSrcMetaFile to either
+ *  a disk file, if a filename is given, or to a new memory based
+ *  metafile, if lpFileName is NULL.
+ *
+ * RETURNS
+ *
+ *  Handle to metafile copy on success, NULL on failure.
+ *
+ * BUGS
+ *
+ *  Copying to disk returns NULL even if successful.
  */
-HMETAFILE32 WINAPI CopyMetaFile32A(HMETAFILE32 hSrcMetaFile, LPCSTR lpFilename)
+HMETAFILE32 WINAPI CopyMetaFile32A(
+				   HMETAFILE32 hSrcMetaFile, 
+				   /* handle of metafile to copy */
+				   LPCSTR lpFilename
+				   /* filename if copying to a file */
+)
 {
     HMETAFILE16 handle = 0;
     METAHEADER *mh;
@@ -214,7 +236,17 @@
 
 /******************************************************************
  *         IsValidMetaFile   (GDI.410)
- *         (This is not exactly what windows does, see "Undoc Win")
+ *
+ *  Attempts to check if a given metafile is correctly formatted.
+ *  Currently, the only things verified are several properties of the
+ *  header.
+ *
+ * RETURNS
+ *  TRUE if hmf passes some tests for being a valid metafile, FALSE otherwise.
+ *
+ * BUGS
+ *  This is not exactly what windows does, see _Undocumented_Windows_
+ *  for details.
  */
 
 BOOL16 WINAPI IsValidMetaFile(HMETAFILE16 hmf)
@@ -235,6 +267,7 @@
 
 /******************************************************************
  *         PlayMetaFile16   (GDI.123)
+ *
  */
 BOOL16 WINAPI PlayMetaFile16( HDC16 hdc, HMETAFILE16 hmf )
 {
@@ -243,8 +276,14 @@
 
 /******************************************************************
  *         PlayMetaFile32   (GDI32.265)
+ *
+ *  Renders the metafile specified by hmf in the DC specified by
+ *  hdc. Returns FALSE on failure, TRUE on success.
  */
-BOOL32 WINAPI PlayMetaFile32( HDC32 hdc, HMETAFILE32 hmf )
+BOOL32 WINAPI PlayMetaFile32( 
+			     HDC32 hdc, /* handle of DC to render in */
+			     HMETAFILE32 hmf /* handle of metafile to render */
+)
 {
     METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
     METARECORD *mr;
@@ -303,10 +342,24 @@
 
 /******************************************************************
  *            EnumMetaFile16   (GDI.175)
- *                                    Niels de carpentier, april 1996
+ *
+ *  Loop through the metafile records in hmf, calling the user-specified
+ *  function for each one, stopping when the user's function returns FALSE
+ *  (which is considered to be failure)
+ *  or when no records are left (which is considered to be success). 
+ *
+ * RETURNS
+ *  TRUE on success, FALSE on failure.
+ * 
+ * HISTORY
+ *   Niels de carpentier, april 1996
  */
-BOOL16 WINAPI EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf,
-                              MFENUMPROC16 lpEnumFunc, LPARAM lpData )
+BOOL16 WINAPI EnumMetaFile16( 
+			     HDC16 hdc, 
+			     HMETAFILE16 hmf,
+			     MFENUMPROC16 lpEnumFunc, 
+			     LPARAM lpData 
+)
 {
     METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
     METARECORD *mr;
@@ -319,6 +372,7 @@
     HBRUSH32 hBrush;
     HFONT32 hFont;
     DC *dc;
+    BOOL16 result = TRUE;
     
     dprintf_metafile(stddeb,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
 		     hdc, hmf, (DWORD)lpEnumFunc, lpData);
@@ -345,8 +399,11 @@
 	mr = (METARECORD *)((char *)mh + offset);
         if (!lpEnumFunc( hdc, (HANDLETABLE16 *)spht,
                          (METARECORD *)((UINT32)spRecord + offset),
-                         mh->mtNoObjects, (LONG)lpData))
-	    break;
+                         mh->mtNoObjects, (LONG)lpData)) {
+	  result = FALSE;
+	  break;
+	}
+	
 
 	offset += (mr->rdSize * 2);
     }
@@ -365,16 +422,37 @@
     /* free handle table */
     GlobalFree16(hHT);
 
-    return TRUE;
+    return result;
 }
 
 static BOOL32 MF_Meta_CreateRegion( METARECORD *mr, HRGN32 hrgn );
 
 /******************************************************************
  *             PlayMetaFileRecord16   (GDI.176)
+ *
+ *   Render a single metafile record specified by *mr in the DC hdc, while
+ *   using the handle table *ht, of length nHandles, 
+ *   to store metafile objects.
+ *
+ * BUGS
+ *  The following metafile records are unimplemented:
+ *
+ *  FRAMEREGION, DRAWTEXT, SETDIBTODEV, ANIMATEPALETTE, SETPALENTRIES,
+ *  RESIZEPALETTE, EXTFLOODFILL, RESETDC, STARTDOC, STARTPAGE, ENDPAGE,
+ *  ABORTDOC, ENDDOC, CREATEBRUSH, CREATEBITMAPINDIRECT, and CREATEBITMAP.
+ *
  */
-void WINAPI PlayMetaFileRecord16( HDC16 hdc, HANDLETABLE16 *ht, METARECORD *mr,
-                                  UINT16 nHandles )
+
+void WINAPI PlayMetaFileRecord16( 
+				 HDC16 hdc, 
+				 /* DC to render metafile into */
+				 HANDLETABLE16 *ht, 
+				 /* pointer to handle table for metafile objects */
+				 METARECORD *mr, 
+				 /* pointer to metafile record to render */
+				 UINT16 nHandles 
+				 /* size of handle table */
+)
 {
     short s1;
     HANDLE16 hndl;
@@ -820,22 +898,30 @@
 /******************************************************************
  *         GetMetaFileBits   (GDI.159)
  *
- * Trade in a meta file object handle for a handle to the meta file memory
+ * Trade in a metafile object handle for a handle to the metafile memory.
+ *
  */
 
-HGLOBAL16 WINAPI GetMetaFileBits(HMETAFILE16 hmf)
+HGLOBAL16 WINAPI GetMetaFileBits(
+				 HMETAFILE16 hmf /* metafile handle */
+				 )
 {
     dprintf_metafile(stddeb,"GetMetaFileBits: hMem out: %04x\n", hmf);
-
     return hmf;
 }
 
 /******************************************************************
  *         SetMetaFileBits   (GDI.160)
  *
- * Trade in a meta file memory handle for a handle to a meta file object
+ * Trade in a metafile memory handle for a handle to a metafile object.
+ * The memory region should hold a proper metafile, otherwise
+ * problems will occur when it is used. Validity of the memory is not
+ * checked. The function is essentially just the identity function.
  */
-HMETAFILE16 WINAPI SetMetaFileBits( HGLOBAL16 hMem )
+HMETAFILE16 WINAPI SetMetaFileBits( 
+				   HGLOBAL16 hMem 
+			/* handle to a memory region holding a metafile */
+)
 {
     dprintf_metafile(stddeb,"SetMetaFileBits: hmf out: %04x\n", hMem);
 
@@ -844,6 +930,13 @@
 
 /******************************************************************
  *         SetMetaFileBitsBetter   (GDI.196)
+ *
+ * Trade in a metafile memory handle for a handle to a metafile object,
+ * making a cursory check (using IsValidMetaFile()) that the memory
+ * handle points to a valid metafile.
+ *
+ * RETURNS
+ *  Handle to a metafile on success, NULL on failure..
  */
 HMETAFILE16 WINAPI SetMetaFileBitsBetter( HMETAFILE16 hMeta )
 {
diff --git a/objects/oembitmap.c b/objects/oembitmap.c
index 3a7bcaa..9fb5881 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -7,9 +7,9 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/xpm.h>
+#include "ts_xlib.h"
+#include "ts_xutil.h"
+#include "ts_xpm.h"
 #include "gdi.h"
 #include "bitmap.h"
 #include "callback.h"
@@ -330,14 +330,14 @@
     int err;
 
     attrs = (XpmAttributes *)HEAP_xalloc( GetProcessHeap(), 0,
-                                          XpmAttributesSize() );
+                                          TSXpmAttributesSize() );
     attrs->valuemask    = XpmColormap | XpmDepth | XpmColorSymbols |XpmHotspot;
     attrs->colormap     = COLOR_GetColormap();
     attrs->depth        = descr->color ? screenDepth : 1;
     attrs->colorsymbols = (attrs->depth > 1) ? OBM_Colors : OBM_BlackAndWhite;
     attrs->numsymbols   = (attrs->depth > 1) ? NB_COLOR_SYMBOLS : 2;
         
-    err = XpmCreatePixmapFromData( display, rootWindow, descr->data,
+    err = TSXpmCreatePixmapFromData( display, rootWindow, descr->data,
                                    &pixmap, &pixmask, attrs );
 
     if (err != XpmSuccess)
@@ -355,8 +355,8 @@
     HeapFree( GetProcessHeap(), 0, attrs );
     if (!descr->bitmap)
     {
-        if (pixmap) XFreePixmap( display, pixmap );
-        if (pixmask) XFreePixmap( display, pixmask );
+        if (pixmap) TSXFreePixmap( display, pixmap );
+        if (pixmask) TSXFreePixmap( display, pixmask );
         if (descr->bitmap) GDI_FreeObject( descr->bitmap );
         if (descr->need_mask && descr->mask) GDI_FreeObject( descr->mask );
         return FALSE;
@@ -456,23 +456,23 @@
     {
           /* Invert the mask */
 
-        XSetFunction( display, BITMAP_monoGC, GXinvert );
-        XFillRectangle( display, bmpAnd->pixmap, BITMAP_monoGC, 0, 0,
+        TSXSetFunction( display, BITMAP_monoGC, GXinvert );
+        TSXFillRectangle( display, bmpAnd->pixmap, BITMAP_monoGC, 0, 0,
                         bmpAnd->bitmap.bmWidth, bmpAnd->bitmap.bmHeight );
-        XSetFunction( display, BITMAP_monoGC, GXcopy );
+        TSXSetFunction( display, BITMAP_monoGC, GXcopy );
 
           /* Set the masked pixels to black */
 
         if (bmpXor->bitmap.bmBitsPixel != 1)
         {
-            XSetForeground( display, BITMAP_colorGC,
+            TSXSetForeground( display, BITMAP_colorGC,
                             COLOR_ToPhysical( NULL, RGB(0,0,0) ));
-            XSetBackground( display, BITMAP_colorGC, 0 );
-            XSetFunction( display, BITMAP_colorGC, GXor );
-            XCopyPlane(display, bmpAnd->pixmap, bmpXor->pixmap, BITMAP_colorGC,
+            TSXSetBackground( display, BITMAP_colorGC, 0 );
+            TSXSetFunction( display, BITMAP_colorGC, GXor );
+            TSXCopyPlane(display, bmpAnd->pixmap, bmpXor->pixmap, BITMAP_colorGC,
                        0, 0, bmpXor->bitmap.bmWidth, bmpXor->bitmap.bmHeight,
                        0, 0, 1 );
-            XSetFunction( display, BITMAP_colorGC, GXcopy );
+            TSXSetFunction( display, BITMAP_colorGC, GXcopy );
         }
     }
 
diff --git a/objects/palette.c b/objects/palette.c
index a1f6153..67f4411 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -10,7 +10,7 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 
 #include "gdi.h"
 #include "color.h"
diff --git a/objects/region.c b/objects/region.c
index a26cb96..f3adee4 100644
--- a/objects/region.c
+++ b/objects/region.c
@@ -505,7 +505,7 @@
     if(count < (size + sizeof(RGNDATAHEADER)) || rgndata == NULL)
     {
         GDI_HEAP_UNLOCK( hrgn );
-        return size;
+        return size + sizeof(RGNDATAHEADER);
     }
 
     rgndata->rdh.dwSize = sizeof(RGNDATAHEADER);
diff --git a/ole/compobj.c b/ole/compobj.c
index 96a300e..ef476a9 100644
--- a/ole/compobj.c
+++ b/ole/compobj.c
@@ -4,22 +4,24 @@
  *	Copyright 1995	Martin von Loewis
  */
 
-/*	At the moment, these are only empty stubs.
- */
 #define INITGUID
 
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include "ole.h"
 #include "ole2.h"
 #include "stddebug.h"
 #include "debug.h"
+#include "file.h"
 #include "compobj.h"
 #include "interfaces.h"
 #include "shlobj.h"
 #include "ddraw.h"
 #include "dsound.h"
+#include "dinput.h"
+#include "d3d.h"
 
 DWORD currentMalloc=0;
 
@@ -155,9 +157,8 @@
 }
 
 /***********************************************************************
- *           CLSIDFromString [COMPOBJ.19]
+ *           StringFromCLSID [COMPOBJ.19]
  */
-
 OLESTATUS WINAPI StringFromCLSID(const CLSID *id, LPSTR idstr)
 {
   static const char *hex = "0123456789ABCDEF";
@@ -187,3 +188,98 @@
   return OLE_OK;
 }
 
+/***********************************************************************
+ *           CLSIDFromProgID [COMPOBJ.61]
+ */
+
+OLESTATUS WINAPI CLSIDFromProgID(LPCSTR progid,LPCLSID riid)
+{
+	char	*buf,buf2[80];
+	DWORD	buf2len;
+	HRESULT	err;
+	HKEY	xhkey;
+
+	buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
+	sprintf(buf,"%s\\CLSID",progid);
+	if ((err=RegOpenKey32A(HKEY_CLASSES_ROOT,buf,&xhkey))) {
+		HeapFree(GetProcessHeap(),0,buf);
+		return OLE_ERROR_GENERIC;
+	}
+	HeapFree(GetProcessHeap(),0,buf);
+	buf2len = sizeof(buf2);
+	if ((err=RegQueryValue32A(xhkey,NULL,buf2,&buf2len))) {
+		RegCloseKey(xhkey);
+		return OLE_ERROR_GENERIC;
+	}
+	RegCloseKey(xhkey);
+	return CLSIDFromString(buf2,riid);
+}
+
+OLESTATUS WINAPI LookupETask(LPVOID p1,LPVOID p2) {
+	fprintf(stderr,"LookupETask(%p,%p),stub!\n",p1,p2);
+	return 0;
+}
+
+OLESTATUS WINAPI CallObjectInWOW(LPVOID p1,LPVOID p2) {
+	fprintf(stderr,"CallObjectInWOW(%p,%p),stub!\n",p1,p2);
+	return 0;
+}
+
+/***********************************************************************
+ *		CoRegisterClassObject [COMPOBJ.5]
+ */
+OLESTATUS WINAPI CoRegisterClassObject(
+	REFCLSID rclsid, LPUNKNOWN pUnk,DWORD dwClsContext,DWORD flags,
+	LPDWORD lpdwRegister
+) {
+	char	buf[80];
+
+	StringFromCLSID(rclsid,buf);
+
+	fprintf(stderr,"CoRegisterClassObject(%s,%p,0x%08lx,0x%08lx,%p),stub\n",
+		buf,pUnk,dwClsContext,flags,lpdwRegister
+	);
+	return 0;
+}
+
+/***********************************************************************
+ *		CoRegisterClassObject [COMPOBJ.27]
+ */
+OLESTATUS WINAPI CoRegisterMessageFilter16(
+	LPMESSAGEFILTER lpMessageFilter,LPMESSAGEFILTER *lplpMessageFilter
+) {
+	fprintf(stderr,"CoRegisterMessageFilter(%p,%p),stub!\n",
+		lpMessageFilter,lplpMessageFilter
+	);
+	return 0;
+}
+
+/***********************************************************************
+ *           CoCreateInstance [COMPOBJ.13, OLE32.7]
+ */
+HRESULT WINAPI CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter,
+				DWORD dwClsContext, REFIID riid, LPVOID *ppv)
+{
+	fprintf(stderr, "CoCreateInstance(): stub !\n");
+	*ppv = NULL;
+	return S_OK;
+}
+
+/***********************************************************************
+ *           CoFreeUnusedLibraries [COMPOBJ.17]
+ */
+void WINAPI CoFreeUnusedLibraries()
+{
+	fprintf(stderr, "CoFreeUnusedLibraries(): stub !\n");
+}
+
+/***********************************************************************
+ *           CoFileTimeNow [COMPOBJ.82, OLE32.10]
+ *
+ *	stores the current system time in lpFileTime
+ */
+HRESULT WINAPI CoFileTimeNow(FILETIME *lpFileTime)
+{
+	DOSFS_UnixTimeToFileTime(time(NULL), lpFileTime, 0);
+	return S_OK;
+}
diff --git a/ole/ole2.c b/ole/ole2.c
index fce01ad..565b0a6 100644
--- a/ole/ole2.c
+++ b/ole/ole2.c
@@ -49,7 +49,7 @@
 /***********************************************************************
  *           CoRegisterMessageFilter   [OLE32.38]
  */
-HRESULT CoRegisterMessageFilter(
+HRESULT WINAPI CoRegisterMessageFilter32(
     LPMESSAGEFILTER lpMessageFilter,	/* Pointer to interface */
     LPMESSAGEFILTER *lplpMessageFilter	/* Indirect pointer to prior instance if non-NULL */
 ) {
diff --git a/ole/ole2disp.c b/ole/ole2disp.c
index 76f6181..405ce66 100644
--- a/ole/ole2disp.c
+++ b/ole/ole2disp.c
@@ -5,7 +5,9 @@
  */
 
 #include "windows.h"
+#include "ole.h"
 #include "ole2.h"
+#include "interfaces.h"
 #include "heap.h"
 #include "ldt.h"
 #include "stddebug.h"
@@ -92,3 +94,17 @@
 {
 	return strlen(BSTR_GetAddr(str));
 }
+
+OLESTATUS WINAPI CreateDispTypeInfo(INTERFACEDATA * pidata,LCID lcid,LPVOID/*ITypeInfo*/ * * pptinfo) {
+	fprintf(stderr,"CreateDispTypeInfo(%p,%ld,%p),stub\n",pidata,lcid,pptinfo);
+	return 0;
+}
+
+OLESTATUS WINAPI RegisterActiveObject(
+	IUnknown * punk,REFCLSID rclsid,DWORD dwFlags, DWORD * pdwRegister
+) {
+	char	buf[80];
+	StringFromCLSID(rclsid,buf);
+	fprintf(stderr,"RegisterActiveObject(%p,%s,0x%08lx,%p),stub\n",punk,buf,dwFlags,pdwRegister);
+	return 0;
+}
diff --git a/ole/ole2nls.c b/ole/ole2nls.c
index 6f18100..500a3fe 100644
--- a/ole/ole2nls.c
+++ b/ole/ole2nls.c
@@ -212,10 +212,11 @@
  /* case LANG_Ru: return 0x19; */      /* Russian */
  /* case LANG_Cr: return 0x1a; */      /* Croatian */
  /* case LANG_Sl: return 0x1b; */      /* Slovak */
- /* case LANG_Sw: return 0x1d; */      /* Swedish */
+    case LANG_Sw: return 0x1d;         /* Swedish */
  /* case LANG_Tu: return 0x1f; */      /* Turkish */
  /* case LANG_Sv: return 0x24; */      /* Slovenian */
     case LANG_Eo: return 0x25;         /* Esperanto (not official) */
+    case LANG_Ca: return 0x26;         /* Catalan */
 
     default:
 	return 0x00;                   /* Neutral language */
@@ -1676,6 +1677,110 @@
 	}
     break; /* LANG(Po) */
 
+case LANG_Sw:
+    	switch (LCType) {
+LOCVAL(LOCALE_ILANGUAGE,"1d")
+LOCVAL(LOCALE_SLANGUAGE,"Svenska")
+LOCVAL(LOCALE_SENGLANGUAGE,"Swedish")
+LOCVAL(LOCALE_SABBREVLANGNAME,"SV")
+LOCVAL(LOCALE_SNATIVELANGNAME,"Svenska")
+LOCVAL(LOCALE_ICOUNTRY,"45")
+LOCVAL(LOCALE_SCOUNTRY,"SWE")
+LOCVAL(LOCALE_SENGCOUNTRY,"Sweden")
+LOCVAL(LOCALE_SABBREVCTRYNAME,"SVE")
+LOCVAL(LOCALE_SNATIVECTRYNAME,"Sverige")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"1d")
+LOCVAL(LOCALE_IDEFAULTCOUNTRY,"45")
+/* LOCVAL(LOCALE_IDEFAULTCODEPAGE) */
+/* LOCVAL(LOCALE_IDEFAULTANSICODEPAGE) */
+LOCVAL(LOCALE_SLIST,";")
+LOCVAL(LOCALE_IMEASURE,"0")
+LOCVAL(LOCALE_SDECIMAL,",")
+LOCVAL(LOCALE_STHOUSAND,".")
+/* LOCVAL(LOCALE_SGROUPING) */
+LOCVAL(LOCALE_IDIGITS,"2")
+LOCVAL(LOCALE_ILZERO,"1")
+/* LOCVAL(LOCALE_INEGNUMBER) */
+/* LOCVAL(LOCALE_SNATIVEDIGITS) */
+LOCVAL(LOCALE_SCURRENCY,"kr")
+/* LOCVAL(LOCALE_SINTLSYMBOL) */
+LOCVAL(LOCALE_SMONDECIMALSEP,",")
+LOCVAL(LOCALE_SMONTHOUSANDSEP,".")
+/* LOCVAL(LOCALE_SMONGROUPING) */
+LOCVAL(LOCALE_ICURRDIGITS,"2")
+/* LOCVAL(LOCALE_IINTLCURRDIGITS) */
+LOCVAL(LOCALE_ICURRENCY,"3")
+LOCVAL(LOCALE_INEGCURR,"8")
+LOCVAL(LOCALE_SDATE,".")
+LOCVAL(LOCALE_STIME,":")
+LOCVAL(LOCALE_SSHORTDATE,"dd/MM-yyyy")
+LOCVAL(LOCALE_SLONGDATE,"ddd, d. MMMM yyyy")
+/* LOCVAL(LOCALE_STIMEFORMAT) */
+LOCVAL(LOCALE_IDATE,"1")
+/* LOCVAL(LOCALE_ILDATE) */
+LOCVAL(LOCALE_ITIME,"1")
+/* LOCVAL(LOCALE_ITIMEMARKPOSN) */
+/* LOCVAL(LOCALE_ICENTURY) */
+LOCVAL(LOCALE_ITLZERO,"1")
+/* LOCVAL(LOCALE_IDAYLZERO) */
+/* LOCVAL(LOCALE_IMONLZERO) */
+LOCVAL(LOCALE_S1159, "")
+LOCVAL(LOCALE_S2359, "")
+/* LOCVAL(LOCALE_ICALENDARTYPE) */
+/* LOCVAL(LOCALE_IOPTIONALCALENDAR) */
+/* LOCVAL(LOCALE_IFIRSTDAYOFWEEK) */
+/* LOCVAL(LOCALE_IFIRSTWEEKOFYEAR) */
+LOCVAL(LOCALE_SDAYNAME1,"Måndag")
+LOCVAL(LOCALE_SDAYNAME2,"Tisdag")
+LOCVAL(LOCALE_SDAYNAME3,"Onsdag")
+LOCVAL(LOCALE_SDAYNAME4,"Torsdag")
+LOCVAL(LOCALE_SDAYNAME5,"Fredag")
+LOCVAL(LOCALE_SDAYNAME6,"Lördag")
+LOCVAL(LOCALE_SDAYNAME7,"Söndag")
+LOCVAL(LOCALE_SABBREVDAYNAME1,"Må")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"Ti")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"On")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"To")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"Fr")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"Lö")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"Sö")
+LOCVAL(LOCALE_SMONTHNAME1,"Januari")
+LOCVAL(LOCALE_SMONTHNAME2,"Februari")
+LOCVAL(LOCALE_SMONTHNAME3,"Mars")
+LOCVAL(LOCALE_SMONTHNAME4,"April")
+LOCVAL(LOCALE_SMONTHNAME5,"Maj")
+LOCVAL(LOCALE_SMONTHNAME6,"Juni")
+LOCVAL(LOCALE_SMONTHNAME7,"Juli")
+LOCVAL(LOCALE_SMONTHNAME8,"Augusti")
+LOCVAL(LOCALE_SMONTHNAME9,"September")
+LOCVAL(LOCALE_SMONTHNAME10,"Oktober")
+LOCVAL(LOCALE_SMONTHNAME11,"November")
+LOCVAL(LOCALE_SMONTHNAME12,"December")
+LOCVAL(LOCALE_SMONTHNAME13,"")
+LOCVAL(LOCALE_SABBREVMONTHNAME1,"Jan")
+LOCVAL(LOCALE_SABBREVMONTHNAME2,"Feb")
+LOCVAL(LOCALE_SABBREVMONTHNAME3,"Mar")
+LOCVAL(LOCALE_SABBREVMONTHNAME4,"Apr")
+LOCVAL(LOCALE_SABBREVMONTHNAME5,"Maj")
+LOCVAL(LOCALE_SABBREVMONTHNAME6,"Jun")
+LOCVAL(LOCALE_SABBREVMONTHNAME7,"Jul")
+LOCVAL(LOCALE_SABBREVMONTHNAME8,"Aug")
+LOCVAL(LOCALE_SABBREVMONTHNAME9,"Sep")
+LOCVAL(LOCALE_SABBREVMONTHNAME10,"Okt")
+LOCVAL(LOCALE_SABBREVMONTHNAME11,"Nov")
+LOCVAL(LOCALE_SABBREVMONTHNAME12,"Dec")
+LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
+LOCVAL(LOCALE_IPOSSIGNPOSN, "3")
+LOCVAL(LOCALE_INEGSIGNPOSN, "3")
+LOCVAL(LOCALE_IPOSSYMPRECEDES, "1")
+LOCVAL(LOCALE_IPOSSEPBYSPACE, "0")
+LOCVAL(LOCALE_INEGSYMPRECEDES, "1")
+LOCVAL(LOCALE_INEGSEPBYSPACE, "0")
+	default: found=0;break;
+	}
+    break; /* LANG(Sw) */
 
 /*Insert other languages here*/
 
diff --git a/programs/notepad/ChangeLog b/programs/notepad/ChangeLog
index 0a13af9..1662094 100644
--- a/programs/notepad/ChangeLog
+++ b/programs/notepad/ChangeLog
@@ -1,3 +1,7 @@
+Sun Jan 18 23:05:04 1998  Karl Backström <karl_b@geocities.com>
+	* [Sw.rc]
+	Added/updated Swedish language support.
+
 Tue Dec 23 23:35:04 1997  Marcel Baur <mbaur@g26.ethz.ch>
        * Fixed lots of bugs w/ resources in *.rc
        * moved [notepad.c] into [main.c]
diff --git a/programs/notepad/Makefile.in b/programs/notepad/Makefile.in
index ed5ffe1..6b254f7 100644
--- a/programs/notepad/Makefile.in
+++ b/programs/notepad/Makefile.in
@@ -8,7 +8,7 @@
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
 
-LANGUAGES   = En De
+LANGUAGES   = En De Sw
 LICENSELANG = En
 
 MOSTSRCS = \
diff --git a/programs/notepad/Sw.rc b/programs/notepad/Sw.rc
new file mode 100644
index 0000000..8b6d49d
--- /dev/null
+++ b/programs/notepad/Sw.rc
@@ -0,0 +1,90 @@
+/*
+ * Notepad (Swedish resources)
+ *
+ * Copyright 1997 Marcel Baur <mbaur@g26.ethz.ch>
+ * Swedish language by Karl Backström <karl_b@geocities.com>
+ */
+
+#define LANGUAGE_ID                  Sw
+#define LANGUAGE_NUMBER              1d
+#define LANGUAGE_MENU_ITEM           "&Svenska"
+
+/* Menu */
+
+#define MENU_FILE                    "&Arkiv"
+#define MENU_FILE_NEW                "&Ny..."
+#define MENU_FILE_OPEN               "Ö&ppna"
+#define MENU_FILE_SAVE               "&Spara"
+#define MENU_FILE_SAVEAS             "Spara &som..."
+#define MENU_FILE_PRINT              "&Skriv ut"
+#define MENU_FILE_PAGESETUP          "Sid La&yout..."
+#define MENU_FILE_PRINTSETUP         "Skrivar &inställningar..."
+#define MENU_FILE_EXIT               "&Avsluta"
+
+#define MENU_EDIT                    "&Redigera"
+#define MENU_EDIT_UNDO               "&Undo\tCtrl+Z"
+#define MENU_EDIT_CUT                "Klippa\tCtrl+X"
+#define MENU_EDIT_COPY               "&Kopiera\tCtrl+C"
+#define MENU_EDIT_PASTE              "&Klistra in\tCtrl+V"
+#define MENU_EDIT_DELETE             "&Ta bort\tDel"
+#define MENU_EDIT_SELECTALL          "Markera &allt"
+#define MENU_EDIT_TIMEDATE           "&Tid/Datum\tF5"
+#define MENU_EDIT_WRAP               "&Dela långa meningar"
+
+#define MENU_SEARCH                  "&Sök"
+#define MENU_SEARCH_SEARCH           "Sök..."
+#define MENU_SEARCH_NEXT             "&Sök nästa\tF3"
+
+#define MENU_LANGUAGE                "&Språk"
+
+#define MENU_HELP                    "&Hjälp"
+#define MENU_HELP_CONTENTS           "&Innehåll"
+#define MENU_HELP_SEARCH             "&Sök..."
+#define MENU_HELP_HELP_ON_HELP       "Användningen &av hjälp"
+
+#define MENU_INFO                    "Inf&ormation..."
+#define MENU_INFO_LICENSE            "&Licens"
+#define MENU_INFO_NO_WARRANTY        "&INGEN GARANTI"
+#define MENU_INFO_ABOUT_WINE         "&Om Wine"
+
+/* Dialogs */
+
+#define DIALOG_OK                    "OK"
+#define DIALOG_CANCEL                "Avbryt"
+#define DIALOG_BROWSE                "&Bläddra..."
+#define DIALOG_HELP                  "&Hjälp"
+
+#define DIALOG_PAGESETUP_CAPTION     "Sid Layout"
+#define DIALOG_PAGESETUP_HEAD        "&Huvudnot:"
+#define DIALOG_PAGESETUP_TAIL        "&Fotnot:"
+#define DIALOG_PAGESETUP_BORDER      "Kanter:"
+#define DIALOG_PAGESETUP_LEFT        "&Vänster:"
+#define DIALOG_PAGESETUP_RIGHT       "&Höger:"
+#define DIALOG_PAGESETUP_TOP         "&Över:"
+#define DIALOG_PAGESETUP_BOTTOM      "&Under:"
+
+
+/* Strings */
+#define STRING_NOTEPAD               "Anteckningar"
+#define STRING_ERROR                 "FEL"
+#define STRING_WARNING               "VARNING"
+#define STRING_INFO                  "Information"
+
+#define STRING_UNTITLED              "(untitled)"
+
+#define STRING_ALLFILES              "Alla filer (*.*)"
+#define STRING_TEXTFILES             "Text filer (*.txt)"
+
+#define STRING_TOOLARGE         "Filen '%s' är för stor för notepad.\n \
+Använd en annan editor."
+
+#define STRING_NOTEXT           "Du skrev inte in någon text. \
+\nSkriv något och försök sedan igen"
+
+#define STRING_NOTFOUND         "'%s' hittades inte."
+
+#define STRING_OUT_OF_MEMORY    "Inte tillräkligt med minne för att slutföra \
+den här uppgiften. \nAvsluta ett eller flera program för att öka mängden \nfritt \
+minne."
+
+#include "notepad.rc"
diff --git a/programs/notepad/TODO b/programs/notepad/TODO
index d2d28b4..a14a2b4 100644
--- a/programs/notepad/TODO
+++ b/programs/notepad/TODO
@@ -1,8 +1,2 @@
 
- - En.rc is translated from german version of Notepad. 
-   I don't know what the real strings are, as I do not have an english
-   copy of Notepad. Please check strings in En.rc and submit corrections.
-
  - create new *.rc files for all languages you know.
-
-
diff --git a/programs/notepad/main.c b/programs/notepad/main.c
index b236c09..cdc2b64 100644
--- a/programs/notepad/main.c
+++ b/programs/notepad/main.c
@@ -85,7 +85,11 @@
      case NP_EDIT_PASTE:        break;
      case NP_EDIT_DELETE:       break;
      case NP_EDIT_TIMEDATE:     break;
-     case NP_EDIT_WRAP:         break;
+     case NP_EDIT_WRAP:         
+        Globals.bWrapLongLines = !Globals.bWrapLongLines;
+	CheckMenuItem(Globals.hEditMenu, NP_EDIT_WRAP, MF_BYCOMMAND | 
+                (Globals.bWrapLongLines ? MF_CHECKED : MF_UNCHECKED));
+        break;
 
      case NP_SEARCH_SEARCH:     break;
      case NP_SEARCH_NEXT:       break;
diff --git a/programs/notepad/main.h b/programs/notepad/main.h
index 3c701b5..bb2fd2f 100644
--- a/programs/notepad/main.h
+++ b/programs/notepad/main.h
@@ -30,6 +30,7 @@
   LPCSTR  lpszIcoFile;
   LPCSTR  lpszLanguage;
   UINT    wStringTableOffset;
+  BOOL    bWrapLongLines;
 } NOTEPAD_GLOBALS;
 
 extern NOTEPAD_GLOBALS Globals;
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
index 222f96c..f387edb 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -8,7 +8,7 @@
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
 
-LANGUAGES   = En Da De Fr Fi Ko Hu It Va
+LANGUAGES   = En Da De Fr Fi Ko Hu It Va Sw
 LICENSELANG = En
 
 MOSTSRCS = \
diff --git a/programs/progman/Sw.rc b/programs/progman/Sw.rc
new file mode 100644
index 0000000..ed0e32a
--- /dev/null
+++ b/programs/progman/Sw.rc
@@ -0,0 +1,119 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1998 Karl Backström
+ */
+
+#define LANGUAGE_ID                  Sw
+#define LANGUAGE_NUMBER              1d
+#define LANGUAGE_MENU_ITEM           "&Svenska"
+
+/* Menu */
+
+#define MENU_FILE                    "&Arkiv"
+#define MENU_FILE_NEW                "&Ny..."
+#define MENU_FILE_OPEN               "Ö&ppna\tEnter"
+#define MENU_FILE_MOVE               "&Flytta...\tF7"
+#define MENU_FILE_COPY               "&Kopiera...\tF8"
+#define MENU_FILE_DELETE             "&Ta bort\tEntf"
+#define MENU_FILE_ATTRIBUTES         "&Egenskaper...\tAlt+Enter"
+#define MENU_FILE_EXECUTE            "&Kör..."
+#define MENU_FILE_EXIT               "A&vsluta Windows..."
+
+#define MENU_OPTIONS                 "&Inställningar"
+#define MENU_OPTIONS_AUTO_ARRANGE    "&Arrangera automatiskt"
+#define MENU_OPTIONS_MIN_ON_RUN      "&Minimera vid körning"
+#define MENU_OPTIONS_SAVE_SETTINGS   "&Spara inställningarna vid avslut"
+
+#define MENU_WINDOWS                 "&Fönster"
+#define MENU_WINDOWS_OVERLAP         "&Överlappande\tShift+F5"
+#define MENU_WINDOWS_SIDE_BY_SIDE    "&Sida vid sida\tShift+F4"
+#define MENU_WINDOWS_ARRANGE         "&Arrangra Ikoner"
+
+#define MENU_LANGUAGE                "&Språk"
+
+#define MENU_HELP                    "&Hjälp"
+#define MENU_HELP_CONTENTS           "&Innehåll"
+#define MENU_HELP_SEARCH             "&Sök..."
+#define MENU_HELP_HELP_ON_HELP       "&Användningen av Hjälp"
+#define MENU_HELP_TUTORIAL           "&Windows Självstudier"
+
+#define MENU_INFO                    "&Information..."
+#define MENU_INFO_LICENSE            "&Licens"
+#define MENU_INFO_NO_WARRANTY        "&INGEN GARANTI"
+#define MENU_INFO_ABOUT_WINE         "&Om WINE"
+
+/* Dialogs */
+
+#define DIALOG_OK                    "OK"
+#define DIALOG_CANCEL                "Avbryt"
+#define DIALOG_BROWSE                "&Bläddra"
+#define DIALOG_HELP                  "&Hjälp"
+
+#define DIALOG_NEW_CAPTION           "Nytt Program Objekt"
+#define DIALOG_NEW_NEW               "Nytt"
+#define DIALOG_NEW_GROUP             "Program &grupp"
+#define DIALOG_NEW_PROGRAM           "&Program"
+
+#define DIALOG_MOVE_CAPTION          "Flytta Program"
+#define DIALOG_MOVE_PROGRAM          "Flytta program:"
+#define DIALOG_MOVE_FROM_GROUP       "Från grupp:"
+#define DIALOG_MOVE_TO_GROUP         "&Till grupp:"
+
+#define DIALOG_COPY_CAPTION          "Kopiera Program"
+#define DIALOG_COPY_PROGRAM          "Kopiera program:"
+#define DIALOG_COPY_FROM_GROUP       DIALOG_MOVE_FROM_GROUP
+#define DIALOG_COPY_TO_GROUP         DIALOG_MOVE_TO_GROUP
+
+#define DIALOG_GROUP_CAPTION         "Programgrupps egenskaper"
+#define DIALOG_GROUP_DESCRIPTION     "&Beskrivning:"
+#define DIALOG_GROUP_FILE            "&Gruppfil:"
+
+#define DIALOG_PROGRAM_CAPTION       "Program egenskaper"
+#define DIALOG_PROGRAM_DESCRIPTION   DIALOG_GROUP_DESCRIPTION
+#define DIALOG_PROGRAM_COMMAND_LINE  "&Kommando rad:"
+#define DIALOG_PROGRAM_DIRECTORY     "&Arbets katalog:"
+#define DIALOG_PROGRAM_HOT_KEY       "&Tangentbords kombination:"
+#define DIALOG_PROGRAM_SYMBOL        "Kör &minimerat"
+#define DIALOG_PROGRAM_OTHER_SYMBOL  "&Byt Ikon..."
+
+#define DIALOG_SYMBOL_CAPTION        "Byt Ikon"
+#define DIALOG_SYMBOL_FILE           "&Filnamn:"
+#define DIALOG_SYMBOL_CURRENT        "&Nuvarande ikon:"
+
+#define DIALOG_EXECUTE_CAPTION       "Kör"
+#define DIALOG_EXECUTE_COMMAND_LINE  DIALOG_PROGRAM_COMMAND_LINE
+#define DIALOG_EXECUTE_SYMBOL        DIALOG_PROGRAM_SYMBOL
+
+/* Strings */
+
+#define STRING_PROGRAM_MANAGER            "Programhanteraren"
+#define STRING_ERROR                      "FEL"
+#define STRING_WARNING                    "VARNING"
+#define STRING_INFO                       "Information"
+#define STRING_DELETE                     "Ta bort"
+#define STRING_DELETE_GROUP_s             "Ta bort grupp `%s' ?"
+#define STRING_DELETE_PROGRAM_s           "Ta bort program `%s' ?"
+#define STRING_NOT_IMPLEMENTED            "Ej implementerat"
+#define STRING_FILE_READ_ERROR_s          "Kan ej läsa filen `%s'"
+#define STRING_FILE_WRITE_ERROR_s         "Kan ej skriva till filen `%s'"
+
+#define STRING_GRPFILE_READ_ERROR_s       "\
+Kan inte öppna gruppfilen `%s'.\n\
+Önskar du att Programhanteraren i framtiden ska försöka öppna den?"
+
+#define STRING_OUT_OF_MEMORY              "Slut på minne"
+#define STRING_WINHELP_ERROR              "Hjälp ej tillgänglig"
+#define STRING_UNKNOWN_FEATURE_s          "Okänt innehåll i %s"
+#define STRING_FILE_NOT_OVERWRITTEN_s     "Filen `%s' existerar. Den har ej skrivits över."
+#define STRING_SAVE_GROUP_AS_s            "Spara filen som `%s' för att förhindra att orginalfilen skrivs över"
+
+#define STRING_NO_HOT_KEY                 "Ingen"
+
+#define STRING_ALL_FILES                  "Alla filer (*.*)"
+#define STRING_PROGRAMS                   "Program"
+#define STRING_LIBRARIES_DLL              "Biblioteksfiler (*.dll)"
+#define STRING_SYMBOL_FILES               "Ikonfiler"
+#define STRING_SYMBOLS_ICO                "Ikoner (*.ico)"
+
+#include "Xx.rc"
diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in
index dbe0daf..fa90628 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -8,7 +8,7 @@
 ALL_LIBS  = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LIBS)
 RCFLAGS   = -w32 -h
 
-LANGUAGES   = En Da De Fr Fi Ko Hu It Va
+LANGUAGES   = En Da De Fr Fi Ko Hu It Va Sw
 
 MOSTSRCS = \
 	winhelp.c \
diff --git a/programs/winhelp/Sw.rc b/programs/winhelp/Sw.rc
new file mode 100644
index 0000000..687c7a2
--- /dev/null
+++ b/programs/winhelp/Sw.rc
@@ -0,0 +1,49 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Swedish language by Karl Backström <karl_b@geocities.com>
+ */
+
+/* This file is not yet complete !! */
+
+#define LANGUAGE_ID                  Sw
+#define LANGUAGE_NUMBER              1d
+
+/* Menu */
+
+#define MENU_FILE                    "&Arkiv"
+#define MENU_FILE_OPEN               "&Öppna..."
+#define MENU_FILE_PRINT              "&Skriv ut"
+#define MENU_FILE_PRINTER_SETUP      "Skrivar &inställningar..."
+#define MENU_FILE_EXIT               "&Avsluta"
+
+#define MENU_EDIT                    "&Redigera"
+#define MENU_EDIT_COPY_DIALOG        "&Kopiera..."
+#define MENU_EDIT_ANNOTATE           "&Annmärk..."
+
+#define MENU_BOOKMARK                "&Bokmärke"
+#define MENU_BOOKMARK_DEFINE         "&Defingera..."
+
+#define MENU_HELP                    "&Hjälp"
+#define MENU_HELP_ON_HELP            "Användningen &av hjälp"
+#define MENU_HELP_ON_TOP             "Alltid &överst"
+#define MENU_HELP_INFO               "&Information..."
+#define MENU_HELP_ABOUT_WINE         "&Om WINE"
+
+/* Strings */
+
+#define STRING_WINE_HELP             "WINE Hjälp"
+#define STRING_ERROR                 "FEL"
+#define STRING_WARNING               "VARNING"
+#define STRING_INFO                  "Information"
+#define STRING_NOT_IMPLEMENTED       "Ej implementererat"
+#define STRING_HLPFILE_ERROR_s       "FEL vid läsning av hjälp filen `%s'"
+#define STRING_CONTENTS              "&Innehåll"
+#define STRING_SEARCH                "&Sök"
+#define STRING_BACK                  "&Tillbaka"
+#define STRING_HISTORY               "&Översikt"
+#define STRING_ALL_FILES             "Alla filer (*.*)"
+#define STRING_HELP_FILES_HLP        "Hjälp filer (*.hlp)"
+
+#include "Xx.rc"
diff --git a/relay32/Makefile.in b/relay32/Makefile.in
index 39880ce..52e1e6a 100644
--- a/relay32/Makefile.in
+++ b/relay32/Makefile.in
@@ -12,6 +12,8 @@
 	crtdll.spec \
 	dciman32.spec \
 	ddraw.spec \
+	dinput.spec \
+	dplay.spec \
 	dsound.spec \
 	gdi32.spec \
 	kernel32.spec \
diff --git a/relay32/builtin32.c b/relay32/builtin32.c
index 01f9a7d..b9f48d9 100644
--- a/relay32/builtin32.c
+++ b/relay32/builtin32.c
@@ -45,6 +45,8 @@
 extern const BUILTIN32_DESCRIPTOR CRTDLL_Descriptor;
 extern const BUILTIN32_DESCRIPTOR DCIMAN32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR DDRAW_Descriptor;
+extern const BUILTIN32_DESCRIPTOR DINPUT_Descriptor;
+extern const BUILTIN32_DESCRIPTOR DPLAY_Descriptor;
 extern const BUILTIN32_DESCRIPTOR DSOUND_Descriptor;
 extern const BUILTIN32_DESCRIPTOR GDI32_Descriptor;
 extern const BUILTIN32_DESCRIPTOR KERNEL32_Descriptor;
@@ -73,6 +75,8 @@
     { &CRTDLL_Descriptor,   NULL, TRUE  },
     { &DCIMAN32_Descriptor, NULL, TRUE  },
     { &DDRAW_Descriptor,    NULL, TRUE  },
+    { &DINPUT_Descriptor,   NULL, TRUE  },
+    { &DPLAY_Descriptor,    NULL, TRUE  },
     { &DSOUND_Descriptor,   NULL, TRUE  },
     { &GDI32_Descriptor,    NULL, TRUE  },
     { &KERNEL32_Descriptor, NULL, TRUE  },
diff --git a/relay32/comdlg32.spec b/relay32/comdlg32.spec
index bcb0a91..c5aeb46 100644
--- a/relay32/comdlg32.spec
+++ b/relay32/comdlg32.spec
@@ -4,7 +4,7 @@
  0 stub ArrowBtnWndProc
  1 stub ChooseColorA
  2 stub ChooseColorW
- 3 stub ChooseFontA
+ 3 stdcall ChooseFontA(ptr) ChooseFont32A
  4 stub ChooseFontW
  5 stdcall CommDlgExtendedError() CommDlgExtendedError
  6 stub FindTextA
diff --git a/relay32/dinput.spec b/relay32/dinput.spec
new file mode 100644
index 0000000..23ba6e9
--- /dev/null
+++ b/relay32/dinput.spec
@@ -0,0 +1,10 @@
+name dinput
+type win32
+
+0 stdcall DirectInputCreateA(long long ptr ptr) DirectInputCreate32A
+1 stub DirectInputCreateW
+2 stub DllCanUnloadNow
+3 stub DllGetClassObject
+4 stub DllRegisterServer
+5 stub DllUnregisterServer
+
diff --git a/relay32/dplay.spec b/relay32/dplay.spec
new file mode 100644
index 0000000..d8dbe2c
--- /dev/null
+++ b/relay32/dplay.spec
@@ -0,0 +1,5 @@
+name dplay
+type win32
+
+  1 stub DirectPlayCreate
+  2 stub DirectPlayEnumerate
diff --git a/relay32/gdi32.spec b/relay32/gdi32.spec
index b6c5bea..8e82413 100644
--- a/relay32/gdi32.spec
+++ b/relay32/gdi32.spec
@@ -145,7 +145,7 @@
 138 stub GdiSetAttrs
 139 stdcall GdiSetBatchLimit(long) GdiSetBatchLimit
 140 stub GdiSetServerAttr
-141 stub GetArcDirection
+141 stdcall GetArcDirection(long) GetArcDirection32
 142 stub GetAspectRatioFilterEx
 143 stdcall GetBitmapBits(long long ptr) GetBitmapBits32
 144 stdcall GetBitmapDimensionEx(long ptr) GetBitmapDimensionEx32
@@ -306,7 +306,7 @@
 299 stdcall SelectObject(long long) SelectObject32
 300 stdcall SelectPalette(long long long) SelectPalette32
 301 stub SetAbortProc
-302 stub SetArcDirection
+302 stdcall SetArcDirection(long long) SetArcDirection32
 303 stdcall SetBitmapBits(long long ptr) SetBitmapBits32
 304 stdcall SetBitmapDimensionEx(long long long ptr) SetBitmapDimensionEx32
 305 stdcall SetBkColor(long long) SetBkColor32
@@ -351,7 +351,7 @@
 343 stub SetWinMetaFileBits
 344 stdcall SetWindowExtEx(long long long ptr) SetWindowExtEx32
 345 stdcall SetWindowOrgEx(long long long ptr) SetWindowOrgEx32
-346 stub SetWorldTransform
+346 stdcall SetWorldTransform(long ptr) SetWorldTransform
 347 stub StartDocA
 348 stub StartDocW
 349 stub StartPage
diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec
index 1d29cf2..644978a 100644
--- a/relay32/kernel32.spec
+++ b/relay32/kernel32.spec
@@ -44,9 +44,9 @@
 
 # WOW calls
  54 stdcall WOWCallback16(long long) WOWCallback16
- 55 stub WOWCallback16Ex
+ 55 stdcall WOWCallback16Ex(ptr long long ptr ptr) WOWCallback16Ex
  56 stdcall WOWGetVDMPointer(long long long) WOWGetVDMPointer
- 57 stub WOWHandle32
+ 57 stdcall WOWHandle32(long long) WOWHandle32
  58 stub WOWHandle16
  59 stdcall WOWGlobalAlloc16(long long) GlobalAlloc16
  60 stdcall WOWGlobalLock16(long) WIN16_GlobalLock16
@@ -139,7 +139,7 @@
 148 stdcall ConvertToGlobalHandle(long) ConvertToGlobalHandle
 149 stdcall CopyFileA(str str long) CopyFile32A
 150 stdcall CopyFileW(wstr wstr long) CopyFile32W
-151 stub CreateConsoleScreenBuffer
+151 stdcall CreateConsoleScreenBuffer(long long ptr long ptr) CreateConsoleScreenBuffer
 152 stdcall CreateDirectoryA(str ptr) CreateDirectory32A
 153 stdcall CreateDirectoryExA(str str ptr) CreateDirectoryEx32A
 154 stdcall CreateDirectoryExW(wstr wstr ptr) CreateDirectoryEx32W
@@ -611,7 +611,7 @@
 620 stdcall SetCommTimeouts(long ptr) SetCommTimeouts
 621 stub SetComputerNameA
 622 stub SetComputerNameW
-623 stub SetConsoleActiveScreenBuffer
+623 stdcall SetConsoleActiveScreenBuffer(long) SetConsoleActiveScreenBuffer
 624 stub SetConsoleCP
 625 stdcall SetConsoleCtrlHandler(ptr long) SetConsoleCtrlHandler
 626 stdcall SetConsoleCursorInfo(long ptr) SetConsoleCursorInfo32
@@ -720,7 +720,7 @@
 729 stdcall WriteConsoleA(long ptr long ptr ptr) WriteConsole32A
 730 stub WriteConsoleInputA
 731 stub WriteConsoleInputW
-732 stub WriteConsoleOutputA
+732 stdcall WriteConsoleOutputA(long ptr long long ptr) WriteConsoleOutput32A
 733 stub WriteConsoleOutputAttribute
 734 stub WriteConsoleOutputCharacterA
 735 stub WriteConsoleOutputCharacterW
diff --git a/relay32/ole32.spec b/relay32/ole32.spec
index 3faa9e5..1547f4c 100644
--- a/relay32/ole32.spec
+++ b/relay32/ole32.spec
@@ -7,14 +7,14 @@
   4 stdcall CoBuildVersion() CoBuildVersion
   5 stub CoCreateFreeThreadedMarshaler
   6 stub CoCreateGuid
-  7 stub CoCreateInstance
+  7 stdcall CoCreateInstance(ptr ptr long ptr ptr) CoCreateInstance
   8 stdcall CoDisconnectObject(ptr long) CoDisconnectObject
-  9 stub CoDosDateTimeToFileTime
- 10 stub CoFileTimeNow
- 11 stub CoFileTimeToDosDateTime
+  9 stdcall CoDosDateTimeToFileTime(long long ptr) DosDateTimeToFileTime
+ 10 stdcall CoFileTimeNow(ptr) CoFileTimeNow
+ 11 stdcall CoFileTimeToDosDateTime(ptr ptr ptr) FileTimeToDosDateTime
  12 stub CoFreeAllLibraries
  13 stub CoFreeLibrary
- 14 stub CoFreeUnusedLibraries
+ 14 stdcall CoFreeUnusedLibraries() CoFreeUnusedLibraries
  15 stub CoGetCallerTID
  16 stub CoGetClassObject
  17 stub CoGetCurrentLogicalThreadId
@@ -38,7 +38,7 @@
  35 stub CoQueryReleaseObject
  36 stub CoRegisterClassObject
  37 stub CoRegisterMallocSpy
- 38 stdcall CoRegisterMessageFilter(ptr ptr) CoRegisterMessageFilter
+ 38 stdcall CoRegisterMessageFilter(ptr ptr) CoRegisterMessageFilter32
  39 stub CoReleaseMarshalData
  40 stub CoRevokeClassObject
  41 stub CoRevokeMallocSpy
diff --git a/relay32/winmm.spec b/relay32/winmm.spec
index a421088..f3b494d 100644
--- a/relay32/winmm.spec
+++ b/relay32/winmm.spec
@@ -35,7 +35,7 @@
  32 stdcall joyGetThreshold(long ptr) joyGetThreshold32
  33 stub joyReleaseCapture
  34 stub joySetCapture
- 35 stub joySetThreshold
+ 35 stdcall joySetThreshold(long long) joySetThreshold32
  36 stub mciDriverNotify
  37 stub mciDriverYield
  38 stub mciExecute
diff --git a/relay32/wow32.spec b/relay32/wow32.spec
index c60e58d..5ff4692 100644
--- a/relay32/wow32.spec
+++ b/relay32/wow32.spec
@@ -3,18 +3,18 @@
 
   1 stdcall WOW_1(long long) WOW32_1
   2 stdcall WOWCallback16(long long) WOWCallback16
-  3 stub    WOWCallback16Ex
+  3 stdcall WOWCallback16Ex(ptr long long ptr ptr) WOWCallback16Ex
   4 stub    WOWDirectedYield16
   5 stdcall WOWGetVDMPointer(long long long) WOWGetVDMPointer
   6 stdcall WOWGetVDMPointerFix(long long long) WOWGetVDMPointerFix
   7 stdcall WOWGetVDMPointerUnfix(long) WOWGetVDMPointerUnfix
   8 stub    WOWGlobalAlloc16
-  9 stub    WOWGlobalAllocLock16
+  9 stdcall WOWGlobalAllocLock16(long long ptr) WOWGlobalAllocLock16
  10 stub    WOWGlobalFree16
  11 stub    WOWGlobalLock16
  12 stub    WOWGlobalLockSize16
  13 stub    WOWGlobalUnlock16
  14 stub    WOWGlobalUnlockFree16
  15 stub    WOWHandle16
- 16 stub    WOWHandle32
+ 16 stdcall WOWHandle32(long long) WOWHandle32
  17 stub    WOWYield16
diff --git a/resources/Makefile.in b/resources/Makefile.in
index a99b605..deaf256 100644
--- a/resources/Makefile.in
+++ b/resources/Makefile.in
@@ -7,6 +7,7 @@
 RCFLAGS   = -w32
 
 RC_SRCS = \
+	sysres_Ca.rc \
 	sysres_Cz.rc \
 	sysres_Da.rc \
 	sysres_De.rc \
@@ -20,7 +21,8 @@
 	sysres_Ko.rc \
 	sysres_No.rc \
 	sysres_Pl.rc \
-	sysres_Po.rc
+	sysres_Po.rc \
+	sysres_Sw.rc
 
 C_SRCS = sysres.c
 
diff --git a/resources/sysres.c b/resources/sysres.c
index 93e1057..25c6d9f 100644
--- a/resources/sysres.c
+++ b/resources/sysres.c
@@ -23,6 +23,8 @@
 extern const struct resource * const sysres_Hu_Table[];
 extern const struct resource * const sysres_Pl_Table[];
 extern const struct resource * const sysres_Po_Table[];
+extern const struct resource * const sysres_Sw_Table[];
+extern const struct resource * const sysres_Ca_Table[];
 
 static const struct resource * const * SYSRES_Resources[] =
 {
@@ -39,7 +41,9 @@
     sysres_Ko_Table,  /* LANG_Ko */
     sysres_Hu_Table,  /* LANG_Hu */
     sysres_Pl_Table,  /* LANG_Pl */
-    sysres_Po_Table   /* LANG_Po */
+    sysres_Po_Table,  /* LANG_Po */
+    sysres_Sw_Table,  /* LANG_Sw */
+    sysres_Ca_Table   /* LANG_Ca */
 };
 
 
diff --git a/resources/sysres_Ca.rc b/resources/sysres_Ca.rc
new file mode 100644
index 0000000..6bcdaaf
--- /dev/null
+++ b/resources/sysres_Ca.rc
@@ -0,0 +1,248 @@
+
+SYSMENU MENU LOADONCALL MOVEABLE DISCARDABLE
+{
+ MENUITEM "&Restauració", 61728
+ MENUITEM "&Desplaçament", 61456
+ MENUITEM "&Grandària", 61440
+ MENUITEM "Mí&nima", 61472
+ MENUITEM "Mà&xima", 61488
+ MENUITEM SEPARATOR
+ MENUITEM "&Tancar\tAlt-F4", 61536
+ MENUITEM SEPARATOR
+ MENUITEM "C&anvi de tasca...\tCtrl-Esc", 61744
+ MENUITEM SEPARATOR
+ MENUITEM "&Quant a WINE...", 61761
+}
+
+EDITMENU MENU LOADONCALL MOVEABLE DISCARDABLE
+{
+	POPUP ""
+	BEGIN
+		MENUITEM "&Desfer", EM_UNDO32
+		MENUITEM SEPARATOR
+		MENUITEM "&Retallar", WM_CUT
+		MENUITEM "&Copiar", WM_COPY
+		MENUITEM "&Enganxar", WM_PASTE
+		MENUITEM "&Suprimir", WM_CLEAR
+		MENUITEM SEPARATOR
+		MENUITEM "Seleccionar &tot el text", EM_SETSEL32
+	END
+}
+
+MSGBOX DIALOG 100, 80, 216, 168
+STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+BEGIN
+        ICON "", 1088, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE
+        LTEXT "", 100, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP
+        PUSHBUTTON "D'Acord", 1, 16, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Anul·lació", 2, 64, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Abortar", 3, 112, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Reintentar", 4, 160, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Ignorar", 5, 208, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Si", 6, 256, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&No", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+END
+
+SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 210, 152
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Quant a %s"
+FONT 10, "System"
+{
+ DEFPUSHBUTTON "D'Acord", 1, 153, 130, 50, 12
+ LISTBOX 99, 8, 65, 137, 82, LBS_NOTIFY | WS_VSCROLL | WS_BORDER
+ ICON "", 1088, 189, 10, 14, 16
+ LTEXT "", 100, 8, 10, 137, 33
+ LTEXT "Wine ha estat construit per:", 98, 8, 55, 137, 10
+}
+
+OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Obrir"
+FONT 8, "Helv"
+{
+ LTEXT "&Nom:", 1090, 6, 6, 76, 9
+ EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "&Directoris:", -1, 110, 6, 92, 9
+ LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
+ LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "&Tipus de fitxers:", 1089, 6, 104, 90, 9
+ COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Unitats:", 1091, 110, 104, 92, 9
+ COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "D'acord", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Anul·lació", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "A&juda", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "Només &lectura", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+SAVE_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Anomenar i desar..."
+FONT 8, "Helv"
+{
+ LTEXT "&Nom:", 1090, 6, 6, 76, 9
+ EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "&Directoris:", -1, 110, 6, 92, 9
+ LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
+ LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "Desar fitxer en f&ormat:", 1089, 6, 104, 90, 9
+ COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Unitats:", 1091, 110, 104, 92, 9
+ COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "D'acord", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Anul·lació", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "A&juda", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "&Fer-ne còpia", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Impressió"
+FONT 8, "Helv"
+{
+ LTEXT "Impressora:", 1088, 6, 6, 40, 9
+ LTEXT "Impressió del document", 1089, 60, 6, 150, 9
+ GROUPBOX "", 1072, 6, 30, 160, 65, BS_GROUPBOX
+ RADIOBUTTON "&Sencer", 1056, 16, 45, 60, 12
+ RADIOBUTTON "&Part seleccionada", 1057, 16, 60, 60, 12
+ RADIOBUTTON "Pà&gines", 1058, 16, 75, 60, 12
+ DEFPUSHBUTTON "D'acord", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Anul·lació", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Configuració", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ LTEXT "P&rimera:", 1090, 60, 80, 30, 9
+ LTEXT "Ú&ltima:", 1091, 120, 80, 30, 9
+ LTEXT "&Qualitat:", 1092, 6, 100, 76, 9
+ COMBOBOX 1136, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ CHECKBOX "Imprimir en un &fitxer", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "S&eparar les còpies", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Configuració de la impressió"
+FONT 8, "Helv"
+{
+ GROUPBOX "Impressora:", 1072, 6, 10, 180, 65, BS_GROUPBOX
+ RADIOBUTTON "Impressora per &defecte", 1056, 16, 20, 80, 12
+ LTEXT "[none]", 1088, 35, 35, 120, 9
+ RADIOBUTTON "Impressora &especificada:", 1057, 16, 50, 80, 12
+ COMBOBOX 1136, 35, 65, 149, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "D'acord", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Anul·lació", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Opcions", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ GROUPBOX "Orientació", 1073, 6, 85, 100, 50, BS_GROUPBOX
+ RADIOBUTTON "&Vertical", 1058, 50, 100, 40, 12
+ RADIOBUTTON "&Horitzontal", 1059, 50, 115, 40, 12
+ ICON "LANDSCAP", 1097, 10, 95, 32, 32
+ ICON "PORTRAIT", 1098, 10, 95, 32, 32
+ GROUPBOX "Paper", 1074, 120, 85, 180, 50, BS_GROUPBOX
+ LTEXT "&Mida", 1089, 130, 95, 30, 9
+ LTEXT "A&limentació:", 1090, 130, 110, 30, 9
+ COMBOBOX 1137, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX 1138, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+}
+
+
+CHOOSE_FONT DIALOG DISCARDABLE  13, 54, 264, 147
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Tipus de lletra"
+FONT 8, "Helv"
+{
+    LTEXT           "&Tipus de lletra:",1088 ,6,3,40,9
+    COMBOBOX        1136 ,6,13,94,54,  CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
+    LTEXT           "&Estil del tipus de lletra:",1089 ,108,3,44,9
+    COMBOBOX        1137,108,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
+    LTEXT           "&Grandària:",1090,179,3,30,9
+    COMBOBOX        1138,179,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT
+    DEFPUSHBUTTON   "D'acord",IDOK,218,6,40,14,WS_GROUP
+    PUSHBUTTON      "Anul·lació",IDCANCEL,218,23,40,14,WS_GROUP
+    PUSHBUTTON      "A&plicar", 1026,218,40,40,14,WS_GROUP
+    PUSHBUTTON      "A&juda" , 1038,218,57,40,14,WS_GROUP
+    GROUPBOX        "Efectes",1072,6,72,84,34,WS_GROUP
+    CHECKBOX        "&Barrar-lo", 1040, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX        "&Subratllar-lo", 1041, 10,94,50,10, BS_AUTOCHECKBOX
+    LTEXT           "&Color:", 1091 ,6,110,30,9
+    COMBOBOX        1139,6,120,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS |
+                    CBS_AUTOHSCROLL |  WS_BORDER | WS_VSCROLL | WS_TABSTOP
+    GROUPBOX        "Exemple",1073,98,72,160,49,WS_GROUP
+    CTEXT           "AaBbYyZz",1093,104,81,149,37,SS_NOPREFIX | WS_VISIBLE
+}
+
+
+CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 200
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Color"
+FONT 8, "Helv"
+{
+ LTEXT "Colors &básics:", 1088, 4, 4, 140, 10
+ LTEXT "Colors person&alitzats:", 1089, 4, 106, 140, 10
+ LTEXT "Color Sòl&id", 1090, 150, 151, 48, 10
+ LTEXT   "&Roig:", 726 /*1094*/,249,126,24,10
+ EDITTEXT 706, 275,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT   "&Verd:",727/*1095*/,249,140,24,10
+ EDITTEXT 707, 275,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT   "Bla&u:",728 /*1096*/,249,154,24,10
+ EDITTEXT 708, 275,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT  "&Tint:" ,723 /*1091*/,202,126,22,10
+ EDITTEXT 703, 226,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT  "&Sat.:" ,724 /*1092*/,202,140,22,10
+ EDITTEXT 704, 226,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT  "&Llum.:" ,725 /*1093*/,202,154,22,10
+ EDITTEXT 705, 226,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86
+ CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28
+ CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116 CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
+ CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
+ CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26
+ DEFPUSHBUTTON "D'acord",  1,  4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Anul·lació", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "A&juda", 1038,100,166, 44, 14
+ PUSHBUTTON "Afegir als &colors personalitzats", 712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Definir colors personalitzats >>", 719/*1025*/,   4, 150, 142, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON  "&i",713,300,200,4,14   /* just a dummy:  'i' is  like  &i in "sol&id" */
+}
+
+
+FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Cerca"
+FONT 8, "Helv"
+{
+ LTEXT "&Cercar:",  -1, 4, 8, 42, 8
+ EDITTEXT 1152, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "C&ercar mots sencers", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "&Distingir majúscules de minúscules", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ GROUPBOX "Direcció", 1072, 107, 26, 68, 28
+ CONTROL "&Amunt", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12
+ CONTROL "A&vall", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12
+ DEFPUSHBUTTON "&Continuació", 1, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Anul·lació", 2, 182, 23, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "A&juda", 1038, 182, 45, 50, 14, WS_GROUP | WS_TABSTOP
+}
+
+
+REPLACE_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 230, 94
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Substitució"
+FONT 8, "Helv"
+{
+ LTEXT "&Cercar:", -1, 4, 9, 48, 8
+ EDITTEXT 1152, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT "&Substituir per:", 1090, -1, 4, 26, 48, 8
+ EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Cercar &mots sencers", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "&Distingir majúscules de minúscules", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ DEFPUSHBUTTON "C&ontinucació", 1, 174, 4, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "S&ubstitució", 1024, 174, 21, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Substitució &automàtica", 1025, 174, 38, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Tancar", 2, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "A&juda", 1038, 174, 75, 50, 14, WS_GROUP | WS_TABSTOP
+}
diff --git a/resources/sysres_Sw.rc b/resources/sysres_Sw.rc
new file mode 100644
index 0000000..f40d7cf
--- /dev/null
+++ b/resources/sysres_Sw.rc
@@ -0,0 +1,262 @@
+SYSMENU MENU LOADONCALL MOVEABLE DISCARDABLE
+{
+ MENUITEM "&Restore", 61728
+ MENUITEM "&Flytta", 61456
+ MENUITEM "&Storlek", 61440
+ MENUITEM "Mi&nimera", 61472
+ MENUITEM "Ma&ximera", 61488
+ MENUITEM SEPARATOR
+ MENUITEM "&Avsluta\tAlt-F4", 61536
+ MENUITEM SEPARATOR
+ MENUITEM "&Byt till ...\tCtrl-Esc", 61744
+ MENUITEM SEPARATOR
+ MENUITEM "&Om WINE ...", 61761
+}
+
+EDITMENU MENU LOADONCALL MOVEABLE DISCARDABLE
+{
+	POPUP ""
+	BEGIN
+		MENUITEM "&Undo", EM_UNDO32
+		MENUITEM SEPARATOR
+		MENUITEM "K&lipp", WM_CUT
+		MENUITEM "&Kopiera", WM_COPY
+		MENUITEM "Klistra &in", WM_PASTE
+		MENUITEM "&Ta bort", WM_CLEAR
+		MENUITEM SEPARATOR
+		MENUITEM "Markera &alla", EM_SETSEL32
+	END
+}
+
+MSGBOX DIALOG 100, 80, 216, 168
+STYLE DS_SYSMODAL | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+BEGIN
+        ICON "", 1088, 8, 20, 16, 16, WS_CHILD | WS_VISIBLE
+        LTEXT "", 100, 32, 4, 176, 48, WS_CHILD | WS_VISIBLE | WS_GROUP
+        PUSHBUTTON "&Ok", 1, 16, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Cancel", 2, 64, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Abort", 3, 112, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Retry", 4, 160, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Ignore", 5, 208, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&Yes", 6, 256, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+        PUSHBUTTON "&No", 7, 304, 56, 40, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
+END
+
+SHELL_ABOUT_MSGBOX DIALOG LOADONCALL MOVEABLE DISCARDABLE 15, 40, 210, 152
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Om %s"
+FONT 10, "System"
+{
+ DEFPUSHBUTTON "OK", 1, 153, 130, 50, 12
+ LISTBOX 99, 8, 65, 137, 82, LBS_NOTIFY | WS_VSCROLL | WS_BORDER
+ ICON "", 1088, 189, 10, 14, 16
+ LTEXT "", 100, 8, 10, 137, 33
+ LTEXT "Wine was brought to you by:", 98, 8, 55, 137, 10
+}
+
+OPEN_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Öppna"
+FONT 8, "Helv"
+{
+ LTEXT "Fil&namn:", 1090, 6, 6, 76, 9
+ EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "&Kataloger:", -1, 110, 6, 92, 9
+ LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
+ LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "Lista över filer av &type:", 1089, 6, 104, 90, 9
+ COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Kataloger:", 1091, 110, 104, 92, 9
+ COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "Öppna", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Avbryt", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Hjälp", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "&Skrivskyddat", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+SAVE_FILE DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 275, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Spara som ..."
+FONT 8, "Helv"
+{
+ LTEXT "&Filnamn:", 1090, 6, 6, 76, 9
+ EDITTEXT 1152, 6, 16, 90, 12, ES_AUTOHSCROLL | ES_OEMCONVERT | WS_BORDER | WS_TABSTOP
+ LISTBOX 1120, 6, 32, 90, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "&Kataloger:", -1, 110, 6, 92, 9
+ LTEXT "", 1088, 110, 18, 92, 9, SS_NOPREFIX | WS_GROUP
+ LISTBOX 1121, 110, 32, 92, 68, LBS_STANDARD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_TABSTOP
+ LTEXT "Lista över filer av &typen:", 1089, 6, 104, 90, 9
+ COMBOBOX 1136, 6, 114, 90, 36, CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ LTEXT "&Kataloger:", 1091, 110, 104, 92, 9
+ COMBOBOX 1137, 110, 114, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "Spara som", 1, 208, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Avbryt", 2, 208, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Hjälp", 1038, 208, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ CHECKBOX "&Skrivskyddad", 1040, 208, 68, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+PRINT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Skriv ut"
+FONT 8, "Helv"
+{
+ LTEXT "Skrivare:", 1088, 6, 6, 40, 9
+ LTEXT "", 1089, 60, 6, 150, 9
+ GROUPBOX "Skriv ut del", 1072, 6, 30, 160, 65, BS_GROUPBOX
+ RADIOBUTTON "&Allt", 1056, 16, 45, 60, 12
+ RADIOBUTTON "&Markerat", 1057, 16, 60, 60, 12
+ RADIOBUTTON "&Sidor", 1058, 16, 75, 60, 12
+ DEFPUSHBUTTON "Skriv ut", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Avbryt", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Inställningar", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ LTEXT "&Fråm:", 1090, 60, 80, 30, 9
+ LTEXT "&Till:", 1091, 120, 80, 30, 9
+ LTEXT "Utskriftskvalitet:", 1092, 6, 100, 76, 9
+ COMBOBOX 1136, 80, 100, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ CHECKBOX "&Skriv till fil", 1040, 20, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Sammantryckt", 1041, 160, 100, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+}
+
+
+PRINT_SETUP DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 134
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Skrivar inställningar"
+FONT 8, "Helv"
+{
+ GROUPBOX "Skrivare", 1072, 6, 10, 180, 65, BS_GROUPBOX
+ RADIOBUTTON "&Standardskrivare", 1056, 16, 20, 80, 12
+ LTEXT "[none]", 1088, 35, 35, 120, 9
+ RADIOBUTTON "Specifierad &skrivare", 1057, 16, 50, 80, 12
+ COMBOBOX 1136, 35, 65, 149, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "Ok", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Avbryt", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Inställningar", 1024, 206, 46, 56, 14, WS_GROUP | WS_TABSTOP
+ GROUPBOX "Orientering", 1073, 6, 85, 100, 50, BS_GROUPBOX
+ RADIOBUTTON "&Porträtt", 1058, 50, 100, 40, 12
+ RADIOBUTTON "&Landskap", 1059, 50, 115, 40, 12
+ ICON "LANDSCAP", 1097, 10, 95, 32, 32
+ ICON "PORTRAIT", 1098, 10, 95, 32, 32
+ GROUPBOX "Paper", 1074, 120, 85, 180, 50, BS_GROUPBOX
+ LTEXT "&Storlek", 1089, 130, 95, 30, 9
+ LTEXT "&Källa", 1090, 130, 110, 30, 9
+ COMBOBOX 1137, 155, 95, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+ COMBOBOX 1138, 155, 110, 92, 68, CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER | WS_VSCROLL | WS_TABSTOP
+}
+
+
+CHOOSE_FONT DIALOG DISCARDABLE  13, 54, 264, 147
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Font"
+FONT 8, "Helv"
+{
+    LTEXT           "&Font:",1088 ,6,3,40,9
+    COMBOBOX        1136 ,6,13,94,54,  CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    CBS_AUTOHSCROLL | CBS_SORT | WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
+    LTEXT           "Font S&til:",1089 ,108,3,44,9
+    COMBOBOX        1137,108,13,64,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE
+    LTEXT           "&Storlek:",1090,179,3,30,9
+    COMBOBOX        1138,179,13,32,54, CBS_OWNERDRAWFIXED | CBS_HASSTRINGS | CBS_DISABLENOSCROLL |
+                    WS_VSCROLL | WS_TABSTOP | CBS_SIMPLE | CBS_SORT
+    DEFPUSHBUTTON   "OK",IDOK,218,6,40,14,WS_GROUP
+    PUSHBUTTON      "Avbryt",IDCANCEL,218,23,40,14,WS_GROUP
+    PUSHBUTTON      "&Använd", 1026,218,40,40,14,WS_GROUP
+    PUSHBUTTON      "&Hjälp" , 1038,218,57,40,14,WS_GROUP
+    GROUPBOX        "Effekter",1072,6,72,84,34,WS_GROUP
+    CHECKBOX	    "Stri&keout", 1040, 10,82,50,10, BS_AUTOCHECKBOX | WS_TABSTOP
+    CHECKBOX 	    "&Understryken", 1041, 10,94,50,10, BS_AUTOCHECKBOX 
+    LTEXT           "&Färg:", 1091 ,6,110,30,9
+    COMBOBOX        1139,6,120,84,100,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED | CBS_HASSTRINGS |
+		    CBS_AUTOHSCROLL |  WS_BORDER | WS_VSCROLL | WS_TABSTOP
+    GROUPBOX        "Test",1073,98,72,160,49,WS_GROUP
+    CTEXT           "AaBbYyZz",1093,104,81,149,37,SS_NOPREFIX | WS_VISIBLE
+}
+
+
+CHOOSE_COLOR DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 300, 200
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Färg"
+FONT 8, "Helv"
+{
+ LTEXT "&Grundläggande färger:",   1088, 4,    4,  140, 10
+ LTEXT "&Egendefinerade färger:",  1089, 4,   106, 140, 10
+ LTEXT "Enfärgat",  1090, 150, 151,  48, 10
+ LTEXT   "&Röd:", 726 /*1094*/,249,126,24,10
+ EDITTEXT 706, 275,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT   "&Grön:",727/*1095*/,249,140,24,10
+ EDITTEXT 707, 275,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT   "&Blå:",728 /*1096*/,249,154,24,10
+ EDITTEXT 708, 275,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT  "&Int:" ,723 /*1091*/,202,126,22,10
+ EDITTEXT 703, 226,124,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT  "&Met:" ,724 /*1092*/,202,140,22,10
+ EDITTEXT 704, 226,138,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT  "&Lum:" ,725 /*1093*/,202,154,22,10
+ EDITTEXT 705, 226,152,18,12, WS_BORDER | WS_GROUP | WS_TABSTOP
+ CONTROL "" ,720,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,14,140,86
+ CONTROL "" ,721,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP,4,116,140,28
+ CONTROL "" ,710,"STATIC",WS_BORDER|SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,4,118,116
+ CONTROL "" ,702,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 278,4,8,116
+ CONTROL "" ,709,"STATIC",SS_SIMPLE|WS_TABSTOP|WS_GROUP, 152,124,40,26
+ DEFPUSHBUTTON "Ok",  1,  4, 166, 44, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Avbryt", 2, 52, 166, 44, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Hjälp", 1038,100,166, 44, 14
+ PUSHBUTTON "&Lägg till egendefinerad färg",    712/*1024*/, 152, 166, 142, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Defingnera egen färg >>", 719/*1025*/,   4, 150, 142, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON  "&i",713,300,200,4,14   /* just a dummy:  'i' is  like  &i  in "sol&id"  */
+}
+
+
+FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Sök"
+FONT 8, "Helv"
+{
+ LTEXT "&Sök efter vad:", -1, 4, 8, 42, 8
+ EDITTEXT 1152, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "&Bara hela ord", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "&Skillnad på stora/små bokstäver", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ GROUPBOX "Riktning", 1072, 107, 26, 68, 28
+ CONTROL "&Upp", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12
+ CONTROL "&Ner", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12
+ DEFPUSHBUTTON "&Sök efter nästa", 1, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Avbryt", 2, 182, 23, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Hjälp", 1038, 182, 45, 50, 14, WS_GROUP | WS_TABSTOP
+}
+
+
+REPLACE_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 230, 94
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Sök/ersätt"
+FONT 8, "Helv"
+{
+ LTEXT "&Söka efter:", -1, 4, 9, 48, 8
+ EDITTEXT 1152, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT "&Ersätta med:", -1, 4, 26, 48, 8
+ EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "&Bara hela ord", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "&Skillnad på stora/små bokstäver", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ DEFPUSHBUTTON "&Sök efter nästa", 1, 174, 4, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Ersätt", 1024, 174, 21, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Ersätt &alla", 1025, 174, 38, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Avbryt", 2, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Hjälp", 1038, 174, 75, 50, 14, WS_GROUP | WS_TABSTOP
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/scheduler/critsection.c b/scheduler/critsection.c
index dc91651..c97c295 100644
--- a/scheduler/critsection.c
+++ b/scheduler/critsection.c
@@ -13,6 +13,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdio.h>
+#include <sys/types.h>
 #include <sys/sem.h>
 #include "windows.h"
 #include "winerror.h"
@@ -230,6 +231,16 @@
 
 
 /***********************************************************************
+ *           ReinitializeCriticalSection   (KERNEL32.581)
+ */
+void WINAPI ReinitializeCriticalSection( CRITICAL_SECTION *crit )
+{
+    DeleteCriticalSection( crit );
+    InitializeCriticalSection( crit );
+}
+
+
+/***********************************************************************
  *           CRIT_SECTION_Signaled
  */
 static BOOL32 CRIT_SECTION_Signaled( K32OBJ *obj, DWORD thread_id )
diff --git a/scheduler/process.c b/scheduler/process.c
index d42f3f3..aa44093 100644
--- a/scheduler/process.c
+++ b/scheduler/process.c
@@ -21,11 +21,6 @@
 #define HTABLE_SIZE  0x30  /* Handle table initial size */
 #define HTABLE_INC   0x10  /* Handle table increment */
 
-/* PDB <-> Process id conversion macros */
-#define PROCESS_OBFUSCATOR     ((DWORD)0xdeadbeef)
-#define PROCESS_ID_TO_PDB(id)  ((PDB32 *)((id) ^ PROCESS_OBFUSCATOR))
-#define PDB_TO_PROCESS_ID(pdb) ((DWORD)(pdb) ^ PROCESS_OBFUSCATOR)
-
 static BOOL32 PROCESS_Signaled( K32OBJ *obj, DWORD thread_id );
 static BOOL32 PROCESS_Satisfied( K32OBJ *obj, DWORD thread_id );
 static void PROCESS_AddWait( K32OBJ *obj, DWORD thread_id );
diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c
index 08c4dc3..92cf811 100644
--- a/scheduler/sysdeps.c
+++ b/scheduler/sysdeps.c
@@ -4,10 +4,24 @@
  * Copyright 1998 Alexandre Julliard
  */
 
+#define NO_REENTRANT_X11
+
+#ifdef NO_REENTRANT_X11
+/* Get pointers to the static errno and h_errno variables used by Xlib. This
+   must be done before including <errno.h> makes the variables invisible.  */
+extern int errno;
+static int *perrno = &errno;
+extern int h_errno;
+static int *ph_errno = &h_errno;
+#endif
+
 #include <signal.h>
 #include <stdio.h>
 #include <unistd.h>
 #include "thread.h"
+#ifdef NO_REENTRANT_X11
+#include "tsx11defs.h"
+#endif
 
 #ifdef __linux__
 # ifdef HAVE_SCHED_H
@@ -35,6 +49,12 @@
 {
     static int static_errno;
     THDB *thdb = THREAD_Current();
+#ifdef NO_REENTRANT_X11
+    /* Use static libc errno while running in Xlib. */
+    if (TSX11_SectionPtr &&
+        (TSX11_SectionPtr->OwningThread == THDB_TO_THREAD_ID(thdb)))
+        return perrno;
+#endif
     if (!thdb) return &static_errno;
     return &thdb->thread_errno;
 }
@@ -48,6 +68,12 @@
 {
     static int static_h_errno;
     THDB *thdb = THREAD_Current();
+#ifdef NO_REENTRANT_X11
+    /* Use static libc h_errno while running in Xlib. */
+    if (TSX11_SectionPtr &&
+        (TSX11_SectionPtr->OwningThread == THDB_TO_THREAD_ID(thdb)))
+        return ph_errno;
+#endif
     if (!thdb) return &static_h_errno;
     return &thdb->thread_h_errno;
 }
diff --git a/scheduler/thread.c b/scheduler/thread.c
index 984b89c..2629419 100644
--- a/scheduler/thread.c
+++ b/scheduler/thread.c
@@ -184,6 +184,7 @@
     thdb->context.SegFs   = thdb->teb_sel;
     thdb->context.Eip     = (DWORD)start_addr;
     thdb->context.Esp     = (DWORD)thdb->teb.stack_top;
+    PE_InitTls( thdb );
     return thdb;
 
 error:
@@ -314,7 +315,11 @@
     while (thdb->mutex_list) MUTEX_Abandon( thdb->mutex_list );
 
     /* FIXME: should free the stack somehow */
+#if 0
+    /* FIXME: We cannot do this; once the current thread is destroyed,
+       synchronization primitives do not work properly. */
     K32OBJ_DecCount( &thdb->header );
+#endif
     /* Completely unlock the system lock just in case */
     count = SYSTEM_LOCK_COUNT();
     while (count--) SYSTEM_UNLOCK();
diff --git a/tools/build.c b/tools/build.c
index 1cc07e7..93a97d7 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -18,6 +18,7 @@
 #include "neexe.h"
 #include "selectors.h"
 #include "stackframe.h"
+#include "thread.h"
 
 #ifdef NEED_UNDERSCORE_PREFIX
 # define PREFIX "_"
@@ -163,6 +164,10 @@
   /* Offset of register relative to the start of the CONTEXT struct */
 #define CONTEXTOFFSET(reg)  STRUCTOFFSET(CONTEXT,reg)
 
+  /* Offset of the stack pointer relative to %fs:(0) */
+#define STACKOFFSET (STRUCTOFFSET(THDB,cur_stack) - STRUCTOFFSET(THDB,teb))
+
+
 static void *xmalloc (size_t size)
 {
     void *res;
@@ -1535,7 +1540,7 @@
 
     fprintf( outfile, "\tpushl %%ebx\n" );
 
-    /* Restore 32-bit ds and es */
+    /* Restore 32-bit segment registers */
 
     fprintf( outfile, "\tmovw $0x%04x,%%bx\n", Data_Selector );
 #ifdef __svr4__
@@ -1546,18 +1551,19 @@
     fprintf( outfile, "\tdata16\n");
 #endif
     fprintf( outfile, "\tmovw %%bx,%%es\n" );
+    fprintf( outfile, "\tmovw " PREFIX "CALLTO16_Current_fs,%%fs\n" );
 
-    /* Get the 32-bit stack pointer */
+    /* Get the 32-bit stack pointer from the TEB */
 
-    fprintf( outfile, "\tmovl " PREFIX "CALLTO16_Saved32_esp,%%ebx\n" );
+    fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%ebx\n", STACKOFFSET );
 
     /* Save the 16-bit stack */
 
 #ifdef __svr4__
     fprintf( outfile,"\tdata16\n");
 #endif
-    fprintf( outfile, "\tmovw %%ss," PREFIX "IF1632_Saved16_ss_sp+2\n" );
-    fprintf( outfile, "\tmovw %%sp," PREFIX "IF1632_Saved16_ss_sp\n" );
+    fprintf( outfile, "\t.byte 0x64\n\tmovw %%ss,(%d)\n", STACKOFFSET + 2 );
+    fprintf( outfile, "\t.byte 0x64\n\tmovw %%sp,(%d)\n", STACKOFFSET );
 
     /* Transfer the arguments */
 
@@ -1633,9 +1639,10 @@
 #ifdef __svr4__
     fprintf( outfile, "\tdata16\n");
 #endif
-    fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp+2,%%ss\n" );
-    fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp,%%sp\n" );
-    fprintf( outfile, "\tpopl " PREFIX "CALLTO16_Saved32_esp\n" );
+    fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%ss\n", STACKOFFSET + 2 );
+    fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%sp\n", STACKOFFSET );
+    fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET );
+    fprintf( outfile, "\tmovw %%fs," PREFIX "CALLTO16_Current_fs\n" );
 
     if (reg_func)
     {
@@ -1673,7 +1680,7 @@
         fprintf( outfile, "\tincl %%esp\n" );
         fprintf( outfile, "\tpopl %%edx\n" );      /* Remove cs and ds */
         fprintf( outfile, "\tmovw %%dx,%%ds\n" );  /* and restore ds */
-        fprintf( outfile, "\t.byte 0x66\n\tpopl %%es\n" );       /* Restore es */
+        fprintf( outfile, "\t.byte 0x66\n\tpopl %%es\n" );    /* Restore es */
 
         if (short_ret) fprintf( outfile, "\tpopl %%edx\n" );  /* Restore edx */
         else
@@ -1793,23 +1800,25 @@
         fprintf( outfile, "\tpopl %%eax\n" );
     }
 
-    /* Save the 32-bit stack */
+    /* Save the 32-bit stack and %fs */
 
-    fprintf( outfile, "\tpushl " PREFIX "IF1632_Saved16_ss_sp\n" );
-    fprintf( outfile, "\tmovl %%esp," PREFIX "CALLTO16_Saved32_esp\n" );
+    fprintf( outfile, "\t.byte 0x64\n\tpushl (%d)\n", STACKOFFSET );
     fprintf( outfile, "\tmovl %%ebp,%%ebx\n" );
+    fprintf( outfile, "\tmovl %%esp,%%edx\n" );
+    fprintf( outfile, "\tmovw %%fs," PREFIX "CALLTO16_Current_fs\n" );
 
     if (reg_func)
     {
         /* Switch to the 16-bit stack, saving the current %%esp, */
         /* and adding the specified offset to the new sp */
-        fprintf( outfile, "\tmovzwl " PREFIX "IF1632_Saved16_ss_sp,%%eax\n" );
+        fprintf( outfile, "\t.byte 0x64\n\tmovzwl (%d),%%eax\n", STACKOFFSET );
         fprintf( outfile, "\tsubl 12(%%ebx),%%eax\n" ); /* Get the offset */
 #ifdef __svr4__
         fprintf( outfile,"\tdata16\n");
 #endif
-        fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp+2,%%ss\n" );
+        fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%ss\n", STACKOFFSET + 2);
         fprintf( outfile, "\tmovl %%eax,%%esp\n" );
+        fprintf( outfile, "\t.byte 0x64\n\tmovl %%edx,(%d)\n", STACKOFFSET );
 
         /* Get the registers. ebx is handled later on. */
 
@@ -1828,13 +1837,13 @@
 	 * With lreg suffix, we push 16:32 address (0x66 lret, for KERNEL32_45)
 	 */
 	if (reg_func == 1)
-	    fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_regs\n" );
+	    fprintf( outfile, "\tpushl " PREFIX "CALLTO16_RetAddr_long\n" );
 	else 
 	{
 	    fprintf( outfile, "\tpushw $0\n" );
-	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_regs+2\n" );
+	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_long+2\n" );
 	    fprintf( outfile, "\tpushw $0\n" );
-	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_regs\n" );
+	    fprintf( outfile, "\tpushw " PREFIX "CALLTO16_RetAddr_long\n" );
 	}
 
         /* Push the called routine address */
@@ -1857,8 +1866,9 @@
 #ifdef __svr4__
         fprintf( outfile,"\tdata16\n");
 #endif
-        fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp+2,%%ss\n" );
-        fprintf( outfile, "\tmovw " PREFIX "IF1632_Saved16_ss_sp,%%sp\n" );
+        fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%ss\n", STACKOFFSET + 2);
+        fprintf( outfile, "\t.byte 0x64\n\tmovw (%d),%%sp\n", STACKOFFSET );
+        fprintf( outfile, "\t.byte 0x64\n\tmovl %%edx,(%d)\n", STACKOFFSET );
 
         /* Make %bp point to the previous stackframe (built by CallFrom16) */
         fprintf( outfile, "\tmovzwl %%sp,%%ebp\n" );
@@ -1916,18 +1926,13 @@
 {
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_word\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_long\n" );
-    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Ret_regs\n" );
 
     fprintf( outfile, PREFIX "CALLTO16_Ret_word:\n" );
     fprintf( outfile, "\txorl %%edx,%%edx\n" );
 
-    /* Remove the arguments just in case */
-
-    fprintf( outfile, PREFIX "CALLTO16_Ret_long:\n" );
-
     /* Put return value into %eax */
 
-    fprintf( outfile, PREFIX "CALLTO16_Ret_regs:\n" );
+    fprintf( outfile, PREFIX "CALLTO16_Ret_long:\n" );
     fprintf( outfile, "\tshll $16,%%edx\n" );
     fprintf( outfile, "\tmovw %%ax,%%dx\n" );
     fprintf( outfile, "\tmovl %%edx,%%eax\n" );
@@ -1943,6 +1948,7 @@
     fprintf( outfile, "\tdata16\n");
 #endif
     fprintf( outfile, "\tmovw %%bx,%%es\n" );
+    fprintf( outfile, "\tmovw " PREFIX "CALLTO16_Current_fs,%%fs\n" );
 
     /* Restore the 32-bit stack */
 
@@ -1950,8 +1956,8 @@
     fprintf( outfile, "\tdata16\n");
 #endif
     fprintf( outfile, "\tmovw %%bx,%%ss\n" );
-    fprintf( outfile, "\tmovl " PREFIX "CALLTO16_Saved32_esp,%%esp\n" );
-    fprintf( outfile, "\tpopl " PREFIX "IF1632_Saved16_ss_sp\n" );
+    fprintf( outfile, "\t.byte 0x64\n\tmovl (%d),%%esp\n", STACKOFFSET );
+    fprintf( outfile, "\t.byte 0x64\n\tpopl (%d)\n", STACKOFFSET );
 
     /* Restore the 32-bit registers */
 
@@ -1970,12 +1976,10 @@
     fprintf( outfile, "\t.data\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_word\n" );
     fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_long\n" );
-    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_RetAddr_regs\n" );
-    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Saved32_esp\n" );
+    fprintf( outfile, "\t.globl " PREFIX "CALLTO16_Current_fs\n" );
     fprintf( outfile, PREFIX "CALLTO16_RetAddr_word:\t.long 0\n" );
     fprintf( outfile, PREFIX "CALLTO16_RetAddr_long:\t.long 0\n" );
-    fprintf( outfile, PREFIX "CALLTO16_RetAddr_regs:\t.long 0\n" );
-    fprintf( outfile, PREFIX "CALLTO16_Saved32_esp:\t.long 0\n" );
+    fprintf( outfile, PREFIX "CALLTO16_Current_fs:\t.long 0\n" );
     fprintf( outfile, "\t.text\n" );
 }
 
diff --git a/tools/make_X11wrappers b/tools/make_X11wrappers
new file mode 100755
index 0000000..8dffbb3
--- /dev/null
+++ b/tools/make_X11wrappers
@@ -0,0 +1,227 @@
+#!/usr/bin/perl -w
+
+# Create threads safe wrappers around X11 calls.
+#
+# Copyright 1998 Kristian Nielsen.
+#
+
+# FIXME: This does not do full C prototype parsing, but relies on
+# knowledge on how the X11 include files are formatted. It will
+# probably need to be modified for new include files. It also fails
+# for certain prototypes (notably those with function pointer
+# arguments or results), so these must be added manually. And it
+# relies on a fixed location of X11 includes (/usr/X11R6/include/).
+#
+# This program expects to be run from Wine's main directory.
+
+$X11_include_dir = "/usr/X11R6/include";
+$outdir = "tsx11";
+$wantfile = "$outdir/X11_calls";
+@dolist = ("Xlib", "Xresource", "Xutil", "xpm", "XShm");
+
+# First read list of wanted function names.
+
+open(WANT, $wantfile) || die "open";
+while(<WANT>) {
+    next if /^\s*\#/;		# Skip comment lines.
+    next if /^\s*$/;		# Skip empty lines.
+    if(/^\s*([a-zA-Z0-9_]+)\s*$/) {
+	$want{$1} = 1;
+    } else {
+	die "syntax error in file '$wantfile', in line '$_'";
+    }
+}
+close(WANT);
+
+foreach $name (@dolist) {
+
+    $ucname = uc $name;
+    $lcname = lc $name;
+
+    $outfile = "/ts_$lcname";
+    open(OUTC, ">$outdir/$outfile.c") || die "open";
+    open(OUTH, ">include/$outfile.h") || die "open";
+
+    $x11_incl = "";
+    $extensions_dir = "";
+    if($name eq "Xutil" || $name eq "Xresource" || $name eq "XShm") {
+	$x11_incl = "#include <X11/Xlib.h>\n";
+	# For Xutil, we need X11/Xresource.h for XUniqueContext().
+	$x11_incl .= "#include <X11/Xresource.h>\n" if $name eq "Xutil";
+    }
+    if($name eq "XShm") {
+	$extensions_dir = "extensions/";
+    }
+
+    print OUTH <<END;
+/*
+ * Thread safe wrappers around $name calls.
+ * Always include this file instead of <X11/$name.h>.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#ifndef __WINE_TS$ucname\_H
+#define __WINE_TS$ucname\_H
+
+$x11_incl#include <X11/$extensions_dir$name.h>
+
+END
+
+    print OUTC <<END;
+/*
+ * Thread safe wrappers around $name calls.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+$x11_incl#include <X11/$extensions_dir$name.h>
+#include "tsx11defs.h"
+#include "stddebug.h"
+#include "debug.h"
+END
+
+    if($name eq "xpm") {	# Handle as special case.
+	output_fn("XpmCreatePixmapFromData", "int",
+		  "Display *, Drawable, char **, Pixmap *, Pixmap *, XpmAttributes *",
+		  "Display *a0, Drawable a1, char **a2, Pixmap *a3, Pixmap *a4, XpmAttributes *a5",
+		  "a0, a1, a2, a3, a4, a5");
+	output_fn("XpmAttributesSize", "int", "void", "void", "");
+    } elsif($name eq "XShm") {
+	output_fn("XShmQueryExtension", "Bool",
+		  "Display *", "Display *a0", "a0");
+	output_fn("XShmPixmapFormat", "int",
+		  "Display *", "Display *a0", "a0");
+	output_fn("XShmDetach", Status,
+		  "Display *, XShmSegmentInfo *",
+		  "Display *a0, XShmSegmentInfo *a1", "a0, a1");
+	output_fn("XShmAttach", Status,
+		  "Display *, XShmSegmentInfo *",
+		  "Display *a0, XShmSegmentInfo *a1", "a0, a1");
+    } else {
+	open(IN, "echo \"$x11_incl#include <X11/$extensions_dir$name.h>\" | gcc -L$X11_include_dir -E - | grep -v '^[ \t]*\$'|") || die "open";
+
+      PROTO: while(<IN>) {
+	  if(m'extern\s+([^()]*)\b([a-zA-Z0-9_]+)\s*\(') {
+	      $result_type = $1;
+	      $fn_name = $2;
+	      $result_type = "int" if $result_type =~ /^\s*$/;
+	      @args = ();
+	      while(<IN>) {
+		  last if m'\)\s*;';
+		  # Give up on vararg functions and function pointer args.
+		  if(m'\.\.\.|\(\*\)') {
+		      undef $fn_name;
+		      last;
+		  }
+		  if(m'\s*([^,]*[^, \t])\s*(,?\n)') {
+		      $args[$#args+1] = $1;
+		  }
+	      }
+	      # Skip if vararg, function pointer arg, or not needed.
+	      next unless $fn_name;
+	      next unless $want{$fn_name} && $want{$fn_name} == 1;
+
+	      # Special case for no arguments (which is specified as "void").
+	      if($#args == 0 && $args[0] eq "void") {
+		  @args = ();
+	      }
+	      $proto = "";
+	      $formals = "";
+	      $actuals = "";
+	      for($i = 0; $i <= $#args; $i++) {
+		  $comma = $i < $#args ? ", " : "";
+		  $proto .= "$args[$i]$comma";
+		  $formals .= "$args[$i] a$i$comma";
+		  $actuals .= "a$i$comma";
+	      }
+	      $proto = $formals = "void" if $#args == -1;
+	      output_fn($fn_name, $result_type, $proto, $formals, $actuals);
+	  }
+      }
+    }
+
+    if($name eq "Xlib") {
+	raw_output_fn("XSynchronize", "int (*r)(Display *)",
+		  "int (*TSXSynchronize(Display *, Bool))(Display *)",
+		  "int (*TSXSynchronize(Display *a0, Bool a1))(Display *)",
+		  "a0, a1");
+	print OUTC "\nextern void _XInitImageFuncPtrs(XImage *);\n";
+	output_fn("_XInitImageFuncPtrs", "void", "XImage *", "XImage *a0", "a0");
+    } elsif($name eq "Xutil") {
+	output_fn("XDestroyImage", "int",
+		  "struct _XImage *", "struct _XImage *a0", "a0");
+	output_fn("XGetPixel", "unsigned long",
+		  "struct _XImage *, int, int",
+		  "struct _XImage *a0, int a1, int a2",
+		  "a0, a1, a2");
+	output_fn("XPutPixel", "int",
+		  "struct _XImage *, int, int, unsigned long",
+		  "struct _XImage *a0, int a1, int a2, unsigned long a3",
+		  "a0, a1, a2, a3");
+	output_fn("XSubImage", "struct _XImage *",
+		  "struct _XImage *, int, int, unsigned int, unsigned int",
+		  "struct _XImage *a0, int a1, int a2, unsigned int a3, unsigned int a4",
+		  "a0, a1, a2, a3, a4");
+	output_fn("XAddPixel", "int",
+		  "struct _XImage *, long",
+		  "struct _XImage *a0, long a1", "a0, a1");
+	output_fn("XUniqueContext", "XContext", "void", "void", "");
+    }
+
+    print OUTH <<END;
+
+#endif /* __WINE_TS$ucname\_H */
+END
+
+}
+
+foreach $i (keys %want) {
+    if($want{$i} == 1) {
+	print "Unresolved: $i\n";
+    }
+}
+
+
+sub output_fn {
+    # Example call:
+    # output_fn("main", "int", "int, char **", "int a0, char **a1", "a0, a1")
+    #
+
+    my ($fn_name, $result_type, $protos, $formals, $actuals) = @_;
+
+    return raw_output_fn($fn_name,
+			 $result_type =~ /^\s*void\s*$/ ? "" : "$result_type r",
+			 "$result_type TS$fn_name($protos)",
+			 "$result_type TS$fn_name($formals)",
+			 $actuals);
+}
+
+sub raw_output_fn {
+    # Example call:
+    # output_fn("main", "int r", "int main(int, char **)", "int main(int a0, char **a1)", "a0, a1")
+    #
+
+    my ($fn_name, $resultdecl, $protodecl, $defdecl, $actuals) = @_;
+
+    return undef unless $want{$fn_name} && $want{$fn_name} == 1;
+
+    print OUTC "\n$defdecl\n";
+    print OUTH "extern $protodecl;\n";
+#    print OUTH "#define $fn_name TS$fn_name\n";
+    print OUTC "{\n";
+    print OUTC "  $resultdecl;\n" if $resultdecl;
+    print OUTC "  dprintf_x11(stddeb, \"Call $fn_name\\n\");\n";
+    print OUTC "  X11_LOCK();\n";
+    print OUTC "  ";
+    print OUTC "r = " if $resultdecl;
+    print OUTC "$fn_name($actuals);\n";
+    print OUTC "  X11_UNLOCK();\n";
+    print OUTC "  dprintf_x11(stddeb, \"Ret $fn_name\\n\");\n";
+    print OUTC "  return r;\n" if $resultdecl;
+    print OUTC "}\n";
+    $want{$fn_name} = 2;
+    return 1;
+}
diff --git a/tsx11/Makefile.in b/tsx11/Makefile.in
new file mode 100644
index 0000000..4f935a1
--- /dev/null
+++ b/tsx11/Makefile.in
@@ -0,0 +1,20 @@
+DEFS      = @DLLFLAGS@ -D__WINE__
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ..
+SRCDIR    = @srcdir@
+VPATH     = @srcdir@
+MODULE    = tsx11
+
+C_SRCS = \
+	ts_xshm.c \
+	ts_xlib.c \
+	ts_xresource.c \
+	ts_xutil.c \
+	ts_xpm.c \
+	tsx11defs.c
+
+all: $(MODULE).o
+
+@MAKE_RULES@
+
+### Dependencies:
diff --git a/tsx11/X11_calls b/tsx11/X11_calls
new file mode 100644
index 0000000..4b442df
--- /dev/null
+++ b/tsx11/X11_calls
@@ -0,0 +1,165 @@
+# This file contains the list of X11 calls that Wine uses and which must be
+# protected by a critical section for multi-threaded use.
+#
+# To add a new call, put it on this list and run tools/make_X11wrappers.
+# Also read the comments at the top of tools_make_X11wrappers.
+#
+XActivateScreenSaver
+XAddPixel
+XAllocClassHint
+XAllocColor
+XAllocColorCells
+XAllocSizeHints
+XAllocWMHints
+XBell
+XChangeGC
+XChangeKeyboardControl
+XChangeProperty
+XChangeWindowAttributes
+XCheckTypedWindowEvent
+XCheckWindowEvent
+XClipBox
+XConvertSelection
+XCopyArea
+XCopyPlane
+XCreateBitmapFromData
+XCreateColormap
+XCreateFontCursor
+XCreateGC
+XCreateImage
+XCreatePixmap
+XCreatePixmapCursor
+XCreateRegion
+XCreateWindow
+XDefineCursor
+XDeleteContext
+XDestroyImage
+XDestroyRegion
+XDestroyWindow
+XDisplayKeycodes
+XDrawArc
+XDrawLine
+XDrawLines
+XDrawPoint
+XDrawRectangle
+XDrawSegments
+XDrawString
+XDrawText
+XEmptyRegion
+XEqualRegion
+XFillArc
+XFillPolygon
+XFillRectangle
+XFindContext
+XFlush
+XFree
+XFreeColors
+XFreeCursor
+XFreeFont
+XFreeFontNames
+XFreeGC
+XFreeModifiermap
+XFreePixmap
+XGetAtomName
+XGetFontProperty
+XGetGeometry
+XGetImage
+XGetInputFocus
+XGetKeyboardControl
+XGetKeyboardMapping
+XGetModifierMapping
+XGetPixel
+XGetScreenSaver
+XGetSelectionOwner
+XGetWMSizeHints
+XGetWindowAttributes
+XGetWindowProperty
+XGrabPointer
+XGrabServer
+XInitThreads
+XInstallColormap
+XInternAtom
+XIntersectRegion
+XKeycodeToKeysym
+XKeysymToKeycode
+XKeysymToString
+XListDepths
+XListFonts
+XLoadQueryFont
+XLookupKeysym
+XLookupString
+XMapWindow
+XNextEvent
+XOffsetRegion
+XOpenDisplay
+XParseGeometry
+XPending
+XPointInRegion
+XPolygonRegion
+XPutBackEvent
+XPutImage
+XPutPixel
+XQueryColor
+XQueryPointer
+XQueryTree
+XReconfigureWMWindow
+XRectInRegion
+XResetScreenSaver
+XResourceManagerString
+XRestackWindows
+XSaveContext
+XSendEvent
+XSetArcMode
+XSetBackground
+XSetClipMask
+XSetClipOrigin
+XSetClipRectangles
+XSetDashes
+XSetFillStyle
+XSetForeground
+XSetFunction
+XSetGraphicsExposures
+XSetIconName
+XSetInputFocus
+XSetLineAttributes
+XSetRegion
+XSetScreenSaver
+XSetSelectionOwner
+XSetSubwindowMode
+XSetTransientForHint
+XSetWMProperties
+XSetWMProtocols
+XSetWMSizeHints
+XShmAttach
+XShmDetach
+XShmPixmapFormat
+XShmQueryExtension
+XShrinkRegion
+XStoreColor
+XStoreName
+XStringListToTextProperty
+XSubImage
+XSubtractRegion
+XSync
+XSynchronize
+XTextExtents
+XTextWidth
+XUngrabPointer
+XUngrabServer
+XUninstallColormap
+XUnionRectWithRegion
+XUnionRegion
+XUniqueContext
+XUnmapWindow
+XWarpPointer
+XXorRegion
+XpmAttributesSize
+XpmCreatePixmapFromData
+XrmGetFileDatabase
+XrmGetResource
+XrmGetStringDatabase
+XrmInitialize
+XrmMergeDatabases
+XrmParseCommand
+XrmUniqueQuark
+_XInitImageFuncPtrs
diff --git a/tsx11/ts_xlib.c b/tsx11/ts_xlib.c
new file mode 100644
index 0000000..6ae7f4f
--- /dev/null
+++ b/tsx11/ts_xlib.c
@@ -0,0 +1,1263 @@
+/*
+ * Thread safe wrappers around Xlib calls.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#include <X11/Xlib.h>
+#include "tsx11defs.h"
+#include "stddebug.h"
+#include "debug.h"
+
+XFontStruct * TSXLoadQueryFont(Display* a0, const  char* a1)
+{
+  XFontStruct * r;
+  dprintf_x11(stddeb, "Call XLoadQueryFont\n");
+  X11_LOCK();
+  r = XLoadQueryFont(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XLoadQueryFont\n");
+  return r;
+}
+
+XModifierKeymap	* TSXGetModifierMapping(Display* a0)
+{
+  XModifierKeymap	* r;
+  dprintf_x11(stddeb, "Call XGetModifierMapping\n");
+  X11_LOCK();
+  r = XGetModifierMapping(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetModifierMapping\n");
+  return r;
+}
+
+XImage * TSXCreateImage(Display* a0, Visual* a1, unsigned int a2, int a3, int a4, char* a5, unsigned int a6, unsigned int a7, int a8, int a9)
+{
+  XImage * r;
+  dprintf_x11(stddeb, "Call XCreateImage\n");
+  X11_LOCK();
+  r = XCreateImage(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCreateImage\n");
+  return r;
+}
+
+XImage * TSXGetImage(Display* a0, Drawable a1, int a2, int a3, unsigned int a4, unsigned int a5, unsigned long a6, int a7)
+{
+  XImage * r;
+  dprintf_x11(stddeb, "Call XGetImage\n");
+  X11_LOCK();
+  r = XGetImage(a0, a1, a2, a3, a4, a5, a6, a7);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetImage\n");
+  return r;
+}
+
+Display * TSXOpenDisplay(const  char* a0)
+{
+  Display * r;
+  dprintf_x11(stddeb, "Call XOpenDisplay\n");
+  X11_LOCK();
+  r = XOpenDisplay(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XOpenDisplay\n");
+  return r;
+}
+
+void  TSXrmInitialize(void)
+{
+  dprintf_x11(stddeb, "Call XrmInitialize\n");
+  X11_LOCK();
+  XrmInitialize();
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XrmInitialize\n");
+}
+
+char * TSXGetAtomName(Display* a0, Atom a1)
+{
+  char * r;
+  dprintf_x11(stddeb, "Call XGetAtomName\n");
+  X11_LOCK();
+  r = XGetAtomName(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetAtomName\n");
+  return r;
+}
+
+char * TSXKeysymToString(KeySym a0)
+{
+  char * r;
+  dprintf_x11(stddeb, "Call XKeysymToString\n");
+  X11_LOCK();
+  r = XKeysymToString(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XKeysymToString\n");
+  return r;
+}
+
+Atom  TSXInternAtom(Display* a0, const  char* a1, int a2)
+{
+  Atom  r;
+  dprintf_x11(stddeb, "Call XInternAtom\n");
+  X11_LOCK();
+  r = XInternAtom(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XInternAtom\n");
+  return r;
+}
+
+Colormap  TSXCreateColormap(Display* a0, Window a1, Visual* a2, int a3)
+{
+  Colormap  r;
+  dprintf_x11(stddeb, "Call XCreateColormap\n");
+  X11_LOCK();
+  r = XCreateColormap(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCreateColormap\n");
+  return r;
+}
+
+Cursor  TSXCreatePixmapCursor(Display* a0, Pixmap a1, Pixmap a2, XColor* a3, XColor* a4, unsigned int a5, unsigned int a6)
+{
+  Cursor  r;
+  dprintf_x11(stddeb, "Call XCreatePixmapCursor\n");
+  X11_LOCK();
+  r = XCreatePixmapCursor(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCreatePixmapCursor\n");
+  return r;
+}
+
+Cursor  TSXCreateFontCursor(Display* a0, unsigned int a1)
+{
+  Cursor  r;
+  dprintf_x11(stddeb, "Call XCreateFontCursor\n");
+  X11_LOCK();
+  r = XCreateFontCursor(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCreateFontCursor\n");
+  return r;
+}
+
+GC  TSXCreateGC(Display* a0, Drawable a1, unsigned long a2, XGCValues* a3)
+{
+  GC  r;
+  dprintf_x11(stddeb, "Call XCreateGC\n");
+  X11_LOCK();
+  r = XCreateGC(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCreateGC\n");
+  return r;
+}
+
+Pixmap  TSXCreatePixmap(Display* a0, Drawable a1, unsigned int a2, unsigned int a3, unsigned int a4)
+{
+  Pixmap  r;
+  dprintf_x11(stddeb, "Call XCreatePixmap\n");
+  X11_LOCK();
+  r = XCreatePixmap(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCreatePixmap\n");
+  return r;
+}
+
+Pixmap  TSXCreateBitmapFromData(Display* a0, Drawable a1, const  char* a2, unsigned int a3, unsigned int a4)
+{
+  Pixmap  r;
+  dprintf_x11(stddeb, "Call XCreateBitmapFromData\n");
+  X11_LOCK();
+  r = XCreateBitmapFromData(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCreateBitmapFromData\n");
+  return r;
+}
+
+Window  TSXGetSelectionOwner(Display* a0, Atom a1)
+{
+  Window  r;
+  dprintf_x11(stddeb, "Call XGetSelectionOwner\n");
+  X11_LOCK();
+  r = XGetSelectionOwner(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetSelectionOwner\n");
+  return r;
+}
+
+Window  TSXCreateWindow(Display* a0, Window a1, int a2, int a3, unsigned int a4, unsigned int a5, unsigned int a6, int a7, unsigned int a8, Visual* a9, unsigned long a10, XSetWindowAttributes* a11)
+{
+  Window  r;
+  dprintf_x11(stddeb, "Call XCreateWindow\n");
+  X11_LOCK();
+  r = XCreateWindow(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCreateWindow\n");
+  return r;
+}
+
+char ** TSXListFonts(Display* a0, const  char* a1, int a2, int* a3)
+{
+  char ** r;
+  dprintf_x11(stddeb, "Call XListFonts\n");
+  X11_LOCK();
+  r = XListFonts(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XListFonts\n");
+  return r;
+}
+
+KeySym  TSXKeycodeToKeysym(Display* a0, unsigned int a1, int a2)
+{
+  KeySym  r;
+  dprintf_x11(stddeb, "Call XKeycodeToKeysym\n");
+  X11_LOCK();
+  r = XKeycodeToKeysym(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XKeycodeToKeysym\n");
+  return r;
+}
+
+KeySym  TSXLookupKeysym(XKeyEvent* a0, int a1)
+{
+  KeySym  r;
+  dprintf_x11(stddeb, "Call XLookupKeysym\n");
+  X11_LOCK();
+  r = XLookupKeysym(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XLookupKeysym\n");
+  return r;
+}
+
+KeySym * TSXGetKeyboardMapping(Display* a0, unsigned int a1, int a2, int* a3)
+{
+  KeySym * r;
+  dprintf_x11(stddeb, "Call XGetKeyboardMapping\n");
+  X11_LOCK();
+  r = XGetKeyboardMapping(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetKeyboardMapping\n");
+  return r;
+}
+
+char * TSXResourceManagerString(Display* a0)
+{
+  char * r;
+  dprintf_x11(stddeb, "Call XResourceManagerString\n");
+  X11_LOCK();
+  r = XResourceManagerString(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XResourceManagerString\n");
+  return r;
+}
+
+int   TSXInitThreads(void)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XInitThreads\n");
+  X11_LOCK();
+  r = XInitThreads();
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XInitThreads\n");
+  return r;
+}
+
+int * TSXListDepths(Display* a0, int a1, int* a2)
+{
+  int * r;
+  dprintf_x11(stddeb, "Call XListDepths\n");
+  X11_LOCK();
+  r = XListDepths(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XListDepths\n");
+  return r;
+}
+
+int   TSXReconfigureWMWindow(Display* a0, Window a1, int a2, unsigned int a3, XWindowChanges* a4)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XReconfigureWMWindow\n");
+  X11_LOCK();
+  r = XReconfigureWMWindow(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XReconfigureWMWindow\n");
+  return r;
+}
+
+int   TSXSetWMProtocols(Display* a0, Window a1, Atom* a2, int a3)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XSetWMProtocols\n");
+  X11_LOCK();
+  r = XSetWMProtocols(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetWMProtocols\n");
+  return r;
+}
+
+int  TSXSetTransientForHint(Display* a0, Window a1, Window a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetTransientForHint\n");
+  X11_LOCK();
+  r = XSetTransientForHint(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetTransientForHint\n");
+  return r;
+}
+
+int  TSXActivateScreenSaver(Display* a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XActivateScreenSaver\n");
+  X11_LOCK();
+  r = XActivateScreenSaver(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XActivateScreenSaver\n");
+  return r;
+}
+
+int   TSXAllocColor(Display* a0, Colormap a1, XColor* a2)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XAllocColor\n");
+  X11_LOCK();
+  r = XAllocColor(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XAllocColor\n");
+  return r;
+}
+
+int   TSXAllocColorCells(Display* a0, Colormap a1, int a2, unsigned long* a3, unsigned int a4, unsigned long* a5, unsigned int a6)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XAllocColorCells\n");
+  X11_LOCK();
+  r = XAllocColorCells(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XAllocColorCells\n");
+  return r;
+}
+
+int  TSXBell(Display* a0, int a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XBell\n");
+  X11_LOCK();
+  r = XBell(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XBell\n");
+  return r;
+}
+
+int  TSXChangeGC(Display* a0, GC a1, unsigned long a2, XGCValues* a3)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XChangeGC\n");
+  X11_LOCK();
+  r = XChangeGC(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XChangeGC\n");
+  return r;
+}
+
+int  TSXChangeKeyboardControl(Display* a0, unsigned long a1, XKeyboardControl* a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XChangeKeyboardControl\n");
+  X11_LOCK();
+  r = XChangeKeyboardControl(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XChangeKeyboardControl\n");
+  return r;
+}
+
+int  TSXChangeProperty(Display* a0, Window a1, Atom a2, Atom a3, int a4, int a5, const  unsigned char* a6, int a7)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XChangeProperty\n");
+  X11_LOCK();
+  r = XChangeProperty(a0, a1, a2, a3, a4, a5, a6, a7);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XChangeProperty\n");
+  return r;
+}
+
+int  TSXChangeWindowAttributes(Display* a0, Window a1, unsigned long a2, XSetWindowAttributes* a3)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XChangeWindowAttributes\n");
+  X11_LOCK();
+  r = XChangeWindowAttributes(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XChangeWindowAttributes\n");
+  return r;
+}
+
+int   TSXCheckTypedWindowEvent(Display* a0, Window a1, int a2, XEvent* a3)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XCheckTypedWindowEvent\n");
+  X11_LOCK();
+  r = XCheckTypedWindowEvent(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCheckTypedWindowEvent\n");
+  return r;
+}
+
+int   TSXCheckWindowEvent(Display* a0, Window a1, long a2, XEvent* a3)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XCheckWindowEvent\n");
+  X11_LOCK();
+  r = XCheckWindowEvent(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCheckWindowEvent\n");
+  return r;
+}
+
+int  TSXConvertSelection(Display* a0, Atom a1, Atom a2, Atom a3, Window a4, Time a5)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XConvertSelection\n");
+  X11_LOCK();
+  r = XConvertSelection(a0, a1, a2, a3, a4, a5);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XConvertSelection\n");
+  return r;
+}
+
+int  TSXCopyArea(Display* a0, Drawable a1, Drawable a2, GC a3, int a4, int a5, unsigned int a6, unsigned int a7, int a8, int a9)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XCopyArea\n");
+  X11_LOCK();
+  r = XCopyArea(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCopyArea\n");
+  return r;
+}
+
+int  TSXCopyPlane(Display* a0, Drawable a1, Drawable a2, GC a3, int a4, int a5, unsigned int a6, unsigned int a7, int a8, int a9, unsigned long a10)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XCopyPlane\n");
+  X11_LOCK();
+  r = XCopyPlane(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCopyPlane\n");
+  return r;
+}
+
+int  TSXDefineCursor(Display* a0, Window a1, Cursor a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDefineCursor\n");
+  X11_LOCK();
+  r = XDefineCursor(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDefineCursor\n");
+  return r;
+}
+
+int  TSXDestroyWindow(Display* a0, Window a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDestroyWindow\n");
+  X11_LOCK();
+  r = XDestroyWindow(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDestroyWindow\n");
+  return r;
+}
+
+int  TSXDisplayKeycodes(Display* a0, int* a1, int* a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDisplayKeycodes\n");
+  X11_LOCK();
+  r = XDisplayKeycodes(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDisplayKeycodes\n");
+  return r;
+}
+
+int  TSXDrawArc(Display* a0, Drawable a1, GC a2, int a3, int a4, unsigned int a5, unsigned int a6, int a7, int a8)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDrawArc\n");
+  X11_LOCK();
+  r = XDrawArc(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDrawArc\n");
+  return r;
+}
+
+int  TSXDrawLine(Display* a0, Drawable a1, GC a2, int a3, int a4, int a5, int a6)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDrawLine\n");
+  X11_LOCK();
+  r = XDrawLine(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDrawLine\n");
+  return r;
+}
+
+int  TSXDrawLines(Display* a0, Drawable a1, GC a2, XPoint* a3, int a4, int a5)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDrawLines\n");
+  X11_LOCK();
+  r = XDrawLines(a0, a1, a2, a3, a4, a5);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDrawLines\n");
+  return r;
+}
+
+int  TSXDrawPoint(Display* a0, Drawable a1, GC a2, int a3, int a4)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDrawPoint\n");
+  X11_LOCK();
+  r = XDrawPoint(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDrawPoint\n");
+  return r;
+}
+
+int  TSXDrawRectangle(Display* a0, Drawable a1, GC a2, int a3, int a4, unsigned int a5, unsigned int a6)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDrawRectangle\n");
+  X11_LOCK();
+  r = XDrawRectangle(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDrawRectangle\n");
+  return r;
+}
+
+int  TSXDrawSegments(Display* a0, Drawable a1, GC a2, XSegment* a3, int a4)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDrawSegments\n");
+  X11_LOCK();
+  r = XDrawSegments(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDrawSegments\n");
+  return r;
+}
+
+int  TSXDrawString(Display* a0, Drawable a1, GC a2, int a3, int a4, const  char* a5, int a6)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDrawString\n");
+  X11_LOCK();
+  r = XDrawString(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDrawString\n");
+  return r;
+}
+
+int  TSXDrawText(Display* a0, Drawable a1, GC a2, int a3, int a4, XTextItem* a5, int a6)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDrawText\n");
+  X11_LOCK();
+  r = XDrawText(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDrawText\n");
+  return r;
+}
+
+int  TSXFillArc(Display* a0, Drawable a1, GC a2, int a3, int a4, unsigned int a5, unsigned int a6, int a7, int a8)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFillArc\n");
+  X11_LOCK();
+  r = XFillArc(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFillArc\n");
+  return r;
+}
+
+int  TSXFillPolygon(Display* a0, Drawable a1, GC a2, XPoint* a3, int a4, int a5, int a6)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFillPolygon\n");
+  X11_LOCK();
+  r = XFillPolygon(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFillPolygon\n");
+  return r;
+}
+
+int  TSXFillRectangle(Display* a0, Drawable a1, GC a2, int a3, int a4, unsigned int a5, unsigned int a6)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFillRectangle\n");
+  X11_LOCK();
+  r = XFillRectangle(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFillRectangle\n");
+  return r;
+}
+
+int  TSXFlush(Display* a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFlush\n");
+  X11_LOCK();
+  r = XFlush(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFlush\n");
+  return r;
+}
+
+int  TSXFree(void* a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFree\n");
+  X11_LOCK();
+  r = XFree(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFree\n");
+  return r;
+}
+
+int  TSXFreeColors(Display* a0, Colormap a1, unsigned long* a2, int a3, unsigned long a4)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFreeColors\n");
+  X11_LOCK();
+  r = XFreeColors(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFreeColors\n");
+  return r;
+}
+
+int  TSXFreeCursor(Display* a0, Cursor a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFreeCursor\n");
+  X11_LOCK();
+  r = XFreeCursor(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFreeCursor\n");
+  return r;
+}
+
+int  TSXFreeFont(Display* a0, XFontStruct* a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFreeFont\n");
+  X11_LOCK();
+  r = XFreeFont(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFreeFont\n");
+  return r;
+}
+
+int  TSXFreeFontNames(char** a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFreeFontNames\n");
+  X11_LOCK();
+  r = XFreeFontNames(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFreeFontNames\n");
+  return r;
+}
+
+int  TSXFreeGC(Display* a0, GC a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFreeGC\n");
+  X11_LOCK();
+  r = XFreeGC(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFreeGC\n");
+  return r;
+}
+
+int  TSXFreeModifiermap(XModifierKeymap* a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFreeModifiermap\n");
+  X11_LOCK();
+  r = XFreeModifiermap(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFreeModifiermap\n");
+  return r;
+}
+
+int  TSXFreePixmap(Display* a0, Pixmap a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFreePixmap\n");
+  X11_LOCK();
+  r = XFreePixmap(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFreePixmap\n");
+  return r;
+}
+
+int   TSXGetFontProperty(XFontStruct* a0, Atom a1, unsigned long* a2)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XGetFontProperty\n");
+  X11_LOCK();
+  r = XGetFontProperty(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetFontProperty\n");
+  return r;
+}
+
+int   TSXGetGeometry(Display* a0, Drawable a1, Window* a2, int* a3, int* a4, unsigned int* a5, unsigned int* a6, unsigned int* a7, unsigned int* a8)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XGetGeometry\n");
+  X11_LOCK();
+  r = XGetGeometry(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetGeometry\n");
+  return r;
+}
+
+int  TSXGetInputFocus(Display* a0, Window* a1, int* a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XGetInputFocus\n");
+  X11_LOCK();
+  r = XGetInputFocus(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetInputFocus\n");
+  return r;
+}
+
+int  TSXGetKeyboardControl(Display* a0, XKeyboardState* a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XGetKeyboardControl\n");
+  X11_LOCK();
+  r = XGetKeyboardControl(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetKeyboardControl\n");
+  return r;
+}
+
+int  TSXGetScreenSaver(Display* a0, int* a1, int* a2, int* a3, int* a4)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XGetScreenSaver\n");
+  X11_LOCK();
+  r = XGetScreenSaver(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetScreenSaver\n");
+  return r;
+}
+
+int  TSXGetWindowProperty(Display* a0, Window a1, Atom a2, long a3, long a4, int a5, Atom a6, Atom* a7, int* a8, unsigned long* a9, unsigned long* a10, unsigned char** a11)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XGetWindowProperty\n");
+  X11_LOCK();
+  r = XGetWindowProperty(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetWindowProperty\n");
+  return r;
+}
+
+int   TSXGetWindowAttributes(Display* a0, Window a1, XWindowAttributes* a2)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XGetWindowAttributes\n");
+  X11_LOCK();
+  r = XGetWindowAttributes(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetWindowAttributes\n");
+  return r;
+}
+
+int  TSXGrabPointer(Display* a0, Window a1, int a2, unsigned int a3, int a4, int a5, Window a6, Cursor a7, Time a8)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XGrabPointer\n");
+  X11_LOCK();
+  r = XGrabPointer(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGrabPointer\n");
+  return r;
+}
+
+int  TSXGrabServer(Display* a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XGrabServer\n");
+  X11_LOCK();
+  r = XGrabServer(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGrabServer\n");
+  return r;
+}
+
+int  TSXInstallColormap(Display* a0, Colormap a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XInstallColormap\n");
+  X11_LOCK();
+  r = XInstallColormap(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XInstallColormap\n");
+  return r;
+}
+
+KeyCode  TSXKeysymToKeycode(Display* a0, KeySym a1)
+{
+  KeyCode  r;
+  dprintf_x11(stddeb, "Call XKeysymToKeycode\n");
+  X11_LOCK();
+  r = XKeysymToKeycode(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XKeysymToKeycode\n");
+  return r;
+}
+
+int  TSXMapWindow(Display* a0, Window a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XMapWindow\n");
+  X11_LOCK();
+  r = XMapWindow(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XMapWindow\n");
+  return r;
+}
+
+int  TSXNextEvent(Display* a0, XEvent* a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XNextEvent\n");
+  X11_LOCK();
+  r = XNextEvent(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XNextEvent\n");
+  return r;
+}
+
+int  TSXParseGeometry(const  char* a0, int* a1, int* a2, unsigned int* a3, unsigned int* a4)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XParseGeometry\n");
+  X11_LOCK();
+  r = XParseGeometry(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XParseGeometry\n");
+  return r;
+}
+
+int  TSXPending(Display* a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XPending\n");
+  X11_LOCK();
+  r = XPending(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XPending\n");
+  return r;
+}
+
+int  TSXPutBackEvent(Display* a0, XEvent* a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XPutBackEvent\n");
+  X11_LOCK();
+  r = XPutBackEvent(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XPutBackEvent\n");
+  return r;
+}
+
+int  TSXPutImage(Display* a0, Drawable a1, GC a2, XImage* a3, int a4, int a5, int a6, int a7, unsigned int a8, unsigned int a9)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XPutImage\n");
+  X11_LOCK();
+  r = XPutImage(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XPutImage\n");
+  return r;
+}
+
+int  TSXQueryColor(Display* a0, Colormap a1, XColor* a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XQueryColor\n");
+  X11_LOCK();
+  r = XQueryColor(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XQueryColor\n");
+  return r;
+}
+
+int   TSXQueryPointer(Display* a0, Window a1, Window* a2, Window* a3, int* a4, int* a5, int* a6, int* a7, unsigned int* a8)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XQueryPointer\n");
+  X11_LOCK();
+  r = XQueryPointer(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XQueryPointer\n");
+  return r;
+}
+
+int   TSXQueryTree(Display* a0, Window a1, Window* a2, Window* a3, Window** a4, unsigned int* a5)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XQueryTree\n");
+  X11_LOCK();
+  r = XQueryTree(a0, a1, a2, a3, a4, a5);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XQueryTree\n");
+  return r;
+}
+
+int  TSXResetScreenSaver(Display* a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XResetScreenSaver\n");
+  X11_LOCK();
+  r = XResetScreenSaver(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XResetScreenSaver\n");
+  return r;
+}
+
+int  TSXRestackWindows(Display* a0, Window* a1, int a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XRestackWindows\n");
+  X11_LOCK();
+  r = XRestackWindows(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XRestackWindows\n");
+  return r;
+}
+
+int   TSXSendEvent(Display* a0, Window a1, int a2, long a3, XEvent* a4)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XSendEvent\n");
+  X11_LOCK();
+  r = XSendEvent(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSendEvent\n");
+  return r;
+}
+
+int  TSXSetArcMode(Display* a0, GC a1, int a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetArcMode\n");
+  X11_LOCK();
+  r = XSetArcMode(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetArcMode\n");
+  return r;
+}
+
+int  TSXSetBackground(Display* a0, GC a1, unsigned long a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetBackground\n");
+  X11_LOCK();
+  r = XSetBackground(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetBackground\n");
+  return r;
+}
+
+int  TSXSetClipMask(Display* a0, GC a1, Pixmap a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetClipMask\n");
+  X11_LOCK();
+  r = XSetClipMask(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetClipMask\n");
+  return r;
+}
+
+int  TSXSetClipOrigin(Display* a0, GC a1, int a2, int a3)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetClipOrigin\n");
+  X11_LOCK();
+  r = XSetClipOrigin(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetClipOrigin\n");
+  return r;
+}
+
+int  TSXSetClipRectangles(Display* a0, GC a1, int a2, int a3, XRectangle* a4, int a5, int a6)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetClipRectangles\n");
+  X11_LOCK();
+  r = XSetClipRectangles(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetClipRectangles\n");
+  return r;
+}
+
+int  TSXSetDashes(Display* a0, GC a1, int a2, const  char* a3, int a4)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetDashes\n");
+  X11_LOCK();
+  r = XSetDashes(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetDashes\n");
+  return r;
+}
+
+int  TSXSetFillStyle(Display* a0, GC a1, int a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetFillStyle\n");
+  X11_LOCK();
+  r = XSetFillStyle(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetFillStyle\n");
+  return r;
+}
+
+int  TSXSetForeground(Display* a0, GC a1, unsigned long a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetForeground\n");
+  X11_LOCK();
+  r = XSetForeground(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetForeground\n");
+  return r;
+}
+
+int  TSXSetFunction(Display* a0, GC a1, int a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetFunction\n");
+  X11_LOCK();
+  r = XSetFunction(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetFunction\n");
+  return r;
+}
+
+int  TSXSetGraphicsExposures(Display* a0, GC a1, int a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetGraphicsExposures\n");
+  X11_LOCK();
+  r = XSetGraphicsExposures(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetGraphicsExposures\n");
+  return r;
+}
+
+int  TSXSetIconName(Display* a0, Window a1, const  char* a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetIconName\n");
+  X11_LOCK();
+  r = XSetIconName(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetIconName\n");
+  return r;
+}
+
+int  TSXSetInputFocus(Display* a0, Window a1, int a2, Time a3)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetInputFocus\n");
+  X11_LOCK();
+  r = XSetInputFocus(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetInputFocus\n");
+  return r;
+}
+
+int  TSXSetLineAttributes(Display* a0, GC a1, unsigned int a2, int a3, int a4, int a5)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetLineAttributes\n");
+  X11_LOCK();
+  r = XSetLineAttributes(a0, a1, a2, a3, a4, a5);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetLineAttributes\n");
+  return r;
+}
+
+int  TSXSetScreenSaver(Display* a0, int a1, int a2, int a3, int a4)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetScreenSaver\n");
+  X11_LOCK();
+  r = XSetScreenSaver(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetScreenSaver\n");
+  return r;
+}
+
+int  TSXSetSelectionOwner(Display* a0, Atom a1, Window a2, Time a3)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetSelectionOwner\n");
+  X11_LOCK();
+  r = XSetSelectionOwner(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetSelectionOwner\n");
+  return r;
+}
+
+int  TSXSetSubwindowMode(Display* a0, GC a1, int a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetSubwindowMode\n");
+  X11_LOCK();
+  r = XSetSubwindowMode(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetSubwindowMode\n");
+  return r;
+}
+
+int  TSXStoreColor(Display* a0, Colormap a1, XColor* a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XStoreColor\n");
+  X11_LOCK();
+  r = XStoreColor(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XStoreColor\n");
+  return r;
+}
+
+int  TSXStoreName(Display* a0, Window a1, const  char* a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XStoreName\n");
+  X11_LOCK();
+  r = XStoreName(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XStoreName\n");
+  return r;
+}
+
+int  TSXSync(Display* a0, int a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSync\n");
+  X11_LOCK();
+  r = XSync(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSync\n");
+  return r;
+}
+
+int  TSXTextExtents(XFontStruct* a0, const  char* a1, int a2, int* a3, int* a4, int* a5, XCharStruct* a6)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XTextExtents\n");
+  X11_LOCK();
+  r = XTextExtents(a0, a1, a2, a3, a4, a5, a6);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XTextExtents\n");
+  return r;
+}
+
+int  TSXTextWidth(XFontStruct* a0, const  char* a1, int a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XTextWidth\n");
+  X11_LOCK();
+  r = XTextWidth(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XTextWidth\n");
+  return r;
+}
+
+int  TSXUngrabPointer(Display* a0, Time a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XUngrabPointer\n");
+  X11_LOCK();
+  r = XUngrabPointer(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XUngrabPointer\n");
+  return r;
+}
+
+int  TSXUngrabServer(Display* a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XUngrabServer\n");
+  X11_LOCK();
+  r = XUngrabServer(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XUngrabServer\n");
+  return r;
+}
+
+int  TSXUninstallColormap(Display* a0, Colormap a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XUninstallColormap\n");
+  X11_LOCK();
+  r = XUninstallColormap(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XUninstallColormap\n");
+  return r;
+}
+
+int  TSXUnmapWindow(Display* a0, Window a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XUnmapWindow\n");
+  X11_LOCK();
+  r = XUnmapWindow(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XUnmapWindow\n");
+  return r;
+}
+
+int  TSXWarpPointer(Display* a0, Window a1, Window a2, int a3, int a4, unsigned int a5, unsigned int a6, int a7, int a8)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XWarpPointer\n");
+  X11_LOCK();
+  r = XWarpPointer(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XWarpPointer\n");
+  return r;
+}
+
+int (*TSXSynchronize(Display *a0, Bool a1))(Display *)
+{
+  int (*r)(Display *);
+  dprintf_x11(stddeb, "Call XSynchronize\n");
+  X11_LOCK();
+  r = XSynchronize(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSynchronize\n");
+  return r;
+}
+
+extern void _XInitImageFuncPtrs(XImage *);
+
+void TS_XInitImageFuncPtrs(XImage *a0)
+{
+  dprintf_x11(stddeb, "Call _XInitImageFuncPtrs\n");
+  X11_LOCK();
+  _XInitImageFuncPtrs(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret _XInitImageFuncPtrs\n");
+}
diff --git a/tsx11/ts_xpm.c b/tsx11/ts_xpm.c
new file mode 100644
index 0000000..10cb12f
--- /dev/null
+++ b/tsx11/ts_xpm.c
@@ -0,0 +1,33 @@
+/*
+ * Thread safe wrappers around xpm calls.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#include <X11/xpm.h>
+#include "tsx11defs.h"
+#include "stddebug.h"
+#include "debug.h"
+
+int TSXpmCreatePixmapFromData(Display *a0, Drawable a1, char **a2, Pixmap *a3, Pixmap *a4, XpmAttributes *a5)
+{
+  int r;
+  dprintf_x11(stddeb, "Call XpmCreatePixmapFromData\n");
+  X11_LOCK();
+  r = XpmCreatePixmapFromData(a0, a1, a2, a3, a4, a5);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XpmCreatePixmapFromData\n");
+  return r;
+}
+
+int TSXpmAttributesSize(void)
+{
+  int r;
+  dprintf_x11(stddeb, "Call XpmAttributesSize\n");
+  X11_LOCK();
+  r = XpmAttributesSize();
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XpmAttributesSize\n");
+  return r;
+}
diff --git a/tsx11/ts_xresource.c b/tsx11/ts_xresource.c
new file mode 100644
index 0000000..cb173d0
--- /dev/null
+++ b/tsx11/ts_xresource.c
@@ -0,0 +1,74 @@
+/*
+ * Thread safe wrappers around Xresource calls.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include "tsx11defs.h"
+#include "stddebug.h"
+#include "debug.h"
+
+XrmQuark  TSXrmUniqueQuark(void)
+{
+  XrmQuark  r;
+  dprintf_x11(stddeb, "Call XrmUniqueQuark\n");
+  X11_LOCK();
+  r = XrmUniqueQuark();
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XrmUniqueQuark\n");
+  return r;
+}
+
+int   TSXrmGetResource(XrmDatabase a0, const  char* a1, const  char* a2, char** a3, XrmValue* a4)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XrmGetResource\n");
+  X11_LOCK();
+  r = XrmGetResource(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XrmGetResource\n");
+  return r;
+}
+
+XrmDatabase  TSXrmGetFileDatabase(const  char* a0)
+{
+  XrmDatabase  r;
+  dprintf_x11(stddeb, "Call XrmGetFileDatabase\n");
+  X11_LOCK();
+  r = XrmGetFileDatabase(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XrmGetFileDatabase\n");
+  return r;
+}
+
+XrmDatabase  TSXrmGetStringDatabase(const  char* a0)
+{
+  XrmDatabase  r;
+  dprintf_x11(stddeb, "Call XrmGetStringDatabase\n");
+  X11_LOCK();
+  r = XrmGetStringDatabase(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XrmGetStringDatabase\n");
+  return r;
+}
+
+void  TSXrmMergeDatabases(XrmDatabase a0, XrmDatabase* a1)
+{
+  dprintf_x11(stddeb, "Call XrmMergeDatabases\n");
+  X11_LOCK();
+  XrmMergeDatabases(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XrmMergeDatabases\n");
+}
+
+void  TSXrmParseCommand(XrmDatabase* a0, XrmOptionDescList a1, int a2, const  char* a3, int* a4, char** a5)
+{
+  dprintf_x11(stddeb, "Call XrmParseCommand\n");
+  X11_LOCK();
+  XrmParseCommand(a0, a1, a2, a3, a4, a5);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XrmParseCommand\n");
+}
diff --git a/tsx11/ts_xshm.c b/tsx11/ts_xshm.c
new file mode 100644
index 0000000..0071cb5
--- /dev/null
+++ b/tsx11/ts_xshm.c
@@ -0,0 +1,56 @@
+/*
+ * Thread safe wrappers around XShm calls.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XShm.h>
+#include "tsx11defs.h"
+#include "stddebug.h"
+#include "debug.h"
+
+Bool TSXShmQueryExtension(Display *a0)
+{
+  Bool r;
+  dprintf_x11(stddeb, "Call XShmQueryExtension\n");
+  X11_LOCK();
+  r = XShmQueryExtension(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XShmQueryExtension\n");
+  return r;
+}
+
+int TSXShmPixmapFormat(Display *a0)
+{
+  int r;
+  dprintf_x11(stddeb, "Call XShmPixmapFormat\n");
+  X11_LOCK();
+  r = XShmPixmapFormat(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XShmPixmapFormat\n");
+  return r;
+}
+
+Status TSXShmDetach(Display *a0, XShmSegmentInfo *a1)
+{
+  Status r;
+  dprintf_x11(stddeb, "Call XShmDetach\n");
+  X11_LOCK();
+  r = XShmDetach(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XShmDetach\n");
+  return r;
+}
+
+Status TSXShmAttach(Display *a0, XShmSegmentInfo *a1)
+{
+  Status r;
+  dprintf_x11(stddeb, "Call XShmAttach\n");
+  X11_LOCK();
+  r = XShmAttach(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XShmAttach\n");
+  return r;
+}
diff --git a/tsx11/ts_xutil.c b/tsx11/ts_xutil.c
new file mode 100644
index 0000000..d2ea0d3
--- /dev/null
+++ b/tsx11/ts_xutil.c
@@ -0,0 +1,372 @@
+/*
+ * Thread safe wrappers around Xutil calls.
+ * This file was generated automatically by tools/make_X11wrappers
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xresource.h>
+#include <X11/Xutil.h>
+#include "tsx11defs.h"
+#include "stddebug.h"
+#include "debug.h"
+
+XClassHint * TSXAllocClassHint(void)
+{
+  XClassHint * r;
+  dprintf_x11(stddeb, "Call XAllocClassHint\n");
+  X11_LOCK();
+  r = XAllocClassHint();
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XAllocClassHint\n");
+  return r;
+}
+
+XSizeHints * TSXAllocSizeHints(void)
+{
+  XSizeHints * r;
+  dprintf_x11(stddeb, "Call XAllocSizeHints\n");
+  X11_LOCK();
+  r = XAllocSizeHints();
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XAllocSizeHints\n");
+  return r;
+}
+
+XWMHints * TSXAllocWMHints(void)
+{
+  XWMHints * r;
+  dprintf_x11(stddeb, "Call XAllocWMHints\n");
+  X11_LOCK();
+  r = XAllocWMHints();
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XAllocWMHints\n");
+  return r;
+}
+
+int  TSXClipBox(Region a0, XRectangle* a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XClipBox\n");
+  X11_LOCK();
+  r = XClipBox(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XClipBox\n");
+  return r;
+}
+
+Region  TSXCreateRegion(void)
+{
+  Region  r;
+  dprintf_x11(stddeb, "Call XCreateRegion\n");
+  X11_LOCK();
+  r = XCreateRegion();
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XCreateRegion\n");
+  return r;
+}
+
+int  TSXDeleteContext(Display* a0, XID a1, XContext a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDeleteContext\n");
+  X11_LOCK();
+  r = XDeleteContext(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDeleteContext\n");
+  return r;
+}
+
+int  TSXDestroyRegion(Region a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XDestroyRegion\n");
+  X11_LOCK();
+  r = XDestroyRegion(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDestroyRegion\n");
+  return r;
+}
+
+int  TSXEmptyRegion(Region a0)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XEmptyRegion\n");
+  X11_LOCK();
+  r = XEmptyRegion(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XEmptyRegion\n");
+  return r;
+}
+
+int  TSXEqualRegion(Region a0, Region a1)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XEqualRegion\n");
+  X11_LOCK();
+  r = XEqualRegion(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XEqualRegion\n");
+  return r;
+}
+
+int  TSXFindContext(Display* a0, XID a1, XContext a2, XPointer* a3)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XFindContext\n");
+  X11_LOCK();
+  r = XFindContext(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XFindContext\n");
+  return r;
+}
+
+int   TSXGetWMSizeHints(Display* a0, Window a1, XSizeHints* a2, long* a3, Atom a4)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XGetWMSizeHints\n");
+  X11_LOCK();
+  r = XGetWMSizeHints(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetWMSizeHints\n");
+  return r;
+}
+
+int  TSXIntersectRegion(Region a0, Region a1, Region a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XIntersectRegion\n");
+  X11_LOCK();
+  r = XIntersectRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XIntersectRegion\n");
+  return r;
+}
+
+int  TSXLookupString(XKeyEvent* a0, char* a1, int a2, KeySym* a3, XComposeStatus* a4)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XLookupString\n");
+  X11_LOCK();
+  r = XLookupString(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XLookupString\n");
+  return r;
+}
+
+int  TSXOffsetRegion(Region a0, int a1, int a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XOffsetRegion\n");
+  X11_LOCK();
+  r = XOffsetRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XOffsetRegion\n");
+  return r;
+}
+
+int   TSXPointInRegion(Region a0, int a1, int a2)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XPointInRegion\n");
+  X11_LOCK();
+  r = XPointInRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XPointInRegion\n");
+  return r;
+}
+
+Region  TSXPolygonRegion(XPoint* a0, int a1, int a2)
+{
+  Region  r;
+  dprintf_x11(stddeb, "Call XPolygonRegion\n");
+  X11_LOCK();
+  r = XPolygonRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XPolygonRegion\n");
+  return r;
+}
+
+int  TSXRectInRegion(Region a0, int a1, int a2, unsigned int a3, unsigned int a4)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XRectInRegion\n");
+  X11_LOCK();
+  r = XRectInRegion(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XRectInRegion\n");
+  return r;
+}
+
+int  TSXSaveContext(Display* a0, XID a1, XContext a2, const  char* a3)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSaveContext\n");
+  X11_LOCK();
+  r = XSaveContext(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSaveContext\n");
+  return r;
+}
+
+void  TSXSetWMProperties(Display* a0, Window a1, XTextProperty* a2, XTextProperty* a3, char** a4, int a5, XSizeHints* a6, XWMHints* a7, XClassHint* a8)
+{
+  dprintf_x11(stddeb, "Call XSetWMProperties\n");
+  X11_LOCK();
+  XSetWMProperties(a0, a1, a2, a3, a4, a5, a6, a7, a8);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetWMProperties\n");
+}
+
+void  TSXSetWMSizeHints(Display* a0, Window a1, XSizeHints* a2, Atom a3)
+{
+  dprintf_x11(stddeb, "Call XSetWMSizeHints\n");
+  X11_LOCK();
+  XSetWMSizeHints(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetWMSizeHints\n");
+}
+
+int  TSXSetRegion(Display* a0, GC a1, Region a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSetRegion\n");
+  X11_LOCK();
+  r = XSetRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSetRegion\n");
+  return r;
+}
+
+int  TSXShrinkRegion(Region a0, int a1, int a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XShrinkRegion\n");
+  X11_LOCK();
+  r = XShrinkRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XShrinkRegion\n");
+  return r;
+}
+
+int   TSXStringListToTextProperty(char** a0, int a1, XTextProperty* a2)
+{
+  int   r;
+  dprintf_x11(stddeb, "Call XStringListToTextProperty\n");
+  X11_LOCK();
+  r = XStringListToTextProperty(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XStringListToTextProperty\n");
+  return r;
+}
+
+int  TSXSubtractRegion(Region a0, Region a1, Region a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XSubtractRegion\n");
+  X11_LOCK();
+  r = XSubtractRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSubtractRegion\n");
+  return r;
+}
+
+int  TSXUnionRectWithRegion(XRectangle* a0, Region a1, Region a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XUnionRectWithRegion\n");
+  X11_LOCK();
+  r = XUnionRectWithRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XUnionRectWithRegion\n");
+  return r;
+}
+
+int  TSXUnionRegion(Region a0, Region a1, Region a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XUnionRegion\n");
+  X11_LOCK();
+  r = XUnionRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XUnionRegion\n");
+  return r;
+}
+
+int  TSXXorRegion(Region a0, Region a1, Region a2)
+{
+  int  r;
+  dprintf_x11(stddeb, "Call XXorRegion\n");
+  X11_LOCK();
+  r = XXorRegion(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XXorRegion\n");
+  return r;
+}
+
+int TSXDestroyImage(struct _XImage *a0)
+{
+  int r;
+  dprintf_x11(stddeb, "Call XDestroyImage\n");
+  X11_LOCK();
+  r = XDestroyImage(a0);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XDestroyImage\n");
+  return r;
+}
+
+unsigned long TSXGetPixel(struct _XImage *a0, int a1, int a2)
+{
+  unsigned long r;
+  dprintf_x11(stddeb, "Call XGetPixel\n");
+  X11_LOCK();
+  r = XGetPixel(a0, a1, a2);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XGetPixel\n");
+  return r;
+}
+
+int TSXPutPixel(struct _XImage *a0, int a1, int a2, unsigned long a3)
+{
+  int r;
+  dprintf_x11(stddeb, "Call XPutPixel\n");
+  X11_LOCK();
+  r = XPutPixel(a0, a1, a2, a3);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XPutPixel\n");
+  return r;
+}
+
+struct _XImage * TSXSubImage(struct _XImage *a0, int a1, int a2, unsigned int a3, unsigned int a4)
+{
+  struct _XImage * r;
+  dprintf_x11(stddeb, "Call XSubImage\n");
+  X11_LOCK();
+  r = XSubImage(a0, a1, a2, a3, a4);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XSubImage\n");
+  return r;
+}
+
+int TSXAddPixel(struct _XImage *a0, long a1)
+{
+  int r;
+  dprintf_x11(stddeb, "Call XAddPixel\n");
+  X11_LOCK();
+  r = XAddPixel(a0, a1);
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XAddPixel\n");
+  return r;
+}
+
+XContext TSXUniqueContext(void)
+{
+  XContext r;
+  dprintf_x11(stddeb, "Call XUniqueContext\n");
+  X11_LOCK();
+  r = XUniqueContext();
+  X11_UNLOCK();
+  dprintf_x11(stddeb, "Ret XUniqueContext\n");
+  return r;
+}
diff --git a/tsx11/tsx11defs.c b/tsx11/tsx11defs.c
new file mode 100644
index 0000000..3713852
--- /dev/null
+++ b/tsx11/tsx11defs.c
@@ -0,0 +1,21 @@
+/*
+ * Thread safe wrappers around XShm calls.
+ *
+ * Copyright 1998 Kristian Nielsen
+ */
+
+#include "tsx11defs.h"
+#include "stddebug.h"
+#include "debug.h"
+
+CRITICAL_SECTION *TSX11_SectionPtr = NULL;
+static CRITICAL_SECTION TSX11_Section;
+
+int TSX11_Init(void)
+{
+    InitializeCriticalSection( &TSX11_Section );
+    dprintf_x11(stddeb, "TSX11_Init: X11 critical section is %p\n",
+                &TSX11_Section);
+    TSX11_SectionPtr = &TSX11_Section;
+    return TRUE;
+}
diff --git a/win32/console.c b/win32/console.c
index fa8166f..8b27d3c 100644
--- a/win32/console.c
+++ b/win32/console.c
@@ -32,6 +32,19 @@
 }
 
 /***********************************************************************
+ *           CreateConsoleScreenBuffer   (KERNEL32.151)
+ */
+HANDLE32 WINAPI CreateConsoleScreenBuffer( DWORD dwDesiredAccess,
+                                           DWORD dwShareMode,
+                                           LPSECURITY_ATTRIBUTES lpSecurityAttributes,
+                                           DWORD dwFlags,
+                                           LPVOID lpScreenBufferData)
+{
+	fprintf(stderr, "CreateConsoleScreenBuffer(): stub !\n");
+	return INVALID_HANDLE_VALUE32;
+}
+
+/***********************************************************************
  *           GetConsoleScreenBufferInfo   (KERNEL32.190)
  */
 BOOL32 WINAPI GetConsoleScreenBufferInfo( HANDLE32 hConsoleOutput,
@@ -52,6 +65,15 @@
 }
 
 /***********************************************************************
+ *           SetConsoleActiveScreenBuffer   (KERNEL32.623)
+ */
+BOOL32 WINAPI SetConsoleActiveScreenBuffer(HANDLE32 hConsoleOutput)
+{
+	fprintf(stderr, "SetConsoleActiveScreenBuffer(): stub !\n");
+	return 0;
+}
+
+/***********************************************************************
  *            GetLargestConsoleWindowSize   (KERNEL32.226)
  */
 DWORD WINAPI GetLargestConsoleWindowSize( HANDLE32 hConsoleOutput )
@@ -114,7 +136,7 @@
 }
 
 /***********************************************************************
- *            WriteConsoleA   (KERNEL32.567)
+ *            WriteConsoleA   (KERNEL32.729)
  */
 BOOL32 WINAPI WriteConsole32A( HANDLE32 hConsoleOutput,
                                LPCVOID lpBuffer,
@@ -129,6 +151,18 @@
 }
 
 /***********************************************************************
+ *            WriteConsoleOutputA   (KERNEL32.732)
+ */
+BOOL32 WINAPI WriteConsoleOutput32A( HANDLE32 hConsoleOutput,
+                                     LPCHAR_INFO lpBuffer,
+                                     COORD dwBufferSize,
+                                     COORD dwBufferCoord,
+                                     LPSMALL_RECT lpWriteRegion)
+{
+	return FALSE;
+}
+
+/***********************************************************************
  *            WriteConsoleW   (KERNEL32.577)
  */
 BOOL32 WINAPI WriteConsole32W( HANDLE32 hConsoleOutput,
@@ -240,16 +274,14 @@
  *            PeekConsoleInputA   (KERNEL32.550)
  */
 BOOL32 WINAPI PeekConsoleInput32A(HANDLE32 hConsoleInput,
-                                  LPDWORD pirBuffer,
+                                  LPINPUT_RECORD pirBuffer,
                                   DWORD cInRecords,
                                   LPDWORD lpcRead)
-/* FIXME: pirBuffer should be a pointer to an INPUT_RECORD structure
-   -Karl Garrison (12/01/97) */
 {
     pirBuffer = NULL;
     cInRecords = 0;
     *lpcRead = 0;
-    fprintf(stderr,"GetNumberOfConsoleMouseButtons: STUB returning NULL\n");
+    fprintf(stderr,"PeekConsoleInput32A: STUB returning TRUE\n");
 	return TRUE;
 }
 
@@ -257,16 +289,14 @@
  *            PeekConsoleInputW   (KERNEL32.551)
  */
 BOOL32 WINAPI PeekConsoleInput32W(HANDLE32 hConsoleInput,
-                                  LPDWORD pirBuffer,
+                                  LPINPUT_RECORD pirBuffer,
                                   DWORD cInRecords,
                                   LPDWORD lpcRead)
-/* FIXME: pirBuffer should be a pointer to an INPUT_RECORD structure
-   -Karl Garrison (12/01/97) */
 {
     pirBuffer = NULL;
     cInRecords = 0;
     *lpcRead = 0;
-    fprintf(stderr,"GetNumberOfConsoleMouseButtons: STUB returning NULL\n");
+    fprintf(stderr,"PeekConsoleInput32W: STUB returning TRUE\n");
     return TRUE;
 }
 
@@ -276,7 +306,7 @@
 BOOL32 WINAPI GetConsoleCursorInfo32(HANDLE32 hcon, LPDWORD cinfo)
 {
   cinfo[0] = 10; /* 10% of character box is cursor.  */
-  cinfo[1] = TRUE;  /* Cursur is visible.  */
+  cinfo[1] = TRUE;  /* Cursor is visible.  */
   fprintf (stdnimp, "GetConsoleCursorInfo32 -- STUB!\n");
   return TRUE;
 }
diff --git a/win32/kernel32.c b/win32/kernel32.c
index ea78c82..a22c775 100644
--- a/win32/kernel32.c
+++ b/win32/kernel32.c
@@ -163,17 +163,18 @@
 {
     CONTEXT context16;
     DWORD argsize;
+    THDB *thdb = THREAD_Current();
 
     memcpy(&context16,context,sizeof(context16));
 
     CS_reg(&context16)  = HIWORD(EDX_reg(context));
     IP_reg(&context16)  = LOWORD(EDX_reg(context));
-    EBP_reg(&context16) = OFFSETOF(IF1632_Saved16_ss_sp)
+    EBP_reg(&context16) = OFFSETOF( thdb->cur_stack )
                            + (WORD)&((STACK16FRAME*)0)->bp;
 
     argsize = EBP_reg(context)-ESP_reg(context)-0x44;
 
-    memcpy( ((LPBYTE)CURRENT_STACK16)-argsize,
+    memcpy( ((LPBYTE)THREAD_STACK16(thdb))-argsize,
             (LPBYTE)ESP_reg(context)+4, argsize );
 
     EAX_reg(context) = Callbacks->CallRegisterShortProc( &context16, argsize );
@@ -181,7 +182,7 @@
 
 
 /**********************************************************************
- *           WOWCallback16 (KERNEL32.62)
+ *           WOWCallback16 (KERNEL32.62)(WOW32.2)
  */
 DWORD WINAPI WOWCallback16(FARPROC16 fproc,DWORD arg)
 {
@@ -192,6 +193,16 @@
 	return ret;
 }
 
+/**********************************************************************
+ *           WOWCallback16Ex (KERNEL32.55)(WOW32.3)
+ */
+BOOL32 WINAPI WOWCallback16Ex(
+	FARPROC16 vpfn16,DWORD dwFlags,DWORD cbArgs,LPVOID pArgs,
+	LPDWORD pdwRetCode
+) {
+	return Callbacks->CallWOWCallback16Ex(vpfn16,dwFlags,cbArgs,pArgs,pdwRetCode);
+}
+
 /***********************************************************************
  *           _KERNEL32_52    (KERNEL32.52)
  * Returns a pointer to ThkBuf in the 16bit library SYSTHUNK.DLL.
@@ -263,7 +274,8 @@
 {
 	CONTEXT	context16;
 	LPBYTE	curstack;
-	DWORD	ret,stacksize;
+        DWORD ret,stacksize;
+	THDB *thdb = THREAD_Current();
 
 	dprintf_thunk(stddeb,"KERNEL32_45(%%eax=0x%08lx(%%cx=0x%04lx,%%edx=0x%08lx))\n",
 		(DWORD)EAX_reg(context),(DWORD)CX_reg(context),(DWORD)EDX_reg(context)
@@ -277,10 +289,10 @@
 	CS_reg(&context16)	 = HIWORD(EAX_reg(context));
 	IP_reg(&context16)	 = LOWORD(EAX_reg(context));
 
-	curstack = PTR_SEG_TO_LIN(STACK16_PUSH(stacksize));
-	memcpy(curstack-stacksize,(LPBYTE)ESP_reg(context),stacksize);
+	curstack = PTR_SEG_TO_LIN(STACK16_PUSH( thdb, stacksize ));
+	memcpy(curstack - stacksize,(LPBYTE)ESP_reg(context),stacksize);
 	ret = Callbacks->CallRegisterLongProc(&context16,0);
-	STACK16_POP(stacksize);
+	STACK16_POP( thdb, stacksize );
 
 	dprintf_thunk(stddeb,". returned %08lx\n",ret);
 	EAX_reg(context) 	 = ret;
@@ -298,6 +310,7 @@
 	CONTEXT	context16;
 	LPBYTE	curstack;
 	DWORD	ret,stacksize;
+	THDB *thdb = THREAD_Current();
 
 	dprintf_thunk(stddeb,"_KERNEL32_40(EDX=0x%08lx)\n",
 		EDX_reg(context)
@@ -311,10 +324,10 @@
 	CS_reg(&context16)	 = HIWORD(EDX_reg(context));
 	IP_reg(&context16)	 = LOWORD(EDX_reg(context));
 
-	curstack = PTR_SEG_TO_LIN(STACK16_PUSH(stacksize));
+	curstack = PTR_SEG_TO_LIN(STACK16_PUSH( thdb, stacksize ));
 	memcpy(curstack-stacksize,(LPBYTE)ESP_reg(context),stacksize);
 	ret = Callbacks->CallRegisterShortProc(&context16,0);
-	STACK16_POP(stacksize);
+	STACK16_POP( thdb, stacksize );
 
 	dprintf_thunk(stddeb,". returned %08lx\n",ret);
 	EAX_reg(context) 	 = ret;
@@ -593,7 +606,7 @@
 		return x;
 
 	sel = SELECTOR_AllocBlock( PTR_SEG_TO_LIN(x) , 0xffff, SEGMENT_CODE, FALSE, FALSE );
-	return (sel<<16)|(0x0000);
+	return PTR_SEG_OFF_TO_SEGPTR( sel, 0 );
 }
 
 /**********************************************************************
@@ -603,14 +616,10 @@
  */
 VOID WINAPI
 _KERNEL_359(DWORD x) {
-	DWORD	savedsssp;
-
 	fprintf(stderr,"_KERNEL_359(0x%08lx),stub\n",x);
 	if ((HIWORD(x) & 7)!=7)
 		return;
-	savedsssp = IF1632_Saved16_ss_sp;IF1632_Saved16_ss_sp = 0;
 	SELECTOR_FreeBlock(x>>16,1);
-	IF1632_Saved16_ss_sp = savedsssp;
 	return;
 }
 
@@ -661,3 +670,8 @@
 	_lclose32(hf);
 	return (xmagic == IMAGE_NT_SIGNATURE);
 }
+
+HANDLE32 WINAPI WOWHandle32(WORD handle,WOW_HANDLE_TYPE type) {
+	fprintf(stderr,"WOWHandle32(0x%04x,%d)\n",handle,type);
+	return (HANDLE32)handle;
+}
diff --git a/win32/thread.c b/win32/thread.c
index bcd4d4a..7ad6585 100644
--- a/win32/thread.c
+++ b/win32/thread.c
@@ -8,8 +8,6 @@
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
 #include "windows.h"
 #include "winbase.h"
 #include "winerror.h"
@@ -129,12 +127,3 @@
 	return ret;
 #endif	
 }
-
-/************************************************************************
-*           ReinitializeCriticalSection			[KERNEL32]	*
-************************************************************************/
-
-void WINAPI ReinitializeCriticalSection(CRITICAL_SECTION *lpCrit)
-{
-   /* hmm ?????? */	
-}
diff --git a/windows/Makefile.in b/windows/Makefile.in
index c18a470..6feb7a3 100644
--- a/windows/Makefile.in
+++ b/windows/Makefile.in
@@ -13,6 +13,7 @@
 	defdlg.c \
 	defwnd.c \
 	dialog.c \
+	dinput.c \
 	driver.c \
 	event.c \
 	focus.c \
diff --git a/windows/clipboard.c b/windows/clipboard.c
index a6a072e..ce99204 100644
--- a/windows/clipboard.c
+++ b/windows/clipboard.c
@@ -13,7 +13,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <string.h>
-#include <X11/Xlib.h>
+#include "ts_xlib.h"
 #include <X11/Xatom.h>
 #include "windows.h"
 #include "win.h"
@@ -112,8 +112,8 @@
 
 	if( selectionWindow != None )
 	{
-	    XSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
-	    if( XGetSelectionOwner(display, XA_PRIMARY) != selectionWindow )
+	    TSXSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
+	    if( TSXGetSelectionOwner(display, XA_PRIMARY) != selectionWindow )
 		selectionWindow = None;
 	}
     }
@@ -206,13 +206,13 @@
    * CLIPBOARD_ReadSelection() will be invoked 
    * from the SelectionNotify event handler */
 
-    XConvertSelection(display,XA_PRIMARY,XA_STRING,
-                      XInternAtom(display,"PRIMARY_TEXT",False),
+    TSXConvertSelection(display,XA_PRIMARY,XA_STRING,
+                      TSXInternAtom(display,"PRIMARY_TEXT",False),
                       WIN_GetXWindow(hWnd),CurrentTime);
 
   /* wait until SelectionNotify is processed 
    *
-   * FIXME: Use XCheckTypedWindowEvent() instead ( same in the 
+   * FIXME: Use TSXCheckTypedWindowEvent() instead ( same in the 
    *	    CLIPBOARD_CheckSelection() ). 
    */
 
@@ -350,7 +350,7 @@
 	dprintf_clipboard(stddeb, "\tgiving up selection (spw = %08x)\n", 
 				 	(unsigned)selectionPrevWindow);
 
-	XSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
+	TSXSetSelectionOwner(display, XA_PRIMARY, None, CurrentTime);
     }
     return TRUE;
 }
@@ -401,8 +401,8 @@
 	(wFormat == CF_TEXT || wFormat == CF_OEMTEXT) )
     {
 	owner = WIN_GetXWindow( hWndClipWindow ? hWndClipWindow : AnyPopup32() );
-	XSetSelectionOwner(display,XA_PRIMARY,owner,CurrentTime);
-	if( XGetSelectionOwner(display,XA_PRIMARY) == owner )
+	TSXSetSelectionOwner(display,XA_PRIMARY,owner,CurrentTime);
+	if( TSXGetSelectionOwner(display,XA_PRIMARY) == owner )
 	{
 	    selectionAcquired = True;
 	    selectionWindow = owner;
@@ -911,17 +911,17 @@
 	unsigned long 	nitems,remain;
 	unsigned char*	val=NULL;
 
-        dprintf_clipboard(stddeb,"\tgot property %s\n",XGetAtomName(display,prop));
+        dprintf_clipboard(stddeb,"\tgot property %s\n",TSXGetAtomName(display,prop));
 
         /* TODO: Properties longer than 64K */
 
-	if(XGetWindowProperty(display,w,prop,0,0x3FFF,True,XA_STRING,
+	if(TSXGetWindowProperty(display,w,prop,0,0x3FFF,True,XA_STRING,
 	    &atype, &aformat, &nitems, &remain, &val) != Success)
 	    dprintf_clipboard(stddeb,"\tcouldn't read property\n");
 	else
 	{
            dprintf_clipboard(stddeb,"\tType %s,Format %d,nitems %ld,value %s\n",
-		             XGetAtomName(display,atype),aformat,nitems,val);
+		             TSXGetAtomName(display,atype),aformat,nitems,val);
 
 	   if(atype == XA_STRING && aformat == 8)
 	   {
@@ -945,7 +945,7 @@
 	        else hText = 0;
 	      }
 	   }
-	   XFree(val);
+	   TSXFree(val);
 	}
    }
 
@@ -995,9 +995,9 @@
 	}
 	else if( w == selectionPrevWindow )
 	{
-	    w = XGetSelectionOwner(display, XA_PRIMARY);
+	    w = TSXGetSelectionOwner(display, XA_PRIMARY);
 	    if( w == None )
-		XSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
+		TSXSetSelectionOwner(display, XA_PRIMARY, selectionWindow, CurrentTime);
 	}
 
     selectionPrevWindow = None;
diff --git a/windows/dce.c b/windows/dce.c
index b82bc95..9ff60c5 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -173,6 +173,9 @@
 	    DeleteObject32( dce->hClipRgn );
 
     dce->hClipRgn = 0;
+
+    dprintf_dc(stddeb,"\trestoring VisRgn\n");
+
     RestoreVisRgn(dce->hDC);
 }
 
@@ -213,12 +216,12 @@
  *   DCE_InvalidateDCE
  *
  * It is called from SetWindowPos() - we have to mark as dirty all busy
- * DCE's for windows whose client rect intersects with specified update 
- * rectangle. wndScope is the immediate parent of the window(s) that 
- * was(were) moved and(or) resized.
+ * DCE's for windows that have pWnd->parent as an ansector and whose client 
+ * rect intersects with specified update rectangle. 
  */
-BOOL32 DCE_InvalidateDCE(WND* wndScope, const RECT32* pRectUpdate)
+BOOL32 DCE_InvalidateDCE(WND* pWnd, const RECT32* pRectUpdate)
 {
+    WND* wndScope = pWnd->parent;
     BOOL32 bRet = FALSE;
 
     if( wndScope )
@@ -257,7 +260,9 @@
 
 			    OffsetRect32( &wndRect, xoffset - wndCurrent->rectClient.left, 
 						    yoffset - wndCurrent->rectClient.top);
-			    if (IntersectRect32( &wndRect, &wndRect, pRectUpdate ))
+
+			    if (pWnd == wndCurrent ||
+				IntersectRect32( &wndRect, &wndRect, pRectUpdate ))
 			    { 
 				if( !(dce->DCXflags & DCX_DCEBUSY) )
 				{
@@ -505,7 +510,7 @@
         dc->w.DCOrgX = 0;
         dc->w.DCOrgY = 0;
         dc->u.x.drawable = rootWindow;
-        XSetSubwindowMode( display, dc->u.x.gc, IncludeInferiors );
+        TSXSetSubwindowMode( display, dc->u.x.gc, IncludeInferiors );
     }
     else
     {
@@ -535,7 +540,7 @@
 	 */
 
 	if( bSetClipOrigin )
-	    XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY );
+	    TSXSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX, dc->w.DCOrgY );
     }
 }
 /***********************************************************************
@@ -760,27 +765,6 @@
 						      SYSMETRICS_CYSCREEN );
 	    else hrgnVisible = DCE_GetVisRgn( hwnd, flags );
 
-
-	if( wndPtr->parent && wndPtr->window )
-	{
-	    /* Problem - X doesn't discard save under buffers when
-	     * the old data is invalidated by the new graphics output.
-	     *
-	     * FIXME: Instead of overriding we should try to discard
-	     *        save_unders by calling XSetWindowAttributes().
-	     *        And we should do it for the child window GetDCEx() 
-	     *	      calls as well. */
-
-            WND*    wnd = wndPtr->parent->child;
-	    RECT32  rect;
-	
-	    for( ; wnd && (wnd != wndPtr); wnd = wnd->next ) {
-		if( wnd->class->style & CS_SAVEBITS && 
-		    wnd->dwStyle & WS_VISIBLE &&
-		    IntersectRect32(&rect, &wndPtr->rectClient, &wnd->rectClient) )
-                    wnd->flags |= WIN_SAVEUNDER_OVERRIDE;
-	    }
-	}
 	dc->w.flags &= ~DC_DIRTY;
 	dce->DCXflags &= ~DCX_DCEDIRTY;
 	SelectVisRgn( hdc, hrgnVisible );
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 644f634..3cb57b8 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -64,8 +64,8 @@
     wndPtr->text = HEAP_strdupA( SystemHeap, 0, text );
     if (wndPtr->window)
     {
-	XStoreName( display, wndPtr->window, wndPtr->text );
-	XSetIconName( display, wndPtr->window, wndPtr->text );
+	TSXStoreName( display, wndPtr->window, wndPtr->text );
+	TSXSetIconName( display, wndPtr->window, wndPtr->text );
     }
 }
 
@@ -78,7 +78,7 @@
 {
     if( ctlType == CTLCOLOR_SCROLLBAR)
     {
-        HBRUSH32 hb = GetSysColorBrush32(COLOR_SCROLLBAR);
+	HBRUSH32 hb = GetSysColorBrush32(COLOR_SCROLLBAR);
 	SetBkColor32( hDC, RGB(255, 255, 255) );
 	SetTextColor32( hDC, RGB(0, 0, 0) );
 	UnrealizeObject32( hb );
@@ -98,12 +98,14 @@
 {
     BOOL32 bVisible = wndPtr->dwStyle & WS_VISIBLE;
 
+dprintf_win(stddeb,"SetRedraw: %04x %i\n", wndPtr->hwndSelf, (wParam!=0) );
+
     if( wParam )
     {
 	if( !bVisible )
 	{
 	    wndPtr->dwStyle |= WS_VISIBLE;
-	    DCE_InvalidateDCE( wndPtr->parent, &wndPtr->rectWindow );
+	    DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
 	}
     }
     else if( bVisible )
@@ -112,7 +114,7 @@
 	else wParam = RDW_ALLCHILDREN | RDW_VALIDATE;
 
 	PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, wParam, 0 );
-	DCE_InvalidateDCE( wndPtr->parent, &wndPtr->rectWindow );
+	DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
 	wndPtr->dwStyle &= ~WS_VISIBLE;
     }
 }
diff --git a/windows/dinput.c b/windows/dinput.c
new file mode 100644
index 0000000..5f510cd
--- /dev/null
+++ b/windows/dinput.c
@@ -0,0 +1,299 @@
+/*		DirectInput
+ *
+ * Copyright 1998 Marcus Meissner
+ */
+/* Status:
+ *
+ * - Tomb Raider 2 Demo:
+ *   Doesn't accept input yet. Although I am sure I've done everything right...
+ * - WingCommander Prophecy Demo:
+ *   dito.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+#include <X11/Xlib.h>
+#include <sys/signal.h>
+
+#include "windows.h"
+#include "winerror.h"
+#include "shell.h"
+#include "ole.h"
+#include "compobj.h"
+#include "interfaces.h"
+#include "gdi.h"
+#include "heap.h"
+#include "win.h"
+#include "dinput.h"
+#include "stddebug.h"
+#include "debug.h"
+
+static IDirectInputA_VTable ddiavt;
+static IDirectInputDeviceA_VTable SysKeyboardAvt;
+static IDirectInputDeviceA_VTable SysMouseAvt;
+
+HRESULT WINAPI DirectInputCreate32A(HINSTANCE32 hinst, DWORD dwVersion, LPDIRECTINPUT32A *ppDI, LPUNKNOWN punkOuter) {
+	fprintf(stderr,"DirectInputCreate32A(0x%08lx,%04lx,%p,%p)\n",
+		(DWORD)hinst,dwVersion,ppDI,punkOuter
+	);
+	(*ppDI) = (LPDIRECTINPUT32A)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInput32A));
+	(*ppDI)->ref = 1;
+	(*ppDI)->lpvtbl = &ddiavt;
+	return 0;
+}
+/******************************************************************************
+ *		IDirectInputA
+ */
+static HRESULT WINAPI IDirectInputA_EnumDevices(
+	LPDIRECTINPUT32A this,DWORD dwFlags,LPDIENUMDEVICESCALLBACK32A cb,
+	LPVOID context,DWORD x
+) {
+	fprintf(stderr,"IDirectInputA(%p)->EnumDevices(0x%08lx,%p,%p,0x%08lx),stub!\n",this,dwFlags,cb,context,x);
+	return 0;
+}
+
+static ULONG WINAPI IDirectInputA_AddRef(LPDIRECTINPUT32A this) {
+	return ++(this->ref);
+}
+
+static ULONG WINAPI IDirectInputA_Release(LPDIRECTINPUT32A this) {
+	if (!(--this->ref)) {
+		HeapFree(GetProcessHeap(),0,this);
+		return 0;
+	}
+	return this->ref;
+}
+
+static HRESULT WINAPI IDirectInputA_CreateDevice(
+	LPDIRECTINPUT32A this,REFGUID rguid,LPDIRECTINPUTDEVICE32A* pdev,
+	LPUNKNOWN punk
+) {
+	char	xbuf[50];
+	
+	StringFromCLSID(rguid,xbuf);
+	fprintf(stderr,"IDirectInputA(%p)->CreateDevice(%s,%p,%p),stub!\n",this,xbuf,pdev,punk);
+	if (!memcmp(&GUID_SysKeyboard,rguid,sizeof(GUID_SysKeyboard))) {
+		*pdev = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectInputDevice32A));
+		(*pdev)->ref = 1;
+		(*pdev)->lpvtbl = &SysKeyboardAvt;
+		memcpy(&((*pdev)->guid),rguid,sizeof(*rguid));
+		return 0;
+	}
+	if (!memcmp(&GUID_SysMouse,rguid,sizeof(GUID_SysMouse))) {
+		*pdev = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectInputDevice32A));
+		(*pdev)->ref = 1;
+		(*pdev)->lpvtbl = &SysMouseAvt;
+		memcpy(&((*pdev)->guid),rguid,sizeof(*rguid));
+		return 0;
+	}
+	return E_FAIL;
+}
+
+static HRESULT WINAPI IDirectInputA_QueryInterface(
+	LPDIRECTINPUT32A this,REFIID riid,LPVOID *ppobj
+) {
+	char	xbuf[50];
+
+	StringFromCLSID(riid,xbuf);
+	fprintf(stderr,"IDirectInputA(%p)->QueryInterface(%s,%p)\n",this,xbuf,ppobj);
+	if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
+		this->lpvtbl->fnAddRef(this);
+		*ppobj = this;
+		return 0;
+	}
+	if (!memcmp(&IID_IDirectInputA,riid,sizeof(*riid))) {
+		this->lpvtbl->fnAddRef(this);
+		*ppobj = this;
+		return 0;
+	}
+	return E_FAIL;
+}
+
+static IDirectInputA_VTable ddiavt= {
+	IDirectInputA_QueryInterface,
+	IDirectInputA_AddRef,
+	IDirectInputA_Release,
+	IDirectInputA_CreateDevice,
+	IDirectInputA_EnumDevices,
+	(void*)6,
+	(void*)7,
+	(void*)8
+};
+
+/******************************************************************************
+ *	IDirectInputDeviceA
+ */
+static HRESULT WINAPI IDirectInputDeviceA_SetDataFormat(
+	LPDIRECTINPUTDEVICE32A this,LPCDIDATAFORMAT df
+) {
+	/*
+	int i;
+	fprintf(stderr,"IDirectInputDeviceA(%p)->SetDataFormat(%p)\n",this,df);
+
+	fprintf(stderr,"df.dwSize %ld\n",df->dwSize);
+	fprintf(stderr,"df.dwObjsize %ld\n",df->dwObjSize);
+	fprintf(stderr,"df.dwFlags 0x%08lx\n",df->dwFlags);
+	fprintf(stderr,"df.dwDataSize %ld\n",df->dwDataSize);
+	fprintf(stderr,"df.dwNumObjs %ld\n",df->dwNumObjs);
+
+	for (i=0;i<df->dwNumObjs;i++) {
+		char	xbuf[50];
+
+		if (df->rgodf[i].pguid)
+			StringFromCLSID(df->rgodf[i].pguid,xbuf);
+		else
+			strcpy(xbuf,"<no guid>");
+		fprintf(stderr,"df.rgodf[%d].guid %s\n",i,xbuf);
+		fprintf(stderr,"df.rgodf[%d].dwOfs %ld\n",i,df->rgodf[i].dwOfs);
+		fprintf(stderr,"	dwType 0x%02lx,dwInstance %ld\n",DIDFT_GETTYPE(df->rgodf[i].dwType),DIDFT_GETINSTANCE(df->rgodf[i].dwType));
+		fprintf(stderr,"df.rgodf[%d].dwFlags 0x%08lx\n",i,df->rgodf[i].dwFlags);
+	}
+	*/
+	return 0;
+}
+
+static HRESULT WINAPI IDirectInputDeviceA_SetCooperativeLevel(
+	LPDIRECTINPUTDEVICE32A this,HWND32 hwnd,DWORD dwflags
+) {
+	fprintf(stderr,"IDirectInputDeviceA(%p)->SetCooperativeLevel(0x%08lx,0x%08lx)\n",this,(DWORD)hwnd,dwflags);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectInputDeviceA_SetProperty(
+	LPDIRECTINPUTDEVICE32A this,REFGUID rguid,LPCDIPROPHEADER ph
+) {
+	char	xbuf[50];
+
+	if (HIWORD(rguid))
+		StringFromCLSID(rguid,xbuf);
+	else
+		strcpy(xbuf,"<no guid>");
+	fprintf(stderr,"IDirectInputDeviceA(%p)->SetProperty(%s,%p)\n",this,xbuf,ph);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectInputDeviceA_SetEventNotification(
+	LPDIRECTINPUTDEVICE32A this,HANDLE32 hnd
+) {
+	fprintf(stderr,"IDirectInputDeviceA(%p)->SetEventNotification(0x%08lx)\n",this,(DWORD)hnd);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectInputDeviceA_GetDeviceData(
+	LPDIRECTINPUTDEVICE32A this,DWORD x,LPDIDEVICEOBJECTDATA dod,
+	LPDWORD y,DWORD z
+) {
+/*
+	fprintf(stderr,"IDirectInputDeviceA(%p)->GetDeviceData(0x%08lx,%p,%p,0x%08lx)\n",this,x,dod,y,z);
+ */
+	return 0;
+}
+
+static HRESULT WINAPI IDirectInputDeviceA_Acquire(LPDIRECTINPUTDEVICE32A this) {
+	fprintf(stderr,"IDirectInputDeviceA(%p)->Aquire()\n",this);
+	return 0;
+}
+
+static HRESULT WINAPI IDirectInputDeviceA_Unacquire(LPDIRECTINPUTDEVICE32A this) {
+	fprintf(stderr,"IDirectInputDeviceA(%p)->Unaquire()\n",this);
+	return 0;
+}
+
+static ULONG WINAPI IDirectInputDeviceA_Release(LPDIRECTINPUTDEVICE32A this) {
+	this->ref--;
+	if (this->ref)
+		return this->ref;
+	HeapFree(GetProcessHeap(),0,this);
+	return 0;
+}
+
+
+extern BYTE InputKeyStateTable[256];
+extern BYTE vkey2scode[512];
+
+static HRESULT WINAPI IDirectInputDeviceA_GetDeviceState(
+	LPDIRECTINPUTDEVICE32A this,DWORD len,LPVOID ptr
+) {
+/*
+	fprintf(stderr,"IDirectInputDeviceA(%p)->GetDeviceState(0x%08lx,%p)\n",
+		this,len,ptr
+	);
+ */
+	if (len==256) {/* && this_is_a_keyboard */
+		int	i;
+
+		memset(ptr,0,256);
+		for (i=0;i<256;i++) {
+			if (InputKeyStateTable[i]&0x80)
+				fprintf(stderr,"VKEY %d pressed (DIK 0x%02x\n",i,vkey2scode[i]);
+			((LPBYTE)ptr)[i]=vkey2scode[InputKeyStateTable[i]]&0x80;
+		}
+		return 0;
+	}
+	return 0;
+}
+
+static HRESULT WINAPI IDirectInputDeviceA_QueryInterface(
+	LPDIRECTINPUTDEVICE32A this,REFIID riid,LPVOID *ppobj
+) {
+	char	xbuf[50];
+
+	StringFromCLSID(riid,xbuf);
+	fprintf(stderr,"IDirectInputA(%p)->QueryInterface(%s,%p)\n",this,xbuf,ppobj);
+	if (!memcmp(&IID_IUnknown,riid,sizeof(*riid))) {
+		this->lpvtbl->fnAddRef(this);
+		*ppobj = this;
+		return 0;
+	}
+	if (!memcmp(&IID_IDirectInputDeviceA,riid,sizeof(*riid))) {
+		this->lpvtbl->fnAddRef(this);
+		*ppobj = this;
+		return 0;
+	}
+	return E_FAIL;
+}
+
+static IDirectInputDeviceA_VTable SysKeyboardAvt={
+	IDirectInputDeviceA_QueryInterface,
+	(void*)2,
+	IDirectInputDeviceA_Release,
+	(void*)4,
+	(void*)5,
+	(void*)6,
+	IDirectInputDeviceA_SetProperty,
+	IDirectInputDeviceA_Acquire,
+	IDirectInputDeviceA_Unacquire,
+	IDirectInputDeviceA_GetDeviceState,
+	IDirectInputDeviceA_GetDeviceData,
+	IDirectInputDeviceA_SetDataFormat,
+	IDirectInputDeviceA_SetEventNotification,
+	IDirectInputDeviceA_SetCooperativeLevel,
+	(void*)15,
+	(void*)16,
+	(void*)17,
+	(void*)18,
+};
+
+static IDirectInputDeviceA_VTable SysMouseAvt={
+	IDirectInputDeviceA_QueryInterface,
+	(void*)2,
+	IDirectInputDeviceA_Release,
+	(void*)4,
+	(void*)5,
+	(void*)6,
+	IDirectInputDeviceA_SetProperty,
+	IDirectInputDeviceA_Acquire,
+	IDirectInputDeviceA_Unacquire,
+	IDirectInputDeviceA_GetDeviceState,
+	IDirectInputDeviceA_GetDeviceData,
+	IDirectInputDeviceA_SetDataFormat,
+	IDirectInputDeviceA_SetEventNotification,
+	IDirectInputDeviceA_SetCooperativeLevel,
+	(void*)15,
+	(void*)16,
+	(void*)17,
+	(void*)18,
+};
diff --git a/windows/event.c b/windows/event.c
index a6888ac..84bc271 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -15,9 +15,9 @@
 #include <sys/types.h>
 #include <errno.h>
 #include <X11/keysym.h>
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xresource.h"
+#include "ts_xutil.h"
 #include <X11/Xatom.h>
 
 #include "windows.h"
@@ -109,7 +109,7 @@
 
 extern void FOCUS_SetXFocus( HWND32 );
 extern BOOL16 DRAG_QueryUpdate( HWND16, SEGPTR, BOOL32 );
-extern BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, fd_set io_set[3] );
+extern BOOL32 WINSOCK_HandleIO( int* max_fd, int num_pending, fd_set p[3], fd_set e[3] );
 
 /***********************************************************************
  *           EVENT_Init
@@ -151,7 +151,7 @@
 {
     WND *pWnd;
     
-    if (XFindContext( display, event->xany.window, winContext,
+    if (TSXFindContext( display, event->xany.window, winContext,
                       (char **)&pWnd ) != 0)
         return;  /* Not for a registered window */
 
@@ -186,7 +186,7 @@
 	 */
         if (InputEnabled)
 	{
-            while (XCheckTypedWindowEvent(display,((XAnyEvent *)event)->window,
+            while (TSXCheckTypedWindowEvent(display,((XAnyEvent *)event)->window,
                                           MotionNotify, event));    
             EVENT_MotionNotify( pWnd, (XMotionEvent*)event );
 	}
@@ -264,18 +264,18 @@
 void EVENT_RegisterWindow( WND *pWnd )
 {
     if (wmProtocols == None)
-        wmProtocols = XInternAtom( display, "WM_PROTOCOLS", True );
+        wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True );
     if (wmDeleteWindow == None)
-        wmDeleteWindow = XInternAtom( display, "WM_DELETE_WINDOW", True );
+        wmDeleteWindow = TSXInternAtom( display, "WM_DELETE_WINDOW", True );
     if( dndProtocol == None )
-	dndProtocol = XInternAtom( display, "DndProtocol" , False );
+	dndProtocol = TSXInternAtom( display, "DndProtocol" , False );
     if( dndSelection == None )
-	dndSelection = XInternAtom( display, "DndSelection" , False );
+	dndSelection = TSXInternAtom( display, "DndSelection" , False );
 
-    XSetWMProtocols( display, pWnd->window, &wmDeleteWindow, 1 );
+    TSXSetWMProtocols( display, pWnd->window, &wmDeleteWindow, 1 );
 
-    if (!winContext) winContext = XUniqueContext();
-    XSaveContext( display, pWnd->window, winContext, (char *)pWnd );
+    if (!winContext) winContext = TSXUniqueContext();
+    TSXSaveContext( display, pWnd->window, winContext, (char *)pWnd );
 }
 
 /***********************************************************************
@@ -285,9 +285,9 @@
 {
    XEvent xe;
 
-   XDeleteContext( display, pWnd->window, winContext );
-   XDestroyWindow( display, pWnd->window );
-   while( XCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) );
+   TSXDeleteContext( display, pWnd->window, winContext );
+   TSXDestroyWindow( display, pWnd->window );
+   while( TSXCheckWindowEvent(display, pWnd->window, NoEventMask, &xe) );
 }
 
 
@@ -320,18 +320,19 @@
 {
     XEvent event;
     LONG maxWait = sleep ? TIMER_GetNextExpiration() : 0;
+    int pending = TSXPending(display);
 
     /* Wait for an event or a timeout. If maxWait is -1, we have no timeout;
      * in this case, we fall through directly to the XNextEvent loop.
      */
 
-    if ((maxWait != -1) && !XPending(display))
+    if ((maxWait != -1) && !pending)
     {
 	int num_pending;
         struct timeval timeout;
-	fd_set read_set = __event_io_set[EVENT_IO_READ];
-	fd_set write_set = __event_io_set[EVENT_IO_WRITE];
-	fd_set except_set = __event_io_set[EVENT_IO_EXCEPT];
+	fd_set io_set[3];
+
+	memcpy( io_set, __event_io_set, sizeof(io_set) );
 
 	timeout.tv_usec = (maxWait % 1000) * 1000;
 	timeout.tv_sec = maxWait / 1000;
@@ -347,7 +348,9 @@
 	}
 	stop_wait_op = STOP_WAIT_X;
 	/* The code up to the next "stop_wait_op = CONT" must be reentrant */
-	num_pending = select( __event_max_fd, &read_set, NULL, NULL, &timeout );
+	num_pending = select( __event_max_fd, &io_set[EVENT_IO_READ], 
+					      &io_set[EVENT_IO_WRITE], 
+					      &io_set[EVENT_IO_EXCEPT], &timeout );
 	if ( num_pending == 0 )
         {
 	    stop_wait_op = CONT;
@@ -356,8 +359,9 @@
 	}
         else stop_wait_op = CONT;
 #else  /* CONFIG_IPC */
-	num_pending = select( __event_max_fd, 
-			&read_set, &write_set, &except_set, &timeout );
+	num_pending = select( __event_max_fd, &io_set[EVENT_IO_READ],
+					      &io_set[EVENT_IO_WRITE],
+					      &io_set[EVENT_IO_EXCEPT], &timeout );
 	if ( num_pending == 0)
         {
             /* Timeout or error */
@@ -368,14 +372,22 @@
 
 	/*  Winsock asynchronous services */
 
-	if( FD_ISSET( __event_x_connection, &read_set) ) 
+	if( FD_ISSET( __event_x_connection, &io_set[EVENT_IO_READ]) ) 
 	{
 	    num_pending--;
 	    if( num_pending )
-		WINSOCK_HandleIO( &__event_max_fd, num_pending, __event_io_set );
+		WINSOCK_HandleIO( &__event_max_fd, num_pending, io_set, __event_io_set );
 	}
 	else /* no X events */
-	    return WINSOCK_HandleIO( &__event_max_fd, num_pending, __event_io_set );
+	    return WINSOCK_HandleIO( &__event_max_fd, num_pending, io_set, __event_io_set );
+    }
+    else if(!pending)
+    {				/* Wait for X11 input. */
+	fd_set set;
+
+	FD_ZERO(&set);
+	FD_SET(__event_x_connection, &set);
+	select(__event_x_connection + 1, &set, 0, 0, 0 );
     }
 
     /* Process current X event (and possibly others that occurred in the meantime) */
@@ -391,14 +403,14 @@
         }
 #endif  /* CONFIG_IPC */
 
-	XNextEvent( display, &event );
+	TSXNextEvent( display, &event );
 
         if( peek )
         {
 	  WND*		pWnd;
 	  MESSAGEQUEUE* pQ;
 
-          if (XFindContext( display, ((XAnyEvent *)&event)->window, winContext,
+          if (TSXFindContext( display, ((XAnyEvent *)&event)->window, winContext,
                             (char **)&pWnd ) || (event.type == NoExpose))
               continue;
 
@@ -420,14 +432,14 @@
             {
               pQ->flags |= QUEUE_FLAG_XEVENT;
               PostEvent(pQ->hTask);
-	      XPutBackEvent(display, &event);
+	      TSXPutBackEvent(display, &event);
               break;
 	    }
           }
         }
         else EVENT_ProcessEvent( &event );
     }
-    while (XPending( display ));
+    while (TSXPending( display ));
     return TRUE;
 }
 
@@ -441,10 +453,10 @@
 {
     XEvent event;
 
-    XSync( display, False );
-    while (XPending( display ))
+    TSXSync( display, False );
+    while (TSXPending( display ))
     {
-	XNextEvent( display, &event );
+	TSXNextEvent( display, &event );
 	EVENT_ProcessEvent( &event );
     }    
 }
@@ -453,6 +465,7 @@
  *           EVENT_QueryZOrder
  *
  * Try to synchronize internal z-order with the window manager's.
+ * Probably a futile endeavor.
  */
 static BOOL32 __check_query_condition( WND** pWndA, WND** pWndB )
 {
@@ -478,10 +491,10 @@
 
     do
     {
-        if( *children ) XFree( *children );
-        XQueryTree( display, A, &root, &A, children, total );
-        XQueryTree( display, B, &root, &B, &childrenB, &totalB );
-        if( childrenB ) XFree( childrenB );
+        if( *children ) TSXFree( *children );
+        TSXQueryTree( display, A, &root, &A, children, total );
+        TSXQueryTree( display, B, &root, &B, &childrenB, &totalB );
+        if( childrenB ) TSXFree( childrenB );
     } while( A != B && A && B );
     return ( A && B ) ? A : 0 ;
 }
@@ -494,8 +507,8 @@
     do
     {
         w = parent;
-        XQueryTree( display, w, &root, &parent, &children, &total );
-        if( children ) XFree( children );
+        TSXQueryTree( display, w, &root, &parent, &children, &total );
+        if( children ) TSXFree( children );
     } while( parent && parent != ancestor );
     dprintf_event( stddeb, "\t%08x -> %08x\n", (unsigned)prev, (unsigned)w );
     return ( parent ) ? w : 0 ;
@@ -547,7 +560,7 @@
             WIN_LinkWindow( pWndCheck->hwndSelf, hwndInsertAfter);
         }
     }
-    if( children ) XFree( children );
+    if( children ) TSXFree( children );
     return bRet;
 }
 
@@ -646,7 +659,7 @@
     int rootX, rootY, winX, winY;
     unsigned int state;
 
-    if (XQueryPointer( display, rootWindow, &root, &child,
+    if (TSXQueryPointer( display, rootWindow, &root, &child,
                        &rootX, &rootY, &winX, &winY, &state ))
     {
         hardware_event( WM_MOUSEMOVE, EVENT_XStateToKeyState( state ), 0L,
@@ -742,9 +755,9 @@
     Window xW;
     int	   state;
 
-    XGetInputFocus(display, &xW, &state);
+    TSXGetInputFocus(display, &xW, &state);
     if( xW == None ||
-        XFindContext(display, xW, winContext, (char **)&pWnd) ) 
+        TSXFindContext(display, xW, winContext, (char **)&pWnd) ) 
         return FALSE;
     return TRUE;
 }
@@ -763,7 +776,7 @@
     int xpos, ypos;
     unsigned int width, height, border, depth, nb_children;
 
-    if (!XGetGeometry( display, win, &root, px, py, pwidth, pheight,
+    if (!TSXGetGeometry( display, win, &root, px, py, pwidth, pheight,
                        &border, &depth )) return;
     if (win == rootWindow)
     {
@@ -773,12 +786,12 @@
 
     for (;;)
     {
-        if (!XQueryTree(display, win, &root, &parent, &children, &nb_children))
+        if (!TSXQueryTree(display, win, &root, &parent, &children, &nb_children))
             return;
-        XFree( children );
+        TSXFree( children );
         if (parent == rootWindow) break;
         win = parent;
-        if (!XGetGeometry( display, win, &root, &xpos, &ypos,
+        if (!TSXGetGeometry( display, win, &root, &xpos, &ypos,
                            &width, &height, &border, &depth )) return;
         *px += xpos;
         *py += ypos;
@@ -907,7 +920,7 @@
 	    }
 	    lpstr[j]='\0';
 
-	    XChangeProperty(display, request, rprop, 
+	    TSXChangeProperty(display, request, rprop, 
 			    XA_STRING, 8, PropModeReplace, 
 			    lpstr, j);
 	    HeapFree( GetProcessHeap(), 0, lpstr );
@@ -919,7 +932,7 @@
     }
 
     if(rprop == None) 
-       dprintf_event(stddeb,"Request for %s ignored\n", XGetAtomName(display,event->target));
+       dprintf_event(stddeb,"Request for %s ignored\n", TSXGetAtomName(display,event->target));
 
     result.type = SelectionNotify;
     result.display = display;
@@ -928,7 +941,7 @@
     result.property = rprop;
     result.target = event->target;
     result.time = event->time;
-    XSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
+    TSXSendEvent(display,event->requestor,False,NoEventMask,(XEvent*)&result);
 }
 
 
@@ -987,7 +1000,7 @@
 	  
           if( !lpDragInfo || !spDragInfo ) return;
 
-	  XQueryPointer( display, pWnd->window, &w_aux_root, &w_aux_child, 
+	  TSXQueryPointer( display, pWnd->window, &w_aux_root, &w_aux_child, 
 		 &x, &y, &u.pt_aux.x, &u.pt_aux.y, (unsigned int*)&aux_long);
 
           lpDragInfo->hScope = pWnd->hwndSelf;
@@ -1008,7 +1021,7 @@
 
 	  if( bAccept )
 	  {
-	      XGetWindowProperty( display, DefaultRootWindow(display),
+	      TSXGetWindowProperty( display, DefaultRootWindow(display),
 			      dndSelection, 0, 65535, FALSE,
                               AnyPropertyType, &u.atom_aux, &u.pt_aux.y,
 		             &data_length, &aux_long, &p_data);
@@ -1069,7 +1082,7 @@
 		  }
 	        }
 	      }
-	      if( p_data ) XFree(p_data);  
+	      if( p_data ) TSXFree(p_data);  
 
 	  } /* WS_EX_ACCEPTFILES */
        } /* dndProtocol */
@@ -1089,7 +1102,7 @@
   {
    if( !Options.managed && rootWindow == DefaultRootWindow(display) &&
      (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE) && GetFocus32() )
-      XInstallColormap( display, COLOR_GetColormap() );
+      TSXInstallColormap( display, COLOR_GetColormap() );
   }
  */ 
 
@@ -1119,7 +1132,7 @@
 
     if (!hwnd)
     {
-        XUngrabPointer(display, CurrentTime );
+        TSXUngrabPointer(display, CurrentTime );
         captureWnd = NULL; captureHT = 0; 
     }
     else if ((win = WIN_GetXWindow( hwnd )))
@@ -1127,7 +1140,7 @@
 	WND* wndPtr = WIN_FindWndPtr( hwnd );
 
         if ( wndPtr && 
-	     (XGrabPointer(display, win, False, 
+	     (TSXGrabPointer(display, win, False, 
 			   ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
                            GrabModeAsync, GrabModeAsync,
                            None, None, CurrentTime ) == GrabSuccess) )
@@ -1231,11 +1244,11 @@
     if (AX_reg(context) & ME_MOVE)
     {
         /* We have to actually move the cursor */
-        XWarpPointer( display, rootWindow, None, 0, 0, 0, 0,
+        TSXWarpPointer( display, rootWindow, None, 0, 0, 0, 0,
                       (short)BX_reg(context), (short)CX_reg(context) );
         return;
     }
-    if (!XQueryPointer( display, rootWindow, &root, &child,
+    if (!TSXQueryPointer( display, rootWindow, &root, &child,
                         &rootX, &rootY, &winX, &winY, &state )) return;
     if (AX_reg(context) & ME_LDOWN)
         hardware_event( WM_LBUTTONDOWN, EVENT_XStateToKeyState( state ),
diff --git a/windows/focus.c b/windows/focus.c
index 9f7bb9b..38ef5c5 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -34,20 +34,20 @@
     if (!hwnd)	/* If setting the focus to 0, uninstall the colormap */
     {
 	if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE)
-	    XUninstallColormap( display, COLOR_GetColormap() );
+	    TSXUninstallColormap( display, COLOR_GetColormap() );
 	return;
     }
 
       /* Set X focus and install colormap */
 
     if (!(win = WIN_GetXWindow( hwnd ))) return;
-    if (!XGetWindowAttributes( display, win, &win_attr ) ||
+    if (!TSXGetWindowAttributes( display, win, &win_attr ) ||
         (win_attr.map_state != IsViewable))
         return;  /* If window is not viewable, don't change anything */
 
-    XSetInputFocus( display, win, RevertToParent, CurrentTime );
+    TSXSetInputFocus( display, win, RevertToParent, CurrentTime );
     if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE)
-        XInstallColormap( display, COLOR_GetColormap() );
+        TSXInstallColormap( display, COLOR_GetColormap() );
 
     EVENT_Synchronize();
 }
diff --git a/windows/graphics.c b/windows/graphics.c
index a4953c6..e3e1d25 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -7,8 +7,8 @@
 
 #include <assert.h>
 #include <stdlib.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xutil.h"
 #include <X11/Intrinsic.h>
 #include "graphics.h"
 #include "color.h"
@@ -48,7 +48,7 @@
 		 l[i].y1 = pXY[j].y + dc->w.DCOrgY;
 		 l[i].y2 = pXY[j + 1].y + dc->w.DCOrgY;
 	    }
-	    XDrawSegments( display, dc->u.x.drawable, dc->u.x.gc, l, N );
+	    TSXDrawSegments( display, dc->u.x.drawable, dc->u.x.gc, l, N );
 	    bRet = TRUE;
 	}
 	if( hPrevPen ) SelectObject32( hdc, hPrevPen );
@@ -76,12 +76,12 @@
 
     xdest += dc->w.DCOrgX; ydest += dc->w.DCOrgY;
 
-    XSetFunction( display, dc->u.x.gc, GXcopy );
+    TSXSetFunction( display, dc->u.x.gc, GXcopy );
     if (bmp->bitmap.bmBitsPixel == 1)
     {
-        XSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel );
-        XSetBackground( display, dc->u.x.gc, dc->w.textPixel );
-        XCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc,
+        TSXSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel );
+        TSXSetBackground( display, dc->u.x.gc, dc->w.textPixel );
+        TSXCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc,
                     xsrc, ysrc, width, height, xdest, ydest, 1 );
     }
     else if (bmp->bitmap.bmBitsPixel == dc->w.bitsPerPixel)
@@ -92,19 +92,19 @@
 
 	    if( COLOR_GetMonoPlane(&plane) )
 	    {
-		XSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel );
-		XSetBackground( display, dc->u.x.gc, dc->w.textPixel );
+		TSXSetForeground( display, dc->u.x.gc, dc->w.backgroundPixel );
+		TSXSetBackground( display, dc->u.x.gc, dc->w.textPixel );
 	    }
 	    else
 	    {
-		XSetForeground( display, dc->u.x.gc, dc->w.textPixel );
-		XSetBackground( display, dc->u.x.gc, dc->w.backgroundPixel );
+		TSXSetForeground( display, dc->u.x.gc, dc->w.textPixel );
+		TSXSetBackground( display, dc->u.x.gc, dc->w.backgroundPixel );
 	    }
-	    XCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc,
+	    TSXCopyPlane( display, bmp->pixmap, dc->u.x.drawable, dc->u.x.gc,
 			xsrc, ysrc, width, height, xdest, ydest, plane );
 	}
 	else 
-	    XCopyArea( display, bmp->pixmap, dc->u.x.drawable, 
+	    TSXCopyArea( display, bmp->pixmap, dc->u.x.drawable, 
 		       dc->u.x.gc, xsrc, ysrc, width, height, xdest, ydest );
     }
     else 
@@ -169,12 +169,12 @@
     {
          INT32	i;
 
-	 XSetFunction( display, dc->u.x.gc, GXcopy );
+	 TSXSetFunction( display, dc->u.x.gc, GXcopy );
          for (i = 0; i < highlight_size; i++)
          {
-	      XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+	      TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
 					r.left + i, r.top, 1, h - i );
-	      XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+	      TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
 					r.left, r.top + i, w - i, 1 );
          }
     }
@@ -184,12 +184,12 @@
     {
 	 INT32	i;
 
-	 XSetFunction( display, dc->u.x.gc, GXcopy );
+	 TSXSetFunction( display, dc->u.x.gc, GXcopy );
          for (i = 0; i < shadow_size; i++)
          {
-	      XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+	      TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
 			      r.right - i - 1, r.top + i, 1, h - i );
-	      XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+	      TSXFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
 			      r.left + i, r.bottom - i - 1, w - i, 1 );
          }
     }
@@ -213,7 +213,7 @@
 
 	if( hPen ) hPrevPen = SelectObject32( hdc, hPen );
 	if( DC_SetupGCForPen( dc ) )
-	    XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc, 
+	    TSXDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc, 
 			    x + dc->w.DCOrgX, y + dc->w.DCOrgY, w - 1, h - 1);
 	if( hPrevPen ) SelectObject32( hdc, hPrevPen );
     }
@@ -233,10 +233,10 @@
        if ( !(bmp = (BITMAPOBJ *) GDI_GetObjPtr( hMonoBitmap, BITMAP_MAGIC)) 
 	   || bmp->bitmap.bmBitsPixel != 1 ) return FALSE;
 	  
-       XSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX + x, dc->w.DCOrgY + y);
+       TSXSetClipOrigin( display, dc->u.x.gc, dc->w.DCOrgX + x, dc->w.DCOrgY + y);
     }
 
-    XSetClipMask( display, dc->u.x.gc, (bmp) ? bmp->pixmap : None );
+    TSXSetClipMask( display, dc->u.x.gc, (bmp) ? bmp->pixmap : None );
 
     GDI_HEAP_UNLOCK( hMonoBitmap );
     return TRUE;
diff --git a/windows/hook.c b/windows/hook.c
index 0fa854d..ebf20c6 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -99,6 +99,7 @@
             else WINPROC_MapMsg16To32W( lpcwp16->message, lpcwp16->wParam, 
                                         &lpcwp32->message, &lpcwp32->wParam,
                                         &lpcwp32->lParam );
+	    *plParam = (LPARAM)lpcwp32;
 	    break;
 	}
 
diff --git a/windows/keyboard.c b/windows/keyboard.c
index 2f2f594..faadc7d 100644
--- a/windows/keyboard.c
+++ b/windows/keyboard.c
@@ -12,9 +12,9 @@
 #include <string.h>
 #include <ctype.h>
 #include <X11/keysym.h>
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xresource.h"
+#include "ts_xutil.h"
 #include <X11/Xatom.h>
 
 #include "windows.h"
@@ -107,7 +107,7 @@
 /*
  * Table for vkey to scancode translation - 5/29/97 chrisf@america.com 
  */
-static const BYTE vkey2scode[512] = {
+const BYTE vkey2scode[512] = {
   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x0e,0x0f,0x00,0x00,0x00,0x1c,0x00,0x00,
   0x2a,0x1d,0x38,0x00,0x3a,0x00,0x00,0x00, 0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
   0x39,0x49,0x51,0x4f,0x47,0x4b,0x48,0x4d, 0x50,0x00,0x00,0x00,0x00,0x52,0x53,0x00,
@@ -147,7 +147,7 @@
 {
     KeySym keysym;
 
-    XLookupString(e, NULL, 0, &keysym, NULL);
+    TSXLookupString(e, NULL, 0, &keysym, NULL);
 
     if ((keysym >= 0xFFAE) && (keysym <= 0xFFB9) && (e->state & NumLockMask)) 
         /* Only the Keypad keys 0-9 and . send different keysyms
@@ -170,13 +170,13 @@
     XKeyEvent e2;
     WORD vkey, OEMvkey;
 
-    XDisplayKeycodes(display, &min_keycode, &max_keycode);
-    ksp = XGetKeyboardMapping(display, min_keycode,
+    TSXDisplayKeycodes(display, &min_keycode, &max_keycode);
+    ksp = TSXGetKeyboardMapping(display, min_keycode,
                               max_keycode + 1 - min_keycode, &keysyms_per_keycode);
     /* We are only interested in keysyms_per_keycode.
        There is no need to hold a local copy of the keysyms table */
-    XFree(ksp);
-    mmp = XGetModifierMapping(display);
+    TSXFree(ksp);
+    mmp = TSXGetModifierMapping(display);
     kcp = mmp->modifiermap;
     for (i = 0; i < 8; i += 1) /* There are 8 modifier keys */
     {
@@ -188,19 +188,19 @@
 		int k;
                 
 		for (k = 0; k < keysyms_per_keycode; k += 1)
-                    if (XKeycodeToKeysym(display, *kcp, k) == XK_Mode_switch)
+                    if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Mode_switch)
 		    {
                         AltGrMask = 1 << i;
                         dprintf_key(stddeb, "AltGrMask is %x\n", AltGrMask);
 		    }
-                    else if (XKeycodeToKeysym(display, *kcp, k) == XK_Num_Lock)
+                    else if (TSXKeycodeToKeysym(display, *kcp, k) == XK_Num_Lock)
 		    {
                         NumLockMask = 1 << i;
                         dprintf_key(stddeb, "NumLockMask is %x\n", NumLockMask);
 		    }
             }
     }
-    XFreeModifiermap(mmp);
+    TSXFreeModifiermap(mmp);
 
     /* Now build two conversion arrays :
      * keycode -> vkey + extended
@@ -212,7 +212,7 @@
     OEMvkey = 0xb9; /* first OEM virtual key available is ba */
     for (e2.keycode=min_keycode; e2.keycode<=max_keycode; e2.keycode++)
     {
-        XLookupString(&e2, NULL, 0, &keysym, NULL);
+        TSXLookupString(&e2, NULL, 0, &keysym, NULL);
         vkey = 0;
         if (keysym)  /* otherwise, keycode not used */
         {
@@ -263,7 +263,7 @@
             }
             for (i = 0; (i < keysyms_per_keycode) && (!vkey); i++)
             {
-                keysym = XLookupKeysym(&e2, i);
+                keysym = TSXLookupKeysym(&e2, i);
                 if ((keysym >= VK_0 && keysym <= VK_9)
                     || (keysym >= VK_A && keysym <= VK_Z)
                     || keysym == VK_SPACE)
@@ -291,8 +291,8 @@
                     {
                         char	*ksname;
                         
-                        keysym = XLookupKeysym(&e2, i);
-                        ksname = XKeysymToString(keysym);
+                        keysym = TSXLookupKeysym(&e2, i);
+                        ksname = TSXKeysymToString(keysym);
                         if (!ksname)
 			    ksname = "NoSymbol";
                         fprintf(stddeb, "%lX (%s) ", keysym, ksname);
@@ -366,7 +366,7 @@
     KEYLP keylp;
     static BOOL32 force_extended = FALSE; /* hack for AltGr translation */
 
-    int ascii_chars = XLookupString(event, Str, 1, &keysym, &cs);
+    int ascii_chars = TSXLookupString(event, Str, 1, &keysym, &cs);
 
     INT32 event_x = pWnd->rectWindow.left + event->x;
     INT32 event_y = pWnd->rectWindow.top + event->y;
@@ -376,10 +376,10 @@
     if (keysym == XK_Mode_switch)
 	{
 	dprintf_key(stddeb, "Alt Gr key event received\n");
-	event->keycode = XKeysymToKeycode(event->display, XK_Control_L);
+	event->keycode = TSXKeysymToKeycode(event->display, XK_Control_L);
 	dprintf_key(stddeb, "Control_L is keycode 0x%x\n", event->keycode);
 	KEYBOARD_HandleEvent( pWnd, event );
-	event->keycode = XKeysymToKeycode(event->display, XK_Alt_L);
+	event->keycode = TSXKeysymToKeycode(event->display, XK_Alt_L);
 	dprintf_key(stddeb, "Alt_L is keycode 0x%x\n", event->keycode);
 	force_extended = TRUE;
 	KEYBOARD_HandleEvent( pWnd, event );
@@ -392,7 +392,7 @@
 	{
 	char	*ksname;
 
-	ksname = XKeysymToString(keysym);
+	ksname = TSXKeysymToString(keysym);
 	if (!ksname)
 	    ksname = "No Name";
 	fprintf(stddeb, "%s : keysym=%lX (%s), ascii chars=%u / %X / '%s'\n", 
@@ -817,10 +817,10 @@
 	keysym=(unsigned char) cChar;/* (!) cChar is signed */
 	if (keysym<=27) keysym+=0xFF00;/*special chars : return, backspace...*/
 	
-	keycode = XKeysymToKeycode(display, keysym);  /* keysym -> keycode */
+	keycode = TSXKeysymToKeycode(display, keysym);  /* keysym -> keycode */
 	if (!keycode)
 	{ /* It didn't work ... let's try with deadchar code. */
-	  keycode = XKeysymToKeycode(display, keysym | 0xFE00);
+	  keycode = TSXKeysymToKeycode(display, keysym | 0xFE00);
 	}
 
 	dprintf_keyboard(stddeb,"VkKeyScan '%c'(%#lx, %lu) : got keycode %#.2x ",
@@ -829,7 +829,7 @@
 	if (keycode)
 	  {
 	    for (index=-1, i=0; (i<8) && (index<0); i++) /* find shift state */
-	      if (XKeycodeToKeysym(display,keycode,i)==keysym) index=i;
+	      if (TSXKeycodeToKeysym(display,keycode,i)==keysym) index=i;
 	    switch (index) {
 	    case -1 :
 	      fprintf(stderr,"Keysym %lx not found while parsing the keycode table\n",keysym); break;
@@ -947,7 +947,7 @@
 			e.display = display;
 			e.state = 0; /* unshifted */
 			e.keycode = MapVirtualKey16( wCode, 0);
-			if (!XLookupString(&e, s , 2 , &keysym, NULL))
+			if (!TSXLookupString(&e, s , 2 , &keysym, NULL))
 			  returnMVK (*s);
 			
 			return 0;
@@ -1065,9 +1065,9 @@
     if ((!e.keycode) && (lpKeyState[VK_NUMLOCK] & 0x01)) 
       {
 	if ((virtKey>=VK_NUMPAD0) && (virtKey<=VK_NUMPAD9))
-	  e.keycode = XKeysymToKeycode(e.display, virtKey-VK_NUMPAD0+XK_KP_0);
+	  e.keycode = TSXKeysymToKeycode(e.display, virtKey-VK_NUMPAD0+XK_KP_0);
 	if (virtKey==VK_DECIMAL)
-	  e.keycode = XKeysymToKeycode(e.display, XK_KP_Decimal);
+	  e.keycode = TSXKeysymToKeycode(e.display, XK_KP_Decimal);
       }
     if (!e.keycode)
       {
@@ -1089,7 +1089,7 @@
 	e.state |= NumLockMask;
     dprintf_key(stddeb, "ToAscii(%04X, %04X) : faked state = %X\n",
 		virtKey, scanCode, e.state);
-    ret = XLookupString(&e, (LPVOID)lpChar, 2, &keysym, &cs);
+    ret = TSXLookupString(&e, (LPVOID)lpChar, 2, &keysym, &cs);
     if (ret == 0)
 	{
 	BYTE dead_char = 0;
@@ -1189,7 +1189,7 @@
 	    {
 	    char	*ksname;
 
-	    ksname = XKeysymToString(keysym);
+	    ksname = TSXKeysymToString(keysym);
 	    if (!ksname)
 		ksname = "No Name";
 	    if ((keysym >> 8) != 0xff)
diff --git a/windows/mdi.c b/windows/mdi.c
index e9e1980..e2049fd 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -1603,26 +1603,26 @@
     INT32 newPos = -1;
     INT32 curPos, length, minPos, maxPos, shift;
 
- if( !wndPtr ) return;
+    if( !wndPtr ) return;
 
- if( uMsg == WM_HSCROLL )
-   {
-     GetScrollRange32(hWnd,SB_HORZ,&minPos,&maxPos);
-     curPos = GetScrollPos32(hWnd,SB_HORZ);
-     length = (wndPtr->rectClient.right - wndPtr->rectClient.left)/2;
-     shift = SYSMETRICS_CYHSCROLL;
-   }
- else if( uMsg == WM_VSCROLL )
-	{
-	  GetScrollRange32(hWnd,SB_VERT,&minPos,&maxPos);
-	  curPos = GetScrollPos32(hWnd,SB_VERT);
-	  length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2;
-	  shift = SYSMETRICS_CXVSCROLL;
-	}
-      else return;
+    if( uMsg == WM_HSCROLL )
+    {
+	GetScrollRange32(hWnd,SB_HORZ,&minPos,&maxPos);
+	curPos = GetScrollPos32(hWnd,SB_HORZ);
+	length = (wndPtr->rectClient.right - wndPtr->rectClient.left)/2;
+	shift = SYSMETRICS_CYHSCROLL;
+    }
+    else if( uMsg == WM_VSCROLL )
+    {
+	GetScrollRange32(hWnd,SB_VERT,&minPos,&maxPos);
+	curPos = GetScrollPos32(hWnd,SB_VERT);
+	length = (wndPtr->rectClient.bottom - wndPtr->rectClient.top)/2;
+	shift = SYSMETRICS_CXVSCROLL;
+    }
+    else return;
 
- switch( wParam )
-   {
+    switch( wParam )
+    {
 	case SB_LINEUP:	
 		        newPos = curPos - shift;
 			break;
@@ -1652,20 +1652,21 @@
 	case SB_ENDSCROLL:
 			CalcChildScroll(hWnd,(uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ);
 			return;
-   }
+    }
 
- if( newPos > maxPos )
-     newPos = maxPos;
- else if( newPos < minPos )
-	  newPos = minPos;
+    if( newPos > maxPos )
+	newPos = maxPos;
+    else 
+	if( newPos < minPos )
+	    newPos = minPos;
 
- SetScrollPos32(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
+    SetScrollPos32(hWnd, (uMsg == WM_VSCROLL)?SB_VERT:SB_HORZ , newPos, TRUE);
 
- if( uMsg == WM_VSCROLL )
-     ScrollWindowEx32(hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL, 
+    if( uMsg == WM_VSCROLL )
+	ScrollWindowEx32(hWnd ,0 ,curPos - newPos, NULL, NULL, 0, NULL, 
 			SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
- else
-     ScrollWindowEx32(hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
+    else
+	ScrollWindowEx32(hWnd ,curPos - newPos, 0, NULL, NULL, 0, NULL,
 			SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN );
 }
 
diff --git a/windows/message.c b/windows/message.c
index 08a4d7d..1668722 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -449,7 +449,7 @@
     joySendMessages();
 
     /* If the queue is empty, attempt to fill it */
-    if (!sysMsgQueue->msgCount && XPending(display))
+    if (!sysMsgQueue->msgCount && TSXPending(display))
         EVENT_WaitNetEvent( FALSE, FALSE );
 
     for (i = kbd_msg = 0; i < sysMsgQueue->msgCount; i++, pos++)
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 720c2ab..145ded0 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -1511,7 +1511,7 @@
     else
     {  /* Grab the server only when moving top-level windows without desktop */
 	hdc = GetDC32( 0 );
-	if (rootWindow == DefaultRootWindow(display)) XGrabServer( display );
+	if (rootWindow == DefaultRootWindow(display)) TSXGrabServer( display );
     }
 
     if( iconic ) /* create a cursor for dragging */
@@ -1610,7 +1610,7 @@
     else
     {
 	ReleaseDC32( 0, hdc );
-	if (rootWindow == DefaultRootWindow(display)) XUngrabServer( display );
+	if (rootWindow == DefaultRootWindow(display)) TSXUngrabServer( display );
     }
 
     if (HOOK_IsHooked( WH_CBT ))
diff --git a/windows/painting.c b/windows/painting.c
index fba790b..9baba58 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -9,8 +9,6 @@
  */
 
 #include <stdio.h>
-#include <X11/Xlib.h>
-
 #include "win.h"
 #include "queue.h"
 #include "gdi.h"
diff --git a/windows/queue.c b/windows/queue.c
index 6c6cf30..f23542f 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -712,14 +712,9 @@
     if (!wndPtr) return 0;
     htask=QUEUE_GetQueueTask( wndPtr->hmemTaskQ );
     tdb = (TDB*)GlobalLock16(htask);
-    if (!tdb) return 0;
-    if (tdb->thdb) {
-    	if (process)
-		*process = (DWORD)tdb->thdb->process;
-	return (DWORD)tdb->thdb;
-    }
-    return 0;
-
+    if (!tdb || !tdb->thdb) return 0;
+    if (process) *process = PDB_TO_PROCESS_ID( tdb->thdb->process );
+    return THDB_TO_THREAD_ID( tdb->thdb );
 }
 
 
diff --git a/windows/scroll.c b/windows/scroll.c
index b4daae6..efe1cc3 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -399,15 +399,15 @@
 	    else src.y = (dst.y = dc->w.DCOrgY + cliprc.top) - dy;
 
 	    if( bUpdate ) /* handles non-Wine windows hanging over the scrolled area */
-		XSetGraphicsExposures( display, dc->u.x.gc, True );
+		TSXSetGraphicsExposures( display, dc->u.x.gc, True );
 
-	    XSetFunction( display, dc->u.x.gc, GXcopy );
-	    XCopyArea( display, dc->u.x.drawable, dc->u.x.drawable, dc->u.x.gc, 
+	    TSXSetFunction( display, dc->u.x.gc, GXcopy );
+	    TSXCopyArea( display, dc->u.x.drawable, dc->u.x.drawable, dc->u.x.gc, 
 		       src.x, src.y, cliprc.right - cliprc.left - abs(dx),
 		       cliprc.bottom - cliprc.top - abs(dy), dst.x, dst.y );
 
 	    if( bUpdate )
-		XSetGraphicsExposures( display, dc->u.x.gc, False );
+		TSXSetGraphicsExposures( display, dc->u.x.gc, False );
 
 	    if( dc->w.hVisRgn && bUpdate )
 	    {
diff --git a/windows/user.c b/windows/user.c
index f791b00..8faf91b 100644
--- a/windows/user.c
+++ b/windows/user.c
@@ -299,3 +299,15 @@
     if (result) USER_ExitWindows();
     return FALSE;
 }
+
+
+/***********************************************************************
+ *           SetEventHook   (USER.321)
+ *
+ *	Used by Turbo Debugger for Windows
+ */
+FARPROC16 SetEventHook(FARPROC16 lpfnEventHook)
+{
+	fprintf(stderr, "SetEventHook(lpfnEventHook = %08x): stub !\n", (UINT32)lpfnEventHook);
+	return NULL;
+}
diff --git a/windows/win.c b/windows/win.c
index 69f88b4..74b55ea 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -666,7 +666,7 @@
         win_attr.backing_store = Options.backingstore ? WhenMapped : NotUseful;
         win_attr.save_under    = ((classPtr->style & CS_SAVEBITS) != 0);
         win_attr.cursor        = CURSORICON_XCursor;
-        wndPtr->window = XCreateWindow( display, rootWindow, cs->x, cs->y,
+        wndPtr->window = TSXCreateWindow( display, rootWindow, cs->x, cs->y,
                                         cs->cx, cs->cy, 0, CopyFromParent,
                                         InputOutput, CopyFromParent,
                                         CWEventMask | CWOverrideRedirect |
@@ -676,23 +676,23 @@
         if ((wndPtr->flags & WIN_MANAGED) &&
             (cs->dwExStyle & WS_EX_DLGMODALFRAME))
         {
-            XSizeHints* size_hints = XAllocSizeHints();
+            XSizeHints* size_hints = TSXAllocSizeHints();
 
             if (size_hints)
             {
                 size_hints->min_width = size_hints->max_width = cs->cx;
                 size_hints->min_height = size_hints->max_height = cs->cy;
                 size_hints->flags = (PSize | PMinSize | PMaxSize);
-                XSetWMSizeHints( display, wndPtr->window, size_hints,
+                TSXSetWMSizeHints( display, wndPtr->window, size_hints,
                                  XA_WM_NORMAL_HINTS );
-                XFree(size_hints);
+                TSXFree(size_hints);
             }
         }
 
 	if (cs->hwndParent)  /* Get window owner */
 	{
             Window win = WIN_GetXWindow( cs->hwndParent );
-            if (win) XSetTransientForHint( display, wndPtr->window, win );
+            if (win) TSXSetTransientForHint( display, wndPtr->window, win );
 	}
         EVENT_RegisterWindow( wndPtr );
     }
@@ -1786,30 +1786,48 @@
  */
 HWND32 WINAPI SetParent32( HWND32 hwndChild, HWND32 hwndNewParent )
 {
-    HWND32 oldParent;
-
     WND *wndPtr = WIN_FindWndPtr( hwndChild );
-    WND *pWndParent = WIN_FindWndPtr( hwndNewParent );
+    WND *pWndParent = (hwndNewParent) ? WIN_FindWndPtr( hwndNewParent )
+				      : pWndDesktop;
 
-    if (!wndPtr || !pWndParent) return 0;
-    oldParent = wndPtr->parent->hwndSelf;
+    if( wndPtr && pWndParent && (wndPtr != pWndDesktop) )
+    {
+	WND* pWndPrev = wndPtr->parent;
 
-    if (!(wndPtr->dwStyle & WS_CHILD)) {
-	if (wndPtr->window) {
-	    /* Toplevel window needs to be reparented.  Used by Tk 8.0 */
-	    XDestroyWindow( display, wndPtr->window );
-	    wndPtr->window = None;
+	if( pWndParent != pWndPrev )
+	{
+	    BOOL32 bFixupDCE = IsWindowVisible32(hwndChild);
+
+	    if ( wndPtr->window )
+	    {
+		/* Toplevel window needs to be reparented.  Used by Tk 8.0 */
+
+		TSXDestroyWindow( display, wndPtr->window );
+		wndPtr->window = None;
+	    }
+	    else if( bFixupDCE )
+		DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
+
+	    WIN_UnlinkWindow(hwndChild);
+	    wndPtr->parent = pWndParent;
+
+	    /* FIXME: Create an X counterpart for reparented top-level windows
+	     * when not in the desktop mode. */
+     
+	    if ( pWndParent == pWndDesktop ) 
+		 wndPtr->dwStyle &= ~WS_CHILD;
+	    else wndPtr->dwStyle |= WS_CHILD;
+	    WIN_LinkWindow(hwndChild, HWND_BOTTOM);
+
+	    if( bFixupDCE )
+	    {
+	        DCE_InvalidateDCE( wndPtr, &wndPtr->rectWindow );
+		UpdateWindow32(hwndChild);
+	    }
 	}
-	wndPtr->dwStyle |= WS_CHILD;
-    }
-
-    WIN_UnlinkWindow(hwndChild);
-    if (hwndNewParent) wndPtr->parent = pWndParent;
-    WIN_LinkWindow(hwndChild, HWND_BOTTOM);
-
-    if (IsWindowVisible32(hwndChild)) UpdateWindow32(hwndChild);
-    
-    return oldParent;
+	return pWndPrev->hwndSelf;
+    } /* failure */
+    return 0;
 }
 
 
diff --git a/windows/winpos.c b/windows/winpos.c
index 8b51066..1c1bdd4 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -5,8 +5,8 @@
  *                       1995, 1996 Alex Korobka
  */
 
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include "ts_xlib.h"
+#include "ts_xutil.h"
 #include <X11/Xatom.h>
 #include "sysmetrics.h"
 #include "heap.h"
@@ -956,6 +956,8 @@
                          WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
                          CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
 			 wndPtr->dwStyle |= WS_MAXIMIZE;
+			 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
+			 break;
 		     }
 		 } 
 		 else 
@@ -1337,7 +1339,7 @@
     winChanges.stack_mode = Above;
     while (pWnd)
     {
-        if (pWnd->window) XReconfigureWMWindow( display, pWnd->window, 0,
+        if (pWnd->window) TSXReconfigureWMWindow( display, pWnd->window, 0,
                                                 CWStackMode, &winChanges );
         wndPrev = WIN_GetDesktop()->child;
         if (wndPrev == pWnd) break;
@@ -1952,9 +1954,9 @@
         window = wndPtr->window;
         for (;;)
         {
-            XQueryTree( display, window, &root, &parent,
+            TSXQueryTree( display, window, &root, &parent,
                         &children, &nchildren );
-            XFree( children );
+            TSXFree( children );
             if (parent == root)
                 return window;
             window = parent;
@@ -1984,19 +1986,19 @@
         if ((wndPtr->flags & WIN_MANAGED) &&
             (wndPtr->dwExStyle & WS_EX_DLGMODALFRAME))
         {
-            XSizeHints *size_hints = XAllocSizeHints();
+            XSizeHints *size_hints = TSXAllocSizeHints();
 
             if (size_hints)
             {
                 long supplied_return;
 
-                XGetWMSizeHints( display, wndPtr->window, size_hints,
+                TSXGetWMSizeHints( display, wndPtr->window, size_hints,
                                  &supplied_return, XA_WM_NORMAL_HINTS);
                 size_hints->min_width = size_hints->max_width = winpos->cx;
                 size_hints->min_height = size_hints->max_height = winpos->cy;
-                XSetWMSizeHints( display, wndPtr->window, size_hints,
+                TSXSetWMSizeHints( display, wndPtr->window, size_hints,
                                  XA_WM_NORMAL_HINTS );
-                XFree(size_hints);
+                TSXFree(size_hints);
             }
         }
     }
@@ -2022,13 +2024,13 @@
 
 	    /* for stupid window managers (i.e. all of them) */
 
-	    XRestackWindows(display, stack, 2); 
+	    TSXRestackWindows(display, stack, 2); 
 	    changeMask &= ~CWStackMode;
 	}
     }
     if (!changeMask) return;
 
-    XReconfigureWMWindow( display, wndPtr->window, 0, changeMask, &winChanges );
+    TSXReconfigureWMWindow( display, wndPtr->window, 0, changeMask, &winChanges );
 }
 
 
@@ -2216,7 +2218,7 @@
         RECT32 rect;
 
         UnionRect32(&rect, &newWindowRect, &wndPtr->rectWindow);
-	DCE_InvalidateDCE(wndPtr->parent, &rect);
+	DCE_InvalidateDCE(wndPtr, &rect);
     }
 
     /* change geometry */
@@ -2234,10 +2236,10 @@
 	/* postpone geometry change */
 
 	if( !(flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) )
-	  {
+	{
               WINPOS_SetXWindowPos( &winpos );
 	      winpos.hwndInsertAfter = tempInsertAfter;
-	  }
+	}
 	else  uFlags |= SMC_SETXPOS;
 
         wndPtr->rectWindow = newWindowRect;
@@ -2323,13 +2325,13 @@
               WINPOS_SetXWindowPos( &winpos );
               winpos.hwndInsertAfter = tempInsertAfter;
 	    }
-            XMapWindow( display, wndPtr->window );
+            TSXMapWindow( display, wndPtr->window );
 
 	    /* If focus was set to an unmapped window, reset X focus now */
 	    focus = curr = GetFocus32();
-	    while (curr != NULL) {
+	    while (curr) {
 		if (curr == hwnd) {
-		    SetFocus32( NULL );
+		    SetFocus32( 0 );
 		    SetFocus32( focus );
 		    break;
 		}
@@ -2349,7 +2351,7 @@
 	wndPtr->dwStyle &= ~WS_VISIBLE;
         if (wndPtr->window)
         {
-            XUnmapWindow( display, wndPtr->window );
+            TSXUnmapWindow( display, wndPtr->window );
 	    if( uFlags & SMC_SETXPOS )
 	    {
               WINPOS_SetXWindowPos( &winpos );
@@ -2390,13 +2392,7 @@
         EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
 
     if (!(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) )
-    {
-        PAINT_RedrawWindow( wndPtr->parent->hwndSelf,
-              (wndPtr->flags & WIN_SAVEUNDER_OVERRIDE) ? &oldWindowRect : NULL,
-              0, RDW_ALLCHILDREN | RDW_ERASENOW |
-                            ((wndPtr->flags & WIN_SAVEUNDER_OVERRIDE) ? RDW_INVALIDATE : 0), 0 );
-        wndPtr->flags &= ~WIN_SAVEUNDER_OVERRIDE;
-    }
+        PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW, 0 );
     else if( wndPtr->parent == WIN_GetDesktop() && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND )
 	PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_NOCHILDREN | RDW_ERASENOW, 0 );
 
@@ -2405,9 +2401,8 @@
     dprintf_win(stddeb,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
 
     if ( ((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) && 
-	!(winpos.flags & SWP_NOSENDCHANGING))
-        SendMessage32A( winpos.hwnd, WM_WINDOWPOSCHANGED,
-                        0, (LPARAM)&winpos );
+	 !(winpos.flags & SWP_NOSENDCHANGING))
+        SendMessage32A( winpos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM)&winpos );
 
     return TRUE;
 }
diff --git a/wine.ini b/wine.ini
index 8da8b56..7cde88b 100644
--- a/wine.ini
+++ b/wine.ini
@@ -8,12 +8,14 @@
 ;; Label=xxx      (drive label, at most 11 characters)
 ;; Serial=xxx     (serial number, 8 characters hexadecimal number)
 ;; Filesystem=xxx (supported types are 'msdos','win95','unix')
+;; Device=/dev/xx (only if you want to allow raw device access)
 ;;
 [Drive A]
 Path=/mnt/fd0
 Type=floppy
 Label=Floppy
 Serial=87654321
+Device=/dev/fd0
 
 [Drive C]
 Path=/c