Release 950706

Wed Jul  5 19:06:35 1995  Alexandre Julliard  <julliard@sunsite.unc.edu>

	* [controls/scroll.c]
	Fixed drawing bug that caused part of a non-client scroll bar
	to be painted even when the scroll-bar was hidden.

	* [debugger/break.c] [debugger/dbg.y]
	Rewrote breakpoint handling to work in 16-bit mode.
	Implemented single-stepping ('step' and 'next' instructions).

	* [debugger/debug.l]
	Format specifier is now a separate token.
	Entering an empty line at the debugger prompt causes the previous
	command to be repeated, like under gdb.
	
	* [debugger/debug.l] [debugger/registers.c]
	Differentiate 16-bit and 32-bit registers without taking current
	mode into account ($eax is always 32-bit, $ax always 16-bit).

	* [debugger/stack.c]
	Fixed stack information routines to differentiate between 16-bit
	and 32-bit stacks.

	* [loader/task.c]
	Option -debug now sets a breakpoint at the first instruction of
	every loaded task.

	* [miscemu/instr.c]
	Added handling of lock, repe and repne prefixes.

	* [objects/dib.c]
	Changed StretchDIBits() to do the correct thing, even if it's still
	not really optimal.

	* [windows/graphics.c]
	Fixes in RoundRect(), thanks to Babak Masalehdan.

	* [windows/message.c]
	Tried to fix mouse event handling with respect to disabled
	windows.

	* [windows/painting.c]
	Clear WIN_NEEDS_NCPAINT flag before sending WM_NCPAINT to avoid
	infinite loops.

	* [windows/win.c]
	Fixed IsWindowVisible() to return FALSE when one of the parent
	windows is hidden.

Sat Jul  1 22:08:21 1995   Martin von Loewis <loewis@informatik.hu-berlin.de>

	* [if1632/compobj.spec][misc/compobj.c]
	CoGetMalloc: New function
	Added relay entries for COMPOBJ ordinals above 100
	CoInitialize: Changed parameter to DWORD

	* [if1632/ole2.spec]
	Exported implementation of OleBuildVersion

	* [if1632/ole2disp.spec][misc/ole2disp.c][misc/Imakefile]
	ole2disp.c: New file
	SysAllocString, SysReallocString, SysAllocStringLen,
	SysReAllocStringLen, SysFreeString, SysStringLen: new functions

	* [if1632/ole2nls.spec][include/winnls.h][misc/ole2nls.c]
	CompareStringA: New function

Thu Jun 29 19:42:02 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>
	* [objects/font.c] [if1632/gdi.spec]
	New stubs for CreateScalableFontResource, GetGlyphOutline.

Thu Jun 29 13:47:08 GMT 1995  Göran Thyni  (goran@norrsken.bildbasen.se)

	* [misc/commdlg.c]
	Extensive changes and bug fixes to FileDialog handling,
        behaves more like native Windows.

Wed Jun 28 13:04:44 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>

        * [controls/listbox.c] [controls/combo.c]
	Some minor optimizations.
	
	* [memory/local.c]
	LOCAL_FindFreeBlock(): Never use the last one.
	
	* [memory/global.c]
	GlobalReAlloc(): GMEM_MODIFY must not be ignored when size==0.
	
	* [misc/file.c]
	read() returns an error when length==0. This is not what Windows
	programs expect, so pay attention to this in _lread(). Changed this
	in _lwrite(), _hread(), _hwrite(), too.

	* [loader/resource.c]
	LoadIcon(): Ignore bih->biSizeImage, some icons have wrong values in
	there.
	
	* [if1632/shell.spec] [misc/shell.c]
	Wrong spec file entries caused havoc: HKEY has 32 bit, not 16.
	Accept some more combinations of parameters in the Reg..() functions.
	
	* [if1632/toolhelp.spec]
	Make InterruptRegister() and InterruptUnregister() return false.

	* [windows/hook.c]
	CallNextHookEx() used to crash when called with a null hhook. Fixed.

Wed Jun 28 10:14:34 1995  Martin von Loewis  <martin@informatik.hu-berlin.de>

	* [include/neexe.h][loader/ne_image.c]
	NE_LoadSegment: Detect iterated segments

	* [misc/ole2nls.c]
	LOCALE_SLONGDATE: fixed typo

	* [miscemu/int5c.c]
	Reordered include files to avoid conflicts with Linux libc.5.1

	* [rc/winerc.c]
	Added -b option to process binary resource files into C arrays

	* [include/callback.h]
	CallWndProc: Added dummy ds parameter for libwine

	* [include/gdi.h][include/user.h]
	USER_HEAP_ALLOC, GDI_HEAP_ALLOC: dropped flags parameter

	* [include/ldt.h][include/stackframe.h]
	defined segment conversion macros for libwine

	* [misc/atom.c]
	Defined USER_HeapSel for libwine

	* [misc/main.c]
	Disable -dll option for libwine

	* [misc/user.c]
	removed GetFreeSystemResources, SystemHeapInfo from libwine for now

	* [toolkit/heap.c]
	fixed LocalLock prototype

	* [toolkit/sup.c]
	sync'ed load_mz_header, load_ne_header with structures

	* [toolkit/winmain.c]
	Disabled resource DLLs for libwine for now

Mon Jun 26 19:30:24 1995  Hans de Graaff  (graaff@twi72.twi.tudelft.nl)

	* [misc/main.c]
	Fixed -enhanced option to report a 386 CPU instead of a 286.

Fri Jun 23 23:18:25 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>

	* [misc/dos_fs.c]
	Remove maximum open dosdirent limit (fixing the winfile.exe
 	problem) by using telldir()/seekdir().
	
Fri Jun 23 13:42:25 1995  Hans de Graaff  (graaff@twi72.twi.tudelft.nl)

	* [misc/profile.c]
	Fixed problem parsing empty lines within sections in .ini files.
diff --git a/ANNOUNCE b/ANNOUNCE
index 97b66e2..35713f1 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,15 +1,14 @@
-This is release 950620 of Wine the MS Windows emulator.  This is still a
+This is release 950706 of Wine the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work.
 
 Patches should be submitted to "wine-new@amscons.com".  Please don't forget
 to include a ChangeLog entry.  I'll make a new release every other Sunday.
 
-WHAT'S NEW with Wine-950620: (see ChangeLog for details)
-	- Many fixes to edit and listbox controls.
-	- Better MDI code.
-	- Many local heap fixes.
-	- Some built-in DLLs are now disabled by default.
+WHAT'S NEW with Wine-950706: (see ChangeLog for details)
+	- Built-in debugger supports single-stepping (please test it on *BSD).
+	- Winelib should compile again.
+	- More OLE2 functions.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -18,11 +17,11 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950620.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950620.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950620.tar.gz
-    ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950620.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-950620.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-950706.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-950706.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-950706.tar.gz
+    ftp.funet.fi:/pub/OS/Linux/ALPHA/Wine/Wine-950706.tar.gz
+    aris.com:/pub/linux/ALPHA/Wine/development/Wine-950706.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 3766178..4eab56d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,169 @@
 ----------------------------------------------------------------------
+Wed Jul  5 19:06:35 1995  Alexandre Julliard  <alex@numenor>
+
+	* [controls/scroll.c]
+	Fixed drawing bug that caused part of a non-client scroll bar
+	to be painted even when the scroll-bar was hidden.
+
+	* [debugger/break.c] [debugger/dbg.y]
+	Rewrote breakpoint handling to work in 16-bit mode.
+	Implemented single-stepping ('step' and 'next' instructions).
+
+	* [debugger/debug.l]
+	Format specifier is now a separate token.
+	Entering an empty line at the debugger prompt causes the previous
+	command to be repeated, like under gdb.
+	
+	* [debugger/debug.l] [debugger/registers.c]
+	Differentiate 16-bit and 32-bit registers without taking current
+	mode into account ($eax is always 32-bit, $ax always 16-bit).
+
+	* [debugger/stack.c]
+	Fixed stack information routines to differentiate between 16-bit
+	and 32-bit stacks.
+
+	* [loader/task.c]
+	Option -debug now sets a breakpoint at the first instruction of
+	every loaded task.
+
+	* [miscemu/instr.c]
+	Added handling of lock, repe and repne prefixes.
+
+	* [objects/dib.c]
+	Changed StretchDIBits() to do the correct thing, even if it's still
+	not really optimal.
+
+	* [windows/graphics.c]
+	Fixes in RoundRect(), thanks to Babak Masalehdan.
+
+	* [windows/message.c]
+	Tried to fix mouse event handling with respect to disabled
+	windows.
+
+	* [windows/painting.c]
+	Clear WIN_NEEDS_NCPAINT flag before sending WM_NCPAINT to avoid
+	infinite loops.
+
+	* [windows/win.c]
+	Fixed IsWindowVisible() to return FALSE when one of the parent
+	windows is hidden.
+
+Sat Jul  1 22:08:21 1995   Martin von Loewis <loewis@informatik.hu-berlin.de>
+
+	* [if1632/compobj.spec][misc/compobj.c]
+	CoGetMalloc: New function
+	Added relay entries for COMPOBJ ordinals above 100
+	CoInitialize: Changed parameter to DWORD
+
+	* [if1632/ole2.spec]
+	Exported implementation of OleBuildVersion
+
+	* [if1632/ole2disp.spec][misc/ole2disp.c][misc/Imakefile]
+	ole2disp.c: New file
+	SysAllocString, SysReallocString, SysAllocStringLen,
+	SysReAllocStringLen, SysFreeString, SysStringLen: new functions
+
+	* [if1632/ole2nls.spec][include/winnls.h][misc/ole2nls.c]
+	CompareStringA: New function
+
+Thu Jun 29 19:42:02 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>
+	* [objects/font.c] [if1632/gdi.spec]
+	New stubs for CreateScalableFontResource, GetGlyphOutline.
+
+Thu Jun 29 13:47:08 GMT 1995  Göran Thyni  (goran@norrsken.bildbasen.se)
+
+	* [misc/commdlg.c]
+	Extensive changes and bug fixes to FileDialog handling,
+        behaves more like native Windows.
+
+Wed Jun 28 13:04:44 1995   Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
+
+        * [controls/listbox.c] [controls/combo.c]
+	Some minor optimizations.
+	
+	* [memory/local.c]
+	LOCAL_FindFreeBlock(): Never use the last one.
+	
+	* [memory/global.c]
+	GlobalReAlloc(): GMEM_MODIFY must not be ignored when size==0.
+	
+	* [misc/file.c]
+	read() returns an error when length==0. This is not what Windows
+	programs expect, so pay attention to this in _lread(). Changed this
+	in _lwrite(), _hread(), _hwrite(), too.
+
+	* [loader/resource.c]
+	LoadIcon(): Ignore bih->biSizeImage, some icons have wrong values in
+	there.
+	
+	* [if1632/shell.spec] [misc/shell.c]
+	Wrong spec file entries caused havoc: HKEY has 32 bit, not 16.
+	Accept some more combinations of parameters in the Reg..() functions.
+	
+	* [if1632/toolhelp.spec]
+	Make InterruptRegister() and InterruptUnregister() return false.
+
+	* [windows/hook.c]
+	CallNextHookEx() used to crash when called with a null hhook. Fixed.
+
+Wed Jun 28 10:14:34 1995  Martin von Loewis  <martin@informatik.hu-berlin.de>
+
+	* [include/neexe.h][loader/ne_image.c]
+	NE_LoadSegment: Detect iterated segments
+
+	* [misc/ole2nls.c]
+	LOCALE_SLONGDATE: fixed typo
+
+	* [miscemu/int5c.c]
+	Reordered include files to avoid conflicts with Linux libc.5.1
+
+	* [rc/winerc.c]
+	Added -b option to process binary resource files into C arrays
+
+	* [include/callback.h]
+	CallWndProc: Added dummy ds parameter for libwine
+
+	* [include/gdi.h][include/user.h]
+	USER_HEAP_ALLOC, GDI_HEAP_ALLOC: dropped flags parameter
+
+	* [include/ldt.h][include/stackframe.h]
+	defined segment conversion macros for libwine
+
+	* [misc/atom.c]
+	Defined USER_HeapSel for libwine
+
+	* [misc/main.c]
+	Disable -dll option for libwine
+
+	* [misc/user.c]
+	removed GetFreeSystemResources, SystemHeapInfo from libwine for now
+
+	* [toolkit/heap.c]
+	fixed LocalLock prototype
+
+	* [toolkit/sup.c]
+	sync'ed load_mz_header, load_ne_header with structures
+
+	* [toolkit/winmain.c]
+	Disabled resource DLLs for libwine for now
+
+Mon Jun 26 19:30:24 1995  Hans de Graaff  (graaff@twi72.twi.tudelft.nl)
+
+	* [misc/main.c]
+	Fixed -enhanced option to report a 386 CPU instead of a 286.
+
+Fri Jun 23 23:18:25 1995  Marcus Meissner  <msmeissn@faui01.informatik.uni-erlangen.de>
+
+	* [misc/dos_fs.c]
+	Remove maximum open dosdirent limit (fixing the winfile.exe
+ 	problem) by using telldir()/seekdir().
+	
+Fri Jun 23 13:42:25 1995  Hans de Graaff  (graaff@twi72.twi.tudelft.nl)
+
+	* [misc/profile.c]
+	Fixed problem parsing empty lines within sections in .ini files.
+
+----------------------------------------------------------------------
 Mon Jun 19 20:29:50 1995  Alexandre Julliard  (julliard@sunsite.unc.edu)
 
 	* [debugger/*.c]
diff --git a/Configure b/Configure
index 892e481..3a4c6f7 100644
--- a/Configure
+++ b/Configure
@@ -103,7 +103,6 @@
 	fi
 	prompt "Where should Windows apps store temp files" CF_Temp $CF_Temp
 	prompt "Which path should be used to find progs/DLL's" CF_Path "$CF_Windows;$CF_System"
-	prompt "Where is sysres.dll" CF_SystemResources `pwd`/sysres.dll
 	prompt "Where is COM1" CF_Com1 '/dev/cua0'
 	prompt "Where is COM2" CF_Com2 '/dev/cua1'
 	prompt "Where is LPT1" CF_Lpt1 '/dev/lp0'
diff --git a/Wine.man b/Wine.man
new file mode 100644
index 0000000..e39bbfd
--- /dev/null
+++ b/Wine.man
@@ -0,0 +1,328 @@
+.\" -*- nroff -*-
+.TH WINE 1 "June 29, 1995" "Version 6/20/95" "Windows Emulation"
+.SH NAME
+wine \- run Windows 3.x programs under Linux
+.SH SYNOPSIS
+.B wine
+[
+.I options
+]
+.I program_name
+[
+.I arguments
+]
+.SH DESCRIPTION
+.B wine
+invokes the Linux Windows emulator.
+.PP
+.B wine 
+currently runs a number of games and small applications (approximately
+half of the applets and common games actually run), although the entire API
+has not been implemented.
+.PP
+See the files 
+.B README,
+.B ChangeLog, 
+.B Configure, 
+and the
+.B Makefile
+contained in the source distribution
+to compile
+.B wine.
+.SH REQUIREMENTS
+At present, 
+.B wine
+will run under any Linux kernel more recent than 0.99.13, or
+under recent releases of NetBSD and FreeBSD.
+.PP
+.B X
+must be installed.
+.PP
+.B libXpm
+must be installed.  (It is probably available from the same site 
+.B wine
+was, or the sources may be FTP'd from ftp.x.org).
+.SH INSTALLATION
+To install 
+.B wine,
+run "./Configure", which will ask for configuration information and
+create the Makefiles, then run "make".
+.SH OPTIONS
+.TP
+.I -depth n
+Change the depth to use for multiple-depth screens
+.TP
+.I -desktop geom
+Use a desktop window of the given geometry
+.TP
+.I -display name
+Use the specified display
+.TP
+.I -iconic
+Start as an icon
+.TP
+.I -debug
+Enter the debugger before starting application
+.TP
+.I -name name
+Set the application name
+.TP
+.I -privatemap
+Use a private color map
+.TP
+.I -synchronous
+Turn on synchronous display mode
+.TP
+.I -backingstore
+Turn on backing store
+.TP
+.I -spy file
+Turn on message spying to the specified file
+.TP
+.I -debugmsg name[,name]
+Turn debugging messages on or off - for instance, 
+.I -debugmsg +dll,+heap
+will turn on DLL and heap debugging messages.  The full list is:
+all, accel, bitblt, bitmap, caret, catch, cdaudio, class, clipboard, clipping,
+combo, comm, cursor, dc, dialog, dll, dosfs, driver, edit, enum, event, exec,
+file, fixup, font, gdi, global, graphics, icon, int, key, keyboard, ldt,
+listbox, local, malloc, mci, mcianim, mciwave, mdi, menu, menucalc, message,
+metafile, midi, mmio, mmsys, mmtime, module, msg, nonclient, ole, palette, 
+profile, prop, reg, region, relay, resource, scroll, selector, selectors, 
+stress, syscolor, task, text, timer, toolhelp, utility, win, winsock.
+.TP
+.I -dll name
+Enables/disables built-in DLL's - starting wine with
+.I -dll -commdlg
+is probably a good idea.
+The full list of DLLs modifiable by this is:
+KERNEL, USER, GDI, WIN87EM, SHELL, SOUND, KEYBOARD, WINSOCK, STRESS, MMSYSTEM,
+SYSTEM, TOOLHELP, MOUSE, COMMDLG, OLE2, OLE2CONV, OLE2DISP, OLE2NLS, OLE2PROX,
+OLECLI, OLESVR, COMPOBJ, STORAGE, WINPROCS, DDEML
+.TP
+.I -allowreadonly
+Read only files may be opened in write mode
+.TP
+.I -enhanced
+Starts wine in Enhanced mode (not guaranteed to work yet)
+.PD 1
+.SH PROGRAM/ARGUMENTS
+The program name may be specified in DOS format (C:\\WINDOWS\\SOL.EXE) or in 
+Linux format (/msdos/windows/sol.exe).  The program being executed may be 
+passed arguments by adding them on to the end of the command line invoking
+.B wine
+(such as: wine "notepad C:\\TEMP\\README.TXT").  Note that
+the program name and its arguments 
+.I must
+be passed as a single parameter, which is usually accomplished by placing
+them together in quotation marks.  Multiple applications may be started
+by placing all of them on the command line (such as: wine notepad clock).
+.SH CONFIGURATION FILE
+.B wine
+expects a configuration file (/usr/local/etc/wine.conf), 
+which should conform to the following rules.  The actual file name may
+be specified during the execution of the
+.B Configure
+script.  Alternatively, you may have a 
+.I .winerc
+file of this format in your home directory.
+.SH CONFIGURATION FILE FORMAT
+.B [drives]
+.br
+.I format: <driveletter> = <rootdirectory>
+.br
+default: none
+.br
+This section is used to specify the root directory of each 
+.B DOS
+drive, since most Windows applications require a DOS/MS-Windows based 
+disk drive & directory scheme.
+.br
+If you mounted your dos partition as 
+.I /dos
+and installed Microsoft Windows in 
+C:\\WINDOWS then you should specify 
+.I c=/dos
+in the drives section.
+.PP
+.B [wine]
+.br
+.I format: windows = <directory>
+.br
+default: C:\\WINDOWS
+.br
+Used to specify a different Windows directory
+.PP
+.I format: system = <directory>
+.br
+default: C:\\WINDOWS\\SYSTEM
+.br
+Used to specify a different system directory
+.PP
+.I format: temp = <directory>
+.br
+default: C:\\TEMP
+.br
+Used to specify a directory where Windows applications can store 
+temporary files.
+.PP
+.I format: path = <directories separated by semi-colons>
+.br
+default: C:\\WINDOWS;C:\\WINDOWS\\SYSTEM
+.br
+Used to specify the path which will be used to find executables and .DLL's.
+.PP
+.I format: symboltablefile = <filename>
+.br
+default: wine.sym
+.br
+Used to specify the path and file name of the symbol table used by the built-in
+debugger.
+.PP
+.B [serialports]
+.br
+.I format: com[12345678] = <devicename>
+.br
+default: none
+.br
+Used to specify the devices which are used as com1 - com8.
+.PP
+.B [parallelports]
+.br
+.I format: lpt[12345678] = <devicename>
+.br
+default: none
+.br
+Used to specify the devices which are used as lpt1 - lpt8.
+.PP
+.B [spy]
+.br
+.I format: file = <filename or CON when logging to stdout>
+.br
+default: none
+.br
+Used to specify the file which will be used as
+.B logfile.
+.PP
+.I format: exclude = <message names separated by semicolons>
+.br
+default: none
+.br
+Used to specify which messages will be excluded from the logfile.
+.PP
+.I format: include = <message names separated by semicolons>
+.br
+default: none
+.br Used to specify which messages will be included in the logfile.
+.SH SAMPLE wine.conf
+[drives]
+.br
+a=/mnt/fd0
+.br
+c=/dos
+.br
+d=~/Wine
+.PP
+[wine]
+.br
+windows=c:\\windows
+.br
+system=c:\\windows\\system
+.br
+temp=c:\\temp
+.br
+path=c:\\windows;c:\\windows\\system;c:\\winapps\\word
+.br
+symboltablefile=/usr/local/lib/wine.sym
+.PP
+[serialports]
+.br
+com1=/dev/cua1
+.br
+com2=/dev/cua1
+.PP
+[parallelports]
+.br
+lpt1=/dev/lp0
+.PP
+[spy]
+.br
+;File=CON
+.br
+;File=spy.log
+.br
+Exclude=WM_TIMER;WM_SETCURSOR;WM_MOUSEMOVE;WM_NCHITTEST;
+.br
+Include=WM_COMMAND;
+.SH AUTHORS
+.B Wine
+is available thanks to the work of Bob Amstadt, Dag Asheim,
+Martin Ayotte, Ross Biro, Erik Bos, Fons Botman, John Brezak,
+Andrew Bulhak, John Burton, Paul Falstad, Olaf Flebbe, Peter Galbavy,
+Cameron Heide, Jeffrey Hsu, Miguel de Icaza, Alexandre Julliard,
+Jon Konrath, Scott A. Laird, Martin von Loewis, Kenneth MacDonald,
+Peter MacDonald, William Magro, David Metcalfe, Michael Patra,
+John Richardson, Johannes Ruscheinski, Thomas Sandford,
+Constantine Sapuntzakis, Bernd Schmidt, Yngvi Sigurjonsson, Rick Sladkey,
+William Smith, Erik Svendsen, Goran Thyni, Jimmy Tirtawangsa, Jon Tombs,
+Linus Torvalds, Michael Veksler, Carl Williams, Karl Guenter Wuensch,
+Eric Youngdale, and James Youngman.
+.PP
+This man page is maintained by Mike Phillips (msphil@mail.wm.edu), so please
+send all corrections, comments, flames, etc., to him.
+.SH BUGS
+There are too many to count, much less list.  Some are of note, however:
+Any Windows program using Visual Basic (VBRUNxxx.DLL) will not run yet,
+nor will any program depending on undocumented functions or on the
+COMMDLG (any standard file open/save interface) unless you disable the 
+internal COMMDLG with the 
+.I -dll -commdlg
+option.  In addition, 16-color support is imperfect at best, and 
+icons sometimes display improperly on some systems.  Certain 
+multi-language modules will not load properly.  Progress is being made 
+regularly, however.
+.PP
+Currently, no directories in the path can have upper-case letters in them
+(ex. /msdos/driveC), as the conversions necessary to handle the msdos 
+filename conventions currently cause them to be lost.
+.PP
+A partial list of applications known to work with 
+.B wine
+include: sol, cruel, golf.exe, clock, notepad, charmap, and calc.
+The following URLs point to different success/testing lists:
+.br
+.I http://www.ifi.uio.no/~dash/wine/working-apps.html
+.br
+.I http://dutifp.twi.tudelft.nl:8000/wine/
+.PP
+We would like to hear about what software does run under 
+.B Wine,
+and such reports may be posted to 
+.I comp.emulators.ms-windows.wine.
+.SH AVAILABILITY
+The most recent public version of 
+.B wine
+can be ftp'ed from tsx-11.mit.edu in the /pub/linux/ALPHA/Wine/development 
+directory.  The releases are in the format 'Wine-yymmdd.tar.gz', 
+or 'Wine-yymmdd.diff.gz' for the diff's from the previous release.
+.SH FILES
+.PD 0
+.TP
+.I /usr/local/bin/wine
+The invoker program.
+.TP
+.I /usr/local/etc/wine.conf
+Main configuration file for wine.
+.TP
+.I ChangeLog
+Changes in Wine, since the beginning (most recent changes first)
+.TP
+.I Configure
+Shell script to automate compilation.  Usually followed by make (or gmake 
+on *BSD systems) to compile wine; it can even build a sample 
+.B wine.conf
+file
+
+.TP
+.I Wine newsgroup
+Subscribe to comp.emulators.ms-windows.wine
diff --git a/controls/combo.c b/controls/combo.c
index abf7abb..1967926 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -29,100 +29,6 @@
   * I hope no programs rely on the implementation of combos.
   */
 
-static LONG CBNCCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBChar( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBGetLBText( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBGetLBTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBShowDropDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-
-static LONG CBLCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLChar( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLActivate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG CBLVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-
-typedef struct {
-  WORD   message;
-  LONG  (*handler)(HWND, WORD, WPARAM, LPARAM);
-} msg_tbl;
-
-static msg_tbl combo_tbl[] = {
-  {WM_NCCREATE, CBNCCreate},
-  {WM_CREATE, CBCreate},
-  {WM_DESTROY, CBDestroy},
-  {WM_GETDLGCODE, CBGetDlgCode},
-  {WM_KEYDOWN, CBKeyDown},
-  {WM_CHAR, CBChar},
-  {WM_SETFONT, CBSetFont},
-  {WM_SETREDRAW, CBSetRedraw},
-  {WM_PAINT, CBPaint},
-  {WM_LBUTTONDOWN, CBLButtonDown},
-  {WM_SETFOCUS, CBSetFocus},
-  {WM_KILLFOCUS, CBKillFocus},
-  {CB_RESETCONTENT, CBResetContent},
-  {CB_DIR, CBDir},
-  {CB_ADDSTRING, CBAddString},
-  {CB_INSERTSTRING, CBInsertString},
-  {CB_DELETESTRING, CBDeleteString},
-  {CB_FINDSTRING, CBFindString},
-  {CB_GETCOUNT, CBGetCount},
-  {CB_GETCURSEL, CBGetCurSel},
-  {CB_GETITEMDATA, CBGetItemData},
-  {CB_GETITEMHEIGHT, CBGetItemHeight},
-  {CB_GETLBTEXT, CBGetLBText},
-  {CB_GETLBTEXTLEN, CBGetLBTextLen},
-  {CB_SELECTSTRING, CBSelectString},
-  {CB_SETITEMDATA, CBSetItemData},
-  {CB_SETCURSEL, CBSetCurSel},
-  {CB_SETITEMHEIGHT, CBSetItemHeight},
-  {CB_SHOWDROPDOWN, CBShowDropDown}
-    
-};
-
-static msg_tbl clbox_tbl[] = {
-  {WM_CREATE, CBLCreate},
-  {WM_GETDLGCODE, CBLGetDlgCode},
-  {WM_KEYDOWN, CBLKeyDown},
-  {WM_CHAR, CBLChar},
-  {WM_PAINT, CBLPaint},
-  {WM_KILLFOCUS, CBLKillFocus},
-  {WM_ACTIVATE, CBLActivate},
-  {WM_LBUTTONDOWN, CBLLButtonDown},
-  {WM_LBUTTONUP, CBLLButtonUp},
-  {WM_MOUSEMOVE, CBLMouseMove},
-  {WM_VSCROLL, CBLVScroll}
-};
-
 static HBITMAP hComboBit = 0;
 static WORD CBitHeight, CBitWidth;
 
@@ -174,7 +80,7 @@
 /***********************************************************************
  *           CBNCCreate
  */
-static LONG CBNCCreate(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBNCCreate(HWND hwnd, WORD wParam, LONG lParam)
 {
   CREATESTRUCT *createStruct;
 
@@ -185,14 +91,14 @@
   SetWindowLong(hwnd, GWL_STYLE, createStruct->style);
 
   dprintf_combo(stddeb,"ComboBox WM_NCCREATE!\n");
-  return DefWindowProc(hwnd, message, wParam, lParam);
+  return DefWindowProc(hwnd, WM_NCCREATE, wParam, lParam);
 
 }
 
 /***********************************************************************
  *           CBCreate
  */
-static LONG CBCreate(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBCreate(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST   lphl;
   LPHEADCOMBO  lphc;
@@ -268,7 +174,7 @@
 /***********************************************************************
  *           CBDestroy
  */
-static LONG CBDestroy(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBDestroy(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
 
@@ -281,7 +187,7 @@
 /***********************************************************************
  *           CBPaint
  */
-static LONG CBPaint(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBPaint(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
@@ -324,7 +230,7 @@
     height = lpls->mis.itemHeight;
     rect.bottom = rect.top + height;
 
-    if (OWNER_DRAWN(lphl)) {
+    if (lphl->OwnerDrawn) {
       ListBoxDrawItem (hwnd, lphl, hdc, lpls, &rect, ODA_DRAWENTIRE, 0);
     } else {
       ListBoxDrawItem (hwnd, lphl, hdc, lpls, &rect, ODA_DRAWENTIRE, 0);
@@ -340,7 +246,7 @@
 /***********************************************************************
  *           CBGetDlgCode
  */
-static LONG CBGetDlgCode(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBGetDlgCode(HWND hwnd, WORD wParam, LONG lParam)
 {
   return DLGC_WANTARROWS | DLGC_WANTCHARS;
 }
@@ -348,7 +254,7 @@
 /***********************************************************************
  *           CBLButtonDown
  */
-static LONG CBLButtonDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBLButtonDown(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
   SendMessage(hwnd,CB_SHOWDROPDOWN,!lphc->DropDownVisible,0);
@@ -358,7 +264,7 @@
 /***********************************************************************
  *           CBKeyDown
  */
-static LONG CBKeyDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBKeyDown(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   WORD       newFocused = lphl->ItemFocused;
@@ -397,7 +303,7 @@
 /***********************************************************************
  *           CBChar
  */
-static LONG CBChar(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBChar(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   WORD       newFocused;
@@ -422,7 +328,7 @@
 /***********************************************************************
  *           CBKillFocus
  */
-static LONG CBKillFocus(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBKillFocus(HWND hwnd, WORD wParam, LONG lParam)
 {
   return 0;
 }
@@ -430,7 +336,7 @@
 /***********************************************************************
  *           CBSetFocus
  */
-static LONG CBSetFocus(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBSetFocus(HWND hwnd, WORD wParam, LONG lParam)
 {
   return 0;
 }
@@ -438,7 +344,7 @@
 /***********************************************************************
  *           CBResetContent
  */
-static LONG CBResetContent(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBResetContent(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
@@ -451,7 +357,7 @@
 /***********************************************************************
  *           CBDir
  */
-static LONG CBDir(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBDir(HWND hwnd, WORD wParam, LONG lParam)
 {
   WORD wRet;
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
@@ -465,13 +371,13 @@
 /***********************************************************************
  *           CBInsertString
  */
-static LONG CBInsertString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBInsertString(HWND hwnd, WORD wParam, LONG lParam)
 {
   WORD  wRet;
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
 
-  if (HasStrings(lphl))
+  if (lphl->HasStrings)
     wRet = ListBoxInsertString(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
   else
     wRet = ListBoxInsertString(lphl, wParam, (LPSTR)lParam);
@@ -483,13 +389,13 @@
 /***********************************************************************
  *           CBAddString
  */
-static LONG CBAddString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBAddString(HWND hwnd, WORD wParam, LONG lParam)
 {
   WORD  wRet;
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
 
-  if (HasStrings(lphl))
+  if (lphl->HasStrings)
     wRet = ListBoxAddString(lphl, (LPSTR)PTR_SEG_TO_LIN(lParam));
   else
     wRet = ListBoxAddString(lphl, (LPSTR)lParam);
@@ -501,7 +407,7 @@
 /***********************************************************************
  *           CBDeleteString
  */
-static LONG CBDeleteString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBDeleteString(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
@@ -514,7 +420,7 @@
 /***********************************************************************
  *           CBSelectString
  */
-static LONG CBSelectString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBSelectString(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   WORD  wRet;
@@ -529,7 +435,7 @@
 /***********************************************************************
  *           CBFindString
  */
-static LONG CBFindString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBFindString(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxFindString(lphl, wParam, lParam);
@@ -538,7 +444,7 @@
 /***********************************************************************
  *           CBGetCount
  */
-static LONG CBGetCount(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBGetCount(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return lphl->ItemsCount;
@@ -547,7 +453,7 @@
 /***********************************************************************
  *           CBSetCurSel
  */
-static LONG CBSetCurSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBSetCurSel(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   WORD  wRet;
@@ -563,7 +469,7 @@
 /***********************************************************************
  *           CBGetCurSel
  */
-static LONG CBGetCurSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBGetCurSel(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return lphl->ItemFocused;
@@ -572,7 +478,7 @@
 /***********************************************************************
  *           CBGetItemHeight
  */
-static LONG CBGetItemHeight(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBGetItemHeight(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   LPLISTSTRUCT lpls = ListBoxGetItem (lphl, wParam);
@@ -584,7 +490,7 @@
 /***********************************************************************
  *           CBSetItemHeight
  */
-static LONG CBSetItemHeight(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBSetItemHeight(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxSetItemHeight(lphl, wParam, lParam);
@@ -593,7 +499,7 @@
 /***********************************************************************
  *           CBSetRedraw
  */
-static LONG CBSetRedraw(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBSetRedraw(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   lphl->bRedrawFlag = wParam;
@@ -603,7 +509,7 @@
 /***********************************************************************
  *           CBSetFont
  */
-static LONG CBSetFont(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBSetFont(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl = ComboGetListHeader(hwnd);
 
@@ -618,19 +524,19 @@
 /***********************************************************************
  *           CBGetLBTextLen
  */
-static LONG CBGetLBTextLen(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBGetLBTextLen(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST   lphl = ComboGetListHeader(hwnd);
   LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wParam);
 
-  if (lpls == NULL || !HasStrings(lphl)) return LB_ERR;
+  if (lpls == NULL || !lphl->HasStrings) return LB_ERR;
   return strlen(lpls->itemText);
 }
 
 /***********************************************************************
  *           CBGetLBText
  */
-static LONG CBGetLBText(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBGetLBText(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxGetText(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
@@ -639,7 +545,7 @@
 /***********************************************************************
  *           CBGetItemData
  */
-static LONG CBGetItemData(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBGetItemData(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxGetItemData(lphl, wParam);
@@ -648,7 +554,7 @@
 /***********************************************************************
  *           CBSetItemData
  */
-static LONG CBSetItemData(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBSetItemData(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ComboGetListHeader(hwnd);
   return ListBoxSetItemData(lphl, wParam, lParam);
@@ -657,7 +563,7 @@
 /***********************************************************************
  *           CBShowDropDown
  */
-static LONG CBShowDropDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG CBShowDropDown(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
   RECT rect;
@@ -681,16 +587,38 @@
  */
 LONG ComboBoxWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  int idx = 0;
-  int table_size = sizeof (combo_tbl) / sizeof (msg_tbl);
-
-  while (idx < table_size) {
-    if (message == combo_tbl[idx].message) {
-      return (*(combo_tbl[idx].handler))(hwnd, message, wParam, lParam);
+    switch(message) {	
+     case WM_NCCREATE: return CBNCCreate(hwnd, wParam, lParam);
+     case WM_CREATE: return CBCreate(hwnd, wParam, lParam);
+     case WM_DESTROY: return CBDestroy(hwnd, wParam, lParam);
+     case WM_GETDLGCODE: return CBGetDlgCode(hwnd, wParam, lParam);
+     case WM_KEYDOWN: return CBKeyDown(hwnd, wParam, lParam);
+     case WM_CHAR: return CBChar(hwnd, wParam, lParam);
+     case WM_SETFONT: return CBSetFont(hwnd, wParam, lParam);
+     case WM_SETREDRAW: return CBSetRedraw(hwnd, wParam, lParam);
+     case WM_PAINT: return CBPaint(hwnd, wParam, lParam);
+     case WM_LBUTTONDOWN: return CBLButtonDown(hwnd, wParam, lParam);
+     case WM_SETFOCUS: return CBSetFocus(hwnd, wParam, lParam);
+     case WM_KILLFOCUS: return CBKillFocus(hwnd, wParam, lParam);
+     case CB_RESETCONTENT: return CBResetContent(hwnd, wParam, lParam);
+     case CB_DIR: return CBDir(hwnd, wParam, lParam);
+     case CB_ADDSTRING: return CBAddString(hwnd, wParam, lParam);
+     case CB_INSERTSTRING: return CBInsertString(hwnd, wParam, lParam);
+     case CB_DELETESTRING: return CBDeleteString(hwnd, wParam, lParam);
+     case CB_FINDSTRING: return CBFindString(hwnd, wParam, lParam);
+     case CB_GETCOUNT: return CBGetCount(hwnd, wParam, lParam);
+     case CB_GETCURSEL: return CBGetCurSel(hwnd, wParam, lParam);
+     case CB_GETITEMDATA: return CBGetItemData(hwnd, wParam, lParam);
+     case CB_GETITEMHEIGHT: return CBGetItemHeight(hwnd, wParam, lParam);
+     case CB_GETLBTEXT: return CBGetLBText(hwnd, wParam, lParam);
+     case CB_GETLBTEXTLEN: return CBGetLBTextLen(hwnd, wParam, lParam);
+     case CB_SELECTSTRING: return CBSelectString(hwnd, wParam, lParam);
+     case CB_SETITEMDATA: return CBSetItemData(hwnd, wParam, lParam);
+     case CB_SETCURSEL: return CBSetCurSel(hwnd, wParam, lParam);
+     case CB_SETITEMHEIGHT: return CBSetItemHeight(hwnd, wParam, lParam);
+     case CB_SHOWDROPDOWN: return CBShowDropDown(hwnd, wParam, lParam);
     }
-    idx++;
-  }
-  return DefWindowProc (hwnd, message, wParam, lParam);
+    return DefWindowProc(hwnd, message, wParam, lParam);
 }
 
 /*--------------------------------------------------------------------*/
@@ -709,7 +637,7 @@
 /***********************************************************************
  *           CBLCreate
  */
-static LONG CBLCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLCreate( HWND hwnd, WORD wParam, LONG lParam )
 {
   CREATESTRUCT *createStruct = (CREATESTRUCT *)PTR_SEG_TO_LIN(lParam);
   SetWindowWord(hwnd,0,LOWORD(createStruct->lpCreateParams));
@@ -719,7 +647,7 @@
 /***********************************************************************
  *           CBLGetDlgCode
  */
-static LONG CBLGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLGetDlgCode( HWND hwnd, WORD wParam, LONG lParam )
 {
   return DLGC_WANTARROWS | DLGC_WANTCHARS;
 }
@@ -727,7 +655,7 @@
 /***********************************************************************
  *           CBLKeyDown
  */
-static LONG CBLKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam ) 
+static LONG CBLKeyDown( HWND hwnd, WORD wParam, LONG lParam ) 
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
   WORD newFocused = lphl->ItemFocused;
@@ -775,7 +703,7 @@
 /***********************************************************************
  *           CBLChar
  */
-static LONG CBLChar( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLChar( HWND hwnd, WORD wParam, LONG lParam )
 {
   return 0;
 }
@@ -783,7 +711,7 @@
 /***********************************************************************
  *           CBLPaint
  */
-static LONG CBLPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLPaint( HWND hwnd, WORD wParam, LONG lParam )
 {
   LPHEADLIST   lphl = CLBoxGetListHeader(hwnd);
   LPLISTSTRUCT lpls;
@@ -828,7 +756,7 @@
       lpls->itemRect.right  = rect.right;
 
       dprintf_listbox(stddeb,"drawing item: %d %d %d %d %d\n",rect.left,top,rect.right,top+height,lpls->itemState);
-      if (OWNER_DRAWN(lphl)) {
+      if (lphl->OwnerDrawn) {
 	ListBoxDrawItem (combohwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 0);
 	if (lpls->itemState)
 	  ListBoxDrawItem (combohwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_SELECT, ODS_SELECTED);
@@ -854,7 +782,7 @@
 /***********************************************************************
  *           CBLKillFocus
  */
-static LONG CBLKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLKillFocus( HWND hwnd, WORD wParam, LONG lParam )
 {
 /*  SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);*/
   return 0;
@@ -863,7 +791,7 @@
 /***********************************************************************
  *           CBLActivate
  */
-static LONG CBLActivate( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLActivate( HWND hwnd, WORD wParam, LONG lParam )
 {
   if (wParam == WA_INACTIVE)
     SendMessage(CLBoxGetCombo(hwnd),CB_SHOWDROPDOWN,0,0);
@@ -873,7 +801,7 @@
 /***********************************************************************
  *           CBLLButtonDown
  */
-static LONG CBLLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLLButtonDown( HWND hwnd, WORD wParam, LONG lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
   int        y;
@@ -898,7 +826,7 @@
 /***********************************************************************
  *           CBLLButtonUp
  */
-static LONG CBLLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLLButtonUp( HWND hwnd, WORD wParam, LONG lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
 
@@ -916,7 +844,7 @@
 /***********************************************************************
  *           CBLMouseMove
  */
-static LONG CBLMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLMouseMove( HWND hwnd, WORD wParam, LONG lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
   int  y;
@@ -959,7 +887,7 @@
 /***********************************************************************
  *           CBLVScroll
  */
-static LONG CBLVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam )
+static LONG CBLVScroll( HWND hwnd, WORD wParam, LONG lParam )
 {
   LPHEADLIST lphl = CLBoxGetListHeader(hwnd);
   int  y;
@@ -1009,16 +937,20 @@
  */
 LONG ComboLBoxWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 {
-  int idx = 0;
-  int table_size = sizeof (clbox_tbl) / sizeof (msg_tbl);
-
-  while (idx < table_size) {
-    if (message == clbox_tbl[idx].message) {
-      return (*(clbox_tbl[idx].handler))(hwnd, message, wParam, lParam);
+    switch(message) {	
+     case WM_CREATE: return CBLCreate(hwnd, wParam, lParam);
+     case WM_GETDLGCODE: return CBLGetDlgCode(hwnd, wParam, lParam);
+     case WM_KEYDOWN: return CBLKeyDown(hwnd, wParam, lParam);
+     case WM_CHAR: return CBLChar(hwnd, wParam, lParam);
+     case WM_PAINT: return CBLPaint(hwnd, wParam, lParam);
+     case WM_KILLFOCUS: return CBLKillFocus(hwnd, wParam, lParam);
+     case WM_ACTIVATE: return CBLActivate(hwnd, wParam, lParam);
+     case WM_LBUTTONDOWN: return CBLLButtonDown(hwnd, wParam, lParam);
+     case WM_LBUTTONUP: return CBLLButtonUp(hwnd, wParam, lParam);
+     case WM_MOUSEMOVE: return CBLMouseMove(hwnd, wParam, lParam);
+     case WM_VSCROLL: return CBLVScroll(hwnd, wParam, lParam);
     }
-    idx++;
-  }
-  return DefWindowProc (hwnd, message, wParam, lParam);
+    return DefWindowProc(hwnd, message, wParam, lParam);
 }
 
 /************************************************************************
diff --git a/controls/listbox.c b/controls/listbox.c
index a2518b6..d1fc9ac 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -40,120 +40,6 @@
 
 #define LIST_HEAP_SIZE 0x10000
 
-/* Design notes go here */
-
-static LONG LBCreate( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetDlgCode( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBDestroy( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBVScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBHScroll( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBLButtonDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBLButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBRButtonUp( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBMouseMove( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBKeyDown( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBChar( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetFont( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetRedraw( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBPaint( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBKillFocus( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBResetContent( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBDir( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBAddString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetText( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBInsertString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBDeleteString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBFindString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetItemRect( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetSelCount( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetSelItems( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetTextLen( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBGetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSelectString( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSelItemRange( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetCaretIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetColumnWidth( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetItemData( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetTabStops( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetCurSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetSel( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetTopIndex( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-static LONG LBSetItemHeight( HWND hwnd, WORD message, WORD wParam, LONG lParam );
-
-typedef struct {
-  WORD   message;
-  LONG  (*handler)(HWND, WORD, WPARAM, LPARAM);
-} msg_tbl;
-
-static msg_tbl methods[] = {
-  {WM_CREATE, LBCreate},
-  {WM_DESTROY, LBDestroy},
-  {WM_GETDLGCODE, LBGetDlgCode},
-  {WM_VSCROLL, LBVScroll},
-  {WM_HSCROLL, LBHScroll},
-  {WM_LBUTTONDOWN, LBLButtonDown},
-  {WM_LBUTTONUP, LBLButtonUp},
-  {WM_RBUTTONUP, LBRButtonUp},
-  {WM_LBUTTONDBLCLK, LBRButtonUp},
-  {WM_MOUSEMOVE, LBMouseMove},
-  {WM_KEYDOWN, LBKeyDown},
-  {WM_CHAR, LBChar},
-  {WM_SETFONT, LBSetFont},
-  {WM_SETREDRAW, LBSetRedraw},
-  {WM_PAINT, LBPaint},
-  {WM_SETFOCUS, LBSetFocus},
-  {WM_KILLFOCUS, LBKillFocus},
-  {LB_RESETCONTENT, LBResetContent},
-  {LB_DIR, LBDir},
-  {LB_ADDSTRING, LBAddString},
-  {LB_INSERTSTRING, LBInsertString},
-  {LB_DELETESTRING, LBDeleteString},
-  {LB_FINDSTRING, LBFindString},
-  {LB_GETCARETINDEX, LBGetCaretIndex},
-  {LB_GETCOUNT, LBGetCount},
-  {LB_GETCURSEL, LBGetCurSel},
-  {LB_GETHORIZONTALEXTENT, LBGetHorizontalExtent},
-  {LB_GETITEMDATA, LBGetItemData},
-  {LB_GETITEMHEIGHT, LBGetItemHeight},
-  {LB_GETITEMRECT, LBGetItemRect},
-  {LB_GETSEL, LBGetSel},
-  {LB_GETSELCOUNT, LBGetSelCount},
-  {LB_GETSELITEMS, LBGetSelItems},
-  {LB_GETTEXT, LBGetText},
-  {LB_GETTEXTLEN, LBGetTextLen},
-  {LB_GETTOPINDEX, LBGetTopIndex},
-  {LB_SELECTSTRING, LBSelectString},
-  {LB_SELITEMRANGE, LBSelItemRange},
-  {LB_SETCARETINDEX, LBSetCaretIndex},
-  {LB_SETCOLUMNWIDTH, LBSetColumnWidth},
-  {LB_SETHORIZONTALEXTENT, LBSetHorizontalExtent},
-  {LB_SETITEMDATA, LBSetItemData},
-  {LB_SETTABSTOPS, LBSetTabStops},
-  {LB_SETCURSEL, LBSetCurSel},
-  {LB_SETSEL, LBSetSel},
-  {LB_SETTOPINDEX, LBSetTopIndex},
-  {LB_SETITEMHEIGHT, LBSetItemHeight}
-};
-
-BOOL OWNER_DRAWN(LPHEADLIST lphl)
-{
-  return lphl->dwStyle & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE);
-}
-
-BOOL HasStrings(LPHEADLIST lphl)
-{
-  return (lphl->dwStyle & LBS_HASSTRINGS) || !OWNER_DRAWN(lphl);
-}
-
 static void ListBoxInitialize(LPHEADLIST lphl)
 {
   lphl->lpFirst        = NULL;
@@ -187,8 +73,10 @@
   lphl->hParent        = parent;
   lphl->StdItemHeight  = 15; /* FIXME: should get the font height */
   lphl->dwStyle        = styles;
+  lphl->OwnerDrawn     = styles & (LBS_OWNERDRAWFIXED | LBS_OWNERDRAWVARIABLE);
+  lphl->HasStrings     = (styles & LBS_HASSTRINGS) || !lphl->OwnerDrawn;
 
-  if (OWNER_DRAWN(lphl)) {
+  if (lphl->OwnerDrawn) {
     LISTSTRUCT dummyls;
     
     lphl->hDrawItemStruct = USER_HEAP_ALLOC(sizeof(DRAWITEMSTRUCT));
@@ -302,7 +190,7 @@
 void ListBoxDrawItem (HWND hwnd, LPHEADLIST lphl, HDC hdc, LPLISTSTRUCT lpls, 
 		      RECT *rect, WORD itemAction, WORD itemState)
 {
-  if (OWNER_DRAWN(lphl)) {
+  if (lphl->OwnerDrawn) {
     DRAWITEMSTRUCT   *dis = USER_HEAP_LIN_ADDR(lphl->hDrawItemStruct);
 
     dis->CtlID    = lpls->mis.CtlID;
@@ -446,7 +334,8 @@
   lphl->ItemsCount++;
   
   hStr = 0;
-  if (HasStrings(lphl)) {
+  if (lphl->HasStrings) {
+    dprintf_listbox(stddeb,"  string: %s\n", newstr);
     hStr = LIST_HEAP_ALLOC(lphl, LMEM_MOVEABLE, strlen(newstr) + 1);
     str = (LPSTR)LIST_HEAP_ADDR(lphl, hStr);
     if (str == NULL) return LB_ERRSPACE;
@@ -480,7 +369,7 @@
 {
     UINT pos = (UINT) -1;
     
-    if (HasStrings(lphl) && (lphl->dwStyle & LBS_SORT)) {
+    if (lphl->HasStrings && (lphl->dwStyle & LBS_SORT)) {
 	LPLISTSTRUCT lpls = lphl->lpFirst;
 	for (pos = 0; lpls != NULL; lpls = lpls->lpNext, pos++)
 	    if (strcmp(lpls->itemText, newstr) >= 0)
@@ -502,7 +391,7 @@
   lpls = ListBoxGetItem (lphl, uIndex);
   if (lpls == NULL) return LB_ERR;
 
-  if (!HasStrings(lphl)) {
+  if (!lphl->HasStrings) {
     *((long *)OutStr) = lpls->mis.itemData;
     return 4;
   }
@@ -578,12 +467,12 @@
 
   if (First > lphl->ItemsCount) return LB_ERR;
 
-  if (HasStrings(lphl)) lpMatchStr = PTR_SEG_TO_LIN(MatchStr);
+  if (lphl->HasStrings) lpMatchStr = PTR_SEG_TO_LIN(MatchStr);
   
   lpls = ListBoxGetItem(lphl, First);
   Count = 0;
   while(lpls != NULL) {
-    if (HasStrings(lphl)) {
+    if (lphl->HasStrings) {
       if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
     } else if (lphl->dwStyle & LBS_SORT) {
       /* XXX Do a compare item */
@@ -600,7 +489,7 @@
   lpls = lphl->lpFirst;
 
   while (Count < First) {
-    if (HasStrings(lphl)) {
+    if (lphl->HasStrings) {
       if (strstr(lpls->itemText, lpMatchStr) == lpls->itemText) return Count;
     } else if (lphl->dwStyle & LBS_SORT) {
       /* XXX Do a compare item */
@@ -794,7 +683,7 @@
   UINT	       count,first;
 
   if ((char)wChar < ' ') return LB_ERR;
-  if (!HasStrings(lphl)) return LB_ERR;
+  if (!lphl->HasStrings) return LB_ERR;
 
   lpls = lphl->lpFirst;
   
@@ -815,7 +704,7 @@
 /***********************************************************************
  *           LBCreate
  */
-static LONG LBCreate(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBCreate(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST   lphl;
   RECT rect;
@@ -836,7 +725,7 @@
 /***********************************************************************
  *           LBDestroy
  */
-static LONG LBDestroy(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBDestroy(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
@@ -850,7 +739,7 @@
 /***********************************************************************
  *           LBVScroll
  */
-static LONG LBVScroll(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBVScroll(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   int  y;
@@ -899,7 +788,7 @@
 /***********************************************************************
  *           LBHScroll
  */
-static LONG LBHScroll(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBHScroll(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl;
   int        y;
@@ -956,7 +845,7 @@
 /***********************************************************************
  *           LBLButtonDown
  */
-static LONG LBLButtonDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBLButtonDown(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD       wRet;
@@ -992,7 +881,7 @@
 /***********************************************************************
  *           LBLButtonUp
  */
-static LONG LBLButtonUp(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBLButtonUp(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
@@ -1007,7 +896,7 @@
 /***********************************************************************
  *           LBRButtonUp
  */
-static LONG LBRButtonUp(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBRButtonUp(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
@@ -1020,7 +909,7 @@
 /***********************************************************************
  *           LBMouseMove
  */
-static LONG LBMouseMove(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   int  y;
@@ -1071,7 +960,7 @@
 /***********************************************************************
  *           LBKeyDown
  */
-static LONG LBKeyDown(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBKeyDown(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD       newFocused = lphl->ItemFocused;
@@ -1143,7 +1032,7 @@
 /***********************************************************************
  *           LBChar
  */
-static LONG LBChar(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBChar(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD       newFocused;
@@ -1169,7 +1058,7 @@
 /***********************************************************************
  *           LBSetRedraw
  */
-static LONG LBSetRedraw(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetRedraw(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
 
@@ -1182,7 +1071,7 @@
 /***********************************************************************
  *           LBSetFont
  */
-static LONG LBSetFont(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetFont(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
 
@@ -1197,7 +1086,7 @@
 /***********************************************************************
  *           LBPaint
  */
-static LONG LBPaint(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBPaint(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
   LPLISTSTRUCT lpls;
@@ -1260,7 +1149,7 @@
       lpls->itemRect.right  = rect.right;
 
       dprintf_listbox(stddeb,"drawing item: %d %d %d %d %d\n",rect.left,top,rect.right,top+height,lpls->itemState);
-      if (OWNER_DRAWN(lphl)) {
+      if (lphl->OwnerDrawn) {
 	ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 0);
 	if (lpls->itemState)
 	  ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_SELECT, ODS_SELECTED);
@@ -1286,7 +1175,7 @@
 /***********************************************************************
  *           LBSetFocus
  */
-static LONG LBSetFocus(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetFocus(HWND hwnd, WORD wParam, LONG lParam)
 {
   dprintf_listbox(stddeb,"ListBox WM_SETFOCUS !\n");
 
@@ -1296,7 +1185,7 @@
 /***********************************************************************
  *           LBKillFocus
  */
-static LONG LBKillFocus(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBKillFocus(HWND hwnd, WORD wParam, LONG lParam)
 {
   dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS !\n");
 
@@ -1308,7 +1197,7 @@
 /***********************************************************************
  *           LBResetContent
  */
-static LONG LBResetContent(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBResetContent(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
@@ -1321,7 +1210,7 @@
 /***********************************************************************
  *           LBDir
  */
-static LONG LBDir(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBDir(HWND hwnd, WORD wParam, LONG lParam)
 {
   WORD   wRet;
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
@@ -1335,12 +1224,12 @@
 /***********************************************************************
  *           LBAddString
  */
-static LONG LBAddString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBAddString(HWND hwnd, WORD wParam, LONG lParam)
 {
   WORD  wRet;
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
-  if (HasStrings(lphl))
+  if (lphl->HasStrings)
     wRet = ListBoxAddString(lphl, (LPSTR)PTR_SEG_TO_LIN(lParam));
   else
     wRet = ListBoxAddString(lphl, (LPSTR)lParam);
@@ -1352,7 +1241,7 @@
 /***********************************************************************
  *           LBGetText
  */
-static LONG LBGetText(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetText(HWND hwnd, WORD wParam, LONG lParam)
 {
   LONG   wRet;
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
@@ -1366,12 +1255,12 @@
 /***********************************************************************
  *           LBInsertString
  */
-static LONG LBInsertString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBInsertString(HWND hwnd, WORD wParam, LONG lParam)
 {
   WORD  wRet;
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
-  if (HasStrings(lphl))
+  if (lphl->HasStrings)
     wRet = ListBoxInsertString(lphl, wParam, (LPSTR)PTR_SEG_TO_LIN(lParam));
   else
     wRet = ListBoxInsertString(lphl, wParam, (LPSTR)lParam);
@@ -1383,7 +1272,7 @@
 /***********************************************************************
  *           LBDeleteString
  */
-static LONG LBDeleteString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBDeleteString(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   LONG lRet = ListBoxDeleteString(lphl,wParam);
@@ -1395,7 +1284,7 @@
 /***********************************************************************
  *           LBFindString
  */
-static LONG LBFindString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBFindString(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   return ListBoxFindString(lphl, wParam, lParam);
@@ -1404,7 +1293,7 @@
 /***********************************************************************
  *           LBGetCaretIndex
  */
-static LONG LBGetCaretIndex(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetCaretIndex(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   return lphl->ItemFocused;
@@ -1413,7 +1302,7 @@
 /***********************************************************************
  *           LBGetCount
  */
-static LONG LBGetCount(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetCount(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl;
 
@@ -1424,7 +1313,7 @@
 /***********************************************************************
  *           LBGetCurSel
  */
-static LONG LBGetCurSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetCurSel(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl;
 
@@ -1437,7 +1326,7 @@
 /***********************************************************************
  *           LBGetHorizontalExtent
  */
-static LONG LBGetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetHorizontalExtent(HWND hwnd, WORD wParam, LONG lParam)
 {    
   return 0;
 }
@@ -1445,7 +1334,7 @@
 /***********************************************************************
  *           LBGetItemHeight
  */
-static LONG LBGetItemHeight(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetItemHeight(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   LPLISTSTRUCT lpls = ListBoxGetItem (lphl, wParam);
@@ -1457,7 +1346,7 @@
 /***********************************************************************
  *           LBGetItemRect
  */
-static LONG LBGetItemRect(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetItemRect(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   return ListBoxGetItemRect(lphl, wParam, PTR_SEG_TO_LIN(lParam));
@@ -1466,7 +1355,7 @@
 /***********************************************************************
  *           LBGetSel
  */
-static LONG LBGetSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetSel(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   return ListBoxGetSel(lphl, wParam);
@@ -1475,7 +1364,7 @@
 /***********************************************************************
  *           LBGetSelCount
  */
-static LONG LBGetSelCount(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetSelCount(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   LPLISTSTRUCT lpls;
@@ -1497,7 +1386,7 @@
 /***********************************************************************
  *           LBGetSelItems
  */
-static LONG LBGetSelItems(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetSelItems(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl = ListBoxGetStorageHeader(hwnd);
   LPLISTSTRUCT lpls;
@@ -1525,19 +1414,19 @@
 /***********************************************************************
  *           LBGetTextLen
  */
-static LONG LBGetTextLen(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetTextLen(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
   LPLISTSTRUCT lpls = ListBoxGetItem(lphl,wParam);
 
-  if (lpls == NULL || !HasStrings(lphl)) return LB_ERR;
+  if (lpls == NULL || !lphl->HasStrings) return LB_ERR;
   return strlen(lpls->itemText);
 }
 
 /***********************************************************************
  *           LBGetDlgCode
  */
-static LONG LBGetDlgCode(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetDlgCode(HWND hwnd, WORD wParam, LONG lParam)
 {
   return DLGC_WANTARROWS | DLGC_WANTCHARS;
 }
@@ -1545,7 +1434,7 @@
 /***********************************************************************
  *           LBGetTopIndex
  */
-static LONG LBGetTopIndex(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetTopIndex(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
@@ -1556,7 +1445,7 @@
 /***********************************************************************
  *           LBSelectString
  */
-static LONG LBSelectString(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSelectString(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD  wRet;
@@ -1571,7 +1460,7 @@
 /***********************************************************************
  *           LBSelItemRange
  */
-static LONG LBSelItemRange(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSelItemRange(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
   LPLISTSTRUCT lpls;
@@ -1604,7 +1493,7 @@
 /***********************************************************************
  *           LBSetCaretIndex
  */
-static LONG LBSetCaretIndex(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetCaretIndex(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
@@ -1622,7 +1511,7 @@
 /***********************************************************************
  *           LBSetColumnWidth
  */
-static LONG LBSetColumnWidth(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetColumnWidth(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   lphl->ColumnsWidth = wParam;
@@ -1633,7 +1522,7 @@
 /***********************************************************************
  *           LBSetHorizontalExtent
  */
-static LONG LBSetHorizontalExtent(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetHorizontalExtent(HWND hwnd, WORD wParam, LONG lParam)
 {
   return 0;
 }
@@ -1641,7 +1530,7 @@
 /***********************************************************************
  *           LBGetItemData
  */
-static LONG LBGetItemData(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBGetItemData(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   dprintf_listbox(stddeb, "LB_GETITEMDATA wParam=%x\n", wParam);
@@ -1651,7 +1540,7 @@
 /***********************************************************************
  *           LBSetItemData
  */
-static LONG LBSetItemData(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetItemData(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   dprintf_listbox(stddeb, "LB_SETITEMDATA  wParam=%x  lParam=%lx\n", wParam, lParam);
@@ -1661,7 +1550,7 @@
 /***********************************************************************
  *           LBSetTabStops
  */
-static LONG LBSetTabStops(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetTabStops(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST  lphl;
 
@@ -1685,7 +1574,7 @@
 /***********************************************************************
  *           LBSetCurSel
  */
-static LONG LBSetCurSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetCurSel(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD  wRet;
@@ -1704,7 +1593,7 @@
 /***********************************************************************
  *           LBSetSel
  */
-static LONG LBSetSel(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetSel(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD wRet;
@@ -1720,7 +1609,7 @@
 /***********************************************************************
  *           LBSetTopIndex
  */
-static LONG LBSetTopIndex(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetTopIndex(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
@@ -1737,7 +1626,7 @@
 /***********************************************************************
  *           LBSetItemHeight
  */
-static LONG LBSetItemHeight(HWND hwnd, WORD message, WORD wParam, LONG lParam)
+static LONG LBSetItemHeight(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD wRet;
@@ -1753,16 +1642,57 @@
  */
 LONG ListBoxWndProc(HWND hwnd, WORD message, WORD wParam, LONG lParam)
 { 
-  int idx = 0;
-  int table_size = sizeof (methods) / sizeof (msg_tbl);
-
-  while (idx < table_size) {
-    if (message == methods[idx].message) {
-      return (*(methods[idx].handler))(hwnd, message, wParam, lParam);
+    switch (message) {
+     case WM_CREATE: return LBCreate(hwnd, wParam, lParam);
+     case WM_DESTROY: return LBDestroy(hwnd, wParam, lParam);
+     case WM_GETDLGCODE: return LBGetDlgCode(hwnd, wParam, lParam);
+     case WM_VSCROLL: return LBVScroll(hwnd, wParam, lParam);
+     case WM_HSCROLL: return LBHScroll(hwnd, wParam, lParam);
+     case WM_LBUTTONDOWN: return LBLButtonDown(hwnd, wParam, lParam);
+     case WM_LBUTTONUP: return LBLButtonUp(hwnd, wParam, lParam);
+     case WM_RBUTTONUP: return LBRButtonUp(hwnd, wParam, lParam);
+     case WM_LBUTTONDBLCLK: return LBRButtonUp(hwnd, wParam, lParam);
+     case WM_MOUSEMOVE: return LBMouseMove(hwnd, wParam, lParam);
+     case WM_KEYDOWN: return LBKeyDown(hwnd, wParam, lParam);
+     case WM_CHAR: return LBChar(hwnd, wParam, lParam);
+     case WM_SETFONT: return LBSetFont(hwnd, wParam, lParam);
+     case WM_SETREDRAW: return LBSetRedraw(hwnd, wParam, lParam);
+     case WM_PAINT: return LBPaint(hwnd, wParam, lParam);
+     case WM_SETFOCUS: return LBSetFocus(hwnd, wParam, lParam);
+     case WM_KILLFOCUS: return LBKillFocus(hwnd, wParam, lParam);
+     case LB_RESETCONTENT: return LBResetContent(hwnd, wParam, lParam);
+     case LB_DIR: return LBDir(hwnd, wParam, lParam);
+     case LB_ADDSTRING: return LBAddString(hwnd, wParam, lParam);
+     case LB_INSERTSTRING: return LBInsertString(hwnd, wParam, lParam);
+     case LB_DELETESTRING: return LBDeleteString(hwnd, wParam, lParam);
+     case LB_FINDSTRING: return LBFindString(hwnd, wParam, lParam);
+     case LB_GETCARETINDEX: return LBGetCaretIndex(hwnd, wParam, lParam);
+     case LB_GETCOUNT: return LBGetCount(hwnd, wParam, lParam);
+     case LB_GETCURSEL: return LBGetCurSel(hwnd, wParam, lParam);
+     case LB_GETHORIZONTALEXTENT: return LBGetHorizontalExtent(hwnd, wParam, lParam);
+     case LB_GETITEMDATA: return LBGetItemData(hwnd, wParam, lParam);
+     case LB_GETITEMHEIGHT: return LBGetItemHeight(hwnd, wParam, lParam);
+     case LB_GETITEMRECT: return LBGetItemRect(hwnd, wParam, lParam);
+     case LB_GETSEL: return LBGetSel(hwnd, wParam, lParam);
+     case LB_GETSELCOUNT: return LBGetSelCount(hwnd, wParam, lParam);
+     case LB_GETSELITEMS: return LBGetSelItems(hwnd, wParam, lParam);
+     case LB_GETTEXT: return LBGetText(hwnd, wParam, lParam);
+     case LB_GETTEXTLEN: return LBGetTextLen(hwnd, wParam, lParam);
+     case LB_GETTOPINDEX: return LBGetTopIndex(hwnd, wParam, lParam);
+     case LB_SELECTSTRING: return LBSelectString(hwnd, wParam, lParam);
+     case LB_SELITEMRANGE: return LBSelItemRange(hwnd, wParam, lParam);
+     case LB_SETCARETINDEX: return LBSetCaretIndex(hwnd, wParam, lParam);
+     case LB_SETCOLUMNWIDTH: return LBSetColumnWidth(hwnd, wParam, lParam);
+     case LB_SETHORIZONTALEXTENT: return LBSetHorizontalExtent(hwnd, wParam, lParam);
+     case LB_SETITEMDATA: return LBSetItemData(hwnd, wParam, lParam);
+     case LB_SETTABSTOPS: return LBSetTabStops(hwnd, wParam, lParam);
+     case LB_SETCURSEL: return LBSetCurSel(hwnd, wParam, lParam);
+     case LB_SETSEL: return LBSetSel(hwnd, wParam, lParam);
+     case LB_SETTOPINDEX: return LBSetTopIndex(hwnd, wParam, lParam);
+     case LB_SETITEMHEIGHT: return LBSetItemHeight(hwnd, wParam, lParam);
     }
-    idx++;
-  }
-  return DefWindowProc (hwnd, message, wParam, lParam);
+    
+    return DefWindowProc(hwnd, message, wParam, lParam);
 }
 
 /************************************************************************
diff --git a/controls/scroll.c b/controls/scroll.c
index 1f30bee..11b8e20 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -340,9 +340,6 @@
                                  BOOL bottom_selected )
 {
     RECT r;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-    if (((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL))
-        || ((nBar == SB_HORZ) && (!wndPtr->dwStyle & WS_HSCROLL))) return;
 
       /* Select the correct brush and pen */
 
@@ -440,9 +437,13 @@
     WORD arrowSize, thumbPos;
     RECT rect;
     BOOL vertical;
-
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
     SCROLLINFO *infoPtr = SCROLL_GetScrollInfo( hwnd, nBar );
-    if (!infoPtr) return;
+
+    if (!wndPtr || !infoPtr ||
+        ((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) ||
+        ((nBar == SB_HORZ) && !(wndPtr->dwStyle & WS_HSCROLL))) return;
+
     vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
                                         &arrowSize, &thumbPos );
       /* Draw the arrows */
@@ -467,9 +468,13 @@
     RECT rect;
     BOOL vertical;
     HDC hdc;
-
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
     SCROLLINFO *infoPtr = SCROLL_GetScrollInfo( hwnd, nBar );
-    if (!infoPtr) return;
+
+    if (!wndPtr || !infoPtr ||
+        ((nBar == SB_VERT) && !(wndPtr->dwStyle & WS_VSCROLL)) ||
+        ((nBar == SB_HORZ) && !(wndPtr->dwStyle & WS_HSCROLL))) return;
+
     vertical = SCROLL_GetScrollBarRect( hwnd, nBar, &rect,
                                         &arrowSize, &thumbPos );
     hdc = (nBar == SB_CTL) ? GetDC(hwnd) : GetWindowDC(hwnd);
diff --git a/debugger/Imakefile b/debugger/Imakefile
index 7b7ea9d..39c46f4 100644
--- a/debugger/Imakefile
+++ b/debugger/Imakefile
@@ -16,7 +16,9 @@
 	dbg.tab.c \
 	hash.c \
 	info.c \
-	lex.yy.c
+	lex.yy.c \
+	registers.c \
+	stack.c
 
 SUBDIRS_OBJS = readline/readline.o
 
diff --git a/debugger/break.c b/debugger/break.c
index 711c495..e143669 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -1,3 +1,9 @@
+/*
+ * Debugger break-points handling
+ *
+ * Copyright 1994 Martin von Loewis
+ * Copyright 1995 Alexandre Julliard
+ */
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -5,100 +11,42 @@
 #ifdef linux
 #include <sys/utsname.h>
 #endif
-#include <windows.h>
-#include "db_disasm.h"
+#include "windows.h"
+#include "debugger.h"
 
-#define N_BP 25
+#define INT3          0xcc   /* int 3 opcode */
+#define STEP_FLAG     0x100  /* single-step flag */
 
-extern int dbg_mode;
+#define MAX_BREAKPOINTS 25
 
-struct wine_bp{
-  unsigned long addr;
-  unsigned long next_addr;
-  char in_use;
-  char enabled;
-  unsigned char databyte;
-};
-
-static struct wine_bp wbp[N_BP] = {{0,},};
-
-static int current_bp = -1;
-static int cont_mode=0;	/* 0 - continuous execution
-			   1 - advancing after breakpoint
-			   2 - single step - not implemented
-			*/
-
-void info_break(void)
+typedef struct
 {
-  int j;
-  fprintf(stderr,"Breakpoint status\n");
-  for(j=0; j<N_BP; j++)
-    if(wbp[j].in_use)
-      fprintf(stderr,"%d: %c %8lx\n", j, (wbp[j].enabled ? 'y' : 'n'),
-	      wbp[j].addr);
-}
+    unsigned int  segment;
+    unsigned int  addr;
+    BYTE          addrlen;
+    BYTE          opcode;
+    BOOL          enabled;
+    BOOL          in_use;
+} BREAKPOINT;
 
-void disable_break(int bpnum)
+static BREAKPOINT breakpoints[MAX_BREAKPOINTS] = { { 0, }, };
+
+static int next_bp = 1;  /* breakpoint 0 is reserved for step-over */
+
+
+/***********************************************************************
+ *           DEBUG_ChangeOpcode
+ *
+ * Change the opcode at segment:addr.
+ */
+static void DEBUG_SetOpcode( unsigned int segment, unsigned int addr, BYTE op )
 {
-  if(bpnum >= N_BP || bpnum < 0)
-    fprintf(stderr,"Breakpoint number out of range\n");
-
-  wbp[bpnum].enabled = 0;
-}
-
-void enable_break(int bpnum)
-{
-  if(bpnum >= N_BP || bpnum < 0)
-    fprintf(stderr,"Breakpoint number out of range\n");
-
-  wbp[bpnum].enabled = 1;
-}
-
-void add_break(unsigned long addr)
-{
-  int j;
-  for(j=0; j<N_BP; j++)
-    if(!wbp[j].in_use)
-      {
-	wbp[j].in_use = 1;
-	wbp[j].enabled = 1;
-	wbp[j].addr = addr;
-	wbp[j].next_addr = 0;
-	return;
-      }
-  fprintf(stderr,"No more breakpoints\n");
-}
-
-static void bark()
-{
-  static int barked=0;
-  if(barked)return;
-  barked=1;
-  perror("Sorry, can't set break point");
-#ifdef linux
-  {struct utsname buf;
-  uname(&buf);
-  if(strcmp(buf.sysname,"Linux")==0)
-  {	if(strcmp(buf.release,"1.1.62")<0)
-	  fprintf(stderr,"Your current Linux release is %s. "
-		"You should upgrade to 1.1.62 or higher\n"
-		"Alternatively, in /usr/src/linux/fs/exec.c,"
-		" change MAP_SHARED to MAP_PRIVATE.\n", buf.release);
-  } else
-  fprintf(stderr,"Why did you compile for Linux, while your system is"
-   " actually %s?\n",buf.sysname);
-  }
-#endif
-}
-  
-void insert_break(int flag)
-{
-  unsigned char * pnt;
-  int j;
-
-  for(j=0; j<N_BP; j++)
-    if(wbp[j].enabled)
-      {
+    if (segment)
+    {
+        *(BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) = op;
+    }
+    else  /* 32-bit code, so we have to change the protection first */
+    {
         /* There are a couple of problems with this. On Linux prior to
            1.1.62, this call fails (ENOACCESS) due to a bug in fs/exec.c.
            This code is currently not tested at all on BSD.
@@ -108,54 +56,221 @@
            Not that portability matters, this code is i386 only anyways...
            How do I get the old protection in order to restore it later on?
         */
-	if(mprotect((caddr_t)(wbp[j].addr & (~4095)), 4096, 
-	  PROT_READ|PROT_WRITE|PROT_EXEC) == -1){
-	    bark();
+        if (mprotect((caddr_t)(addr & (~4095)), 4096,
+                     PROT_READ|PROT_WRITE|PROT_EXEC) == -1)
+        {
+            perror( "Can't set break point" );
             return;
 	}
-	pnt = (unsigned char *) wbp[j].addr;
-	if(flag) {
-	  wbp[j].databyte = *pnt;
-	  *pnt = 0xcc;  /* Change to an int 3 instruction */
-	} else {
-	  *pnt = wbp[j].databyte;
-	}
-	mprotect((caddr_t)(wbp[j].addr & ~4095), 4096, PROT_READ|PROT_EXEC);
-      }
-}
-
-/* Get the breakpoint number that we broke upon */
-int get_bpnum(unsigned int addr)
-{
-  int j;
-
-  for(j=0; j<N_BP; j++)
-    if(wbp[j].enabled)
-      if(wbp[j].addr == addr) return j;
-
-  return -1;
-}
-
-void toggle_next(int num)
-{
-   unsigned int addr;
-   addr=wbp[num].addr;
-   if(wbp[num].next_addr == 0)
-	wbp[num].next_addr = db_disasm( 0, addr, (dbg_mode == 16) );
-   wbp[num].addr=wbp[num].next_addr;
-   wbp[num].next_addr=addr;
-}
-
-int should_continue(int bpnum)
-{
-    if(bpnum<0)return 0;
-    toggle_next(bpnum);
-    if(bpnum==current_bp){
-        current_bp=-1;
-	cont_mode=0;
-	return 1;
+        *(BYTE *)addr = op;
+	mprotect((caddr_t)(addr & ~4095), 4096, PROT_READ|PROT_EXEC);
     }
-    cont_mode=1;
-    current_bp=bpnum;
-    return 0;
+}
+
+
+/***********************************************************************
+ *           DEBUG_SetBreakpoints
+ *
+ * Set or remove all the breakpoints.
+ */
+void DEBUG_SetBreakpoints( BOOL set )
+{
+    int i;
+
+    for (i = 0; i < MAX_BREAKPOINTS; i++)
+    {
+        if (breakpoints[i].in_use && breakpoints[i].enabled)
+            DEBUG_SetOpcode( breakpoints[i].segment, breakpoints[i].addr,
+                             set ? INT3 : breakpoints[i].opcode );
+    }
+}
+
+
+/***********************************************************************
+ *           DEBUG_FindBreakpoint
+ *
+ * Find the breakpoint for a given address. Return the breakpoint
+ * number or -1 if none.
+ */
+int DEBUG_FindBreakpoint( unsigned int segment, unsigned int addr )
+{
+    int i;
+
+    for (i = 0; i < MAX_BREAKPOINTS; i++)
+    {
+        if (breakpoints[i].in_use && breakpoints[i].enabled &&
+            breakpoints[i].segment == segment && breakpoints[i].addr == addr)
+            return i;
+    }
+    return -1;
+}
+
+
+/***********************************************************************
+ *           DEBUG_AddBreakpoint
+ *
+ * Add a breakpoint.
+ */
+void DEBUG_AddBreakpoint( unsigned int segment, unsigned int addr )
+{
+    int num;
+    BYTE *p;
+
+    if (segment == 0xffffffff) segment = CS;
+    if (segment == WINE_CODE_SELECTOR) segment = 0;
+
+    if (next_bp < MAX_BREAKPOINTS)
+        num = next_bp++;
+    else  /* try to find an empty slot */  
+    {
+        for (num = 1; num < MAX_BREAKPOINTS; num++)
+            if (!breakpoints[num].in_use) break;
+        if (num >= MAX_BREAKPOINTS)
+        {
+            fprintf( stderr, "Too many breakpoints. Please delete some.\n" );
+            return;
+        }
+    }
+    p = segment ? (BYTE *)PTR_SEG_OFF_TO_LIN( segment, addr ) : (BYTE *)addr;
+    breakpoints[num].segment = segment;
+    breakpoints[num].addr    = addr;
+    breakpoints[num].addrlen = !segment ? 32 :
+                          (GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT) ? 32 : 16;
+    breakpoints[num].opcode  = *p;
+    breakpoints[num].enabled = TRUE;
+    breakpoints[num].in_use  = TRUE;
+    fprintf( stderr, "Breakpoint %d at ", num );
+    print_address( segment, addr, breakpoints[num].addrlen );
+    fprintf( stderr, "\n" );
+}
+
+
+/***********************************************************************
+ *           DEBUG_DelBreakpoint
+ *
+ * Delete a breakpoint.
+ */
+void DEBUG_DelBreakpoint( int num )
+{
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    {
+        fprintf( stderr, "Invalid breakpoint number %d\n", num );
+        return;
+    }
+    breakpoints[num].enabled = FALSE;
+    breakpoints[num].in_use  = FALSE;
+}
+
+
+/***********************************************************************
+ *           DEBUG_EnableBreakpoint
+ *
+ * Enable or disable a break point.
+ */
+void DEBUG_EnableBreakpoint( int num, BOOL enable )
+{
+    if ((num <= 0) || (num >= next_bp) || !breakpoints[num].in_use)
+    {
+        fprintf( stderr, "Invalid breakpoint number %d\n", num );
+        return;
+    }
+    breakpoints[num].enabled = enable;
+}
+
+
+/***********************************************************************
+ *           DEBUG_InfoBreakpoints
+ *
+ * Display break points information.
+ */
+void DEBUG_InfoBreakpoints(void)
+{
+    int i;
+
+    fprintf( stderr, "Breakpoints:\n" );
+    for (i = 1; i < next_bp; i++)
+    {
+        if (breakpoints[i].in_use)
+        {
+            fprintf( stderr, "%d: %c ", i, breakpoints[i].enabled ? 'y' : 'n');
+            print_address( breakpoints[i].segment, breakpoints[i].addr,
+                           breakpoints[i].addrlen );
+            fprintf( stderr, "\n" );
+        }
+    }
+}
+
+
+/***********************************************************************
+ *           DEBUG_ShouldContinue
+ *
+ * Determine if we should continue execution after a SIGTRAP signal when
+ * executing in the given mode.
+ */
+BOOL DEBUG_ShouldContinue( struct sigcontext_struct *context,
+                           enum exec_mode mode )
+{
+    unsigned int segment, addr;
+    int bpnum;
+
+      /* If not single-stepping, back up over the int3 instruction */
+    if (!(EFL & STEP_FLAG)) EIP--;
+
+    segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
+    addr    = EIP;
+    bpnum  = DEBUG_FindBreakpoint( segment, addr );
+    breakpoints[0].enabled = 0;  /* disable the step-over breakpoint */
+
+    if ((bpnum != 0) && (bpnum != -1))
+    {
+        fprintf( stderr, "Stopped on breakpoint %d at ", bpnum );
+        print_address( breakpoints[bpnum].segment, breakpoints[bpnum].addr,
+                       breakpoints[bpnum].addrlen );
+        fprintf( stderr, "\n" );
+        return FALSE;
+    }
+      /* no breakpoint, continue if in continuous mode */
+    return (mode == EXEC_CONT);
+}
+
+
+/***********************************************************************
+ *           DEBUG_RestartExecution
+ *
+ * Set the breakpoints to the correct state to restart execution
+ * in the given mode.
+ */
+void DEBUG_RestartExecution( struct sigcontext_struct *context,
+                             enum exec_mode mode, int instr_len )
+{
+    unsigned int segment, addr;
+
+    segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
+    addr    = EIP;
+
+    if (DEBUG_FindBreakpoint( segment, addr ) != -1)
+        mode = EXEC_STEP_INSTR;  /* If there's a breakpoint, skip it */
+
+    switch(mode)
+    {
+    case EXEC_CONT: /* Continuous execution */
+        EFL &= ~STEP_FLAG;
+        DEBUG_SetBreakpoints( TRUE );
+        break;
+
+    case EXEC_STEP_OVER:  /* Stepping over a call */
+        EFL &= ~STEP_FLAG;
+        breakpoints[0].segment = segment;
+        breakpoints[0].addr    = addr + instr_len;
+        breakpoints[0].enabled = TRUE;
+        breakpoints[0].in_use  = TRUE;
+        breakpoints[0].opcode  = segment ?
+           *(BYTE *)PTR_SEG_OFF_TO_LIN(segment,addr+instr_len) : *(BYTE *)addr;
+        DEBUG_SetBreakpoints( TRUE );
+        break;
+
+    case EXEC_STEP_INSTR: /* Single-stepping an instruction */
+        EFL |= STEP_FLAG;
+        break;
+    }
 }
diff --git a/debugger/db_disasm.c b/debugger/db_disasm.c
index 5d7d176..50474d6 100644
--- a/debugger/db_disasm.c
+++ b/debugger/db_disasm.c
@@ -61,25 +61,15 @@
 /*
  * Instruction disassembler.
  */
-#if 0
-#include <mach/boolean.h>
-#include "db_machdep.h"
 
-#include "db_access.h"
-#include "db_sym.h"
-
-#include <kern/task.h>
-#endif
 #include <stdio.h>
-#include "db_disasm.h"
+#include "windows.h"
 #include "ldt.h"
 
-extern void print_address( unsigned int seg, unsigned int addr, int addrlen );
-
 /*
  * Switch to disassemble 16-bit code.
  */
-static boolean_t	db_disasm_16 = FALSE;
+static BOOL db_disasm_16 = FALSE;
 
 /*
  * Size attributes
@@ -932,13 +922,9 @@
 /*
  * Read address at location and return updated location.
  */
-db_addr_t
-db_read_address(segment, loc, short_addr, regmodrm, addrp)
-        unsigned int segment;
-	db_addr_t	loc;
-	int		short_addr;
-	int		regmodrm;
-	struct i_addr	*addrp;		/* out */
+unsigned int db_read_address( unsigned int segment, unsigned int loc,
+                              int short_addr, int regmodrm,
+                              struct i_addr *addrp )
 {
 	int		mod, rm, sib, index, disp;
 
@@ -1058,21 +1044,15 @@
 		fprintf(stderr,",%s,%d", addrp->index, 1<<addrp->ss);
 	    fprintf(stderr,")");
 	} else
-	    db_task_printsym((db_addr_t)addrp->disp, size);
+	    db_task_printsym(addrp->disp, size);
 }
 
 /*
  * Disassemble floating-point ("escape") instruction
  * and return updated location.
  */
-db_addr_t
-db_disasm_esc(segment, loc, inst, short_addr, size, seg)
-        unsigned int segment;
-	db_addr_t	loc;
-	int		inst;
-	int		short_addr;
-	int		size;
-	char *		seg;
+unsigned int db_disasm_esc( unsigned int segment, unsigned int loc,
+                            int inst, int short_addr, int size, char *seg )
 {
 	int		regmodrm;
 	struct finst	*fp;
@@ -1151,11 +1131,7 @@
  * Disassemble instruction at 'loc'.  Return address of start of
  * next instruction.
  */
-db_addr_t
-db_disasm(segment, loc, flag16)
-        unsigned int segment;
-	db_addr_t	loc;
-        boolean_t       flag16;
+unsigned int db_disasm( unsigned int segment, unsigned int loc )
 {
 	int	inst;
 	int	size;
@@ -1166,7 +1142,7 @@
 	int	i_size;
 	int	i_mode;
 	int	regmodrm = 0;
-	boolean_t	first;
+	BOOL    first;
 	int	displ;
 	int	prefix;
 	int	imm;
@@ -1174,7 +1150,8 @@
 	int	len;
 	struct i_addr	address;
 
-	db_disasm_16 = flag16;
+        if (!segment) db_disasm_16 = FALSE;
+        else db_disasm_16 = !(GET_SEL_FLAGS(segment) & LDT_FLAGS_32BIT);
 
 	get_value_inc(inst, segment, loc, 1, FALSE);
 
@@ -1240,7 +1217,7 @@
 	} while (prefix);
 
 	if (inst >= 0xd8 && inst <= 0xdf) {
-	    loc = db_disasm_esc(loc, inst, short_addr, size, seg);
+	    loc = db_disasm_esc(segment, loc, inst, short_addr, size, seg);
 	    fprintf(stderr,"\n");
 	    return (loc);
 	}
@@ -1441,8 +1418,7 @@
 		    if (seg)
 			fprintf(stderr,"%s:%d",seg, displ);
 		    else
-			db_task_printsym((db_addr_t)displ,
-                                         short_addr ? WORD : LONG);
+			db_task_printsym(displ, short_addr ? WORD : LONG);
 		    break;
 
 		case Db:
@@ -1454,8 +1430,7 @@
 		    }
 		    else
 			displ = displ + loc;
-		    db_task_printsym((db_addr_t)displ,
-                                     short_addr ? WORD : LONG);
+		    db_task_printsym(displ, short_addr ? WORD : LONG);
 		    break;
 
 		case Dl:
@@ -1469,8 +1444,7 @@
 			get_value_inc(displ, segment, loc, 4, TRUE);
 			displ = displ + loc;
 		    }
-		    db_task_printsym((db_addr_t)displ,
-                                     short_addr ? WORD : LONG);
+		    db_task_printsym( displ, short_addr ? WORD : LONG);
 		    break;
 
 		case o1:
diff --git a/debugger/db_disasm.h b/debugger/db_disasm.h
deleted file mode 100644
index 73992d7..0000000
--- a/debugger/db_disasm.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#define FALSE 0
-#define TRUE 1
-
-typedef unsigned char boolean_t;
-typedef unsigned long db_addr_t;
-
-extern db_addr_t db_disasm(unsigned int segment, db_addr_t loc,
-                           boolean_t flag16);
diff --git a/debugger/dbg.y b/debugger/dbg.y
index fd8748d..c9a5585 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -10,24 +10,25 @@
 
 #include <stdio.h>
 #include <signal.h>
-#include "ldt.h"
+#include <unistd.h>
 #include "windows.h"
-#include "wine.h"
+#include "debugger.h"
 
 #define YYSTYPE int
 
-#include "regpos.h"
 extern FILE * yyin;
-unsigned int * regval = NULL;
-unsigned int dbg_mask = 0;
 unsigned int dbg_mode = 0;
 
+static enum exec_mode dbg_exec_mode = EXEC_CONT;
+
 void issue_prompt(void);
 void mode_command(int);
 %}
 
 
 %token CONT
+%token STEP
+%token NEXT
 %token QUIT
 %token HELP
 %token BACKTRACE
@@ -40,10 +41,13 @@
 %token ENABLE
 %token DISABLE
 %token BREAK
+%token DELETE
 %token SET
 %token MODE
 %token PRINT
+%token EXAM
 %token IDENTIFIER
+%token FORMAT
 %token NO_SYMBOL
 %token SYMBOLFILE
 %token DEFINE
@@ -58,68 +62,59 @@
 	| infocmd '\n'
 	| error '\n'       { yyerrok; }
 	| QUIT  '\n'       { exit(0); }
-	| 'q' '\n'         { exit(0); }
 	| HELP  '\n'       { dbg_help(); }
-	| CONT '\n'        { return 0; }
-	| 'c' '\n'         { return 0; }
+	| CONT '\n'        { dbg_exec_mode = EXEC_CONT; return 0; }
+	| STEP '\n'        { dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
+	| NEXT '\n'        { dbg_exec_mode = EXEC_STEP_OVER; return 0; }
 	| ABORT '\n'       { kill(getpid(), SIGABRT); }
- 	| SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); }
+ 	| SYMBOLFILE IDENTIFIER '\n'   { read_symboltable($2); }
 	| DEFINE IDENTIFIER expr '\n'  { add_hash($2, 0, $3); }
-	| MODE NUM	   { mode_command($2); }
-	| ENABLE NUM	   { enable_break($2); }
-	| DISABLE NUM	   { disable_break($2); }
-	| BREAK '*' expr   { add_break($3); }
+	| MODE NUM '\n'         { mode_command($2); }
+	| ENABLE NUM '\n'       { DEBUG_EnableBreakpoint( $2, TRUE ); }
+	| DISABLE NUM '\n'      { DEBUG_EnableBreakpoint( $2, FALSE ); }
+	| BREAK '*' expr        { DEBUG_AddBreakpoint( 0xffffffff, $3 ); }
+        | BREAK '\n'            { DEBUG_AddBreakpoint( 0xffffffff, EIP ); }
+        | DELETE BREAK NUM '\n' { DEBUG_DelBreakpoint( $3 ); }
+	| BACKTRACE '\n'        { DEBUG_BackTrace(); }
 	| x_command
-	| BACKTRACE '\n'   { dbg_bt(); }
 	| print_command
 	| deposit_command
 
 deposit_command:
-	SET REG '=' expr '\n' { if(regval) regval[$2] = $4; else application_not_running();}
+	SET REG '=' expr '\n'        { DEBUG_SetRegister( $2, $4 ); }
 	| SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; }
-	| SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; }
+	| SET symbol '=' expr '\n'   { *((unsigned int *) $2) = $4; }
 
 
 x_command:
-	  'x' expr  '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
-	| 'x' '/' fmt expr  '\n' { examine_memory( 0xffffffff, $4, 1, $3); }
-	| 'x' '/' NUM fmt expr  '\n' { examine_memory( 0xffffffff, $5, $3, $4); }
+	  EXAM expr  '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
+	| EXAM FORMAT expr  '\n' { examine_memory( 0xffffffff, $3,
+                                                  $2 >> 8, $2 & 0xff ); }
 
-print:
-	  'p'
-	| PRINT
-	
  print_command:
-	  print expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1, 'x'); }
-	| print '/' fmt expr '\n' { examine_memory( 0, (unsigned int) &$4, 1, $3); }
+	  PRINT expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1,'x'); }
+	| PRINT FORMAT expr '\n' { examine_memory( 0, (unsigned int)&$3,
+                                                   $2 >> 8, $2 & 0xff ); }
 
- fmt:  'x'     { $$ = 'x'; }
-	| 'd'  { $$ = 'd'; }
-	| 'i'  { $$ = 'i'; }
-	| 'w'  { $$ = 'w'; }
-	| 's'  { $$ = 's'; }
-	| 'c'  { $$ = 'c'; }
-	| 'b' { $$ = 'b'; }
-
- symbol: IDENTIFIER             { $$ = find_hash($1);
-			           if($$ == 0xffffffff) {
-					   fprintf(stderr,"Symbol %s not found\n", $1);
-					   YYERROR;
-				   }
-			        } 
+ symbol: IDENTIFIER   { if (($$ = find_hash($1)) == 0xffffffff)
+                        {
+                           fprintf(stderr,"Symbol %s not found\n", (char *)$1);
+                           YYERROR;
+                        }
+                      } 
 
  expr:  NUM			{ $$ = $1;	}
-	| REG			{ if(regval) $$ = regval[$1]; else application_not_running();}
+	| REG			{ $$ = DEBUG_GetRegister($1); }
 	| symbol   		{ $$ = $1; }
 	| expr '+' NUM		{ $$ = $1 + $3; }
 	| expr '-' NUM		{ $$ = $1 - $3; }
 	| '(' expr ')'		{ $$ = $2; }
 	| '*' expr		{ $$ = *((unsigned int *) $2); }
 	
- infocmd: INFO REGS     { info_reg(); }
-	| INFO STACK    { info_stack(); }
+ infocmd: INFO REGS     { DEBUG_InfoRegisters(); }
+	| INFO STACK    { DEBUG_InfoStack(); }
+	| INFO BREAK    { DEBUG_InfoBreakpoints(); }
 	| INFO SEGMENTS { LDT_Print(); }
-	| INFO BREAK    { info_break(); }
 
 
 %%
@@ -133,78 +128,55 @@
 
 void mode_command(int newmode)
 {
-  if(newmode == 16){
-    dbg_mask = 0xffff;
-    dbg_mode = 16;
-    return;
-  }
-  if(newmode == 32){ 
-    dbg_mask = 0xffffffff;
-    dbg_mode = 32;
-    return;
-  }
-  fprintf(stderr,"Invalid mode (use 16 or 32)\n");
+    if ((newmode == 16) || (newmode == 32)) dbg_mode = newmode;
+    else fprintf(stderr,"Invalid mode (use 16 or 32)\n");
 }
 
-static int loaded_symbols = 0;
 
-void
-wine_debug(int signal, int * regs)
+void wine_debug( int signal, struct sigcontext_struct *regs )
 {
-	static int dummy_regs[32];
-	char SymbolTableFile[256];
+    static int loaded_symbols = 0;
+    char SymbolTableFile[256];
+    int instr_len = 0, newmode;
 #ifdef YYDEBUG
-	yydebug = 0;
+    yydebug = 1;
 #endif
 
-	yyin = stdin;
-	regval = regs ? regs : dummy_regs;
+    yyin = stdin;
+    context = (struct sigcontext_struct *)regs;
 
-	if (SC_CS == WINE_CODE_SELECTOR) dbg_mode = 32;
-        else dbg_mode = (GET_SEL_FLAGS(SC_CS) & LDT_FLAGS_32BIT) ? 32 : 16;
-        dbg_mask = (dbg_mode == 32) ? 0xffffffff : 0xffff;
+    if (CS == WINE_CODE_SELECTOR) newmode = 32;
+    else newmode = (GET_SEL_FLAGS(CS) & LDT_FLAGS_32BIT) ? 32 : 16;
 
-	fprintf(stderr,"In %d bit mode.\n", dbg_mode);
+    if (newmode != dbg_mode)
+        fprintf(stderr,"In %d bit mode.\n", dbg_mode = newmode);
 
-	if(dbg_mode == 32 && !loaded_symbols)
-        {
-		loaded_symbols++;
-		GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym",
-			SymbolTableFile, sizeof(SymbolTableFile), WINE_INI);
-		read_symboltable(SymbolTableFile);
-	}
+    if(dbg_mode == 32 && !loaded_symbols)
+    {
+        loaded_symbols++;
+        GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym",
+                          SymbolTableFile, sizeof(SymbolTableFile), WINE_INI);
+        read_symboltable(SymbolTableFile);
+    }
 
-	/* Remove the breakpoints from memory... */
-	insert_break(0);
+    DEBUG_SetBreakpoints( FALSE );
 
-	/* If we stopped on a breakpoint, report this fact */
-	if(signal == SIGTRAP)
-	  {
-	    unsigned int addr;
-	    int bpnum;
-	    addr = SC_EIP(dbg_mask);
-	    if (dbg_mode == 16) addr = PTR_SEG_OFF_TO_LIN( SC_CS, addr );
-	    if(should_continue(bpnum=get_bpnum(addr))){
-		insert_break(1);
-		return;
-	    }
-	    fprintf(stderr,"Stopped on breakpoint %d\n", bpnum);
-	  }
+    if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( regs, dbg_exec_mode ))
+    {
+        unsigned int segment = (CS == WINE_CODE_SELECTOR) ? 0 : CS;
 
-	/* Show where we crashed */
-	if(regs)
-	  examine_memory(0xffffffff, SC_EIP(dbg_mask), 1, 'i');
+        /* Show where we crashed */
+        print_address( segment, EIP, dbg_mode );
+        fprintf(stderr,":  ");
+        instr_len = db_disasm( segment, EIP ) - EIP;
+        fprintf(stderr,"\n");
+        
+        issue_prompt();
+        yyparse();
+        flush_symbols();
+    }
 
-	issue_prompt();
-
-	yyparse();
-	flush_symbols();
-
-	/* Re-insert the breakpoints from memory... */
-	insert_break(1);
-
-	fprintf(stderr,"Returning to Wine...\n");
-
+    DEBUG_RestartExecution( regs, dbg_exec_mode, instr_len );
 }
 
 
diff --git a/debugger/debug.l b/debugger/debug.l
index 68975b7..4b8ccf1 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -7,9 +7,10 @@
 
 %{
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include "dbg.tab.h"
-#include "regpos.h"
+#include "debugger.h"
 
 #ifdef USE_READLINE
 #undef YY_INPUT
@@ -19,102 +20,89 @@
 #endif
 
 extern char * readline(char *);
+extern void add_history(char *);
+static int dbg_read(char * buf, int size);
 static char * make_symbol(char *);
 void flush_symbols();
 static int syntax_error;
 extern int yylval;
 %}
 
-DIGIT	[0-9]
-HEXDIGIT [0-9a-fA-F]
-
+DIGIT	   [0-9]
+HEXDIGIT   [0-9a-fA-F]
+FORMAT     [bcdiswx]
 IDENTIFIER [_a-zA-Z\.~][_a-zA-Z0-9\.~]*
 
 %%
 
-\n		{ syntax_error = 0; return '\n'; } /* Indicate end of command */
+\n		{ syntax_error = 0; return '\n'; } /*Indicate end of command*/
 
-"+"		{ return '+'; } 
+[-+=()*]        { return *yytext; }
 
-"-"		{ return '-'; } 
+"0x"{HEXDIGIT}+      { sscanf(yytext, "%x", &yylval); return NUM; }
+{DIGIT}+             { sscanf(yytext, "%d", &yylval); return NUM; }
 
-"/"		{ return '/'; } 
+"/"{DIGIT}+{FORMAT}  { char *last; yylval = strtol( yytext+1, &last, NULL );
+                       yylval = (yylval << 8) | *last; return FORMAT; }
+"/"{FORMAT}          { yylval = (1 << 8) | yytext[1]; return FORMAT; }
 
-"="		{ return '='; } 
+$pc     { yylval = REG_EIP; return REG; }
+$flags  { yylval = REG_EFL; return REG; }
+$eip    { yylval = REG_EIP; return REG; }
+$ip     { yylval = REG_IP;  return REG; }
+$esp    { yylval = REG_ESP; return REG; }
+$sp     { yylval = REG_SP;  return REG; }
+$eax    { yylval = REG_EAX; return REG; }
+$ebx    { yylval = REG_EBX; return REG; }
+$ecx    { yylval = REG_ECX; return REG; }
+$edx    { yylval = REG_EDX; return REG; }
+$esi    { yylval = REG_ESI; return REG; }
+$edi    { yylval = REG_EDI; return REG; }
+$ebp    { yylval = REG_EBP; return REG; }
+$ax     { yylval = REG_AX;  return REG; }
+$bx     { yylval = REG_BX;  return REG; }
+$cx     { yylval = REG_CX;  return REG; }
+$dx     { yylval = REG_DX;  return REG; }
+$si     { yylval = REG_SI;  return REG; }
+$di     { yylval = REG_DI;  return REG; }
+$bp     { yylval = REG_BP;  return REG; }
+$es     { yylval = REG_ES;  return REG; }
+$ds     { yylval = REG_DS;  return REG; }
+$cs     { yylval = REG_CS;  return REG; }
+$ss     { yylval = REG_SS;  return REG; }
 
-"("		{ return '('; } 
-
-")"		{ return ')'; } 
-
-"*"		{ return '*'; } 
-
-"?"		{ return HELP; }
-
-"0x"+{HEXDIGIT}+   {
-		sscanf(yytext, "%x", &yylval);
-		return NUM;
-		}
-
-{DIGIT}+   {
-		sscanf(yytext, "%d", &yylval);
-		return NUM;
-		}
-
-$pc		{ yylval = RN_EIP; return REG;}
-$sp		{ yylval = RN_ESP_AT_SIGNAL; return REG;}
-$eip		{ yylval = RN_EIP; return REG;}
-$esp		{ yylval = RN_ESP_AT_SIGNAL; return REG;}
-$ebp		{ yylval = RN_EBP; return REG;}
-$eax		{ yylval = RN_EAX; return REG;}
-$ebx		{ yylval = RN_EBX; return REG;}
-$ecx		{ yylval = RN_ECX; return REG;}
-$edx		{ yylval = RN_EDX; return REG;}
-$esi		{ yylval = RN_ESI; return REG;}
-$edi		{ yylval = RN_EDI; return REG;}
-
-$es		{ yylval = RN_ES;  return REG;}
-$ds		{ yylval = RN_DS;  return REG;}
-$cs		{ yylval = RN_CS;  return REG;}
-$ss		{ yylval = RN_SS;  return REG;}
-
-info|inf|in		{ return INFO; }
-segments|segm           { return SEGMENTS; }
-break|brea|bre          { return BREAK; }
-enable|enabl|enab|ena   { return ENABLE;}
+info|inf|in		      { return INFO; }
+segments|segm                 { return SEGMENTS; }
+break|brea|bre|br|b           { return BREAK; }
+enable|enabl|enab|ena         { return ENABLE;}
 disable|disabl|disab|disa|dis { return DISABLE; }
-
-quit|qui|qu 	{ return QUIT; }
+delete|delet|dele|del         { return DELETE; }
+quit|qui|qu|q                 { return QUIT; }
+x                             { return EXAM; }
 
 help|hel|he	{ return HELP; }
+"?"		{ return HELP; }
 
 set|se		{ return SET; }
 
 bt		{ return BACKTRACE; }
 
-cont|con|co		{ return CONT; }
+cont|con|co|c   { return CONT; }
+step|ste|st|s   { return STEP; }
+next|nex|ne|n   { return NEXT; }
 
 symbolfile|symbolfil|symbolfi|symbolf|symbol|symbo|symb { return SYMBOLFILE; }
 
 define|defin|defi|def|de        { return DEFINE; }
 abort|abor|abo         	        { return ABORT; }
-print|prin|pri|pr		{ return PRINT; }
+print|prin|pri|pr|p		{ return PRINT; }
 
 mode				{ return MODE; }
 
-regs|reg|re	{ return REGS; }
+registers|regs|reg|re	{ return REGS; }
 
 stack|stac|sta|st     	{ return STACK; }
 
-p  		{ return 'p'; }
-x  		{ return 'x'; }
-d		{ return 'd'; }
-i		{ return 'i'; }
-w		{ return 'w'; }
-b		{ return 'b'; }
-s		{ return 's'; }
-c		{ return 'c'; }
-q		{ return 'q'; }
-
 {IDENTIFIER}	{yylval = (int) make_symbol(yytext); 
 	          return IDENTIFIER;
 	         }
@@ -161,35 +149,45 @@
   string[++i] = '\0';
 }
 
-dbg_read(char * buf, int size){
-	char * line;
-	int len;
+static int dbg_read(char * buf, int size)
+{
+    static char last_line[256] = "";
+    char * line;
+    int len;
+    
+    for (;;)
+    {
+        flush_symbols();
+        line = readline ("Wine-dbg>");
+        if (!line) exit(0);
 
-	do{
-		flush_symbols();
-		line = readline ("Wine-dbg>");
-                if (!line) return 0;
-		len = strlen(line);
+        /* Remove leading and trailing whitespace from the line.
+           Then, if there is anything left, add it to the history list
+           and execute it. */
+        stripwhite (line);
 
-                /* Remove leading and trailing whitespace from the line.
-                   Then, if there is anything left, add it to the history list
-                   and execute it. */
-                stripwhite (line);
-			
-                if (*line)
-                {
-                    add_history (line);
-                    if(size < len + 1){
-                        fprintf(stderr,"Fatal readline goof.\n");
-                        exit(0);
-                    }
-                    strcpy(buf, line);
-                    buf[len] = '\n';
-                    buf[len+1] = 0;
-                    free(line);
-                    return len + 1;
-                }
-	} while (1==1);
+        if (*line)
+        {
+            add_history( line );
+            strncpy( last_line, line, 255 );
+            last_line[255] = '\0'; 
+       }
+        else line = last_line;  /* Repeat previous command */
+
+        if ((len = strlen(line)) > 0)
+        {
+            if (size < len + 1)
+            {
+                fprintf(stderr,"Fatal readline goof.\n");
+                exit(0);
+            }
+            strcpy(buf, line);
+            buf[len] = '\n';
+            buf[len+1] = 0;
+            free(line);
+            return len + 1;
+        }
+    }
 }
 
 static char *local_symbols[10];
diff --git a/debugger/dtest.c b/debugger/dtest.c
deleted file mode 100644
index 3872cbf..0000000
--- a/debugger/dtest.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <signal.h>
-#include <stdio.h>
-
-extern void wine_debug(unsigned int*);
-
-
-#ifdef linux
-#include <linux/sched.h>
-#include <asm/system.h>
-#endif
-
-struct sigaction segv_act;
-
-#ifdef linux
-
-struct sigcontext_struct {
-	unsigned short sc_gs, __gsh;
-	unsigned short sc_fs, __fsh;
-	unsigned short sc_es, __esh;
-	unsigned short sc_ds, __dsh;
-	unsigned long sc_edi;
-	unsigned long sc_esi;
-	unsigned long sc_ebp;
-	unsigned long sc_esp;
-	unsigned long sc_ebx;
-	unsigned long sc_edx;
-	unsigned long sc_ecx;
-	unsigned long sc_eax;
-	unsigned long sc_trapno;
-	unsigned long sc_err;
-	unsigned long sc_eip;
-	unsigned short sc_cs, __csh;
-	unsigned long sc_eflags;
-	unsigned long esp_at_signal;
-	unsigned short sc_ss, __ssh;
-	unsigned long i387;
-	unsigned long oldmask;
-	unsigned long cr2;
-};
-#endif
-
-#ifdef linux
-static void win_fault(int signal, struct sigcontext_struct context){
-        struct sigcontext_struct *scp = &context;
-#else
-static void win_fault(int signal, int code, struct sigcontext *scp){
-#endif
-
-	wine_debug((unsigned int *) scp);  /* Enter our debugger */
-}
-
-char realtext[] = "This is what should really be printed\n";
-
-int 
-main(){
-	char * pnt;
-#ifdef linux
-	segv_act.sa_handler = (__sighandler_t) win_fault;
-	sigaction(SIGSEGV, &segv_act, NULL);
-#endif
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-        sigset_t sig_mask;
-        
-        sigemptyset(&sig_mask);
-        segv_act.sa_handler = (__sighandler_t) win_fault;
-	segv_act.sa_flags = 0;
-        segv_act.sa_mask = sig_mask;
-	if (sigaction(SIGSEGV, &segv_act, NULL) < 0) {
-                perror("sigaction");
-                exit(1);
-        }
-#endif
-
-	fprintf(stderr,"%x\n", realtext);
-
-	/* Now force a segmentation fault */
-	pnt = (char *) 0xc0000000;
-
-	fprintf(stderr,"%s", pnt);
-	return 0;
-
-}
-
-
-unsigned int * wine_files = NULL;
-
-GetEntryPointFromOrdinal(int wpnt, int ordinal) {}
diff --git a/debugger/hash.c b/debugger/hash.c
index 5136c1c..bca6553 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -155,10 +155,6 @@
 }
 
 
-/* Load the entry points from the dynamic linking into the hash tables. 
- * This does not work yet - something needs to be added before it scans the
- * tables correctly 
- */
 
 void load_entrypoints( HMODULE hModule )
 {
diff --git a/debugger/info.c b/debugger/info.c
index 3f99349..65f8bbd 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -6,16 +6,10 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "ldt.h"
-#include "db_disasm.h"
-#include "regpos.h"
+#include "debugger.h"
 
 extern char * find_nearest_symbol( unsigned int seg, unsigned int addr );
 
-extern int * regval;
-extern unsigned int dbg_mask;
-extern unsigned int dbg_mode;
-
 void application_not_running()
 {
   fprintf(stderr,"Application not running\n");
@@ -32,54 +26,6 @@
 }
 
 
-void info_reg(){
-
-	  if(!regval) {
-	    application_not_running();
-	    return;
-	  }
-
-	fprintf(stderr,"Register dump:\n");
-	/* First get the segment registers out of the way */
-	fprintf(stderr," CS:%4.4x SS:%4.4x DS:%4.4x ES:%4.4x GS:%4.4x FS:%4.4x\n", 
-		SC_CS, SC_SS, SC_DS, SC_ES, SC_GS, SC_FS);
-
-	/* Now dump the main registers */
-	fprintf(stderr," EIP:%8.8x ESP:%8.8x EBP:%8.8x EFLAGS:%8.8x\n", 
-		SC_EIP(dbg_mask), SC_ESP(dbg_mask), SC_EBP(dbg_mask), SC_EFLAGS);
-
-	/* And dump the regular registers */
-
-	fprintf(stderr," EAX:%8.8x EBX:%8.8x ECX:%8.8x EDX:%8.8x\n", 
-		SC_EAX(dbg_mask), SC_EBX(dbg_mask), SC_ECX(dbg_mask), SC_EDX(dbg_mask));
-
-	/* Finally dump these main registers */
-	fprintf(stderr," EDI:%8.8x ESI:%8.8x\n", 
-		SC_EDI(dbg_mask), SC_ESI(dbg_mask));
-
-}
-
-void info_stack(){
-	unsigned int * dump;
-	int i;
-
-	if(!regval) {
-	  application_not_running();
-	  return;
-	}
-
-	fprintf(stderr,"Stack dump:\n");
-	dump = (int*) SC_ESP(dbg_mask);
-	for(i=0; i<22; i++) 
-	{
-	    fprintf(stderr," %8.8x", *dump++);
-	    if ((i % 8) == 7)
-		fprintf(stderr,"\n");
-	}
-	fprintf(stderr,"\n");
-}
-
-
 void examine_memory( unsigned int segment, unsigned int addr,
                      int count, char format )
 {
@@ -88,9 +34,10 @@
     unsigned short int * wdump;
     int i;
 
-    if (segment == 0xffffffff)
-        segment = (dbg_mode == 32) ? 0 : (format == 'i' ? SC_CS : SC_DS);
-    
+    if (segment == 0xffffffff) segment = (format == 'i' ? CS : DS);
+    if ((segment == WINE_CODE_SELECTOR) || (segment == WINE_DATA_SELECTOR))
+        segment = 0;
+
     if (format != 'i' && count > 1)
     {
         print_address( segment, addr, dbg_mode );
@@ -114,7 +61,7 @@
 		for(i=0; i<count; i++) {
 			print_address( segment, addr, dbg_mode );
 			fprintf(stderr,":  ");
-			addr = db_disasm( segment, addr, (dbg_mode == 16) );
+			addr = db_disasm( segment, addr );
 			fprintf(stderr,"\n");
 		};
 		return;
@@ -152,7 +99,7 @@
 		wdump = (unsigned short *)pnt;
 		for(i=0; i<count; i++) 
 		{
-			fprintf(stderr," %x", *wdump++);
+			fprintf(stderr," %04x", *wdump++);
                         addr += 2;
 			if ((i % 10) == 7) {
 				fprintf(stderr,"\n");
@@ -205,14 +152,15 @@
 "The commands accepted by the Wine debugger are a small subset",
 "of the commands that gdb would accept.  The commands currently",
 "are:\n",
-"  break *<addr>                        bt",
+"  break [*<addr>]                      delete break bpnum",
 "  disable bpnum                        enable bpnum",
 "  help                                 quit",
 "  x <expr>                             cont",
+"  step                                 next",
 "  mode [16,32]                         print <expr>",
 "  set <reg> = <expr>                   set *<expr> = <expr>",
-"  info [reg,stack,break,segments]      symbolfile <filename>",
-"  define <identifier> <expr>",
+"  info [reg,stack,break,segments]      bt",
+"  symbolfile <filename>                define <identifier> <expr>",
 "",
 "The 'x' command accepts repeat counts and formats (including 'i') in the",
 "same way that gdb does.",
@@ -230,57 +178,3 @@
 	i = 0;
 	while(helptext[i]) fprintf(stderr,"%s\n", helptext[i++]);
 }
-
-
-struct frame{
-  union{
-    struct {
-      unsigned short saved_bp;
-      unsigned short saved_ip;
-      unsigned short saved_cs;
-    } win16;
-    struct {
-      unsigned long saved_bp;
-      unsigned long saved_ip;
-      unsigned short saved_cs;
-    } win32;
-  } u;
-};
-
-
-void dbg_bt(){
-  struct frame * frame;
-  unsigned short cs;
-  int frameno = 0;
-
-  if(!regval) {
-    application_not_running();
-    return;
-  }
-
-  if (dbg_mode == 16)
-      frame = (struct frame *)PTR_SEG_OFF_TO_LIN( SC_SS, SC_BP & ~1 );
-  else
-      frame = (struct frame *)SC_EBP(dbg_mask);
-
-  fprintf(stderr,"Backtrace:\n");
-  cs = SC_CS;
-  while((cs & 3) == 3) {
-    /* See if in 32 bit mode or not.  Assume GDT means 32 bit. */
-    if ((cs & 7) != 7) {
-      fprintf(stderr,"%d ",frameno++);
-      print_address( 0, frame->u.win32.saved_ip, 32 );
-      fprintf( stderr, "\n" );
-      if (!frame->u.win32.saved_ip) break;
-      frame = (struct frame *) frame->u.win32.saved_bp;
-    } else {
-      if (frame->u.win16.saved_bp & 1) cs = frame->u.win16.saved_cs;
-      fprintf(stderr,"%d %4.4x:%4.4x\n", frameno++, cs, 
-	      frame->u.win16.saved_ip);
-      if (!frame->u.win16.saved_bp) break;
-      frame = (struct frame *) PTR_SEG_OFF_TO_LIN( SC_SS, frame->u.win16.saved_bp & ~1);
-    }
-  }
-  putchar('\n');
-}
-
diff --git a/debugger/registers.c b/debugger/registers.c
new file mode 100644
index 0000000..4d948e9
--- /dev/null
+++ b/debugger/registers.c
@@ -0,0 +1,119 @@
+/*
+ * Debugger register handling
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include "debugger.h"
+
+
+struct sigcontext_struct *context;
+
+
+
+/***********************************************************************
+ *           DEBUG_SetRegister
+ *
+ * Set a register value.
+ */
+void DEBUG_SetRegister( enum debug_regs reg, int val )
+{
+    switch(reg)
+    {
+        case REG_EAX: EAX = val; break;
+        case REG_EBX: EBX = val; break;
+        case REG_ECX: ECX = val; break;
+        case REG_EDX: EDX = val; break;
+        case REG_ESI: ESI = val; break;
+        case REG_EDI: EDI = val; break;
+        case REG_EBP: EBP = val; break;
+        case REG_EFL: EFL = val; break;
+        case REG_EIP: EIP = val; break;
+        case REG_ESP: ESP = val; break;
+        case REG_AX:  AX  = val; break;
+        case REG_BX:  BX  = val; break;
+        case REG_CX:  CX  = val; break;
+        case REG_DX:  DX  = val; break;
+        case REG_SI:  SI  = val; break;
+        case REG_DI:  DI  = val; break;
+        case REG_BP:  BP  = val; break;
+        case REG_FL:  FL  = val; break;
+        case REG_IP:  IP  = val; break;
+        case REG_SP:  SP  = val; break;
+        case REG_CS:  CS  = val; break;
+        case REG_DS:  DS  = val; break;
+        case REG_ES:  ES  = val; break;
+        case REG_SS:  SS  = val; break;
+    }
+}
+
+
+/***********************************************************************
+ *           DEBUG_GetRegister
+ *
+ * Get a register value.
+ */
+int DEBUG_GetRegister( enum debug_regs reg )
+{
+    switch(reg)
+    {
+        case REG_EAX: return EAX;
+        case REG_EBX: return EBX;
+        case REG_ECX: return ECX;
+        case REG_EDX: return EDX;
+        case REG_ESI: return ESI;
+        case REG_EDI: return EDI;
+        case REG_EBP: return EBP;
+        case REG_EFL: return EFL;
+        case REG_EIP: return EIP;
+        case REG_ESP: return ESP;
+        case REG_AX:  return AX;
+        case REG_BX:  return BX;
+        case REG_CX:  return CX;
+        case REG_DX:  return DX;
+        case REG_SI:  return SI;
+        case REG_DI:  return DI;
+        case REG_BP:  return BP;
+        case REG_FL:  return FL;
+        case REG_IP:  return IP;
+        case REG_SP:  return SP;
+        case REG_CS:  return CS;
+        case REG_DS:  return DS;
+        case REG_ES:  return ES;
+        case REG_SS:  return SS;
+    }
+    return 0;  /* should not happen */
+}
+
+
+
+/***********************************************************************
+ *           DEBUG_InfoRegisters
+ *
+ * Display registers information. 
+ */
+void DEBUG_InfoRegisters(void)
+{
+    fprintf(stderr,"Register dump:\n");
+
+    /* First get the segment registers out of the way */
+    fprintf( stderr," CS:%04x SS:%04x DS:%04x ES:%04x\n", CS, SS, DS, ES );
+
+    if (dbg_mode == 16)
+    {
+        fprintf( stderr," IP:%04x SP:%04x BP:%04x FLAGS:%04x\n",
+                 IP, SP, BP, FL );
+	fprintf( stderr," AX:%04x BX:%04x CX:%04x DX:%04x SI:%04x DI:%04x\n",
+                 AX, BX, CX, DX, SI, DI );
+    }
+    else  /* 32-bit mode */
+    {
+        fprintf( stderr, " EIP:%08lx ESP:%08lx EBP:%08lx EFLAGS:%08lx\n", 
+                 EIP, ESP, EBP, EFL );
+	fprintf( stderr, " EAX:%08lx EBX:%08lx ECX:%08lx EDX:%08lx\n", 
+		 EAX, EBX, ECX, EDX);
+	fprintf( stderr, " ESI:%08lx EDI:%08lx\n", ESI, EDI);
+    }
+}
+
diff --git a/debugger/regpos.h b/debugger/regpos.h
deleted file mode 100644
index e4068e1..0000000
--- a/debugger/regpos.h
+++ /dev/null
@@ -1,106 +0,0 @@
-
-#ifdef linux
-/* Register numbers */
-#define  RN_GS			0
-#define  RN_FS			1
-#define  RN_ES			2
-#define  RN_DS			3
-#define  RN_EDI  		4
-#define  RN_ESI			5
-#define  RN_EBP			6
-#define  RN_ESP			7
-#define  RN_EBX			8
-#define  RN_EDX			9
-#define  RN_ECX			10
-#define  RN_EAX			11
-#define  RN_TRAPNO		12
-#define  RN_ERR			13
-#define  RN_EIP			14
-#define  RN_CS			15
-#define  RN_EFLAGS		16
-#define  RN_ESP_AT_SIGNAL	17
-#define  RN_SS			18
-#define  RN_I387		19
-#define  RN_OLDMASK		20
-#define  RN_CR2			21
-#endif
-
-#ifdef __NetBSD__
-/* Register numbers */
-#define  RN_GS			0
-#define  RN_FS			1
-#define  RN_ES			2
-#define  RN_DS			3
-#define  RN_EDI  		4
-#define  RN_ESI			5
-#define  RN_EBP			6
-#define  RN_EBX			7
-#define  RN_EDX			8
-#define  RN_ECX			9
-#define  RN_EAX			10
-#define  RN_EIP			11
-#define  RN_CS			12
-#define  RN_EFLAGS		13
-#define  RN_ESP_AT_SIGNAL	14
-#define  RN_SS			15
-#define  RN_OLDMASK		17
-#endif
-
-#ifdef __FreeBSD__
-#define  RN_OLDMASK		1
-/* Register numbers */
-#define  RN_ESP			2
-#define  RN_EBP			3
-#define  RN_ESP_AT_SIGNAL	4
-#define  RN_EIP			5
-#define  RN_EFLAGS		6
-#define  RN_ES			7
-#define  RN_DS			8
-#define  RN_CS			9
-#define  RN_SS			10
-#define  RN_EDI  		11
-#define  RN_ESI			12
-#define  RN_EBX			13
-#define  RN_EDX			14
-#define  RN_ECX			15
-#define  RN_EAX			16
-/* FreeBSD doesn't save gs or fs */
-#define  SC_GS			0x27
-#define  SC_FS			0x27
-#endif
-
-#ifdef linux
-#define  SC_GS			regval[RN_GS]
-#define  SC_FS			regval[RN_FS]
-#define  I387			regval[RN_I387]
-#define  CR2			regval[RN_CR2]
-#endif
-#ifdef __NetBSD__
-#define  SC_GS			regval[RN_GS]
-#define  SC_FS			regval[RN_FS]
-#endif
-#define  SC_ES			regval[RN_ES]
-#define  SC_DS			regval[RN_DS]
-#define  SC_EDI(dbg_mask)  	(regval[RN_EDI] & dbg_mask)
-#define  SC_ESI(dbg_mask)	(regval[RN_ESI] & dbg_mask)
-#define  SC_EBP(dbg_mask)	(regval[RN_EBP] & dbg_mask)
-#define  SC_EBX(dbg_mask)	(regval[RN_EBX] & dbg_mask)
-#define  SC_EDX(dbg_mask)	(regval[RN_EDX] & dbg_mask)
-#define  SC_ECX(dbg_mask)	(regval[RN_ECX] & dbg_mask)
-#define  SC_EAX(dbg_mask)	(regval[RN_EAX] & dbg_mask)
-#define  SC_DI                  (regval[RN_EDI] & 0xffff)
-#define  SC_SI                  (regval[RN_ESI] & 0xffff)
-#define  SC_BP                  (regval[RN_EBP] & 0xffff)
-#define  SC_SP                  (regval[RN_ESP] & 0xffff)
-#define  SC_BX                  (regval[RN_EBX] & 0xffff)
-#define  SC_DX                  (regval[RN_EDX] & 0xffff)
-#define  SC_CX                  (regval[RN_ECX] & 0xffff)
-#define  SC_AX                  (regval[RN_EAX] & 0xffff)
-#define  SC_TRAPNO		regval[RN_TRAPNO]
-#define  SC_ERR			regval[RN_ERR]
-#define  SC_EIP(dbg_mask)	(regval[RN_EIP] & dbg_mask)
-#define  SC_CS			regval[RN_CS]
-#define  SC_EFLAGS		regval[RN_EFLAGS]
-#define  SC_ESP(dbg_mask)	(regval[RN_ESP_AT_SIGNAL] & dbg_mask)
-#define  SC_SS			regval[RN_SS]
-#define  OLDMASK		regval[RN_OLDMASK]
diff --git a/debugger/stack.c b/debugger/stack.c
new file mode 100644
index 0000000..16a4b62
--- /dev/null
+++ b/debugger/stack.c
@@ -0,0 +1,89 @@
+/*
+ * Debugger stack handling
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#include <stdio.h>
+#include "windows.h"
+#include "debugger.h"
+
+
+typedef struct
+{
+    WORD bp;
+    WORD ip;
+    WORD cs;
+} FRAME16;
+
+typedef struct
+{
+    DWORD bp;
+    DWORD ip;
+    WORD cs;
+} FRAME32;
+
+
+
+/***********************************************************************
+ *           DEBUG_InfoStack
+ *
+ * Dump the top of the stack
+ */
+void DEBUG_InfoStack(void)
+{
+    fprintf(stderr,"Stack dump:\n");
+    if ((SS == WINE_DATA_SELECTOR) ||
+        (GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT))  /* 32-bit mode */
+    {
+        examine_memory( 0, ESP, 10, 'x' );
+    }
+    else  /* 16-bit mode */
+    {
+        examine_memory( SS, SP, 10, 'w' );
+    }
+    fprintf(stderr,"\n");
+}
+
+
+/***********************************************************************
+ *           DEBUG_BackTrace
+ *
+ * Display a stack back-trace.
+ */
+void DEBUG_BackTrace(void)
+{
+  int frameno = 0;
+
+  fprintf(stderr,"Backtrace:\n");
+  if (SS == WINE_DATA_SELECTOR)  /* 32-bit mode */
+  {
+      FRAME32 *frame = (FRAME32 *)EBP;
+      while (frame->ip)
+      {
+          fprintf(stderr,"%d ",frameno++);
+          print_address( 0, frame->ip, 32 );
+          fprintf( stderr, "\n" );
+          frame = (FRAME32 *)frame->bp;
+      }
+  }
+  else  /* 16-bit mode */
+  {
+      FRAME16 *frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, BP & ~1 );
+      WORD cs = CS;
+      if (GET_SEL_FLAGS(SS) & LDT_FLAGS_32BIT)
+      {
+          fprintf( stderr, "Not implemented: 32-bit backtrace on a different stack segment.\n" );
+          return;
+      }
+      while (frame->bp)
+      {
+          if (frame->bp & 1) cs = frame->cs;
+          fprintf( stderr,"%d ", frameno++ );
+          print_address( cs, frame->ip, 16 );
+          fprintf( stderr, "\n" );
+          frame = (FRAME16 *)PTR_SEG_OFF_TO_LIN( SS, frame->bp & ~1 );
+      }
+  }
+  fprintf( stderr, "\n" );
+}
diff --git a/if1632/compobj.spec b/if1632/compobj.spec
index 765ad30..c7cffb8 100644
--- a/if1632/compobj.spec
+++ b/if1632/compobj.spec
@@ -2,9 +2,9 @@
 id	22
 
 1 pascal CoBuildVersion() CoBuildVersion
-2 pascal CoInitialize(ptr) CoInitialize
+2 pascal CoInitialize(long) CoInitialize
 3 pascal CoUninitialize() CoUnitialize
-4 stub COGETMALLOC
+4 pascal CoGetMalloc(long ptr) CoGetMalloc
 5 stub COREGISTERCLASSOBJECT
 6 stub COREVOKECLASSOBJECT
 7 stub COGETCLASSOBJECT
@@ -97,49 +97,49 @@
 95 stub SETETASK
 96 stub LRPCFREEMONITORDATA
 97 stub REMLOOKUPSHUNK
-#100 ??0CARRAYFVALUE@@REC@KI@Z
-#101 ??1CARRAYFVALUE@@REC@XZ
-#102 ?ASSERTVALID@CARRAYFVALUE@@RFCXXZ
-#103 ?FREEEXTRA@CARRAYFVALUE@@RECXXZ
-#104 ?_GETAT@CARRAYFVALUE@@RFCPEXH@Z
-#105 ?GETSIZE@CARRAYFVALUE@@RFCHXZ
-#108 ?INDEXOF@CARRAYFVALUE@@RECHPEXII@Z
-#109 ?INSERTAT@CARRAYFVALUE@@RECHHPEXH@Z
-#111 ?REMOVEAT@CARRAYFVALUE@@RECXHH@Z
-#112 ?SETAT@CARRAYFVALUE@@RECXHPEX@Z
-#113 ?SETATGROW@CARRAYFVALUE@@RECHHPEX@Z
-#114 ?SETSIZE@CARRAYFVALUE@@RECHHH@Z
-#120 ?GETASSOCAT@CMAPKEYTOVALUE@@BFCPEUCASSOC@1@PEXIAEI@Z
-#121 ?SETASSOCKEY@CMAPKEYTOVALUE@@BFCHPEUCASSOC@1@PEXI@Z
-#122 ??1CMAPKEYTOVALUE@@REC@XZ
-#123 ?GETASSOCKEYPTR@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEPEXPEI@Z
-#124 ?NEWASSOC@CMAPKEYTOVALUE@@BECPEUCASSOC@1@IPEXI0@Z
-#125 ?SIZEASSOC@CMAPKEYTOVALUE@@BFCIXZ
-#126 ?FREEASSOC@CMAPKEYTOVALUE@@BECXPEUCASSOC@1@@Z
-#127 ?GETSTARTPOSITION@CMAPKEYTOVALUE@@RFCPEXXZ
-#128 ?GETNEXTASSOC@CMAPKEYTOVALUE@@RFCXPEPEXPEXPEI1@Z
-#129 ?COMPAREASSOCKEY@CMAPKEYTOVALUE@@BFCHPEUCASSOC@1@PEXI@Z
-#130 ?REMOVEHKEY@CMAPKEYTOVALUE@@RECHK@Z
-#131 ?GETHKEY@CMAPKEYTOVALUE@@RFCKPEXI@Z
-#132 ?GETCOUNT@CMAPKEYTOVALUE@@RFCHXZ
-#133 ?LOOKUP@CMAPKEYTOVALUE@@RFCHPEXI0@Z
-#134 ?GETASSOCVALUE@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEX@Z
-#135 ?REMOVEKEY@CMAPKEYTOVALUE@@RECHPEXI@Z
-#136 ?REMOVEALL@CMAPKEYTOVALUE@@RECXXZ
-#138 ?FREEASSOCKEY@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@@Z
-#139 ?SETAT@CMAPKEYTOVALUE@@RECHPEXI0@Z
-#140 ?LOOKUPHKEY@CMAPKEYTOVALUE@@RFCHKPEX@Z
-#141 ?ASSERTVALID@CMAPKEYTOVALUE@@RFCXXZ
-#142 ?SETASSOCVALUE@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEX@Z
-#143 ?SETATHKEY@CMAPKEYTOVALUE@@RECHKPEX@Z
-#144 ??0CMAPKEYTOVALUE@@REC@KIIHP7CIPEXI@ZI@Z
-#145 ?INITHASHTABLE@CMAPKEYTOVALUE@@BECHXZ
-#146 ?GETASSOCVALUEPTR@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEPEX@Z
-#147 ?LOOKUPADD@CMAPKEYTOVALUE@@RFCHPEXI0@Z
-#148 MKVDEFAULTHASHKEY
-#150 COMEMCTXOF
-#151 COMEMALLOC
-#152 COMEMFREE
-#160 CORUNMODALLOOP
-#161 COHANDLEINCOMINGCALL
-#162 COSETACKSTATE
+100 stub ??0CARRAYFVALUE@@REC@KI@Z
+101 stub ??1CARRAYFVALUE@@REC@XZ
+102 stub ?ASSERTVALID@CARRAYFVALUE@@RFCXXZ
+103 stub ?FREEEXTRA@CARRAYFVALUE@@RECXXZ
+104 stub ?_GETAT@CARRAYFVALUE@@RFCPEXH@Z
+105 stub ?GETSIZE@CARRAYFVALUE@@RFCHXZ
+108 stub ?INDEXOF@CARRAYFVALUE@@RECHPEXII@Z
+109 stub ?INSERTAT@CARRAYFVALUE@@RECHHPEXH@Z
+111 stub ?REMOVEAT@CARRAYFVALUE@@RECXHH@Z
+112 stub ?SETAT@CARRAYFVALUE@@RECXHPEX@Z
+113 stub ?SETATGROW@CARRAYFVALUE@@RECHHPEX@Z
+114 stub ?SETSIZE@CARRAYFVALUE@@RECHHH@Z
+120 stub ?GETASSOCAT@CMAPKEYTOVALUE@@BFCPEUCASSOC@1@PEXIAEI@Z
+121 stub ?SETASSOCKEY@CMAPKEYTOVALUE@@BFCHPEUCASSOC@1@PEXI@Z
+122 stub ??1CMAPKEYTOVALUE@@REC@XZ
+123 stub ?GETASSOCKEYPTR@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEPEXPEI@Z
+124 stub ?NEWASSOC@CMAPKEYTOVALUE@@BECPEUCASSOC@1@IPEXI0@Z
+125 stub ?SIZEASSOC@CMAPKEYTOVALUE@@BFCIXZ
+126 stub ?FREEASSOC@CMAPKEYTOVALUE@@BECXPEUCASSOC@1@@Z
+127 stub ?GETSTARTPOSITION@CMAPKEYTOVALUE@@RFCPEXXZ
+128 stub ?GETNEXTASSOC@CMAPKEYTOVALUE@@RFCXPEPEXPEXPEI1@Z
+129 stub ?COMPAREASSOCKEY@CMAPKEYTOVALUE@@BFCHPEUCASSOC@1@PEXI@Z
+130 stub ?REMOVEHKEY@CMAPKEYTOVALUE@@RECHK@Z
+131 stub ?GETHKEY@CMAPKEYTOVALUE@@RFCKPEXI@Z
+132 stub ?GETCOUNT@CMAPKEYTOVALUE@@RFCHXZ
+133 stub ?LOOKUP@CMAPKEYTOVALUE@@RFCHPEXI0@Z
+134 stub ?GETASSOCVALUE@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEX@Z
+135 stub ?REMOVEKEY@CMAPKEYTOVALUE@@RECHPEXI@Z
+136 stub ?REMOVEALL@CMAPKEYTOVALUE@@RECXXZ
+138 stub ?FREEASSOCKEY@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@@Z
+139 stub ?SETAT@CMAPKEYTOVALUE@@RECHPEXI0@Z
+140 stub ?LOOKUPHKEY@CMAPKEYTOVALUE@@RFCHKPEX@Z
+141 stub ?ASSERTVALID@CMAPKEYTOVALUE@@RFCXXZ
+142 stub ?SETASSOCVALUE@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEX@Z
+143 stub ?SETATHKEY@CMAPKEYTOVALUE@@RECHKPEX@Z
+144 stub ??0CMAPKEYTOVALUE@@REC@KIIHP7CIPEXI@ZI@Z
+145 stub ?INITHASHTABLE@CMAPKEYTOVALUE@@BECHXZ
+146 stub ?GETASSOCVALUEPTR@CMAPKEYTOVALUE@@BFCXPEUCASSOC@1@PEPEX@Z
+147 stub ?LOOKUPADD@CMAPKEYTOVALUE@@RFCHPEXI0@Z
+148 stub MKVDEFAULTHASHKEY
+150 stub COMEMCTXOF
+151 stub COMEMALLOC
+152 stub COMEMFREE
+160 stub CORUNMODALLOOP
+161 stub COHANDLEINCOMINGCALL
+162 stub COSETACKSTATE
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 99b769b..94a31ec 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -205,8 +205,8 @@
 306 stub ENGINEMAKEFONTDIR
 307 stub GetCharABCWidths
 308 stub GetOutLineTextMetrics
-309 stub GetGlyphOutLine
-310 stub CreateScalableFontResource
+309 pascal   GetGlyphOutLine(word word word ptr long ptr ptr) GetGlyphOutLine
+310 pascal16 CreateScalableFontResource(word ptr ptr ptr) CreateScalableFontResource
 311 stub GetFontData
 312 stub ConvertOutLineFontFile
 313 pascal16 GetRasterizerCaps(ptr word) GetRasterizerCaps
diff --git a/if1632/ole2.spec b/if1632/ole2.spec
index fe82b71..c3caa82 100644
--- a/if1632/ole2.spec
+++ b/if1632/ole2.spec
@@ -1,7 +1,7 @@
 name	OLE2
 id	15
 
-1 stub OleBuildVersion
+1 pascal OleBuildVersion() OleBuildVersion
 2 pascal OleInitialize(ptr) OleInitialize
 3 pascal OleUninitialize() OleUninitialize
 4 stub DLLGETCLASSOBJECT
diff --git a/if1632/ole2disp.spec b/if1632/ole2disp.spec
index 7f09aec..e8f34bf 100644
--- a/if1632/ole2disp.spec
+++ b/if1632/ole2disp.spec
@@ -2,12 +2,12 @@
 id	17
 
 1 stub DLLGETCLASSOBJECT
-2 stub SYSALLOCSTRING
-3 stub SYSREALLOCSTRING
-4 stub SYSALLOCSTRINGLEN
-5 stub SYSREALLOCSTRINGLEN
-6 stub SYSFREESTRING
-7 stub SYSSTRINGLEN
+2 pascal SysAllocString(ptr)	SysAllocString
+3 pascal SysReallocString(ptr ptr)	SysReAllocString
+4 pascal SysAllocStringLen(ptr word)	SysAllocStringLen
+5 pascal SysReAllocStringLen(ptr ptr word) SysReAllocStringLen
+6 pascal SysFreeString(long)	SysFreeString
+7 pascal SysStringLen(long)	SysStringLen
 8 stub VARIANTINIT
 9 stub VARIANTCLEAR
 10 stub VARIANTCOPY
diff --git a/if1632/ole2nls.spec b/if1632/ole2nls.spec
index bafbc4f..9e70445 100644
--- a/if1632/ole2nls.spec
+++ b/if1632/ole2nls.spec
@@ -8,7 +8,7 @@
 5 pascal GetLocaleInfoA(long long ptr word) GetLocaleInfoA
 6 stub LCMAPSTRINGA
 7 stub GETSTRINGTYPEA
-8 stub COMPARESTRINGA
+8 pascal16 CompareStringA(long long ptr word ptr word) CompareStringA
 #9 WEP
 10 stub LIBMAIN
 11 stub NOTIFYWINDOWPROC
diff --git a/if1632/shell.spec b/if1632/shell.spec
index da6e571..8f01e02 100644
--- a/if1632/shell.spec
+++ b/if1632/shell.spec
@@ -6,13 +6,13 @@
 # 			proper parameters. It's just to have stub for PROGMAN.EXE ...
 #
 
-  1 pascal   RegOpenKey(word ptr ptr) RegOpenKey
-  2 pascal   RegCreateKey(word ptr ptr) RegCreateKey
-  3 pascal   RegCloseKey(word) RegCloseKey
-  4 pascal   RegDeleteKey(word ptr) RegDeleteKey
-  5 pascal   RegSetValue(word ptr long ptr long) RegSetValue
-  6 pascal   RegQueryValue(word ptr ptr ptr) RegQueryValue
-  7 pascal   RegEnumKey(word long ptr long) RegEnumKey
+  1 pascal   RegOpenKey(long ptr ptr) RegOpenKey
+  2 pascal   RegCreateKey(long ptr ptr) RegCreateKey
+  3 pascal   RegCloseKey(long) RegCloseKey
+  4 pascal   RegDeleteKey(long ptr) RegDeleteKey
+  5 pascal   RegSetValue(long ptr long ptr long) RegSetValue
+  6 pascal   RegQueryValue(long ptr ptr ptr) RegQueryValue
+  7 pascal   RegEnumKey(long long ptr long) RegEnumKey
   9 pascal16 DragAcceptFiles(word word) DragAcceptFiles
  11 pascal16 DragQueryFile(word s_word ptr s_word) DragQueryFile
  12 pascal16 DragFinish(word) DragFinish
diff --git a/if1632/toolhelp.spec b/if1632/toolhelp.spec
index 1d6c2f0..3a45fda 100644
--- a/if1632/toolhelp.spec
+++ b/if1632/toolhelp.spec
@@ -26,8 +26,8 @@
 72 pascal16 MemManInfo(ptr) MemManInfo
 73 stub NOTIFYREGISTER
 74 stub NOTIFYUNREGISTER
-75 stub INTERRUPTREGISTER
-76 stub INTERRUPTUNREGISTER
+75 return INTERRUPTREGISTER 6 0
+76 return INTERRUPTUNREGISTER 2 0
 77 stub TERMINATEAPP
 78 pascal   MemoryRead(word long ptr long) MemoryRead
 79 pascal   MemoryWrite(word long ptr long) MemoryWrite
diff --git a/include/callback.h b/include/callback.h
index 3a2dba3..fac8cd2 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -88,7 +88,7 @@
     (*func)( code, wParam, lParam )
 #define CallTimeFuncProc( func, id, msg, dwUser, dw1, dw2 ) \
     (*func)( id, msg, dwUser, dw1, dw2 )
-#define CallWndProc( func, hwnd, msg, wParam, lParam ) \
+#define CallWndProc( func, ds, hwnd, msg, wParam, lParam ) \
     (*func)( hwnd, msg, wParam, lParam )
 
 #endif  /* WINELIB */
diff --git a/include/debugger.h b/include/debugger.h
new file mode 100644
index 0000000..1955620
--- /dev/null
+++ b/include/debugger.h
@@ -0,0 +1,63 @@
+/*
+ * Debugger definitions
+ *
+ * Copyright 1995 Alexandre Julliard
+ */
+
+#ifndef DEBUGGER_H
+#define DEBUGGER_H
+
+#include "ldt.h"
+#include "registers.h"
+#include "wine.h"
+
+
+enum debug_regs
+{
+    REG_EAX, REG_EBX, REG_ECX, REG_EDX, REG_ESI,
+    REG_EDI, REG_EBP, REG_EFL, REG_EIP, REG_ESP,
+    REG_AX, REG_BX, REG_CX, REG_DX, REG_SI,
+    REG_DI, REG_BP, REG_FL, REG_IP, REG_SP,
+    REG_CS, REG_DS, REG_ES, REG_SS
+};
+
+
+enum exec_mode
+{
+    EXEC_CONT,       /* Continuous execution */
+    EXEC_STEP_OVER,  /* Stepping over a call */
+    EXEC_STEP_INSTR  /* Single-stepping an instruction */
+};
+
+extern struct sigcontext_struct *context;  /* debugger/registers.c */
+extern unsigned int dbg_mode;
+
+  /* debugger/break.c */
+extern void DEBUG_SetBreakpoints( BOOL set );
+extern int DEBUG_FindBreakpoint( unsigned int segment, unsigned int addr );
+extern void DEBUG_AddBreakpoint( unsigned int segment, unsigned int addr );
+extern void DEBUG_DelBreakpoint( int num );
+extern void DEBUG_EnableBreakpoint( int num, BOOL enable );
+extern void DEBUG_InfoBreakpoints(void);
+extern BOOL DEBUG_HandleTrap( struct sigcontext_struct *context );
+extern BOOL DEBUG_ShouldContinue( struct sigcontext_struct *context,
+                                  enum exec_mode mode );
+extern void DEBUG_RestartExecution( struct sigcontext_struct *context,
+                                    enum exec_mode mode, int instr_len );
+
+  /* debugger/registers.c */
+extern void DEBUG_SetRegister( enum debug_regs reg, int val );
+extern int DEBUG_GetRegister( enum debug_regs reg );
+extern void DEBUG_InfoRegisters(void);
+
+  /* debugger/stack.c */
+extern void DEBUG_InfoStack(void);
+extern void DEBUG_BackTrace(void);
+
+  /* debugger/dbg.y */
+extern void wine_debug( int signal, struct sigcontext_struct * regs );
+
+extern void print_address( unsigned int seg, unsigned int addr, int addrlen );
+extern unsigned int db_disasm( unsigned int segment, unsigned int loc );
+
+#endif  /* DEBUGGER_H */
diff --git a/include/font.h b/include/font.h
index 3f90f9a..6b2f8c8 100644
--- a/include/font.h
+++ b/include/font.h
@@ -20,6 +20,25 @@
     LOGFONT     logfont WINE_PACKED;
 } FONTOBJ;
 
+/* may be switched... */
+#define GGO_BITMAP	0x4F4D
+#define GGO_NATIVE	0x4F50
+typedef struct
+{
+	UINT	gmBlackBoxX;
+	UINT	gmBlackBoxY;
+	POINT	gmptGlyphOrigin;
+	int	gmCellIncX;
+	int	gmCellIncY;
+} GLYPHMETRICS,*LPGLYPHMETRICS;
+typedef struct
+{
+	DWORD	eM11; /* all type FIXED in Borlands Handbook */
+	DWORD	eM12; 
+	DWORD	eM21;
+	DWORD	eM22;
+} MAT2,*LPMAT2;
+
 #ifndef WINELIB
 #pragma pack(4)
 #endif
diff --git a/include/gdi.h b/include/gdi.h
index 561e882..04a2185 100644
--- a/include/gdi.h
+++ b/include/gdi.h
@@ -245,7 +245,7 @@
 
 #ifdef WINELIB
 
-#define GDI_HEAP_ALLOC(f,size)     LocalAlloc (f,size)
+#define GDI_HEAP_ALLOC(size)     LocalAlloc (LMEM_FIXED,size)
 #define GDI_HEAP_LIN_ADDR(handle)  LocalLock (handle)
 #define GDI_HEAP_SEG_ADDR(handle)  LocalLock (handle)
 #define GDI_HEAP_FREE(handle)      LocalFree (handle)
diff --git a/include/ldt.h b/include/ldt.h
index 5ee3fb9..6e7c853 100644
--- a/include/ldt.h
+++ b/include/ldt.h
@@ -47,19 +47,33 @@
 #define __AHSHIFT  3
 #define __AHINCR   (1 << __AHSHIFT)
 
+#ifndef WINELIB
 #define SELECTOR_TO_ENTRY(sel)  (((int)(sel) & 0xffff) >> __AHSHIFT)
 #define ENTRY_TO_SELECTOR(i)    ((i) ? (((int)(i) << __AHSHIFT) | 7) : 0)
 #define IS_LDT_ENTRY_FREE(i)    (!(ldt_copy[(i)].base || ldt_copy[(i)].limit))
 #define IS_SELECTOR_FREE(sel)   (IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel)))
 #define GET_SEL_BASE(sel)       (ldt_copy[SELECTOR_TO_ENTRY(sel)].base)
 #define GET_SEL_LIMIT(sel)      (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit)
+#else
+/* Complain if these are used in WineLib */
+#define SELECTOR_TO_ENTRY(sel)  error.error
+#define ENTRY_TO_SELECTOR(i)    error.error
+#define IS_LDT_ENTRY_FREE(i)    error.error
+#define GET_SEL_BASE(sel)       error.error
+#define GET_SEL_LIMIT(sel)      error.error
+#endif
 
+#ifndef WINELIB
   /* Convert a segmented ptr (16:16) to a linear (32) pointer */
 #define PTR_SEG_TO_LIN(ptr) \
            ((void*)(GET_SEL_BASE((int)(ptr) >> 16) + ((int)(ptr) & 0xffff)))
 
 #define PTR_SEG_OFF_TO_LIN(seg,off) \
            ((void*)(GET_SEL_BASE(seg) + (unsigned int)(off)))
+#else
+#define PTR_SEG_TO_LIN(ptr)	((void*)(ptr))
+#define PTR_SEG_OFF_TO_LIN(seg,off)	((void*)(off))
+#endif
 
 
 extern unsigned char ldt_flags_copy[LDT_SIZE];
diff --git a/include/listbox.h b/include/listbox.h
index f3ab26f..491ed20 100644
--- a/include/listbox.h
+++ b/include/listbox.h
@@ -28,6 +28,8 @@
 	HWND    hParent;
 	HFONT   hFont;
 	BOOL    bRedrawFlag;
+        BOOL    HasStrings;
+        BOOL    OwnerDrawn;
 	WORD    iNumStops;
 	LPINT   TabStops;
 	HANDLE  hDrawItemStruct;
@@ -41,9 +43,6 @@
 
 extern void ListBoxSendNotification(LPHEADLIST lphl,HWND hwnd, WORD code);
 
-extern BOOL OWNER_DRAWN(LPHEADLIST lphl);
-extern BOOL HasStrings(LPHEADLIST lphl);
-
 extern LPLISTSTRUCT ListBoxGetItem(LPHEADLIST lphl, UINT uIndex);
 extern int ListMaxFirstVisible(LPHEADLIST lphl);
 extern int ListBoxScrollToFocus(LPHEADLIST lphl);
diff --git a/include/msdos.h b/include/msdos.h
index c5392aa..1a94bca 100644
--- a/include/msdos.h
+++ b/include/msdos.h
@@ -15,6 +15,7 @@
 	char search_attribute;
 	long filesize;
 	long filetime;
+        int telldirnum;
         short entnum;           /* Directory entry number */
 };
 
diff --git a/include/neexe.h b/include/neexe.h
index ad596fe..c24f2f6 100644
--- a/include/neexe.h
+++ b/include/neexe.h
@@ -102,6 +102,7 @@
 #define NE_SEGFLAGS_DATA	0x0001
 #define NE_SEGFLAGS_ALLOCATED	0x0002
 #define NE_SEGFLAGS_LOADED	0x0004
+#define NE_SEGFLAGS_ITERATED	0x0008
 #define NE_SEGFLAGS_MOVEABLE	0x0010
 #define NE_SEGFLAGS_SHAREABLE	0x0020
 #define NE_SEGFLAGS_PRELOAD	0x0040
diff --git a/include/prototypes.h b/include/prototypes.h
index b2288c6..5c8d64d 100644
--- a/include/prototypes.h
+++ b/include/prototypes.h
@@ -20,7 +20,6 @@
 /* loader/signal.c */
 
 extern void init_wine_signals(void);
-extern void wine_debug(int signal, int * regs);
 
 /* loader/wine.c */
 
diff --git a/include/registers.h b/include/registers.h
index ed323f9..4af04bc 100644
--- a/include/registers.h
+++ b/include/registers.h
@@ -13,6 +13,7 @@
 #define EDX (context->sc_edx)
 #define ESI (context->sc_esi)
 #define EDI (context->sc_edi)
+#define EBP (context->sc_ebp)
 
 #define AX (*(WORD*)&context->sc_eax)
 #define BX (*(WORD*)&context->sc_ebx)
@@ -20,6 +21,7 @@
 #define DX (*(WORD*)&context->sc_edx)
 #define SI (*(WORD*)&context->sc_esi)
 #define DI (*(WORD*)&context->sc_edi)
+#define BP (*(WORD*)&context->sc_ebp)
 
 #define AL (*(BYTE*)&context->sc_eax)
 #define AH (*(((BYTE*)&context->sc_eax)+1))
@@ -37,8 +39,10 @@
 
 #ifndef __FreeBSD__
 #define EFL (context->sc_eflags)
+#define FL (*(WORD*)&context->sc_eflags)
 #else
 #define EFL (context->sc_efl)
+#define FL (*(WORD*)&context->sc_efl)
 #endif
 
 #define EIP (context->sc_eip)
diff --git a/include/stackframe.h b/include/stackframe.h
index 3295e83..ee0195b 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -57,6 +57,7 @@
 extern SEGPTR IF1632_Stack32_base;
 extern DWORD IF1632_Original32_esp;
 
+#ifndef WINELIB
 #define CURRENT_STACK16 \
     ((STACK16FRAME *)PTR_SEG_OFF_TO_LIN(IF1632_Saved16_ss,IF1632_Saved16_sp))
 
@@ -67,5 +68,10 @@
 #define MAKE_SEGPTR(ptr) \
      ((SEGPTR)IF1632_Stack32_base + \
       ((DWORD)(ptr) - (DWORD)PTR_SEG_TO_LIN(IF1632_Stack32_base)))
+#else
+#define CURRENT_STACK16	error.error
+#define CURRENT_DS		0
+#define MAKE_SEGPTR(ptr)	(ptr)
+#endif
 
 #endif /* WINE_STACKFRAME_H */
diff --git a/include/user.h b/include/user.h
index af0ecdf..f749007 100644
--- a/include/user.h
+++ b/include/user.h
@@ -14,8 +14,8 @@
 
 #ifdef WINELIB
 
-#define USER_HEAP_ALLOC(f,size) LocalAlloc (f, size)
-#define USER_HEAP_REALLOC(handle,size,f) LocalReAlloc (handle,size,f)
+#define USER_HEAP_ALLOC(size) LocalAlloc (LMEM_FIXED, size)
+#define USER_HEAP_REALLOC(handle,size) LocalReAlloc (handle,size,LMEM_FIXED)
 #define USER_HEAP_LIN_ADDR(handle) LocalLock (handle)
 #define USER_HEAP_SEG_ADDR(handle) LocalLock (handle)
 #define USER_HEAP_FREE(handle) LocalFree (handle)
diff --git a/include/winnls.h b/include/winnls.h
index 2e5c652..77d3890 100644
--- a/include/winnls.h
+++ b/include/winnls.h
@@ -98,3 +98,7 @@
 #define LOCALE_INEGSYMPRECEDES      0x00000056   
 #define LOCALE_INEGSEPBYSPACE       0x00000057   
 
+#define NORM_IGNORECASE				1
+#define NORM_IGNORENONSPACE			2
+#define NORM_IGNORESYMBOLS			4
+#define NORM_STRINGSORT				0x1000
diff --git a/include/winpos.h b/include/winpos.h
index 19ca5c7..4105eb5 100644
--- a/include/winpos.h
+++ b/include/winpos.h
@@ -20,7 +20,6 @@
 } DWP;
 
 
-extern HWND WINPOS_NextWindowFromPoint( HWND hwnd, POINT pt );
 extern HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg );
 extern LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
 				   RECT *newWindowRect, RECT *oldWindowRect,
diff --git a/loader/main.c b/loader/main.c
index e6ad03e..7a2d435 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -11,13 +11,13 @@
 #include <string.h>
 #include <errno.h>
 #include "windows.h"
+#include "debugger.h"
 #include "dos_fs.h"
 #include "dlls.h"
 #include "miscemu.h"
 #include "neexe.h"
-#include "wineopts.h"
-#include "task.h"
 #include "options.h"
+#include "task.h"
 #include "pe_image.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -115,7 +115,7 @@
         }
     }
 
-    if (Options.debug) wine_debug(0, NULL);
+    if (Options.debug) DEBUG_SetBreakpoints( TRUE );  /* Setup breakpoints */
 
     Yield();  /* Start the first task */
     fprintf( stderr, "WinMain: Should never happen: returned from Yield()\n" );
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 98ec822..2a4e9ea 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -50,6 +50,18 @@
     pModuleTable = NE_MODULE_TABLE( pModule );
 
     if (!pSeg->filepos) return TRUE;  /* No file image, just return */
+	
+	if (pSeg->flags & NE_SEGFLAGS_ITERATED)
+	{
+		fprintf(stderr, "Sorry, iterated segments are not supported\n"
+			"Please report that %*.*s, segment %d is such a segment\n",
+			*((BYTE*)pModule + pModule->name_table), 
+			*((BYTE*)pModule + pModule->name_table), 
+			(char *)pModule + pModule->name_table + 1,
+			segnum
+		);
+		exit(1);
+	}
 
     fd = MODULE_OpenFile( hModule );
     dprintf_module( stddeb, "Loading segment %d, selector=%04x\n",
@@ -277,6 +289,9 @@
  */
 void NE_FixupPrologs( HMODULE hModule )
 {
+#ifdef WINELIB
+	fprintf(stderr,"NE_FixupPrologs should not be called for libwine\n");
+#else
     NE_MODULE *pModule;
     SEGTABLEENTRY *pSegTable;
     WORD dgroup = 0;
@@ -357,6 +372,7 @@
             p += (sel == 0xff) ? 6 : 3;  
         }
     }
+#endif
 }
 
 
diff --git a/loader/resource.c b/loader/resource.c
index 2a008ab..4cf44cf 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -343,14 +343,14 @@
     if (rsc_mem == (HANDLE)NULL) {
 	printf("LoadIcon / Icon %08x not Found !\n", (int) icon_name);
 	return 0;
-	}
+    }
     lp = (WORD *)LockResource(rsc_mem);
     lpicodesc = (ICONDESCRIP *)(lp + 3);
     hIcon = GlobalAlloc(GMEM_MOVEABLE, sizeof(ICONALLOC) + 1024);
     if (hIcon == (HICON)NULL) {
         FreeResource( rsc_mem );
 	return 0;
-	}
+    }
     lpico = (ICONALLOC *)GlobalLock(hIcon);
     lpico->descriptor = *lpicodesc;
     width = lpicodesc->Width;
@@ -373,20 +373,15 @@
     lpico->hBitmap = CreateDIBitmap( hdc, &pInfo->bmiHeader, CBM_INIT,
                                     (char*)bmi + size, pInfo, DIB_RGB_COLORS );
 
-    if (bih->biSizeImage == 0)
+    if (bih->biCompression != BI_RGB)
     {
-	if (bih->biCompression != BI_RGB)
-        {
-	    fprintf(stderr,"Unknown size for compressed Icon bitmap.\n");
-            FreeResource( rsc_mem );
-	    ReleaseDC( 0, hdc); 
-	    return 0;
-        }
-	bih->biSizeImage = (DIB_GetImageWidthBytes(bih->biWidth,bih->biBitCount) +
-                     DIB_GetImageWidthBytes(bih->biWidth,1)) * bih->biHeight/2;
+	fprintf(stderr,"Unknown size for compressed Icon bitmap.\n");
+	FreeResource( rsc_mem );
+	ReleaseDC( 0, hdc); 
+	return 0;
     }
     bits = (char *)bmi + size +
-             bih->biSizeImage * bih->biBitCount / (bih->biBitCount+1);
+      DIB_GetImageWidthBytes(bih->biWidth,bih->biBitCount) * bih->biHeight;
     bih->biBitCount = 1;
     bih->biClrUsed = bih->biClrImportant = 2;
     rgbq = &pInfo->bmiColors[0];
diff --git a/loader/signal.c b/loader/signal.c
index 37109ecba..e7c8381 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -14,7 +14,7 @@
 #include <syscall.h>
 #endif
 
-#include "wine.h"
+#include "debugger.h"
 #include "prototypes.h"
 #include "miscemu.h"
 #include "registers.h"
@@ -53,37 +53,20 @@
 static void win_fault(int signal, int code, struct sigcontext *context)
 {
 #endif
-
-#if !(defined (linux) || defined (__NetBSD__))
-    int i, *dump;
-#endif
-
-    if(signal == SIGTRAP) EIP--;   /* Back up over the int3 instruction. */
-    else if (CS == WINE_CODE_SELECTOR)
+    if (signal != SIGTRAP)
     {
-	fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)."
-		        "  Please debug\n", CS, EIP );
+        if (CS == WINE_CODE_SELECTOR)
+        {
+            fprintf(stderr, "Segmentation fault in Wine program (%x:%lx)."
+                            "  Please debug\n", CS, EIP );
+        }
+        else if (INSTR_EmulateInstruction( context )) return;
+        fprintf(stderr,"In win_fault %x:%lx\n", CS, EIP );
     }
-    else if (INSTR_EmulateInstruction( context )) return;
-
     XUngrabPointer(display, CurrentTime);
     XUngrabServer(display);
     XFlush(display);
-    fprintf(stderr,"In win_fault %x:%lx\n", CS, EIP );
-#if defined(linux) || defined(__NetBSD__) || defined(__FreeBSD__)
-    wine_debug(signal, (int *)context);  /* Enter our debugger */
-#else
-    fprintf(stderr,"Stack: %x:%x\n", SS, ESP );
-    dump = (int*) context;
-    for(i=0; i<22; i++) 
-    {
-	fprintf(stderr," %8.8x", *dump++);
-	if ((i % 8) == 7)
-	    fprintf(stderr,"\n");
-    }
-    fprintf(stderr,"\n");
-    exit(1);
-#endif
+    wine_debug( signal, context );  /* Enter our debugger */
 }
 
 void init_wine_signals(void)
diff --git a/loader/task.c b/loader/task.c
index 9e39700..222bd01 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -10,14 +10,15 @@
 #include "windows.h"
 #include "task.h"
 #include "callback.h"
+#include "debugger.h"
 #include "global.h"
 #include "instance.h"
 #include "miscemu.h"
 #include "module.h"
 #include "neexe.h"
+#include "options.h"
 #include "selectors.h"
 #include "toolhelp.h"
-#include "wine.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -220,6 +221,7 @@
     dprintf_task( stddeb, "Starting main program: cs:ip=%04x:%04x ds=%04x ss:sp=%04x:%04x\n",
                  cs_reg, ip_reg, ds_reg,
                  IF1632_Saved16_ss, IF1632_Saved16_sp);
+
     CallTo16_regs_( (FARPROC)(cs_reg << 16 | ip_reg), ds_reg,
                    pTask->hPDB /*es*/, 0 /*bp*/, 0 /*ax*/,
                    pModule->stack_size /*bx*/, pModule->heap_size /*cx*/,
@@ -365,6 +367,14 @@
         IF1632_Saved16_sp = pTask->sp;
     }
 
+      /* Add a breakpoint at the start of the task */
+
+    if (Options.debug)
+    {
+        fprintf( stderr, "Task '%s': ", name );
+        DEBUG_AddBreakpoint( pSegTable[pModule->cs-1].selector, pModule->ip );
+    }
+
       /* Add the task to the linked list */
 
     TASK_LinkTask( hTask );
@@ -891,6 +901,7 @@
             (pTask->hInstance == owner) ||
             (pTask->hQueue == owner) ||
             (pTask->hPDB == owner)) return pTask->hModule;
+        hTask = pTask->hNext;
     }
     return 0;
 }
diff --git a/memory/global.c b/memory/global.c
index 4a51b5e..c1f5ab9 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -194,7 +194,7 @@
 
       /* Discard the block if requested */
 
-    if ((size == 0) && (flags & GMEM_MOVEABLE))
+    if ((size == 0) && (flags & GMEM_MOVEABLE) && !(flags & GMEM_MODIFY))
     {
         if (!(pArena->flags & GA_MOVEABLE) ||
             !(pArena->flags & GA_DISCARDABLE) ||
diff --git a/memory/local.c b/memory/local.c
index f42b8d3..a026447 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -115,13 +115,13 @@
 
 
 /***********************************************************************
- *           LOCAL_AddFreeBlock
+ *           LOCAL_MakeBlockFree
  *
  * Make a block free, inserting it in the free-list.
  * 'block' is the handle of the block arena; 'baseptr' points to
  * the beginning of the data segment containing the heap.
  */
-static void LOCAL_AddFreeBlock( char *baseptr, WORD block )
+static void LOCAL_MakeBlockFree( char *baseptr, WORD block )
 {
     LOCALARENA *pArena, *pNext;
     WORD next;
@@ -308,7 +308,6 @@
       if (debugging_local) LOCAL_PrintHeap(selector);
     }
 
-#if 1
     if (start == 0) {
       /* Check if the segment is the DGROUP of a module */
 
@@ -316,6 +315,10 @@
 	{
 	    SEGTABLEENTRY *pSeg = NE_SEG_TABLE( pModule ) + pModule->dgroup - 1;
 	    if (pModule->dgroup && (pSeg->selector == selector)) {
+		/* We can't just use the simple method of using the value
+                 * of minsize + stacksize, since there are programs that
+                 * resize the data segment before calling InitTask(). So,
+                 * we must put it at the end of the segment */
 		start = GlobalSize( GlobalHandle( selector ) );
 		start -= end;
 		end += start;
@@ -323,7 +326,6 @@
 	    }
 	}
     }
-#endif
     ptr = PTR_SEG_OFF_TO_LIN( selector, 0 );
 
     start = LALIGN( max( start, sizeof(INSTANCEDATA) ) );
@@ -489,9 +491,10 @@
 
     arena = pInfo->first;
     pArena = ARENA_PTR( ptr, arena );
-    while (arena != pArena->free_next) {
+    for (;;) {
         arena = pArena->free_next;
         pArena = ARENA_PTR( ptr, arena );
+	if (arena == pArena->free_next) break;
         if (pArena->size >= size) return arena;
     }
     dprintf_local( stddeb, "Local_FindFreeBlock: not enough space\n" );
@@ -539,13 +542,14 @@
 	return 0;
     }
 
-    dprintf_local( stddeb, "LOCAL_GetBlock size = %04x\n", size );
       /* Make a block out of the free arena */
     pArena = ARENA_PTR( ptr, arena );
+    dprintf_local( stddeb, "LOCAL_GetBlock size = %04x, arena at %04x size %04x\n", size,
+		   arena, pArena->size );
     if (pArena->size > size + LALIGN(sizeof(LOCALARENA)))
     {
         LOCAL_AddBlock( ptr, arena, arena+size );
-        LOCAL_AddFreeBlock( ptr, arena+size );
+        LOCAL_MakeBlockFree( ptr, arena+size );
         pInfo->items++;
     }
     LOCAL_RemoveFreeBlock( ptr, arena );
@@ -618,7 +622,7 @@
 /***********************************************************************
  *           LOCAL_FreeArena
  */
-HLOCAL LOCAL_FreeArena( WORD ds, WORD arena )
+static HLOCAL LOCAL_FreeArena( WORD ds, WORD arena )
 {
     char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
     LOCALHEAPINFO *pInfo;
@@ -648,7 +652,7 @@
     }
     else  /* Make a new free block */
     {
-        LOCAL_AddFreeBlock( ptr, arena );
+        LOCAL_MakeBlockFree( ptr, arena );
     }
 
       /* Check if we can merge with the next block */
@@ -769,7 +773,7 @@
 	    dprintf_local( stddeb, "size reduction, making new free block\n");
               /* It is worth making a new free block */
             LOCAL_AddBlock( ptr, arena, nextarena );
-            LOCAL_AddFreeBlock( ptr, nextarena );
+            LOCAL_MakeBlockFree( ptr, nextarena );
             pInfo->items++;
         }
         dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
@@ -788,7 +792,7 @@
 	    dprintf_local( stddeb, "size increase, making new free block\n");
               /* It is worth making a new free block */
             LOCAL_AddBlock( ptr, arena, nextarena );
-            LOCAL_AddFreeBlock( ptr, nextarena );
+            LOCAL_MakeBlockFree( ptr, nextarena );
             pInfo->items++;
         }
         dprintf_local( stddeb, "LocalReAlloc: returning %04x\n", handle );
diff --git a/misc/Imakefile b/misc/Imakefile
index bbf9b32..9e52608 100644
--- a/misc/Imakefile
+++ b/misc/Imakefile
@@ -18,6 +18,7 @@
 	lstr.c \
 	main.c \
 	ole2.c \
+	ole2disp.c \
 	ole2nls.c \
 	olecli.c \
 	olesvr.c \
diff --git a/misc/atom.c b/misc/atom.c
index f22d99e..a34e062 100644
--- a/misc/atom.c
+++ b/misc/atom.c
@@ -45,7 +45,10 @@
 
 #define GET_ATOM_TABLE(sel)  ((ATOMTABLE*)PTR_SEG_OFF_TO_LIN(sel, \
           ((INSTANCEDATA*)PTR_SEG_OFF_TO_LIN(sel,0))->atomtable))
-
+		
+#ifdef WINELIB
+#define USER_HeapSel	0
+#endif
 
 /***********************************************************************
  *           ATOM_InitTable
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 2383229..f660674 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -64,38 +64,45 @@
   BOOL 	    bRet;
   LPCSTR    dlgTemplate;
   
-  if (!FileDlg_Init()) return FALSE;
-    
-  if (lpofn == NULL) return FALSE;
-  if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE) {
-    dlgTemplate = GlobalLock(lpofn->hInstance);
-    if (!dlgTemplate) {
-      CommDlgLastError = CDERR_LOADRESFAILURE;
-      return FALSE;
+  if (lpofn == NULL)
+    return FALSE;
+  if (!FileDlg_Init())
+    return FALSE;
+  if (lpofn->Flags & OFN_ENABLETEMPLATEHANDLE)
+    {
+      dlgTemplate = GlobalLock(lpofn->hInstance);
+      if (!dlgTemplate)
+	{
+	  CommDlgLastError = CDERR_LOADRESFAILURE;
+	  return FALSE;
+	}
     }
-  } else {
-    if (lpofn->Flags & OFN_ENABLETEMPLATE) {
-      hInst = lpofn->hInstance;
-      hResInfo = FindResource(hInst, lpofn->lpTemplateName, RT_DIALOG);
-      if (hResInfo == 0) {
-	CommDlgLastError = CDERR_FINDRESFAILURE;
-	return FALSE;
-      }
-      hDlgTmpl = LoadResource(hInst, hResInfo);
-      if (hDlgTmpl == 0) {
-	CommDlgLastError = CDERR_LOADRESFAILURE;
-	return FALSE;
-      }
-      dlgTemplate = GlobalLock(hDlgTmpl);
-    } else {
-      dlgTemplate = sysres_DIALOG_3;
+  else
+    {
+      if (lpofn->Flags & OFN_ENABLETEMPLATE)
+	{
+	  hInst = lpofn->hInstance;
+	  hResInfo = FindResource(hInst, lpofn->lpTemplateName, RT_DIALOG);
+	  if (hResInfo == 0)
+	    {
+	      CommDlgLastError = CDERR_FINDRESFAILURE;
+	      return FALSE;
+	    }
+	  hDlgTmpl = LoadResource(hInst, hResInfo);
+	  if (hDlgTmpl == 0)
+	    {
+	      CommDlgLastError = CDERR_LOADRESFAILURE;
+	      return FALSE;
+	    }
+	  dlgTemplate = GlobalLock(hDlgTmpl);
+	}
+      else
+	dlgTemplate = sysres_DIALOG_3;
     }
-  }
   hInst = GetWindowWord(lpofn->hwndOwner, GWW_HINSTANCE);
   bRet = DialogBoxIndirectParamPtr(hInst, dlgTemplate, lpofn->hwndOwner,
 				   GetWndProcEntry16("FileOpenDlgProc"),
 				   (DWORD)lpofn);
-  
   printf("GetOpenFileName // return lpstrFile='%s' !\n", 
 	 (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFile));
   return bRet;
@@ -187,21 +194,28 @@
 /***********************************************************************
  * 				FILEDLG_GetFileType		[internal]
  */
-static LPSTR FILEDLG_GetFileType(LPSTR ptr, WORD index)
+
+static LPSTR FILEDLG_GetFileType(LPSTR cfptr, LPSTR fptr, WORD index)
 {
-    int n, i;
-    
-    if	(ptr == NULL) return NULL;
-    
-    for (i = 1;;i++) {
-	n = strlen(ptr);
-	if (n == 0) break;
-	ptr += n + 1;
-	if (i == index) return ptr;
-	n = strlen(ptr);
-	ptr += n + 1;
+  int n, i;
+  i = 0;
+  if (cfptr)
+    for ( ;(n = strlen(cfptr)) != 0; i++) 
+      {
+	cfptr += n + 1;
+	if (i == index)
+	  return cfptr;
+	cfptr += strlen(cfptr) + 1;
+      }
+  if (fptr)
+    for ( ;(n = strlen(fptr)) != 0; i++) 
+      {
+	fptr += n + 1;
+	if (i == index)
+	  return fptr;
+	fptr += strlen(fptr) + 1;
     }
-    return NULL;
+  return NULL;
 }
 
 /***********************************************************************
@@ -301,19 +315,33 @@
 /***********************************************************************
  *                              FILEDLG_WMInitDialog            [internal]
  */
+
 static LONG FILEDLG_WMInitDialog(HWND hWnd, WORD wParam, LONG lParam) 
 {
-    int n;
-    LPOPENFILENAME lpofn;
-    char tmpstr[512];
-    LPSTR pstr;
-    
-    SetWindowLong(hWnd, DWL_USER, lParam);
-    lpofn = (LPOPENFILENAME)lParam;
-    
-    /* read filter information */
-    pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
-    while(*pstr) {
+  int n;
+  LPOPENFILENAME lpofn;
+  char tmpstr[512];
+  LPSTR pstr;
+  SetWindowLong(hWnd, DWL_USER, lParam);
+  lpofn = (LPOPENFILENAME)lParam;
+  /* read custom filter information */
+  if (lpofn->lpstrCustomFilter)
+    {
+      pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter);
+      while(*pstr)
+	{
+	  n = strlen(pstr);
+	  strcpy(tmpstr, pstr);
+	  SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, MAKE_SEGPTR(tmpstr));
+	  pstr += n + 1;
+	  n = strlen(pstr);
+	  pstr += n + 1;
+	}
+    }
+  /* read filter information */
+  pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
+  while(*pstr)
+    {
       n = strlen(pstr);
       strcpy(tmpstr, pstr);
       SendDlgItemMessage(hWnd, cmb1, CB_ADDSTRING, 0, MAKE_SEGPTR(tmpstr));
@@ -321,44 +349,34 @@
       n = strlen(pstr);
       pstr += n + 1;
     }
-      
-    /* set default filter */
-    SendDlgItemMessage(hWnd, cmb1, CB_SETCURSEL,
-		       lpofn->nFilterIndex - 1, 0);
-    strcpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), 
-				       lpofn->nFilterIndex));
-    SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
-      
-    /* get drive list */
-    strcpy(tmpstr,"");
-    DlgDirListComboBox(hWnd, MAKE_SEGPTR(tmpstr), cmb2, 0, 0xC000);
-
-    /* read initial directory */
-    if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL) {
-	strcpy(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir));
-	if (strlen(tmpstr) > 0 && tmpstr[strlen(tmpstr)-1] != '\\' 
-	    && tmpstr[strlen(tmpstr)-1] != ':')
-	{
-	    strcat(tmpstr,"\\");
-	}
-    } else {
-	strcpy(tmpstr,"");
+  /* set default filter */
+  SendDlgItemMessage(hWnd, cmb1, CB_SETCURSEL, 0, 0);    
+  strcpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
+				     PTR_SEG_TO_LIN(lpofn->lpstrFilter), 0));
+  SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
+  /* get drive list */
+  *tmpstr = 0;
+  DlgDirListComboBox(hWnd, MAKE_SEGPTR(tmpstr), cmb2, 0, 0xC000);
+  /* read initial directory */
+  if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL) 
+    {
+      strcpy(tmpstr, PTR_SEG_TO_LIN(lpofn->lpstrInitialDir));
+      if (strlen(tmpstr) > 0 && tmpstr[strlen(tmpstr)-1] != '\\' 
+	  && tmpstr[strlen(tmpstr)-1] != ':')
+	strcat(tmpstr,"\\");
     }
-    if (!FILEDLG_ScanDir(hWnd, tmpstr)) {
-	fprintf(stderr, "FileDlg: couldn't read initial directory!\n");
-    } 
-
-    /* select current drive in combo 2 */
-    n = DOS_GetDefaultDrive();
-    SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, n, 0);
-    
-    if (!(lpofn->Flags & OFN_SHOWHELP)) {
-      ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
-    }
-    if (lpofn->Flags & OFN_HIDEREADONLY) {
-      ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); 
-    }
-    return TRUE;
+  else
+    *tmpstr = 0;
+  if (!FILEDLG_ScanDir(hWnd, tmpstr))
+    fprintf(stderr, "FileDlg: couldn't read initial directory!\n");
+  /* select current drive in combo 2 */
+  n = DOS_GetDefaultDrive();
+  SendDlgItemMessage(hWnd, cmb2, CB_SETCURSEL, n - 1, 0);
+  if (!(lpofn->Flags & OFN_SHOWHELP))
+    ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
+  if (lpofn->Flags & OFN_HIDEREADONLY)
+    ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); 
+  return TRUE;
 }
 
 /***********************************************************************
@@ -366,167 +384,183 @@
  */
 static LONG FILEDLG_WMCommand(HWND hWnd, WORD wParam, LONG lParam) 
 {
-    LONG lRet;
-    LPOPENFILENAME lpofn;
-    char tmpstr[512], tmpstr2[512];
-    LPSTR pstr, pstr2;
+  LONG lRet;
+  LPOPENFILENAME lpofn;
+  char tmpstr[512], tmpstr2[512];
+  LPSTR pstr, pstr2;
     
-    lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
-    switch (wParam) {
-     case lst1:
-	FILEDLG_StripEditControl(hWnd);
-	if (HIWORD(lParam) == LBN_DBLCLK) {
-	    lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
-	    if (lRet == LB_ERR) return TRUE;
-	    SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet, MAKE_SEGPTR(tmpstr));
-	    SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
-	    return SendMessage(hWnd, WM_COMMAND, IDOK, 0);
-	}
-	return TRUE;
-     case lst2:
-	FILEDLG_StripEditControl(hWnd);
-	if (HIWORD(lParam) == LBN_DBLCLK) {
-	    lRet = SendDlgItemMessage(hWnd, lst2, LB_GETCURSEL, 0, 0);
-	    if (lRet == LB_ERR) return TRUE;
-	    SendDlgItemMessage(hWnd, lst2, LB_GETTEXT, lRet, MAKE_SEGPTR(tmpstr));
-	    
-	    if (tmpstr[0] == '[') {
-		tmpstr[strlen(tmpstr) - 1] = 0;
-		strcpy(tmpstr,tmpstr+1);
+  lpofn = (LPOPENFILENAME)GetWindowLong(hWnd, DWL_USER);
+  switch (wParam)
+    {
+    case lst1: /* file list */
+      FILEDLG_StripEditControl(hWnd);
+      if (HIWORD(lParam) == LBN_DBLCLK)
+	goto almost_ok;
+      lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
+      if (lRet == LB_ERR) return TRUE;
+      SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet,
+			 MAKE_SEGPTR(tmpstr));
+      SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
+      return TRUE;
+    case lst2: /* directory list */
+      FILEDLG_StripEditControl(hWnd);
+      if (HIWORD(lParam) == LBN_DBLCLK)
+	{
+	  lRet = SendDlgItemMessage(hWnd, lst2, LB_GETCURSEL, 0, 0);
+	  if (lRet == LB_ERR) return TRUE;
+	  SendDlgItemMessage(hWnd, lst2, LB_GETTEXT, lRet,
+			     MAKE_SEGPTR(tmpstr));
+	  if (tmpstr[0] == '[')
+	    {
+	      tmpstr[strlen(tmpstr) - 1] = 0;
+	      strcpy(tmpstr,tmpstr+1);
 	    }
-	    strcat(tmpstr, "\\");
-	    FILEDLG_ScanDir(hWnd, tmpstr);
+	  strcat(tmpstr, "\\");
+	  goto reset_scan;
 	}
-	return TRUE;
-	
-     case cmb1:
-	if (HIWORD(lParam) == CBN_SELCHANGE) {
-	    lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
-	    if (lRet == LB_ERR) return TRUE;
-	    strcpy(tmpstr, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter), 
-					       lRet + 1));
-	    SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
-	    FILEDLG_ScanDir(hWnd, "");
+      return TRUE;
+    case cmb1: /* file type drop list */
+      if (HIWORD(lParam) == CBN_SELCHANGE) 
+	{
+	  *tmpstr = 0;
+	  goto reset_scan;
 	}
+      return TRUE;
+    case cmb2: /* disk drop list */
+      FILEDLG_StripEditControl(hWnd);
+      lRet = SendDlgItemMessage(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
+      if (lRet == LB_ERR) return 0;
+      SendDlgItemMessage(hWnd, cmb2, CB_GETLBTEXT, lRet, MAKE_SEGPTR(tmpstr));
+      sprintf(tmpstr, "%c:", tmpstr[2]);
+    reset_scan:
+      lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
+      if (lRet == LB_ERR)
 	return TRUE;
-	
-     case cmb2:
-	FILEDLG_StripEditControl(hWnd);
-	lRet = SendDlgItemMessage(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
-	if (lRet == LB_ERR) return 0;
-	SendDlgItemMessage(hWnd, cmb2, CB_GETLBTEXT, lRet, MAKE_SEGPTR(tmpstr));
-	sprintf(tmpstr, "%c:", tmpstr[2]);
-	FILEDLG_ScanDir(hWnd, tmpstr);
-	return TRUE;
-	
-     case chx1:
-	return TRUE;
-	
-     case pshHelp:
-	return TRUE;
-
-     case IDOK:
-	SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, MAKE_SEGPTR(tmpstr));
-
-	pstr = strrchr(tmpstr, '\\');
-	if (pstr == NULL) pstr = strrchr(tmpstr, ':');
-	
-	if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL) {
-	    /* edit control contains wildcards */
-	    if (pstr != NULL) {
-		strcpy(tmpstr2, pstr+1);
-		*(pstr+1) = 0;
-	    } else {
-		strcpy(tmpstr2, tmpstr);
-		strcpy(tmpstr, "");
+      pstr = FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
+				 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
+				 lRet);
+      strcpy(tmpstr2, pstr); 
+      SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
+      FILEDLG_ScanDir(hWnd, tmpstr);
+      return TRUE;
+    case chx1:
+      return TRUE;
+    case pshHelp:
+      return TRUE;
+    case IDOK:
+    almost_ok:
+      SendDlgItemMessage(hWnd, edt1, WM_GETTEXT, 511, MAKE_SEGPTR(tmpstr));
+      pstr = strrchr(tmpstr, '\\');
+      if (pstr == NULL)
+	pstr = strrchr(tmpstr, ':');
+      if (strchr(tmpstr,'*') != NULL || strchr(tmpstr,'?') != NULL)
+	{
+	  /* edit control contains wildcards */
+	  if (pstr != NULL)
+	    {
+	      strcpy(tmpstr2, pstr+1);
+	      *(pstr+1) = 0;
 	    }
-	    printf("commdlg: %s, %s\n", tmpstr, tmpstr2);
-	    SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
-	    FILEDLG_ScanDir(hWnd, tmpstr);
-	    return TRUE;
+	  else
+	    {
+	      strcpy(tmpstr2, tmpstr);
+	      strcpy(tmpstr, "");
+	    }
+	  printf("commdlg: %s, %s\n", tmpstr, tmpstr2);
+	  SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
+	  FILEDLG_ScanDir(hWnd, tmpstr);
+	  return TRUE;
 	}
-
-	/* no wildcards, we might have a directory or a filename */
-	/* try appending a wildcard and reading the directory */
-	pstr2 = tmpstr + strlen(tmpstr);
-	if (pstr == NULL || *(pstr+1) != 0) {
-	    strcat(tmpstr, "\\");
+      /* no wildcards, we might have a directory or a filename */
+      /* try appending a wildcard and reading the directory */
+      pstr2 = tmpstr + strlen(tmpstr);
+      if (pstr == NULL || *(pstr+1) != 0)
+	strcat(tmpstr, "\\");
+      lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
+      if (lRet == LB_ERR) return TRUE;
+      strcpy(tmpstr2, 
+	     FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter),
+				 PTR_SEG_TO_LIN(lpofn->lpstrFilter),
+				 lRet));
+      SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
+      /* if ScanDir succeeds, we have changed the directory */
+      if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
+      /* if not, this must be a filename */
+      *pstr2 = 0;
+      if (pstr != NULL)
+	{
+	  /* strip off the pathname */
+	  *pstr = 0;
+	  strcpy(tmpstr2, pstr+1);
+	  SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
+	  /* Should we MessageBox() if this fails? */
+	  if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
+	  strcpy(tmpstr, tmpstr2);
 	}
-	lRet = SendDlgItemMessage(hWnd, cmb1, CB_GETCURSEL, 0, 0);
-	if (lRet == LB_ERR) return TRUE;
-	strcpy(tmpstr2, FILEDLG_GetFileType(PTR_SEG_TO_LIN(lpofn->lpstrFilter),
-					    lRet + 1));
-	SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
-	/* if ScanDir succeeds, we have changed the directory */
-	if (FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
-	
-	/* if not, this must be a filename */
-	*pstr2 = 0;
-	
-	if (pstr != NULL) {
-	    /* strip off the pathname */
-	    *pstr = 0;
-	    strcpy(tmpstr2, pstr+1);
-	    SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr2));
-	    /* Should we MessageBox() if this fails? */
-	    if (!FILEDLG_ScanDir(hWnd, tmpstr)) return TRUE;
-	    strcpy(tmpstr, tmpstr2);
-	} else {
-	    SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
+      else 
+	SendDlgItemMessage(hWnd, edt1, WM_SETTEXT, 0, MAKE_SEGPTR(tmpstr));
+      ShowWindow(hWnd, SW_HIDE);
+      {
+	int drive;
+	drive = DOS_GetDefaultDrive();
+	tmpstr2[0] = 'A'+ drive;
+	tmpstr2[1] = ':';
+	tmpstr2[2] = '\\';
+	strcpy(tmpstr2 + 3, DOS_GetCurrentDir(drive));
+	if (strlen(tmpstr2) > 3)
+	  strcat(tmpstr2, "\\");
+	strcat(tmpstr2, tmpstr);
+	strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr2);
+      }
+      lpofn->nFileOffset = 0;
+      lpofn->nFileExtension = strlen(PTR_SEG_TO_LIN(lpofn->lpstrFile)) - 3;
+      if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL) 
+	{
+	  lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
+	  SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet,
+			     MAKE_SEGPTR(tmpstr));
+	  strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), tmpstr);
 	}
-	
-	ShowWindow(hWnd, SW_HIDE);
-	strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFile), tmpstr);
-	lpofn->nFileOffset = 0;
-	lpofn->nFileExtension = strlen(PTR_SEG_TO_LIN(lpofn->lpstrFile)) - 3;
-	if (PTR_SEG_TO_LIN(lpofn->lpstrFileTitle) != NULL) {
-	    lRet = SendDlgItemMessage(hWnd, lst1, LB_GETCURSEL, 0, 0);
-	    SendDlgItemMessage(hWnd, lst1, LB_GETTEXT, lRet, MAKE_SEGPTR(tmpstr));
-	    strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), tmpstr);
-	}
-	EndDialog(hWnd, TRUE);
-	return TRUE;
-     case IDCANCEL:
-	EndDialog(hWnd, FALSE);
-	return TRUE;
+      EndDialog(hWnd, TRUE);
+      return TRUE;
+    case IDCANCEL:
+      EndDialog(hWnd, FALSE);
+      return TRUE;
     }
-    return FALSE;
+  return FALSE;
 }
 
 /***********************************************************************
  * 				FileOpenDlgProc			[COMMDLG.6]
  */
+
 BOOL FileOpenDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {  
-  switch (wMsg) {
-   case WM_INITDIALOG:
+  switch (wMsg)
+    {
+    case WM_INITDIALOG:
       return FILEDLG_WMInitDialog(hWnd, wParam, lParam);
-      
-   case WM_MEASUREITEM:
+    case WM_MEASUREITEM:
       return FILEDLG_WMMeasureItem(hWnd, wParam, lParam);
-    
-   case WM_DRAWITEM:
+    case WM_DRAWITEM:
       return FILEDLG_WMDrawItem(hWnd, wParam, lParam);
-
-   case WM_COMMAND:
+    case WM_COMMAND:
       return FILEDLG_WMCommand(hWnd, wParam, lParam);
-  }
-  
-  /*
-  case WM_CTLCOLOR:
-   SetBkColor((HDC)wParam, 0x00C0C0C0);
-   switch (HIWORD(lParam))
-   {
-    case CTLCOLOR_BTN:
-     SetTextColor((HDC)wParam, 0x00000000);
-     return hGRAYBrush;
-    case CTLCOLOR_STATIC:
-     SetTextColor((HDC)wParam, 0x00000000);
-     return hGRAYBrush;
-   }
-   return FALSE;
-   
-   */
+#if 0
+    case WM_CTLCOLOR:
+      SetBkColor((HDC)wParam, 0x00C0C0C0);
+      switch (HIWORD(lParam))
+	{
+	case CTLCOLOR_BTN:
+	  SetTextColor((HDC)wParam, 0x00000000);
+	  return hGRAYBrush;
+	case CTLCOLOR_STATIC:
+	  SetTextColor((HDC)wParam, 0x00000000);
+	  return hGRAYBrush;
+	}
+      break;
+#endif
+    }
   return FALSE;
 }
 
@@ -589,24 +623,25 @@
  */
 BOOL ColorDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {
-	switch (wMsg) {
-		case WM_INITDIALOG:
-			printf("ColorDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-			ShowWindow(hWnd, SW_SHOWNORMAL);
-			return (TRUE);
-
-		case WM_COMMAND:
-			switch (wParam) {
-				case IDOK:
-					EndDialog(hWnd, TRUE);
-					return(TRUE);
-				case IDCANCEL:
-					EndDialog(hWnd, FALSE);
-					return(TRUE);
-				}
-			return(FALSE);
-		}
-	return FALSE;
+  switch (wMsg) 
+    {
+    case WM_INITDIALOG:
+      printf("ColorDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
+      ShowWindow(hWnd, SW_SHOWNORMAL);
+      return (TRUE);
+    case WM_COMMAND:
+      switch (wParam)
+	{
+	case IDOK:
+	  EndDialog(hWnd, TRUE);
+	  return(TRUE);
+	case IDCANCEL:
+	  EndDialog(hWnd, FALSE);
+	  return(TRUE);
+	}
+      return(FALSE);
+    }
+  return FALSE;
 }
 
 
@@ -651,23 +686,24 @@
  */
 BOOL FindTextDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {
-  switch (wMsg) {
-   case WM_INITDIALOG:
-    printf("FindTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-    ShowWindow(hWnd, SW_SHOWNORMAL);
-    return (TRUE);
-    
-   case WM_COMMAND:
-    switch (wParam) {
-     case IDOK:
-      EndDialog(hWnd, TRUE);
-      return(TRUE);
-     case IDCANCEL:
-      EndDialog(hWnd, FALSE);
-      return(TRUE);
+  switch (wMsg)
+    {
+    case WM_INITDIALOG:
+      printf("FindTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
+      ShowWindow(hWnd, SW_SHOWNORMAL);
+      return (TRUE);
+    case WM_COMMAND:
+      switch (wParam)
+	{
+	case IDOK:
+	  EndDialog(hWnd, TRUE);
+	  return(TRUE);
+	case IDCANCEL:
+	  EndDialog(hWnd, FALSE);
+	  return(TRUE);
+	}
+      return(FALSE);
     }
-    return(FALSE);
-  }
   return FALSE;
 }
 
@@ -677,23 +713,24 @@
  */
 BOOL ReplaceTextDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {
-  switch (wMsg) {
-   case WM_INITDIALOG:
-    printf("ReplaceTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-    ShowWindow(hWnd, SW_SHOWNORMAL);
-    return (TRUE);
-    
-   case WM_COMMAND:
-    switch (wParam) {
-     case IDOK:
-      EndDialog(hWnd, TRUE);
-      return(TRUE);
-     case IDCANCEL:
-      EndDialog(hWnd, FALSE);
-      return(TRUE);
+  switch (wMsg)
+    {
+    case WM_INITDIALOG:
+      printf("ReplaceTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
+      ShowWindow(hWnd, SW_SHOWNORMAL);
+      return (TRUE);
+    case WM_COMMAND:
+      switch (wParam)
+	{
+	case IDOK:
+	  EndDialog(hWnd, TRUE);
+	  return(TRUE);
+	case IDCANCEL:
+	  EndDialog(hWnd, FALSE);
+	  return(TRUE);
+	}
+      return(FALSE);
     }
-    return(FALSE);
-  }
   return FALSE;
 }
 
@@ -731,23 +768,24 @@
  */
 BOOL PrintDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {
-  switch (wMsg) {
-   case WM_INITDIALOG:
-    printf("PrintDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-    ShowWindow(hWnd, SW_SHOWNORMAL);
-    return (TRUE);
-    
-   case WM_COMMAND:
-    switch (wParam) {
-     case IDOK:
-      EndDialog(hWnd, TRUE);
-      return(TRUE);
-     case IDCANCEL:
-      EndDialog(hWnd, FALSE);
-      return(TRUE);
+  switch (wMsg)
+    {
+    case WM_INITDIALOG:
+      printf("PrintDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
+      ShowWindow(hWnd, SW_SHOWNORMAL);
+      return (TRUE);
+    case WM_COMMAND:
+      switch (wParam)
+	{
+	case IDOK:
+	  EndDialog(hWnd, TRUE);
+	  return(TRUE);
+	case IDCANCEL:
+	  EndDialog(hWnd, FALSE);
+	  return(TRUE);
+	}
+      return(FALSE);
     }
-    return(FALSE);
-  }
   return FALSE;
 }
 
@@ -757,23 +795,23 @@
  */
 BOOL PrintSetupDlgProc(HWND hWnd, WORD wMsg, WORD wParam, LONG lParam)
 {
-  switch (wMsg) {
-   case WM_INITDIALOG:
-    printf("PrintSetupDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-    ShowWindow(hWnd, SW_SHOWNORMAL);
-    return (TRUE);
-    
-   case WM_COMMAND:
-    switch (wParam) {
-     case IDOK:
-      EndDialog(hWnd, TRUE);
-      return(TRUE);
-     case IDCANCEL:
-      EndDialog(hWnd, FALSE);
-      return(TRUE);
+  switch (wMsg)
+    {
+    case WM_INITDIALOG:
+      printf("PrintSetupDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
+      ShowWindow(hWnd, SW_SHOWNORMAL);
+      return (TRUE);
+    case WM_COMMAND:
+      switch (wParam) {
+      case IDOK:
+	EndDialog(hWnd, TRUE);
+	return(TRUE);
+      case IDCANCEL:
+	EndDialog(hWnd, FALSE);
+	return(TRUE);
+      }
+      return(FALSE);
     }
-    return(FALSE);
-  }
   return FALSE;
 }
 
@@ -783,7 +821,7 @@
  */
 DWORD CommDlgExtendError(void)
 {
-	return CommDlgLastError;
+  return CommDlgLastError;
 }
 
 
@@ -792,27 +830,29 @@
  */
 int GetFileTitle(LPCSTR lpFile, LPSTR lpTitle, UINT cbBuf)
 {
-	int    	i, len;
-	printf("GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf);
-	if (lpFile == NULL || lpTitle == NULL) return -1;
-	len = strlen(lpFile);
-	if (len == 0) return -1;
-	if (strchr(lpFile, '*') != NULL) return -1;
-	if (strchr(lpFile, '[') != NULL) return -1;
-	if (strchr(lpFile, ']') != NULL) return -1;
-	len--;
-	if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':') return -1;
-	for (i = len; i >= 0; i--) {
-	  if (lpFile[i] == '/' ||  lpFile[i] == '\\' ||  lpFile[i] == ':') {
-	    i++;
-	    break;
-	  }
-	}
-	printf("\n---> '%s' ", &lpFile[i]);
-	len = min(cbBuf, strlen(&lpFile[i]) + 1);
-	strncpy(lpTitle, &lpFile[i], len + 1);
-	if (len != cbBuf)
-		return len;
-	else
-		return 0;
+  int i, len;
+  printf("GetFileTitle(%p %p %d); \n", lpFile, lpTitle, cbBuf);
+  if (lpFile == NULL || lpTitle == NULL)
+    return -1;
+  len = strlen(lpFile);
+  if (len == 0)
+    return -1;
+  if (strpbrk(lpFile, "*[]"))
+    return -1;
+  len--;
+  if (lpFile[len] == '/' || lpFile[len] == '\\' || lpFile[len] == ':')
+    return -1;
+  for (i = len; i >= 0; i--)
+    if (lpFile[i] == '/' ||  lpFile[i] == '\\' ||  lpFile[i] == ':')
+      {
+	i++;
+	break;
+      }
+  printf("\n---> '%s' ", &lpFile[i]);
+  len = min(cbBuf, strlen(&lpFile[i]) + 1);
+  strncpy(lpTitle, &lpFile[i], len + 1);
+  if (len != cbBuf)
+    return len;
+  else
+    return 0;
 }
diff --git a/misc/compobj.c b/misc/compobj.c
index b4a0f9f..026b681 100644
--- a/misc/compobj.c
+++ b/misc/compobj.c
@@ -14,6 +14,8 @@
 #include "stddebug.h"
 #include "debug.h"
 
+DWORD currentMalloc=0;
+
 /***********************************************************************
  *           CoBuildVersion [COMPOBJ.1]
  */
@@ -25,10 +27,13 @@
 
 /***********************************************************************
  *           CoInitialize	[COMPOBJ.2]
+ * lpReserved is an IMalloc pointer in 16bit OLE. We just stored it as-is.
  */
-HRESULT WINAPI CoInitialize(LPVOID lpReserved)
+HRESULT WINAPI CoInitialize(DWORD lpReserved)
 {
 	dprintf_ole(stdnimp,"CoInitialize\n");
+	/* remember the LPMALLOC, maybe somebody wants to read it later on */
+	currentMalloc = lpReserved;
 	return S_OK;
 }
 
@@ -41,6 +46,21 @@
 }
 
 /***********************************************************************
+ *           CoGetMalloc    [COMPOBJ.4]
+ */
+HRESULT WINAPI CoGetMalloc(DWORD dwMemContext, DWORD * lpMalloc)
+{
+	if(currentMalloc)
+	{
+		*lpMalloc = currentMalloc;
+		return S_OK;
+	}
+	*lpMalloc = 0;
+	/* 16-bit E_NOTIMPL */
+	return 0x80000001L;
+}
+
+/***********************************************************************
  *           CoDisconnectObject
  */
 OLESTATUS WINAPI CoDisconnectObject(
diff --git a/misc/dos_fs.c b/misc/dos_fs.c
index c9864c8..08de3c0 100644
--- a/misc/dos_fs.c
+++ b/misc/dos_fs.c
@@ -35,13 +35,13 @@
 #include "debug.h"
 
 #define WINE_INI_USER "~/.winerc"
-#define MAX_OPEN_DIRS 16
 #define MAX_DOS_DRIVES	26
 
 extern char WindowsDirectory[256], SystemDirectory[256],TempDirectory[256];
 
 char WindowsPath[256];
 
+static int max_open_dirs = 0;
 static int CurrentDrive = 2;
 
 struct DosDriveStruct {			/*  eg: */
@@ -53,7 +53,7 @@
 };
 
 static struct DosDriveStruct DosDrives[MAX_DOS_DRIVES];
-static struct dosdirent DosDirs[MAX_OPEN_DIRS];
+static struct dosdirent *DosDirs=NULL;
 
 static void ExpandTildeString(char *s)
 {
@@ -221,7 +221,7 @@
 		}
 	}
 
-	for (x=0; x!=MAX_OPEN_DIRS ; x++)
+	for (x=0; x!=max_open_dirs ; x++)
 		DosDirs[x].inuse = 0;
 
     dprintf_dosfs(stddeb,"wine.ini = %s\n",WINE_INI);
@@ -869,6 +869,7 @@
 	int x,y;
 	char *unixdirname;
 	char temp[256];
+	DIR  *ds;
 	
 	if ((unixdirname = DOS_GetUnixFileName(dosdirname)) == NULL)
 		return NULL;
@@ -885,10 +886,15 @@
 		}
 	}
 
-        for (x=0; x <= MAX_OPEN_DIRS; x++) {
-	  if (x == MAX_OPEN_DIRS) {
-	    fprintf( stderr, "DOS_opendir(): Too many open directories\n");
-	    return NULL;
+        for (x=0; x <= max_open_dirs; x++) {
+	  if (x == max_open_dirs) {
+	    if (DosDirs) {
+	      DosDirs=(struct dosdirent*)realloc(DosDirs,(++max_open_dirs)*sizeof(DosDirs[0]));
+	    } else {
+	      DosDirs=(struct dosdirent*)malloc(sizeof(DosDirs[0]));
+	      max_open_dirs=1;
+	    }
+	    break; /* this one is definitely not in use */
 	  }
 	  if (!DosDirs[x].inuse) break;
 	  if (strcmp(DosDirs[x].unixpath,temp) == 0) break;
@@ -903,7 +909,13 @@
 	strcpy(DosDirs[x].unixpath, temp);
         DosDirs[x].entnum = 0;
 
-	if ((DosDirs[x].ds = opendir(temp)) == NULL)
+	if ((ds = opendir(temp)) == NULL)
+		return NULL;
+	if (-1==(DosDirs[x].telldirnum=telldir(ds))) {
+		closedir(ds);
+		return NULL;
+	}
+	if (-1==closedir(ds))
 		return NULL;
 
 	return &DosDirs[x];
@@ -915,13 +927,19 @@
 	char temp[256];
 	struct dirent *d;
 	struct stat st;
+	DIR	*ds;
 
 	if (!de->inuse)
 		return NULL;
-	
+	if (-1==(ds=opendir(de->unixpath)))
+		return NULL;
+	seekdir(ds,de->telldirnum); /* returns no error value. strange */
 	do {
-		if ((d = readdir(de->ds)) == NULL) 
+		if ((d = readdir(ds)) == NULL)  {
+			de->telldirnum=telldir(ds);
+			closedir(ds);
 			return NULL;
+		}
 
                 de->entnum++;   /* Increment the directory entry number */
 		strcpy(de->filename, d->d_name);
@@ -944,16 +962,15 @@
 	de->filesize = st.st_size;
 	de->filetime = st.st_mtime;
 
+	de->telldirnum = telldir(ds);
+	closedir(ds);
 	return de;
 }
 
 void DOS_closedir(struct dosdirent *de)
 {
 	if (de && de->inuse)
-	{
-		closedir(de->ds);
 		de->inuse = 0;
-	}
 }
 
 char *DOS_GetRedirectedDir(int drive)
diff --git a/misc/file.c b/misc/file.c
index 5c5eee4..ef45ec5 100644
--- a/misc/file.c
+++ b/misc/file.c
@@ -75,7 +75,7 @@
   dprintf_file(stddeb, "_lread: handle %d, buffer = %ld, length = %d\n",
 	  		hFile, (long) lpBuffer, wBytes);
   
-  result = read (hFile, lpBuffer, wBytes);
+  result = wBytes == 0 ? 0 : read (hFile, lpBuffer, wBytes);
 
   if (result == -1)
   	return HFILE_ERROR;
@@ -93,7 +93,7 @@
     dprintf_file(stddeb, "_lwrite: handle %d, buffer = %ld, length = %d\n",
 		 hFile, (long) lpBuffer, wBytes);
 
-    result = write (hFile, lpBuffer, wBytes);
+    result = wBytes == 0 ? 0 : write (hFile, lpBuffer, wBytes);
 
     if (result == -1)
         return HFILE_ERROR;
@@ -438,12 +438,12 @@
  ***************************************************************************/
 LONG _hread(INT hf, LPSTR hpvBuffer, LONG cbBuffer)
 {
-	return read(hf, hpvBuffer, cbBuffer);
+    return cbBuffer == 0 ? 0 : read(hf, hpvBuffer, cbBuffer);
 }
 /***************************************************************************
  _hwrite
  ***************************************************************************/
 LONG _hwrite(INT hf, LPCSTR hpvBuffer, LONG cbBuffer)
 {
-	return write(hf, hpvBuffer, cbBuffer);
+    return cbBuffer == 0 ? 0 : write(hf, hpvBuffer, cbBuffer);
 }
diff --git a/misc/main.c b/misc/main.c
index 5af55c2..f5f8544 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -224,6 +224,7 @@
 
 #endif
 
+#ifndef WINELIB
 /***********************************************************************
  *           MAIN_ParseDLLOptions
  *
@@ -258,6 +259,7 @@
   else
     return TRUE;
 }
+#endif
 
 
 
@@ -347,6 +349,7 @@
       }
 
       if(MAIN_GetResource( db, ".dll", &value))
+#ifndef WINELIB
        if(MAIN_ParseDLLOptions((char*)value.addr)==FALSE)
        {
          int i;
@@ -359,6 +362,9 @@
          fprintf(stderr,"\n\n");
          exit(1);
        }
+#else
+		fprintf(stderr,"-dll not supported in libwine\n");
+#endif
 }
 
 
@@ -559,7 +565,7 @@
 LONG GetWinFlags(void)
 {
   if (Options.enhanced)
-    return (WF_STANDARD | WF_ENHANCED | WF_CPU286 | WF_PMODE | WF_80x87);
+    return (WF_STANDARD | WF_ENHANCED | WF_CPU386 | WF_PMODE | WF_80x87);
   else
     return (WF_STANDARD | WF_CPU286 | WF_PMODE | WF_80x87);
 }
diff --git a/misc/ole2disp.c b/misc/ole2disp.c
new file mode 100644
index 0000000..92dba48
--- /dev/null
+++ b/misc/ole2disp.c
@@ -0,0 +1,105 @@
+/*
+ *	OLE2DISP library
+ *
+ *	Copyright 1995	Martin von Loewis
+ */
+
+#include "windows.h"
+#include "ole2.h"
+#include "global.h"
+#include "local.h"
+#include "ldt.h"
+#include "stddebug.h"
+#include "debug.h"
+
+/* This implementation of the BSTR API is 16-bit only. It
+   represents BSTR as a 16:16 far pointer, and the strings
+   as ISO-8859 */
+
+typedef DWORD	BSTR;
+HGLOBAL	BSTRheapsel=0;
+#define BSTR_HEAP_SIZE	65536
+
+static BSTR BSTR_AllocBytes(int n)
+{
+	HLOCAL mem;
+	if(!BSTRheapsel)
+	{
+		BSTRheapsel=GlobalAlloc(GMEM_FIXED,BSTR_HEAP_SIZE);
+		LocalInit(BSTRheapsel,0,BSTR_HEAP_SIZE-1);
+	}
+	if(!BSTRheapsel)
+		return 0;
+	mem=LOCAL_Alloc(BSTRheapsel,LMEM_FIXED,n);
+	return mem ? MAKELONG(mem,BSTRheapsel) : 0;
+}
+
+static void BSTR_Free(BSTR in)
+{
+	LOCAL_Free(BSTRheapsel, LOWORD(in));
+}
+
+static void* BSTR_GetAddr(BSTR in)
+{
+	return in ? PTR_SEG_TO_LIN(in) : 0;
+}
+
+/***********************************************************************
+ *           SysAllocString         [OLE2DISP.2]
+ */
+BSTR SysAllocString(char *in)
+{
+	BSTR out=BSTR_AllocBytes(strlen(in)+1);
+	if(!out)return 0;
+	strcpy(BSTR_GetAddr(out),in);
+	return out;
+}
+
+/***********************************************************************
+ *           SysReAllocString       [OLE2DISP.3]
+ */
+int SysReAllocString(BSTR *old,char *in)
+{
+	BSTR new=SysAllocString(in);
+	BSTR_Free(*old);
+	*old=new;
+	return 1;
+}
+
+/***********************************************************************
+ *           SysAllocStringLen      [OLE2DISP.4]
+ */
+BSTR SysAllocStringLen(char *in, int len)
+{
+	BSTR out=BSTR_AllocBytes(len+1);
+	if(!out)return 0;
+	strcpy(BSTR_GetAddr(out),in);
+	return out;
+}
+
+/***********************************************************************
+ *           SysReAllocStringLen    [OLE2DISP.5]
+ */
+int SysReAllocStringLen(BSTR *old,char *in,int len)
+{
+	BSTR new=SysAllocStringLen(in,len);
+	BSTR_Free(*old);
+	*old=new;
+	return 1;
+}
+
+/***********************************************************************
+ *           SysFreeString          [OLE2DISP.6]
+ */
+void SysFreeString(BSTR in)
+{
+	BSTR_Free(in);
+}
+
+/***********************************************************************
+ *           SysStringLen           [OLE2DISP.7]
+ */
+int SysStringLen(BSTR str)
+{
+	return strlen(BSTR_GetAddr(str));
+}
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index de78508..3eccbd3 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -237,7 +237,7 @@
 LOCVAL(LOCALE_SDATE,".")
 LOCVAL(LOCALE_STIME,":")
 LOCVAL(LOCALE_SSHORTDATE,"dd.MM.yyyy")
-LOCVAL(LOCALE_SLONGDATEi,"ddd, d. MMMM yyyy")
+LOCVAL(LOCALE_SLONGDATE,"ddd, d. MMMM yyyy")
 /*
 LOCVAL(LOCALE_STIMEFORMAT)
 */
@@ -329,3 +329,35 @@
 	strncpy(buf,retString,len);
 	return retLen;
 }
+
+
+/***********************************************************************
+ *           CompareStringA       (OLE2NLS.8)
+ * This implementation ignores the locale, and trusts in libc
+ */
+int CompareStringA(DWORD lcid, DWORD fdwStyle, 
+	char *s1, int l1, char *s2,int l2)
+{
+	int len,ret;
+	if(fdwStyle & NORM_IGNORENONSPACE)
+	{
+		fprintf(stdnimp, "CompareStringA: IGNORENONSPACE not supprted\n");
+	}
+	if(fdwStyle & NORM_IGNORESYMBOLS)
+		fprintf(stdnimp, "CompareStringA: IGNORESYMBOLS not supported\n");
+	/* Is strcmp defaulting to string sort or to word sort?? */
+	/* FIXME: Handle NORM_STRINGSORT */
+	l1 = (l1==-1)?strlen(s1):l1;
+	l2 = (l2==-1)?strlen(s2):l2;
+	len = l1<l2 ? l1:l2;
+	ret = (fdwStyle & NORM_IGNORECASE) ?
+		strncasecmp(s1,s2,len)	:
+		strncmp(s1,s2,len);
+	/* not equal, return 1 or 3 */
+	if(ret!=0)return ret+2;
+	/* same len, return 2 */
+	if(l1==l2)return 2;
+	/* the longer one is lexically greater */
+	return (l1<l2)? 1 : 3;
+}
+
diff --git a/misc/profile.c b/misc/profile.c
index 9cf4c52..71e5373 100644
--- a/misc/profile.c
+++ b/misc/profile.c
@@ -184,6 +184,9 @@
 		state = IgnoreToEOL;
 		break;
 	    }
+
+	    if (c == '\n')
+	      break;
 	    
 	    if (c == '=' || overflow){
 		TKeys *temp;
@@ -197,8 +200,9 @@
 		state = KeyValue;
 		next = CharBuffer;
 		dprintf_profile(stddeb,"%s:   key %s\n", file, CharBuffer);
-	    } else
+	    } else {
 		*next++ = c;
+	    }
 	    break;
 
 	case KeyValue:
@@ -293,6 +297,7 @@
 	    }
 	    ReturnedString [Size-1] = 0;
 	    strncpy (ReturnedString, key->Value, Size-1);
+	    dprintf_profile(stddeb,"GetSetProfile // Return ``%s''\n", ReturnedString);
 	    return 1; 
 	}
 	/* If Getting the information, then don't write the information
@@ -303,6 +308,7 @@
         else {
             ReturnedString [Size-1] = 0;
             strncpy (ReturnedString, Default, Size-1);
+	    dprintf_profile(stddeb,"GetSetProfile // Key not found\n");
 	}
 	return 1;
     }
@@ -318,6 +324,7 @@
     } else {
 	ReturnedString [Size-1] = 0;
 	strncpy (ReturnedString, Default, Size-1);
+	dprintf_profile(stddeb,"GetSetProfile // Section not found\n");
     }
     return 1;
 }
diff --git a/misc/shell.c b/misc/shell.c
index 5ef692c..ebdfd91 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -13,7 +13,6 @@
 #include "dlgs.h"
 #include "dialog.h"
 #include "stddebug.h"
-/* #define DEBUG_REG */
 #include "debug.h"
 
 LPKEYSTRUCT	lphRootKey = NULL,lphTopKey = NULL;
@@ -185,7 +184,7 @@
 LONG RegCloseKey(HKEY hKey)
 {
 	dprintf_reg(stdnimp, "EMPTY STUB !!! RegCloseKey(%08lX);\n", hKey);
-	return ERROR_INVALID_PARAMETER;
+	return ERROR_SUCCESS;
 }
 
 
@@ -196,7 +195,7 @@
 {
 	dprintf_reg(stdnimp, "EMPTY STUB !!! RegDeleteKey(%08lX, '%s');\n", 
 												hKey, lpSubKey);
-	return ERROR_INVALID_PARAMETER;
+	return ERROR_SUCCESS;
 }
 
 
@@ -204,29 +203,29 @@
  *				RegSetValue		[SHELL.5]
  */
 LONG RegSetValue(HKEY hKey, LPCSTR lpSubKey, DWORD dwType, 
-					LPCSTR lpVal, DWORD dwIgnored)
+		 LPCSTR lpVal, DWORD dwIgnored)
 {
-	HKEY		hRetKey;
-	LPKEYSTRUCT	lpKey;
-	LONG		dwRet;
-	dprintf_reg(stddeb, "RegSetValue(%08lX, '%s', %08lX, '%s', %08lX);\n",
-						hKey, lpSubKey, dwType, lpVal, dwIgnored);
-	if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
-	if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
-	if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
-	        dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n");
-		if ((dwRet = RegCreateKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
-			fprintf(stderr, "RegSetValue // key creation error %08lX !\n", dwRet);
-			return dwRet;
-			}
-		}
-	lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
-	if (lpKey == NULL) return ERROR_BADKEY;
-	if (lpKey->lpValue != NULL) free(lpKey->lpValue);
-	lpKey->lpValue = malloc(strlen(lpVal) + 1);
-	strcpy(lpKey->lpValue, lpVal);
-	dprintf_reg(stddeb,"RegSetValue // successful key='%s' val='%s' !\n", lpSubKey, lpKey->lpValue);
-	return ERROR_SUCCESS;
+    HKEY       	hRetKey;
+    LPKEYSTRUCT	lpKey;
+    LONG       	dwRet;
+    dprintf_reg(stddeb, "RegSetValue(%08lX, '%s', %08lX, '%s', %08lX);\n",
+		hKey, lpSubKey, dwType, lpVal, dwIgnored);
+    if (lpSubKey == NULL) return ERROR_INVALID_PARAMETER;
+    if (lpVal == NULL) return ERROR_INVALID_PARAMETER;
+    if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
+	dprintf_reg(stddeb, "RegSetValue // key not found ... so create it !\n");
+	if ((dwRet = RegCreateKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
+	    fprintf(stderr, "RegSetValue // key creation error %08lX !\n", dwRet);
+	    return dwRet;
+	}
+    }
+    lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
+    if (lpKey == NULL) return ERROR_BADKEY;
+    if (lpKey->lpValue != NULL) free(lpKey->lpValue);
+    lpKey->lpValue = malloc(strlen(lpVal) + 1);
+    strcpy(lpKey->lpValue, lpVal);
+    dprintf_reg(stddeb,"RegSetValue // successful key='%s' val='%s' !\n", lpSubKey, lpKey->lpValue);
+    return ERROR_SUCCESS;
 }
 
 
@@ -249,7 +248,7 @@
 	if ((dwRet = RegOpenKey(hKey, lpSubKey, &hRetKey)) != ERROR_SUCCESS) {
 		fprintf(stderr, "RegQueryValue // key not found !\n");
 		return dwRet;
-		}
+	}
 	lpKey = (LPKEYSTRUCT)GlobalLock(hRetKey);
 	if (lpKey == NULL) return ERROR_BADKEY;
 	if (lpKey->lpValue != NULL) {
diff --git a/misc/user.c b/misc/user.c
index 9e0333f..86a09f5 100644
--- a/misc/user.c
+++ b/misc/user.c
@@ -24,6 +24,7 @@
 
 #define USER_HEAP_SIZE          0x10000
 
+#ifndef WINELIB
 LPSTR USER_Heap = NULL;
 WORD USER_HeapSel = 0;
 
@@ -73,7 +74,6 @@
 }
 
 
-#ifndef WINELIB
 /***********************************************************************
  *           USER_HeapInit
  */
diff --git a/miscemu/instr.c b/miscemu/instr.c
index b2ef67b..b025452 100644
--- a/miscemu/instr.c
+++ b/miscemu/instr.c
@@ -98,6 +98,10 @@
         case 0x67:
             long_addr = !long_addr;  /* addr size prefix */
             break;
+        case 0xf0:  /* lock */
+        case 0xf2:  /* repne */
+        case 0xf3:  /* repe */
+            break;
         default:
             prefix = 0;  /* no more prefixes */
             break;
@@ -115,6 +119,7 @@
     {
       case 0xcd: /* int <XX> */
             instr++;
+            /* FIXME: should check if handler has been changed */
 	    if (!do_int(*instr, context))
             {
 		fprintf(stderr,"Unexpected Windows interrupt %x\n", *instr);
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 10226b8..078f34e 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -437,7 +437,8 @@
 		drive = BL - 1;
 
 	if (!DOS_ValidDrive(drive)) {
-		AX = 0x02;				
+                Error( FileNotFound, EC_NotFound, EL_Disk );
+                AX = FileNotFound;
 		SetCflag;
 		return;
 	}
@@ -502,7 +503,7 @@
 {
 	AX = ExtendedError;
 	BX = (ErrorClass << 8) | Action;
-	CH = ErrorLocus << 8;
+	CH = ErrorLocus;
 }
 
 static void CreateFile(struct sigcontext_struct *context)
@@ -656,15 +657,17 @@
 	dprintf_int(stddeb,"int21: makedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS,DX) );
 	
 	if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ))== NULL) {
-		AX = CanNotMakeDir;
-		SetCflag;
-		return;
+            Error( CanNotMakeDir, EC_AccessDenied, EL_Disk );
+            AX = CanNotMakeDir;
+            SetCflag;
+            return;
 	}
 
 	if (mkdir(dirname,0) == -1) {
-		AX = CanNotMakeDir;
-		SetCflag;
-		return;
+            Error( CanNotMakeDir, EC_AccessDenied, EL_Disk );
+            AX = CanNotMakeDir;
+            SetCflag;
+            return;
 	}
 	ResetCflag;
 }
@@ -693,9 +696,10 @@
 	dprintf_int(stddeb,"int21: removedir %s\n", (char *)PTR_SEG_OFF_TO_LIN(DS,DX) );
 
 	if ((dirname = DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ))== NULL) {
-		AX = PathNotFound;
-		SetCflag;
-		return;
+            Error( PathNotFound, EC_NotFound, EL_Disk );
+            AX = PathNotFound;
+            SetCflag;
+            return;
 	}
 
 /*
@@ -705,9 +709,10 @@
 	}
 */	
 	if (rmdir(dirname) == -1) {
-		AX = AccessDenied;
-		SetCflag;
-                return;
+            Error( AccessDenied, EC_AccessDenied, EL_Disk );
+            AX = AccessDenied;
+            SetCflag;
+            return;
 	} 
 	ResetCflag;
 }
@@ -839,9 +844,10 @@
 	handle = open(DOS_GetUnixFileName(temp), O_CREAT | O_TRUNC | O_RDWR);
 
 	if (handle == -1) {
-		AX = WriteProtected;
-		SetCflag;
-		return;
+            Error( WriteProtected, EC_AccessDenied, EL_Disk );
+            AX = WriteProtected;
+            SetCflag;
+            return;
 	}
 
 	strcpy(PTR_SEG_OFF_TO_LIN(DS,DX), temp);
@@ -855,9 +861,10 @@
 	int handle;
 	
 	if ((handle = open(DOS_GetUnixFileName( PTR_SEG_OFF_TO_LIN(DS,DX) ), O_CREAT | O_EXCL | O_RDWR)) == -1) {
-		AX = WriteProtected;
-		SetCflag;
-		return;
+            Error( WriteProtected, EC_AccessDenied, EL_Disk );
+            AX = WriteProtected;
+            SetCflag;
+            return;
 	}
 
 	AX = handle;
@@ -874,9 +881,10 @@
 		drive = DL - 1;
 
 	if (!DOS_ValidDrive(drive)) {
-		AX = InvalidDrive;
-		SetCflag;
-		return;
+            Error( InvalidDrive, EC_NotFound, EL_Disk );
+            AX = InvalidDrive;
+            SetCflag;
+            return;
 	}
 
 	strcpy(PTR_SEG_OFF_TO_LIN(DS,SI), DOS_GetCurrentDir(drive) );
@@ -895,9 +903,10 @@
 		drive = BL - 1;
 
 	if (!DOS_ValidDrive(drive)) {
-		AX =InvalidDrive;
-		SetCflag;
-		return;
+            Error( InvalidDrive, EC_NotFound, EL_Disk );
+            AX = InvalidDrive;
+            SetCflag;
+            return;
 	}
 
 	DOS_GetSerialNumber(drive, &serialnumber);
@@ -923,9 +932,10 @@
 		drive = BL - 1;
 
 	if (!DOS_ValidDrive(drive)) {
-		AX = InvalidDrive;
-		SetCflag;
-		return;
+            Error( InvalidDrive, EC_NotFound, EL_Disk );
+            AX = InvalidDrive;
+            SetCflag;
+            return;
 	}
 
 	serialnumber = dataptr[1] + (dataptr[2] << 8) + (dataptr[3] << 16) + 
@@ -1477,8 +1487,9 @@
                 drive = BL ? (BL - 1) : DOS_GetDefaultDrive();
                 if(!DOS_ValidDrive(drive))
                 {
+                    Error( InvalidDrive, EC_NotFound, EL_Disk );
+                    AX = InvalidDrive;
                     SetCflag;
-                    AX = 0x000F;        /* Bad drive number */
                 }
                 else
                 {
@@ -1494,8 +1505,9 @@
                 drive = BL ? (BL - 1) : DOS_GetDefaultDrive();
                 if(!DOS_ValidDrive(drive))
                 {
+                    Error( InvalidDrive, EC_NotFound, EL_Disk );
+                    AX = InvalidDrive;
                     SetCflag;
-                    AX = 0x000F;        /* Bad drive number */
                 }
                 else
                 {
diff --git a/miscemu/int5c.c b/miscemu/int5c.c
index 060da76..0bd1fd1 100644
--- a/miscemu/int5c.c
+++ b/miscemu/int5c.c
@@ -4,12 +4,12 @@
  * Copyright 1995 Alexandre Julliard
  */
 
-#include "miscemu.h"
-#include "registers.h"
 #include "wine.h"
+#include "miscemu.h"
 #include "stddebug.h"
 /* #define DEBUG_INT */
 #include "debug.h"
+#include "registers.h"
 
 
 /***********************************************************************
diff --git a/objects/bitblt.c b/objects/bitblt.c
index 12f8167..38074db 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -1034,6 +1034,16 @@
     yDst      = dcDst->w.DCOrgY + YLPTODP( dcDst, yDst );
     widthDst  = widthDst * dcDst->w.VportExtX / dcDst->w.WndExtX;
     heightDst = heightDst * dcDst->w.VportExtY / dcDst->w.WndExtY;
+
+    dprintf_bitblt( stddeb, "    vportdst=%d,%d-%d,%d wnddst=%d,%d-%d,%d\n",
+                   dcDst->w.VportOrgX, dcDst->w.VportOrgY,
+                   dcDst->w.VportExtX, dcDst->w.VportExtY,
+                   dcDst->w.WndOrgX, dcDst->w.WndOrgY,
+                   dcDst->w.WndExtX, dcDst->w.WndExtY );
+    dprintf_bitblt( stddeb, "    rectdst=%d,%d-%d,%d orgdst=%d,%d\n",
+                    xDst, yDst, widthDst, heightDst,
+                    dcDst->w.DCOrgX, dcDst->w.DCOrgY );
+
     if (useSrc)
     {
         xSrc      = dcSrc->w.DCOrgX + XLPTODP( dcSrc, xSrc );
@@ -1041,10 +1051,23 @@
         widthSrc  = widthSrc * dcSrc->w.VportExtX / dcSrc->w.WndExtX;
         heightSrc = heightSrc * dcSrc->w.VportExtY / dcSrc->w.WndExtY;
         fStretch  = (widthSrc != widthDst) || (heightSrc != heightDst);
+        dprintf_bitblt( stddeb,"    vportsrc=%d,%d-%d,%d wndsrc=%d,%d-%d,%d\n",
+                        dcSrc->w.VportOrgX, dcSrc->w.VportOrgY,
+                        dcSrc->w.VportExtX, dcSrc->w.VportExtY,
+                        dcSrc->w.WndOrgX, dcSrc->w.WndOrgY,
+                        dcSrc->w.WndExtX, dcSrc->w.WndExtY );
+        dprintf_bitblt( stddeb, "    rectsrc=%d,%d-%d,%d orgsrc=%d,%d\n",
+                        xSrc, ySrc, widthSrc, heightSrc,
+                        dcSrc->w.DCOrgX, dcSrc->w.DCOrgY );
         if (!BITBLT_GetVisRectangles( dcDst, xDst, yDst, widthDst, heightDst,
                                       dcSrc, xSrc, ySrc, widthSrc, heightSrc,
                                       &visRectSrc, &visRectDst ))
             return TRUE;
+        dprintf_bitblt( stddeb, "    vissrc=%d,%d-%d,%d visdst=%d,%d-%d,%d\n",
+                        visRectSrc.left, visRectSrc.top,
+                        visRectSrc.right, visRectSrc.bottom,
+                        visRectDst.left, visRectDst.top,
+                        visRectDst.right, visRectDst.bottom );
     }
     else
     {
@@ -1052,6 +1075,9 @@
         if (!BITBLT_GetVisRectangles( dcDst, xDst, yDst, widthDst, heightDst,
                                       NULL, 0, 0, 0, 0, NULL, &visRectDst ))
             return TRUE;
+        dprintf_bitblt( stddeb, "    vissrc=none visdst=%d,%d-%d,%d\n",
+                        visRectDst.left, visRectDst.top,
+                        visRectDst.right, visRectDst.bottom );
     }
 
     width  = visRectDst.right - visRectDst.left;
@@ -1240,12 +1266,7 @@
                 "BitBlt: %04x %d,%d %d bpp -> %04x %d,%d %dx%dx%d rop=%06lx\n",
                 hdcSrc, xSrc, ySrc, dcSrc ? dcSrc->w.bitsPerPixel : 0,
                 hdcDst, xDst, yDst, width, height, dcDst->w.bitsPerPixel, rop);
-    if (dcSrc != NULL) {
-	dprintf_bitblt(stddeb,"        src org=%d,%d",
-		       dcSrc->w.DCOrgX, dcSrc->w.DCOrgY);
-    }
-    dprintf_bitblt(stddeb,"  dst org=%d,%d\n", dcDst->w.DCOrgX, 
-		   dcDst->w.DCOrgY);
+
     return CallTo32_LargeStack( (int(*)())BITBLT_InternalStretchBlt, 11,
                                 dcDst, xDst, yDst, width, height,
                                 dcSrc, xSrc, ySrc, width, height, rop );
diff --git a/objects/dib.c b/objects/dib.c
index 34a202f..78ab1ee 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -541,9 +541,19 @@
 	WORD xSrc, WORD ySrc, WORD wSrcWidth, WORD wSrcHeight,
 	LPSTR bits, LPBITMAPINFO info, WORD wUsage, DWORD dwRop )
 {
-	printf("StretchDIBits // call SetDIBitsToDevice for now !!!!\n");
-	return SetDIBitsToDevice(hdc, xDest, yDest, wDestWidth, wDestHeight,
-		xSrc, ySrc, 1, 1, bits, info, wUsage);
+    HBITMAP hBitmap, hOldBitmap;
+    HDC hdcMem;
+
+    hBitmap = CreateDIBitmap( hdc, &info->bmiHeader, CBM_INIT,
+                              bits, info, wUsage );
+    hdcMem = CreateCompatibleDC( hdc );
+    hOldBitmap = SelectObject( hdcMem, hBitmap );
+    StretchBlt( hdc, xDest, yDest, wDestWidth, wDestHeight,
+                hdcMem, xSrc, ySrc, wSrcWidth, wSrcHeight, dwRop );
+    SelectObject( hdcMem, hOldBitmap );
+    DeleteDC( hdcMem );
+    DeleteObject( hBitmap );
+    return wSrcHeight;
 }
 
 /***********************************************************************
diff --git a/objects/font.c b/objects/font.c
index 57079f0..be92707 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -259,6 +259,34 @@
     metrics->tmAveCharWidth = average;
 }
 
+/***********************************************************************
+ *           GetGlyphOutLine    (GDI.309)
+ */
+DWORD GetGlyphOutLine(
+	HDC hdc, UINT uChar, UINT fuFormat, LPGLYPHMETRICS lpgm, 
+	DWORD cbBuffer, LPSTR lpBuffer, LPMAT2 lpmat2
+) {
+	dprintf_font(stdnimp,"GetGlyphOutLine(0x%x, '%c', 0x%x, %p, %d, %p, %p) // - empty stub!\n",
+		hdc,uChar,fuFormat,lpgm,cbBuffer,lpBuffer,lpmat2
+	);
+	return (DWORD)-1; /* failure */
+}
+/***********************************************************************
+ *           CreateScalableFontResource    (GDI.310)
+ */
+BOOL CreateScalableFontResource(
+	UINT fHidden,LPSTR lpszResourceFile,
+	LPSTR lpszFontFile,LPSTR lpszCurrentPath
+) {
+	/* fHidden=1 - only visible for the calling app, read-only, not
+	 * enumbered with EnumFonts/EnumFontFamilies
+	 * lpszCurrentPath can be NULL
+	 */
+	dprintf_font(stdnimp,"CreateScalableFontResource(%d,%s,%s,%x(%s)) // empty stub!\n",
+		fHidden,lpszResourceFile,lpszFontFile,lpszCurrentPath
+	);
+	return FALSE; /* create failed */
+}
 
 /***********************************************************************
  *           CreateFontIndirect    (GDI.57)
diff --git a/objects/oembitmap.c b/objects/oembitmap.c
index 87093f6..6bb2581 100644
--- a/objects/oembitmap.c
+++ b/objects/oembitmap.c
@@ -11,6 +11,7 @@
 #include <X11/xpm.h>
 #include "gdi.h"
 #include "bitmap.h"
+#include "callback.h"
 #include "color.h"
 #include "icon.h"
 #include "stddebug.h"
@@ -280,9 +281,10 @@
 
     if (!OBM_InitColorSymbols()) return 0;
     
-    if (!OBM_CreateBitmaps( OBM_Pixmaps_Data[id].data,
-                            OBM_Pixmaps_Data[id].color,
-                            FALSE, &hbitmap, &hbitmask ))
+    if (!CallTo32_LargeStack( (int(*)())OBM_CreateBitmaps, 5,
+                              OBM_Pixmaps_Data[id].data,
+                              OBM_Pixmaps_Data[id].color,
+                              FALSE, &hbitmap, &hbitmask ))
     {
         fprintf( stderr, "Error creating OEM bitmap %d\n", OBM_FIRST+id );
         return 0;
@@ -308,8 +310,9 @@
     if (!(hicon = GlobalAlloc( GMEM_MOVEABLE, sizeof(ICONALLOC) ))) return 0;
     pIcon = (ICONALLOC *)GlobalLock( hicon );
 
-    if (!OBM_CreateBitmaps( OBM_Icons_Data[id], TRUE, TRUE,
-                            &pIcon->hBitmap, &pIcon->hBitMask ))
+    if (!CallTo32_LargeStack( (int(*)())OBM_CreateBitmaps, 5,
+                              OBM_Icons_Data[id], TRUE, TRUE,
+                              &pIcon->hBitmap, &pIcon->hBitMask ))
     {
         fprintf( stderr, "Error creating OEM icon %d\n", OIC_FIRST+id );
         GlobalFree( hicon );
diff --git a/rc/Imakefile b/rc/Imakefile
index 56f9e14..4984ba4 100644
--- a/rc/Imakefile
+++ b/rc/Imakefile
@@ -49,6 +49,8 @@
 
 NormalProgramTarget(winerc,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),)
 
+depend:: y.tab.c y.tab.h lex.yy.c
+
 DependTarget()
 
 clean::
diff --git a/rc/winerc.c b/rc/winerc.c
index 45fde21..14f3af0 100644
--- a/rc/winerc.c
+++ b/rc/winerc.c
@@ -16,7 +16,13 @@
 #include "parser.h"
 #include "y.tab.h"
 
-char usage[]="winerc -dvc -p prefix -o outfile < infile \n";
+char usage[]="winerc -bdvc -p prefix -o outfile < infile \n"
+	"   -b            Create a C array from a binary .res file\n"
+	"   -d            Output debugging information\n"
+	"   -p prefix     Give a prefix for the generated names\n"
+	"   -v            Show each resource as it is processed\n"
+	"   -o file       Output to file.c and file.h\n";
+
 
 /*might be overwritten by command line*/
 char *prefix="_Resource";
@@ -29,16 +35,18 @@
 {  
 	extern int yydebug;
 	extern char* optarg;
-	int optc,lose,ret;
-	lose=0;
+	int optc,lose,ret,binary;
+	lose=binary=0;
 #if defined(__NetBSD__) || defined(__FreeBSD__)
-	while((optc=getopt(argc,argv,"dp:vo:"))!=EOF)
+	while((optc=getopt(argc,argv,"bdp:vo:"))!=EOF)
 #else
-	while((optc=getopt(argc,argv,"dp:vo:",0))!=EOF)
+	while((optc=getopt(argc,argv,"bdp:vo:",0))!=EOF)
 #endif
 		switch(optc)
 		{
 			/* bison will print state transitions on stderr */
+			case 'b':binary=1;
+					 break;
 			case 'd':yydebug=1;
 					 setbuf(stdout,0);
 					 setbuf(stderr,0);
@@ -54,7 +62,10 @@
 	if(lose)return fprintf(stderr,usage),1;
 	if(!header)header=stdout;
 	if(!code)code=stdout;
-	ret=yyparse();
+	if(binary)
+		ret=transform_binary_file();
+	else
+		ret=yyparse();
 	fclose(header);
 	fclose(code);
 	return ret;
@@ -68,6 +79,20 @@
 	header=fopen(hname,"w");
 }
 
+int transform_binary_file()
+{
+	int i,c;
+	fprintf(header,"#define APPLICATION_HAS_RESOURCES 1\n");
+	fprintf(code,"char _Application_resources[]={");
+	for(i=0;;i++)
+	{
+		c=getchar();
+		if(c==-1)break;
+		if(i%16==0)fputc('\n',code);
+		fprintf(code,"%3d,",c);
+	}
+	fprintf(code,"\n0}\nint _Aplication_resources_size=%d;\n",i);
+}
 
 /* SunOS' memcpy is wrong for overlapping arrays */
 char *save_memcpy(char *d,char* s,int l)
diff --git a/toolkit/heap.c b/toolkit/heap.c
index d20be76..c1584c7 100644
--- a/toolkit/heap.c
+++ b/toolkit/heap.c
@@ -115,7 +115,7 @@
     return 1;
 }
 
-char *LocalLock (HANDLE hMem)
+WORD LocalLock (HANDLE hMem)
 {
     void **m = HEAP_FindSlot (hMem);
 #ifdef DEBUG_HEAP
diff --git a/toolkit/sup.c b/toolkit/sup.c
index ef95120..25ab9f1 100644
--- a/toolkit/sup.c
+++ b/toolkit/sup.c
@@ -4,6 +4,7 @@
 #include "callback.h"
 #include "wine.h"
 #include "arch.h"
+#include "neexe.h"
 
 LONG CallWindowProc (WNDPROC func, HWND hwnd, WORD message,
 		     WORD wParam, LONG lParam)
@@ -24,9 +25,8 @@
 void load_mz_header (int fd, struct mz_header_s *mz_header)
 {
 #define TAB mz_header
-    LOAD (dont_care1);
-    LOAD (must_be_0x40);
-    LOAD (dont_care2);
+	LOAD (mz_magic);
+    LOAD (dont_care);
     LOADSHORT (ne_offset);
 }
 
@@ -34,7 +34,7 @@
 {
 #undef TAB
 #define TAB ne_header
-    LOAD (header_type);
+    LOAD (ne_magic);
     LOADSHORT (linker_version);
     LOADSHORT (linker_revision);
     LOADSHORT (entry_tab_offset);
diff --git a/toolkit/winmain.c b/toolkit/winmain.c
index 41da3ae..f5bd227 100644
--- a/toolkit/winmain.c
+++ b/toolkit/winmain.c
@@ -10,6 +10,8 @@
     char filename [4096], *module_name, *resource_file;
     HANDLE hTaskMain, hInstance;
     
+	/* The libwine resource DLL is temporarily disabled */
+#if 0
     if ((module_name = strchr (argv [0], '/')) == NULL){
 	printf ("Error: Can't determine base name for resource loading\n");
 	return 0;
@@ -20,9 +22,12 @@
     strcat (resource_file, ".dll");
 
     hInstance = LoadImage (resource_file, 0, 0);
+#endif
     
     USER_InitApp( hInstance );
+#if 0
     hTaskMain = CreateNewTask (1); /* This is not correct */
+#endif
     ret_val = WinMain (hInstance,	/* hInstance */
 		       0,		/* hPrevInstance */
 		       "",		/* lpszCmdParam */
diff --git a/tools/build.c b/tools/build.c
index eee4aac..e88bbd9 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1544,7 +1544,9 @@
     {
         /* Set ax equal to ds for window procedures */
         printf( "\tmovw 16(%%ebx),%%ax\n" );
-/*        printf( "\tmovw %%ax,%%ds\n" ); */
+
+        /* This seems to be needed, although I still don't see why... */
+        printf( "\tmovw %%ax,%%ds\n" );
     }
 
     /* Jump to the called routine */
diff --git a/windows/graphics.c b/windows/graphics.c
index 26ba7b3..bbc674b 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -332,9 +332,8 @@
  *           RoundRect    (GDI.28)
  */
 BOOL RoundRect( HDC hDC, short left, short top, short right, short bottom,
-					short ell_width, short ell_height)
+                short ell_width, short ell_height )
 {
-    int		x1, y1, x2, y2;
     DC * dc = (DC *) GDI_GetObjPtr(hDC, DC_MAGIC);
     if (!dc) 
     {
@@ -346,59 +345,103 @@
     }
     dprintf_graphics(stddeb, "RoundRect(%d %d %d %d  %d %d\n", 
     	left, top, right, bottom, ell_width, ell_height);
-    x1 = XLPTODP(dc, left);
-    y1 = YLPTODP(dc, top);
-    x2 = XLPTODP(dc, right - ell_width);
-    y2 = YLPTODP(dc, bottom - ell_height);
+
+    left   = XLPTODP( dc, left );
+    top    = YLPTODP( dc, top );
+    right  = XLPTODP( dc, right );
+    bottom = YLPTODP( dc, bottom );
+    ell_width  = abs( ell_width * dc->w.VportExtX / dc->w.WndExtX );
+    ell_height = abs( ell_height * dc->w.VportExtY / dc->w.WndExtY );
+
+    /* Fix the coordinates */
+
+    if (left > right) { short t = left; left = right; right = t; }
+    if (top > bottom) { short t = top; top = bottom; bottom = t; }
+    if (ell_width > right - left) ell_width = right - left;
+    if (ell_height > bottom - top) ell_height = bottom - top;
+
     if (DC_SetupGCForBrush( dc ))
     {
-	XFillArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x1, dc->w.DCOrgY + y1,
-		        ell_width, ell_height, 90 * 64, 90 * 64);
-	XFillArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x1, dc->w.DCOrgY + y2,
-		        ell_width, ell_height, 180 * 64, 90 * 64);
-	XFillArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x2, dc->w.DCOrgY + y2,
-		        ell_width, ell_height, 270 * 64, 90 * 64);
-	XFillArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x2, dc->w.DCOrgY + y1,
-		        ell_width, ell_height, 0, 90 * 64);
-	ell_width /= 2;  ell_height /= 2;
-	XFillRectangle(display, dc->u.x.drawable, dc->u.x.gc,
-		dc->w.DCOrgX + left + ell_width, dc->w.DCOrgY + top,
-		right - left - 2 * ell_width, bottom - top);
-	XFillRectangle(display, dc->u.x.drawable, dc->u.x.gc,
-		dc->w.DCOrgX + left, dc->w.DCOrgY + top + ell_height,
-		ell_width, bottom - top - 2 * ell_height);
-	XFillRectangle(display, dc->u.x.drawable, dc->u.x.gc,
-		dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top + ell_height,
-		ell_width, bottom - top - 2 * ell_height);
-	ell_width *= 2;  ell_height *= 2;
-	}    	
-    if (DC_SetupGCForPen(dc)) {
-	XDrawArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x1, dc->w.DCOrgY + y1,
-		        ell_width, ell_height, 90 * 64, 90 * 64);
-	XDrawArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x1, dc->w.DCOrgY + y2,
-		        ell_width, ell_height, 180 * 64, 90 * 64);
-	XDrawArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x2, dc->w.DCOrgY + y2,
-		        ell_width, ell_height, 270 * 64, 90 * 64);
-	XDrawArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x2, dc->w.DCOrgY + y1,
-		        ell_width, ell_height, 0, 90 * 64);
+        if (ell_width && ell_height)
+        {
+            XFillArc( 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,
+                      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,
+                      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,
+                      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,
+                            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,
+                            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,
+                            dc->w.DCOrgX + left,
+                            dc->w.DCOrgY + top + ell_height / 2,
+                            right - left, bottom - top - ell_height );
+        }
+    }
+    if (DC_SetupGCForPen(dc))
+    {
+        if (ell_width && ell_height)
+        {
+            XDrawArc( 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,
+                      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,
+                      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,
+                      dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top,
+                      ell_width, ell_height, 0, 90 * 64 );
 	}
-    ell_width /= 2;  ell_height /= 2;
-    MoveTo(hDC, left, top + ell_height);
-    LineTo(hDC, left, bottom - ell_height);
-    MoveTo(hDC, left + ell_width, bottom);
-    LineTo(hDC, right - ell_width, bottom);
-    MoveTo(hDC, right, bottom - ell_height);
-    LineTo(hDC, right, top + ell_height);
-    MoveTo(hDC, right - ell_width, top);
-    LineTo(hDC, left + ell_width, top);
+        if (ell_width < right - left)
+        {
+            XDrawLine( 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, 
+                       dc->w.DCOrgX + left + ell_width / 2,
+                       dc->w.DCOrgY + bottom,
+                       dc->w.DCOrgX + right - ell_width / 2,
+                       dc->w.DCOrgY + bottom );
+        }
+        if (ell_height < bottom - top)
+        {
+            XDrawLine( 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, 
+                       dc->w.DCOrgX + left,
+                       dc->w.DCOrgY + top + ell_height / 2,
+                       dc->w.DCOrgX + left,
+                       dc->w.DCOrgY + bottom - ell_height / 2 );
+        }
+    }
     return TRUE;
 }
 
diff --git a/windows/hook.c b/windows/hook.c
index 257b754..d4fe2eb 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -152,6 +152,6 @@
 DWORD CallNextHookEx( HHOOK hhook, short code, WPARAM wParam, LPARAM lParam )
 {
     HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
-    if (!data->next) return 0;
+    if (data == NULL || !data->next) return 0;
     else return INTERNAL_CALL_HOOK( data->next, code, wParam, lParam );
 }
diff --git a/windows/message.c b/windows/message.c
index 8135724..37a869c 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -183,6 +183,82 @@
 
 
 /***********************************************************************
+ *           MSG_GetWindowForEvent
+ *
+ * Find the window and hittest for a mouse event.
+ */
+static INT MSG_GetWindowForEvent( POINT pt, HWND *phwnd )
+{
+    WND *wndPtr;
+    HWND hwnd;
+    INT hittest, x, y;
+
+    *phwnd = hwnd = GetDesktopWindow();
+    x = pt.x;
+    y = pt.y;
+    while (hwnd)
+    {
+	  /* If point is in window, and window is visible, and it  */
+          /* is enabled (or it's a top-level window), then explore */
+	  /* its children. Otherwise, go to the next window.       */
+
+	wndPtr = WIN_FindWndPtr( hwnd );
+	if ((wndPtr->dwStyle & WS_VISIBLE) &&
+            (!(wndPtr->dwStyle & WS_DISABLED) ||
+             !(wndPtr->dwStyle & WS_CHILD)) &&
+            (x >= wndPtr->rectWindow.left) &&
+            (x < wndPtr->rectWindow.right) &&
+	    (y >= wndPtr->rectWindow.top) &&
+            (y < wndPtr->rectWindow.bottom))
+	{
+	    *phwnd = hwnd;
+              /* If window is minimized or disabled, ignore its children */
+            if ((wndPtr->dwStyle & WS_MINIMIZE) ||
+                (wndPtr->dwStyle & WS_DISABLED)) break;
+	    x -= wndPtr->rectClient.left;
+	    y -= wndPtr->rectClient.top;
+	    hwnd = wndPtr->hwndChild;
+	}
+	else hwnd = wndPtr->hwndNext;
+    }
+
+
+    /* Send the WM_NCHITTEST message */
+
+    while (*phwnd)
+    {
+        wndPtr = WIN_FindWndPtr( *phwnd );
+        if (wndPtr->dwStyle & WS_DISABLED) hittest = HTERROR;
+        else hittest = (INT)SendMessage( *phwnd, WM_NCHITTEST, 0,
+                                         MAKELONG( pt.x, pt.y ) );
+        if (hittest != HTTRANSPARENT) break;  /* Found the window */
+        hwnd = wndPtr->hwndNext;
+        while (hwnd)
+        {
+            wndPtr = WIN_FindWndPtr( hwnd );
+            if ((wndPtr->dwStyle & WS_VISIBLE) &&
+                (x >= wndPtr->rectWindow.left) &&
+                (x < wndPtr->rectWindow.right) &&
+                (y >= wndPtr->rectWindow.top) &&
+                (y < wndPtr->rectWindow.bottom)) break;
+            hwnd = wndPtr->hwndNext;
+        }
+        if (hwnd) *phwnd = hwnd; /* Found a suitable sibling */
+        else  /* Go back to the parent */
+        {
+            *phwnd = WIN_FindWndPtr( *phwnd )->hwndParent;
+            wndPtr = WIN_FindWndPtr( *phwnd );
+            x += wndPtr->rectClient.left;
+            y += wndPtr->rectClient.top;
+        }
+    }
+
+    if (!*phwnd) *phwnd = GetDesktopWindow();
+    return hittest;
+}
+
+
+/***********************************************************************
  *           MSG_TranslateMouseMsg
  *
  * Translate an mouse hardware event into a real mouse message.
@@ -218,20 +294,7 @@
 	ScreenToClient( msg->hwnd, (LPPOINT)&msg->lParam );
 	return TRUE;  /* No need to further process the message */
     }
-    else msg->hwnd = WindowFromPoint( msg->pt );
-
-      /* Send the WM_NCHITTEST message */
-
-    hittest_result = (INT)SendMessage( msg->hwnd, WM_NCHITTEST, 0,
-                                       MAKELONG( msg->pt.x, msg->pt.y ) );
-    while ((hittest_result == HTTRANSPARENT) && (msg->hwnd))
-    {
-	msg->hwnd = WINPOS_NextWindowFromPoint( msg->hwnd, msg->pt );
-	if (msg->hwnd)
-	    hittest_result = (INT)SendMessage( msg->hwnd, WM_NCHITTEST, 0,
-                                             MAKELONG( msg->pt.x, msg->pt.y ));
-    }
-    if (!msg->hwnd) msg->hwnd = GetDesktopWindow();
+    else hittest_result = MSG_GetWindowForEvent( msg->pt, &msg->hwnd );
 
       /* Send the WM_PARENTNOTIFY message */
 
diff --git a/windows/painting.c b/windows/painting.c
index 774081a..e29056e 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -39,8 +39,8 @@
 
     if (wndPtr->flags & WIN_NEEDS_NCPAINT)
     {
-        SendMessage( hwnd, WM_NCPAINT, 0, 0 );
         wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
+        SendMessage( hwnd, WM_NCPAINT, 0, 0 );
     }
 
     lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_USESTYLE );
@@ -56,8 +56,8 @@
 
     if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
     {
-        lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
         wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
+        lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
     }
     else lps->fErase = TRUE;
 
@@ -225,8 +225,8 @@
     {
         if (wndPtr->flags & WIN_NEEDS_NCPAINT)
         {
-            SendMessage( hwnd, WM_NCPAINT, 0, 0 );
             wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
+            SendMessage( hwnd, WM_NCPAINT, 0, 0 );
         }
         if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
         {
diff --git a/windows/win.c b/windows/win.c
index 6add88a..aad3546 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -892,11 +892,15 @@
 /***********************************************************************
  *           IsWindowVisible   (USER.49)
  */
-BOOL IsWindowVisible(HWND hWnd)
+BOOL IsWindowVisible( HWND hwnd )
 {
-    WND * wndPtr = WIN_FindWndPtr(hWnd);
-    if (wndPtr == 0) return(FALSE);
-    else return ((wndPtr->dwStyle & WS_VISIBLE) != 0);
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
+    {
+        if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
+        wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
+    }
+    return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
 }
 
  
diff --git a/windows/winpos.c b/windows/winpos.c
index bab8113..b241afc 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -531,32 +531,6 @@
 
 
 /*******************************************************************
- *         WINPOS_NextWindowFromPoint
- *
- *  Looks for next enabled window that is
- *  a) sibling of hwnd, later in Z-order and encloses pt, or
- *  b) parent of hwnd
- */
-HWND WINPOS_NextWindowFromPoint( HWND hwnd, POINT pt )
-{
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-
-    if (!wndPtr->hwndParent) return hwnd;  /* desktop window */
-    ScreenToClient( wndPtr->hwndParent, &pt ); /* make pt relative to parent */
-    for (;;)
-    {
-        if (!wndPtr->hwndNext) break;  /* No more children */
-        hwnd = wndPtr->hwndNext;
-        wndPtr = WIN_FindWndPtr( hwnd );
-        if ((wndPtr->dwStyle & WS_VISIBLE) &&
-            !(wndPtr->dwStyle & WS_DISABLED) &&
-            PtInRect( &wndPtr->rectWindow, pt )) return hwnd;
-    }
-    return wndPtr->hwndParent;
-}
-
-
-/*******************************************************************
  *         WINPOS_ChangeActiveWindow
  *
  * Change the active window and send the corresponding messages.