diff --git a/ANNOUNCE b/ANNOUNCE
index cf7b48e7d0ad87d60fd07490e7f8ad7eaea08422..85363a8c12a55018416f235b1022d6715f54268b 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,13 +1,13 @@
-This is release 960728 of Wine, the MS Windows emulator.  This is still a
+This is release 960805 of Wine, the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work correctly.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-960728: (see ChangeLog for details)
-	- Many fixed to the palette management.
-	- DOS real-mode memory emulation.
+WHAT'S NEW with Wine-960805: (see ChangeLog for details)
+	- More metafile features.
+	- Some more Win32 code.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -16,10 +16,10 @@ Because of lags created by using mirror, this message may reach you before
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960728.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960728.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960728.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960728.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960805.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960805.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960805.tar.gz
+    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960805.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 43a3c8f85cf91319351e2cc20f53232b75f5baaf..7ce0a96ce4866824567cbfac8e18b74d2eb903d0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,125 @@
+----------------------------------------------------------------------
+Sun Aug  4 18:18:48 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [controls/scroll.c]
+	Attempted to implement undocumented scroll-bar messages.
+
+	* [tools/build.c] [include/callback.h] [windows/winproc.c]
+	CallTo16_* functions now get DS from the previous 16-bit stackframe.
+
+	* [if1632/thunk.c] [include/callback.h]
+	Added thunks to implement callbacks for the emulator. Now all the
+	Enum* functions always take a real function pointer even in the
+	emulator.
+	
+	* [loader/builtin.c]
+	Removed binary search in BUILTIN_GetEntryPoint32(), as it didn't
+ 	work with NULL entry points. Using linear search now.
+
+	* [loader/module.c]
+	Implemented IsSharedSelector().
+
+	* [loader/task.c]
+	Changed SwitchStackTo/Back to use the instance data to store the
+	previous stack instead of the TDB. Also copy the local variables
+	onto the new stack.
+	Added GetExeVersion() and SetTackSignalProc().
+	Implemented SetSigHandler().
+
+Sat Aug  3 22:19:00 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>
+
+	* [controls/menu.c]
+	"Fixed" problem in deleting menus where win32 could get into an
+	endless loop when it crashed. I think I've fixed the symptoms, not
+	the original problem so it might be worth further investigation.
+
+	* [debugger/registers.c]
+	Added missing #ifdefs on FS_REG and GS_REG, needed for FreeBSD to
+	compile wine properly.
+
+	* [files/dos_fs.c]
+	Made DOSFS_Hash and DOSFS_Match non-static so they can be called
+	from win32/findfile.c (q.v.).
+
+	* [if1632/gdi32.spec]
+	Added SetMapMode (call existing function)
+
+	* [if1632/kernel32.spec]
+	Added FindFirstFileA and SetFileAttributesA.
+
+	* [if1632/user32.spec]
+	Added BringWindowToTop, CreatePopupMenu, GetKeyState, GetParent,
+	IsDlgButtonChecked (call existing functions) and IsDialogMessageA,
+	UnhookWindowsHookEx.
+
+	* [win32/file.c]
+	Added stub function SetFileAttributes32A. It's a stub because I
+	can't really work out what this function should do with most
+	attributes in a Unix environment. Anyone care to expand it?
+
+	* [win32/findfile.c]
+	New file. Initial stab at FindFirstFile. This doesn't work as
+	specified yet, though a lot of the groundwork is there. I haven't
+	time to work on this for the next month, so if anyone wants to pick
+	it up and run with it please do.
+
+	* [win32/memory.c]
+	Removed malloc.h from includes (covered by stdlib.h include, and
+	gets rid of a warning in FreeBSD).
+
+	* [win32/newfns.c]
+	UnhookWindowsHookEx32A stub added.
+
+	* [win32/user32.c]
+	Added implementation of IsDialogMessage32A.
+
+	* [windows/dialog.c]
+	IsDlgButtonChecked now calls SendDlgItemMessage32A instead of
+	SendDlgItemMessage16.
+
+Sat Aug  3 18:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>
+
+	* [windows/graphics.c]
+	Removed rectangle checking (conflicted with nonstandard
+	mapping modes). 
+
+	* [windows/dialog.c]
+	Added check for child-style dialogs to DS_ABSALIGN
+	coordinate conversion.
+
+	* [objects/color.c]
+	Cleaned up misc. bits
+
+Thu Aug  1 10:51:45 1996  Andrew Lewycky <plewycky@oise.utoronto.ca>
+
+	* [windows/focus.c] [windows/event.c] [windows/win.c]
+	  [windows/defdlg.c]
+	Fixes to focusing and activation.
+
+	* [windows/defdlg.c]
+	Properly(?) handle DM_GETDEFID.
+
+	* [controls/combo.c]
+	Handle CB_FINDSTRINGEXACT, CB_SETEDITSEL, CB_GETEDITSEL.
+	CBCheckSize: Adjust edit position.
+
+Tue Jul 30 09:46:36 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [files/file.c] [include/file.h] [loader/module.c] [loader/ne_image.c]
+	Pass HFILEs instead of unix-fds to self-loader code.
+
+Mon Jul 29 21:48:25 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [include/metafile.h] [objects/metafile.c] [objects/text.c]
+	Implemented handling of some new metafile records (META_...)
+	in PlayMetaFileRecord(), rewrite of 'case META_EXTTEXTOUT'.
+	Added functions like MF_StretchBlt() for usage in metafiles.
+	Minor bugfix in CopyMetafile().
+
+	* [objects/bitmap.c][objects/dib.c]
+	Added check for metafile-DC in Bitmap and DIB functions:
+	CreateCompatibleBitmap() etc.
+
 ----------------------------------------------------------------------
 Sun Jul 28 17:57:19 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
diff --git a/controls/combo.c b/controls/combo.c
index 4990654d595b64252a8829d4c88440bad9562124..d7563a9d7bc2e36eb3f943f6719ee7bfdac304c2 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -15,10 +15,10 @@
 
 #include "windows.h"
 #include "sysmetrics.h"
+#include "win.h"
 #include "combo.h"
 #include "stackframe.h"
 #include "user.h"
-#include "win.h"
 #include "graphics.h"
 #include "heap.h"
 #include "listbox.h"
@@ -468,6 +468,15 @@ static LRESULT CBFindString(HWND hwnd, WPARAM wParam, LPARAM lParam)
   return ListBoxFindString(lphl, wParam, (SEGPTR)lParam);
 }
 
+/***********************************************************************
+ *           CBFindStringExact
+ */
+static LRESULT CBFindStringExact(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+  LPHEADLIST lphl = ComboGetListHeader(hwnd);
+  return ListBoxFindStringExact(lphl, wParam, (SEGPTR)lParam);
+}
+
 /***********************************************************************
  *           CBGetCount
  */
@@ -621,7 +630,7 @@ static BOOL CBCheckSize(HWND hwnd)
   LPHEADCOMBO  lphc = ComboGetStorageHeader(hwnd);
   LPHEADLIST   lphl = ComboGetListHeader(hwnd);
   LONG         cstyle = GetWindowLong32A(hwnd,GWL_STYLE);
-  RECT16       cRect,wRect;
+  RECT16       cRect, wRect;
 
   if (lphc->hWndLBox == 0) return FALSE;
 
@@ -632,9 +641,9 @@ static BOOL CBCheckSize(HWND hwnd)
 	 "CBCheckSize: hwnd %04x Rect %d,%d-%d,%d  wRect %d,%d-%d,%d\n", 
 		hwnd,cRect.left,cRect.top,cRect.right,cRect.bottom,
 		wRect.left,wRect.top,wRect.right,wRect.bottom);
-  if ((cstyle & 3) == CBS_SIMPLE  ) return TRUE ;
+  if ((cstyle & 3) == CBS_SIMPLE) return TRUE;
 
-  if ((cRect.bottom - cRect.top) > 
+  if ((cRect.bottom - cRect.top) >
       (lphl->StdItemHeight + 2*SYSMETRICS_CYBORDER)) {
     SetWindowPos(hwnd, 0, 0, 0, 
 		 cRect.right-cRect.left,
@@ -651,7 +660,7 @@ static BOOL CBCheckSize(HWND hwnd)
   }
 
   if (cRect.right < lphc->RectButton.left) {
-    /* if the button is outside the window, move it in */
+    /* if the button is outside the window move it in */
     if ((wRect.right - wRect.left - 2*SYSMETRICS_CXBORDER) == (cRect.right - cRect.left)) {
       lphc->RectButton.right = cRect.right;
       lphc->RectButton.left = cRect.right - 2*SYSMETRICS_CXBORDER - 4 
@@ -662,8 +671,13 @@ static BOOL CBCheckSize(HWND hwnd)
     /* otherwise we need to make the client include the button */
     else
       SetWindowPos(hwnd, 0, 0, 0, lphc->RectButton.right,
-		   lphl->StdItemHeight+2*SYSMETRICS_CYBORDER, 
-		   SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE );
+		   lphl->StdItemHeight+2*SYSMETRICS_CYBORDER,
+		   SWP_NOMOVE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOACTIVATE);
+
+      if ((lphc->dwStyle & 3) != CBS_DROPDOWNLIST)
+        SetWindowPos(lphc->hWndEdit, 0, 0, 0, lphc->RectButton.left,
+		     lphl->StdItemHeight,
+		     SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
   }
 
   CBLCheckSize(hwnd);
@@ -727,6 +741,34 @@ static LRESULT CBCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
 }
 
 
+/***********************************************************************
+ *           CBGetEditSel
+ * Look out! Under Win32, the parameter packing is very different.
+ */
+static LRESULT CBGetEditSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+
+    if ((lphc->dwStyle & 3) == CBS_DROPDOWNLIST)
+      return CB_ERR;	/* err, documented for CBSetEditSel */
+    return SendMessage16(lphc->hWndEdit, EM_GETSEL, 0, 0);
+}
+
+
+/***********************************************************************
+ *           CBSetEditSel
+ * Look out! Under Win32, the parameter packing is very different.
+ */
+static LRESULT CBSetEditSel(HWND hwnd, WPARAM wParam, LPARAM lParam)
+{
+    LPHEADCOMBO lphc = ComboGetStorageHeader(hwnd);
+
+    if ((lphc->dwStyle & 3) == CBS_DROPDOWNLIST)
+      return CB_ERR;
+    return SendMessage16(lphc->hWndEdit, EM_SETSEL, 0, lParam);
+}
+
+
 /***********************************************************************
  *           ComboWndProc
  */
@@ -764,6 +806,9 @@ LRESULT ComboBoxWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM 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);
+     case CB_GETEDITSEL: return CBGetEditSel(hwnd, wParam, lParam);
+     case CB_SETEDITSEL: return CBSetEditSel(hwnd, wParam, lParam);
+     case CB_FINDSTRINGEXACT: return CBFindStringExact(hwnd, wParam, lParam);
     }
     return DefWindowProc16(hwnd, message, wParam, lParam);
 }
diff --git a/controls/menu.c b/controls/menu.c
index e38a4cd7026be7d1a4af8971acf6d30953e6546d..a83db51b6f4c622ba7cfc5577b7f0a8953565e2a 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -1859,7 +1859,7 @@ UINT MENU_GetMenuBarHeight( HWND hwnd, UINT menubarWidth, int orgX, int orgY )
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
     if (!(lppop = (LPPOPUPMENU)USER_HEAP_LIN_ADDR((HMENU)wndPtr->wIDmenu)))
       return 0;
-    hdc = GetDC( hwnd );
+    hdc = GetDCEx( hwnd, 0, DCX_CACHE | DCX_WINDOW );
     SetRect16(&rectBar, orgX, orgY, orgX+menubarWidth, orgY+SYSMETRICS_CYMENU);
     MENU_MenuBarCalcSize( hdc, &rectBar, lppop, hwnd );
     ReleaseDC( hwnd, hdc );
@@ -2353,7 +2353,7 @@ BOOL DestroyMenu(HMENU hMenu)
     lppop = (LPPOPUPMENU) USER_HEAP_LIN_ADDR(hMenu);
     if (!lppop || (lppop->wMagic != MENU_MAGIC)) return FALSE;
     lppop->wMagic = 0;  /* Mark it as destroyed */
-    if ((lppop->wFlags & MF_POPUP) && lppop->hWnd && lppop->hWnd != pTopPWnd->hwndSelf )
+    if ((lppop->wFlags & MF_POPUP) && lppop->hWnd && (!pTopPWnd || (lppop->hWnd != pTopPWnd->hwndSelf)))
         DestroyWindow( lppop->hWnd );
 
     if (lppop->items)
diff --git a/controls/scroll.c b/controls/scroll.c
index 649c81f01d608f3e271077a9f8c552c7d29acf17..c54421c52dad3cdc366c9bc66f659fd78c2d4b0e 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -797,12 +797,23 @@ LONG ScrollBarWndProc( HWND hwnd, WORD message, WORD wParam, LONG lParam )
         }
         break;
 
-    case 0x400: /* SB_SETSCROLLPOS */
-    case 0x401: /* SB_GETSCROLLPOS */
-    case 0x402: /* SB_GETSCROLLRANGE */
-    case 0x403: /* SB_ENABLE */
-    case 0x404: /* SB_REDRAW */
+    case SBM_SETSCROLLPOS:
+        return SetScrollPos( hwnd, SB_CTL, wParam, (BOOL)lParam );
+
+    case SBM_GETSCROLLPOS:
+        return GetScrollPos( hwnd, SB_CTL );
+
+    case SBM_SETSCROLLRANGE:
+        SetScrollRange( hwnd, SB_CTL, LOWORD(lParam), HIWORD(lParam),
+                        wParam  /* FIXME: Is this correct? */ );
+        return 0;
+
+    case SBM_ENABLE:
+        return EnableScrollBar( hwnd, SB_CTL, wParam ); /* FIXME: lParam? */
+
+    case 0x403: /* SBM_REDRAW */
         fprintf(stdnimp,"ScrollBarWndProc: undocumented message %04x, please report\n", message );
+        break;
 
     default:
         return DefWindowProc16( hwnd, message, wParam, lParam );
diff --git a/debugger/registers.c b/debugger/registers.c
index 66b38f337e1f212cfa5b0c753a5373a7cf25eb71..4545d784e034c53a10e3424e5ed64dc56ccc2559 100644
--- a/debugger/registers.c
+++ b/debugger/registers.c
@@ -46,14 +46,14 @@ void DEBUG_SetRegister( enum debug_regs reg, int val )
         case REG_FS:  FS_reg(DEBUG_context)  = val; break;
 #else
         case REG_FS:
-            fprintf( stderr, "Register %fs not supported on this system\n ");
+            fprintf( stderr, "Register %fs not supported on this system\n" );
             break;
 #endif
 #ifdef GS_reg
         case REG_GS:  GS_reg(DEBUG_context)  = val; break;
 #else
         case REG_GS:
-            fprintf( stderr, "Register %gs not supported on this system\n ");
+            fprintf( stderr, "Register %gs not supported on this system\n" );
             break;
 #endif
     }
@@ -97,14 +97,14 @@ int DEBUG_GetRegister( enum debug_regs reg )
         case REG_FS:  return FS_reg(DEBUG_context);
 #else
         case REG_FS:
-            fprintf( stderr, "Register %fs not supported on this system\n ");
+            fprintf( stderr, "Register %fs not supported on this system\n" );
             return 0;
 #endif
 #ifdef GS_reg
         case REG_GS:  return GS_reg(DEBUG_context);
 #else
         case REG_GS:
-            fprintf( stderr, "Register %gs not supported on this system\n ");
+            fprintf( stderr, "Register %gs not supported on this system\n" );
             return 0;
 #endif
     }
@@ -182,10 +182,14 @@ BOOL32 DEBUG_ValidateRegisters(void)
         CHECK_SEG( DS_reg(DEBUG_context), "DS" );
     if (ES_reg(DEBUG_context) != WINE_DATA_SELECTOR)
         CHECK_SEG( ES_reg(DEBUG_context), "ES" );
+#ifdef FS_reg
     if (FS_reg(DEBUG_context) != WINE_DATA_SELECTOR)
         CHECK_SEG( FS_reg(DEBUG_context), "FS" );
+#endif
+#ifdef GS_reg
     if (GS_reg(DEBUG_context) != WINE_DATA_SELECTOR)
         CHECK_SEG( GS_reg(DEBUG_context), "GS" );
+#endif
 
     /* Check that CS and SS are not NULL */
 
diff --git a/files/dos_fs.c b/files/dos_fs.c
index e2086eccbe19fee48a8b5254e424c6b4ae3a425f..e0a1e17f3f64f6773708e61d6997e0f757e56361 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -247,7 +247,7 @@ const char *DOSFS_ToDosDTAFormat( const char *name )
  *
  * Check a DOS file name against a mask (both in FCB format).
  */
-static int DOSFS_Match( const char *mask, const char *name )
+int DOSFS_Match( const char *mask, const char *name )
 {
     int i;
     for (i = 11; i > 0; i--, mask++, name++)
@@ -280,7 +280,7 @@ void DOSFS_ToDosDateTime( time_t unixtime, WORD *pDate, WORD *pTime )
  * hashed version that fits in 8.3 format.
  * File name can be terminated by '\0', '\\' or '/'.
  */
-static const char *DOSFS_Hash( const char *name, int dir_format )
+const char *DOSFS_Hash( const char *name, int dir_format )
 {
     static const char invalid_chars[] = INVALID_DOS_CHARS "~.";
     static const char hash_chars[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
diff --git a/files/file.c b/files/file.c
index 2ea02e3be8a076ae3e0c132ef785d8624eab3353..940ebe1ebebe9c1dee4e8e34beeb663271e11e1b 100644
--- a/files/file.c
+++ b/files/file.c
@@ -282,6 +282,29 @@ void FILE_SetDosError(void)
 }
 
 
+/***********************************************************************
+ *           FILE_DupUnixHandle
+ *
+ * Duplicate a Unix handle into a task handle.
+ */
+HFILE FILE_DupUnixHandle( int fd )
+{
+    HFILE handle;
+    DOS_FILE *file;
+
+    if (!(file = FILE_Alloc())) return HFILE_ERROR;
+    if ((file->unix_handle = dup(fd)) == -1)
+    {
+        FILE_SetDosError();
+        FILE_Close( file );
+        return HFILE_ERROR;
+    }
+    if ((handle = FILE_AllocTaskHandle( file )) == HFILE_ERROR)
+        FILE_Close( file );
+    return handle;
+}
+
+
 /***********************************************************************
  *           FILE_OpenUnixFile
  */
diff --git a/if1632/Makefile.in b/if1632/Makefile.in
index 3774434764604d00ebe4e2eca061b5edbff80060..5eb7110629cdc1ae4673b1553bcd13e3bfe85f78 100644
--- a/if1632/Makefile.in
+++ b/if1632/Makefile.in
@@ -51,7 +51,8 @@ SPEC_FILES = $(DLLS:.spec=.S)
 
 C_SRCS = \
 	dummy.c \
-	relay.c
+	relay.c \
+	thunk.c
 
 ASM_SRCS = \
 	$(SPEC_FILES) \
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index 24b13b825dad4ec03e35e37afce8f9c23b215136..b7e804e27450a3c93384bb03adf38e47280c8ed3 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -77,8 +77,8 @@ heap	65488  # 65536 - 16 (instance data) - 32 (stock objects)
 67  pascal16 DPtoLP(word ptr s_word) DPtoLP16
 68  pascal16 DeleteDC(word) DeleteDC
 69  pascal16 DeleteObject(word) DeleteObject
-70  pascal16 EnumFonts(word ptr segptr long) EnumFonts
-71  pascal16 EnumObjects(word word segptr long) EnumObjects
+70  pascal16 EnumFonts(word ptr segptr long) THUNK_EnumFonts16
+71  pascal16 EnumObjects(word word segptr long) THUNK_EnumObjects16
 72  pascal16 EqualRgn(word word) EqualRgn
 73  pascal16 ExcludeVisRect(word s_word s_word s_word s_word) ExcludeVisRect
 74  pascal GetBitmapBits(word long ptr) GetBitmapBits
@@ -108,7 +108,7 @@ heap	65488  # 65536 - 16 (instance data) - 32 (stock objects)
 98  pascal16 IntersectVisRect(word s_word s_word s_word s_word)
              IntersectVisRect
 99  pascal16 LPtoDP(word ptr s_word) LPtoDP16
-100 pascal16 LineDDA(s_word s_word s_word s_word segptr long) LineDDA
+100 pascal16 LineDDA(s_word s_word s_word s_word segptr long) THUNK_LineDDA16
 101 pascal16 OffsetRgn(word s_word s_word) OffsetRgn
 102 pascal16 OffsetVisRgn(word s_word s_word) OffsetVisRgn
 103 pascal16 PtVisible(word s_word s_word) PtVisible
@@ -150,7 +150,7 @@ heap	65488  # 65536 - 16 (instance data) - 32 (stock objects)
 170 stub SetDCStatus
 172 pascal16 SetRectRgn(word s_word s_word s_word s_word) SetRectRgn
 173 pascal16 GetClipRgn(word) GetClipRgn
-175 pascal16 EnumMetaFile(word word segptr long) EnumMetaFile
+175 pascal16 EnumMetaFile(word word segptr long) THUNK_EnumMetaFile16
 176 pascal16 PlayMetaFileRecord(word ptr ptr word) PlayMetaFileRecord
 179 pascal16 GetDCState(word) GetDCState
 180 pascal16 SetDCState(word word) SetDCState
@@ -227,7 +227,7 @@ heap	65488  # 65536 - 16 (instance data) - 32 (stock objects)
 315 stub EngineRealizeFontExt
 316 stub EngineGetCharWidthStr
 317 stub EngineGetGlyphBmpExt
-330 pascal16 EnumFontFamilies(word ptr segptr long) EnumFontFamilies
+330 pascal16 EnumFontFamilies(word ptr segptr long) THUNK_EnumFontFamilies16
 332 pascal16 GetKerningPairs(word word ptr) GetKerningPairs
 345 pascal16 GetTextAlign(word) GetTextAlign
 346 pascal16 SetTextAlign(word word) SetTextAlign
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index dca8d1bdf089d5fa6ea51310711f63795f8a42ce..9765459700b6e8669b9e1b1e3a6102e701519d1e 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -252,7 +252,7 @@ base	1
 0245 stub IntersectClipRect
 0246 stub InvertRgn
 0247 stdcall LPtoDP(long ptr long) LPtoDP32
-0248 stub LineDDA
+0248 stdcall LineDDA(long long long long ptr long) THUNK_LineDDA32
 0249 stdcall LineTo(long long long) LineTo
 0250 stub LoadImageColorMatcherA
 0251 stub LoadImageColorMatcherW
@@ -326,7 +326,7 @@ base	1
 0318 stub SetICMMode
 0319 stub SetICMProfileA
 0320 stub SetICMProfileW
-0321 stub SetMapMode
+0321 stdcall SetMapMode(long long) SetMapMode
 0322 stub SetMapperFlags
 0323 stub SetMetaFileBitsEx
 0324 stub SetMetaRgn
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index ece398840182f5cc7f990fc083b538a7d63397ed..e7bf1770e1462cd921818f93fc82e6b1fb12079f 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -38,7 +38,7 @@ type	win16
 35  pascal16 GetTaskQueue(word) GetTaskQueue
 36  pascal   GetCurrentTask() WIN16_GetCurrentTask
 37  pascal GetCurrentPDB() GetCurrentPDB
-38  stub SetTaskSignalProc
+38  pascal   SetTaskSignalProc(word segptr) SetTaskSignalProc
 41  return EnableDos 0 0
 42  return DisableDos 0 0
 45  pascal16 LoadModule(ptr ptr) LoadModule
@@ -94,14 +94,14 @@ type	win16
 95  pascal16 LoadLibrary(ptr) LoadLibrary
 96  pascal16 FreeLibrary(word) FreeLibrary
 97  pascal16 GetTempFileName(byte ptr word ptr) GetTempFileName16
-98  stub GetLastDiskChange
+98  return GetLastDiskChange 0 0
 99  stub GetLPErrMode
 100 stub ValidateCodeSegments
 101 stub NoHookDosCall
 102 register DOS3Call() DOS3Call
 103 register NetBIOSCall() NetBIOSCall
 104 stub GetCodeInfo
-105 stub GetExeVersion
+105 pascal16 GetExeVersion() GetExeVersion
 106 pascal SetSwapAreaSize(word) SetSwapAreaSize
 107 pascal16 SetErrorMode(word) SetErrorMode
 108 pascal16 SwitchStackTo(word word word) SwitchStackTo
@@ -162,7 +162,7 @@ type	win16
 162 pascal16 LocalHeapSize() LocalHeapSize
 163 pascal16 GlobalLRUOldest(word) GlobalLRUOldest
 164 pascal16 GlobalLRUNewest(word) GlobalLRUNewest
-165 stub A20Proc
+165 return A20Proc 2 0
 166 pascal16 WinExec(ptr word) WinExec
 167 pascal16 GetExpWinVer(word) GetExpWinVer
 168 pascal16 DirectResAlloc(word word word) DirectResAlloc
@@ -252,7 +252,7 @@ type	win16
 342 stub __GP
 343 stub RegisterWinOldApHook
 344 stub GetWinOldApHooks
-345 stub IsSharedSelector
+345 pascal16 IsSharedSelector(word) IsSharedSelector
 346 pascal16 IsBadHugeReadPtr(segptr long) IsBadHugeReadPtr
 347 pascal16 IsBadHugeWritePtr(segptr long) IsBadHugeWritePtr
 348 pascal16 hmemcpy(ptr ptr long) hmemcpy
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 71833e49603b4693025ccab7d902b3a1d75f333e..0b9bd3aa9397bd6278a02066407bfc716356d3c5 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -125,7 +125,7 @@ base	1
 0120 stub FindCloseChangeNotification
 0121 stub FindFirstChangeNotificationA
 0122 stub FindFirstChangeNotificationW
-0123 stub FindFirstFileA
+0123 stdcall FindFirstFileA(ptr ptr) FindFirstFile32A
 0124 stub FindFirstFileW
 0125 stub FindNextChangeNotification
 0126 stub FindNextFileA
@@ -492,7 +492,7 @@ base	1
 0487 	stdcall	SetEvent(long) SetEvent
 0488 stub SetFileApisToANSI
 0489 stub SetFileApisToOEM
-0490 stub SetFileAttributesA
+0490 stdcall SetFileAttributesA(ptr long) SetFileAttributes32A
 0491 stub SetFileAttributesW
 0492    stdcall SetFilePointer(long long ptr long) SetFilePointer
 0493 stub SetFileTime
diff --git a/if1632/thunk.c b/if1632/thunk.c
new file mode 100644
index 0000000000000000000000000000000000000000..ae623da701db0637cf4d5a5bb9b261aaef331b9e
--- /dev/null
+++ b/if1632/thunk.c
@@ -0,0 +1,250 @@
+/*
+ * Emulator thunks
+ *
+ * Copyright 1996 Alexandre Julliard
+ */
+
+#include "windows.h"
+#include "callback.h"
+#include "heap.h"
+
+typedef void (*RELAY)();
+
+typedef struct
+{
+    BYTE       popl_eax;           /* 0x58  popl  %eax (return address) */
+    BYTE       pushl_func;         /* 0x68  pushl $proc */
+    FARPROC32  proc WINE_PACKED;
+    BYTE       pushl_eax;          /* 0x50  pushl %eax */
+    BYTE       jmp;                /* 0xe9  jmp   relay (relative jump)*/
+    RELAY      relay WINE_PACKED;
+} THUNK;
+
+#define DECL_THUNK(name,proc,relay) \
+    THUNK name = { 0x58, 0x68, (FARPROC32)(proc), 0x50, 0xe9, \
+                    (RELAY)((char *)(relay) - (char *)(&(name) + 1)) }
+
+
+/***********************************************************************
+ *           THUNK_Alloc
+ */
+static THUNK *THUNK_Alloc( FARPROC32 func, RELAY relay )
+{
+    THUNK *thunk = HeapAlloc( SystemHeap, 0, sizeof(*thunk) );
+    if (thunk)
+    {
+        thunk->popl_eax   = 0x58;
+        thunk->pushl_func = 0x68;
+        thunk->proc       = func;
+        thunk->pushl_eax  = 0x50;
+        thunk->jmp        = 0xe9;
+        thunk->relay      = relay;
+    }
+    return thunk;
+}
+
+
+/***********************************************************************
+ *           THUNK_Free
+ */
+static void THUNK_Free( THUNK *thunk )
+{
+    HeapFree( SystemHeap, 0, thunk );
+}
+
+
+/***********************************************************************
+ *           THUNK_EnumObjects16   (GDI.71)
+ */
+INT16 THUNK_EnumObjects16( HDC16 hdc, INT16 nObjType,
+                           GOBJENUMPROC16 func, LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_ll );
+    return EnumObjects( hdc, nObjType, (GOBJENUMPROC16)&thunk, lParam );
+}
+
+
+/*************************************************************************
+ *           THUNK_EnumFonts16   (GDI.70)
+ */
+INT16 THUNK_EnumFonts16( HDC16 hdc, LPCSTR lpFaceName,
+                         FONTENUMPROC16 func, LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_llwl );
+    return EnumFonts( hdc, lpFaceName, (FONTENUMPROC16)&thunk, lParam );
+}
+
+
+/******************************************************************
+ *           THUNK_EnumMetaFile16   (GDI.175)
+ */
+BOOL16 THUNK_EnumMetaFile16( HDC16 hdc, HMETAFILE16 hmf,
+                             MFENUMPROC16 func, LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_wllwl );
+    return EnumMetaFile( hdc, hmf, (MFENUMPROC16)&thunk, lParam );
+}
+
+
+/*************************************************************************
+ *           THUNK_EnumFontFamilies16   (GDI.330)
+ */
+INT16 THUNK_EnumFontFamilies16( HDC16 hdc, LPCSTR lpszFamily,
+                                FONTENUMPROC16 func, LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_llwl );
+    return EnumFontFamilies( hdc, lpszFamily, (FONTENUMPROC16)&thunk, lParam );
+}
+
+
+/**********************************************************************
+ *           THUNK_LineDDA16   (GDI.100)
+ */
+void THUNK_LineDDA16( INT16 nXStart, INT16 nYStart, INT16 nXEnd, INT16 nYEnd,
+                      LINEDDAPROC16 func, LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_wwl );
+    LineDDA16( nXStart, nYStart, nXEnd, nYEnd, (LINEDDAPROC16)&thunk, lParam );
+}
+
+
+/**********************************************************************
+ *           THUNK_LineDDA32   (GDI32.248)
+ */
+BOOL32 THUNK_LineDDA32( INT32 nXStart, INT32 nYStart, INT32 nXEnd, INT32 nYEnd,
+                        LINEDDAPROC32 func, LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_3 );
+    return LineDDA32( nXStart, nYStart, nXEnd, nYEnd,
+                      (LINEDDAPROC32)&thunk, lParam );
+}
+
+
+/*******************************************************************
+ *           THUNK_EnumWindows16   (USER.54)
+ */
+BOOL16 THUNK_EnumWindows16( WNDENUMPROC16 func, LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_wl );
+    return EnumWindows16( (WNDENUMPROC16)&thunk, lParam );
+}
+
+
+/*******************************************************************
+ *           THUNK_EnumWindows32   (USER32.192)
+ */
+BOOL32 THUNK_EnumWindows32( WNDENUMPROC32 func, LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_2 );
+    return EnumWindows32( (WNDENUMPROC32)&thunk, lParam );
+}
+
+
+/**********************************************************************
+ *           THUNK_EnumChildWindows16   (USER.55)
+ */
+BOOL16 THUNK_EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func,
+                                 LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_wl );
+    return EnumChildWindows16( parent, (WNDENUMPROC16)&thunk, lParam );
+}
+
+
+/**********************************************************************
+ *           THUNK_EnumChildWindows32   (USER32.177)
+ */
+BOOL32 THUNK_EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func,
+                                 LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_2 );
+    return EnumChildWindows32( parent, (WNDENUMPROC32)&thunk, lParam );
+}
+
+
+/**********************************************************************
+ *           THUNK_EnumTaskWindows16   (USER.225)
+ */
+BOOL16 THUNK_EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func,
+                                LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_wl );
+    return EnumTaskWindows16( hTask, (WNDENUMPROC16)&thunk, lParam );
+}
+
+
+/**********************************************************************
+ *           THUNK_EnumThreadWindows   (USER32.189)
+ */
+BOOL32 THUNK_EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
+{
+    DECL_THUNK( thunk, func, CallTo32_2 );
+    return EnumThreadWindows( id, (WNDENUMPROC32)&thunk, lParam );
+}
+
+
+/***********************************************************************
+ *           THUNK_EnumProps16   (USER.27)
+ */
+INT16 THUNK_EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_wlw );
+    return EnumProps16( hwnd, (PROPENUMPROC16)&thunk );
+}
+
+
+/***********************************************************************
+ *           THUNK_EnumProps32A   (USER32.185)
+ */
+INT32 THUNK_EnumProps32A( HWND32 hwnd, PROPENUMPROC32A func )
+{
+    DECL_THUNK( thunk, func, CallTo32_3 );
+    return EnumProps32A( hwnd, (PROPENUMPROC32A)&thunk );
+}
+
+
+/***********************************************************************
+ *           THUNK_EnumProps32W   (USER32.188)
+ */
+INT32 THUNK_EnumProps32W( HWND32 hwnd, PROPENUMPROC32W func )
+{
+    DECL_THUNK( thunk, func, CallTo32_3 );
+    return EnumProps32W( hwnd, (PROPENUMPROC32W)&thunk );
+}
+
+
+/***********************************************************************
+ *           THUNK_EnumPropsEx32A   (USER32.186)
+ */
+INT32 THUNK_EnumPropsEx32A( HWND32 hwnd, PROPENUMPROCEX32A func, LPARAM lParam)
+{
+    DECL_THUNK( thunk, func, CallTo32_4 );
+    return EnumPropsEx32A( hwnd, (PROPENUMPROCEX32A)&thunk, lParam );
+}
+
+
+/***********************************************************************
+ *           THUNK_EnumPropsEx32W   (USER32.187)
+ */
+INT32 THUNK_EnumPropsEx32W( HWND32 hwnd, PROPENUMPROCEX32W func, LPARAM lParam)
+{
+    DECL_THUNK( thunk, func, CallTo32_4 );
+    return EnumPropsEx32W( hwnd, (PROPENUMPROCEX32W)&thunk, lParam );
+}
+
+
+/***********************************************************************
+ *           THUNK_GrayString16   (USER.185)
+ */
+BOOL16 THUNK_GrayString16( HDC16 hdc, HBRUSH16 hbr, GRAYSTRINGPROC16 func,
+                           LPARAM lParam, INT16 cch, INT16 x, INT16 y,
+                           INT16 cx, INT16 cy )
+{
+    DECL_THUNK( thunk, func, CallTo16_word_wlw );
+    if (!func)
+        return GrayString( hdc, hbr, NULL, lParam, cch, x, y, cx, cy );
+    else
+        return GrayString( hdc, hbr, (GRAYSTRINGPROC16)&thunk, lParam, cch,
+                           x, y, cx, cy );
+}
+
diff --git a/if1632/user.spec b/if1632/user.spec
index 5e10675291c5136f38f55256111d5cddd4a54ce6..10af4d82a81e038836946a6a63177bd8b903a24e 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -26,7 +26,7 @@ heap	65520
 24  pascal16 RemoveProp(word ptr) RemoveProp16
 25  pascal16 GetProp(word ptr) GetProp16
 26  pascal16 SetProp(word ptr word) SetProp16
-27  pascal16 EnumProps(word segptr) EnumProps16
+27  pascal16 EnumProps(word segptr) THUNK_EnumProps16
 28  pascal16 ClientToScreen(word ptr) ClientToScreen16
 29  pascal16 ScreenToClient(word ptr) ScreenToClient16
 30  pascal16 WindowFromPoint(long) WindowFromPoint16
@@ -54,8 +54,8 @@ heap	65520
 #51 BEAR51
 52  pascal16 AnyPopup() AnyPopup
 53  pascal16 DestroyWindow(word) DestroyWindow
-54  pascal16 EnumWindows(segptr long) EnumWindows16
-55  pascal16 EnumChildWindows(word segptr long) EnumChildWindows16
+54  pascal16 EnumWindows(segptr long) THUNK_EnumWindows16
+55  pascal16 EnumChildWindows(word segptr long) THUNK_EnumChildWindows16
 56  pascal16 MoveWindow(word word word word word word) MoveWindow
 57  pascal16 RegisterClass(ptr) RegisterClass16
 58  pascal16 GetClassName(word ptr word) GetClassName16
@@ -117,7 +117,7 @@ heap	65520
 115 pascal16 ReplyMessage(long) ReplyMessage
 116 pascal16 PostAppMessage(word word word long) PostAppMessage
 118 pascal16 RegisterWindowMessage(segptr) RegisterWindowMessage16
-117 stub WindowFromDC
+117 pascal16 WindowFromDC(word) WindowFromDC
 119 pascal   GetMessagePos() GetMessagePos
 120 pascal   GetMessageTime() GetMessageTime
 121 pascal   SetWindowsHook(s_word segptr) SetWindowsHook
@@ -184,7 +184,7 @@ heap	65520
 182 pascal16 KillSystemTimer(word word) KillSystemTimer16
 183 pascal16 GetCaretPos(ptr) GetCaretPos16
 184 stub QuerySendMessage
-185 pascal16 GrayString(word word segptr segptr s_word s_word s_word s_word s_word) GrayString
+185 pascal16 GrayString(word word segptr segptr s_word s_word s_word s_word s_word) THUNK_GrayString16
 186 pascal16 SwapMouseButton(word) SwapMouseButton
 187 pascal16 EndMenu() EndMenu
 188 pascal16 SetSysModalWindow(word) SetSysModalWindow16
@@ -225,7 +225,7 @@ heap	65520
 222 pascal16 GetKeyboardState(ptr) GetKeyboardState
 223 pascal16 SetKeyboardState(ptr) SetKeyboardState
 224 pascal16 GetWindowTask(word) GetWindowTask16
-225 pascal16 EnumTaskWindows(word segptr long) EnumTaskWindows16
+225 pascal16 EnumTaskWindows(word segptr long) THUNK_EnumTaskWindows16
 226 stub LockInput
 227 pascal16 GetNextDlgGroupItem(word word word) GetNextDlgGroupItem
 228 pascal16 GetNextDlgTabItem(word word word) GetNextDlgTabItem
diff --git a/if1632/user32.spec b/if1632/user32.spec
index d6da5555721b6d6275ee59e882914c40358a98dc..a277e1659cf27ff88b2a81f6ee5a8a652750a7e8 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -12,7 +12,7 @@ base	1
 0007 stub AttachThreadInput
 0008 stub BeginDeferWindowPos
 0009 stdcall BeginPaint(long ptr) BeginPaint32
-0010 stub BringWindowToTop
+0010 stdcall BringWindowToTop(long) BringWindowToTop
 0011 stub BroadcastSystemMessage
 0012 stub CalcChildScroll
 0013 stub CallMsgFilter
@@ -83,7 +83,7 @@ base	1
 0078 stub CreateMDIWindowA
 0079 stub CreateMDIWindowW
 0080 stub CreateMenu
-0081 stub CreatePopupMenu
+0081 stdcall CreatePopupMenu() CreatePopupMenu
 0082 stdcall CreateWindowExA(long ptr ptr long long long long long 
 				long long long ptr) CreateWindowEx32A
 0083 stdcall CreateWindowExW(long ptr ptr long long long long long 
@@ -181,7 +181,7 @@ base	1
 0174 stub EndMenu
 0175 stdcall EndPaint(long ptr) EndPaint32
 0176 stub EndTask
-0177 stdcall EnumChildWindows(long ptr long) EnumChildWindows32
+0177 stdcall EnumChildWindows(long ptr long) THUNK_EnumChildWindows32
 0178 stub EnumClipboardFormats
 0179 stub EnumDesktopsA
 0180 stub EnumDesktopsW
@@ -189,14 +189,14 @@ base	1
 0182 stub EnumDisplayDeviceModesW
 0183 stub EnumDisplayDevicesA
 0184 stub EnumDisplayDevicesW
-0185 stdcall EnumPropsA(long ptr) EnumProps32A
-0186 stdcall EnumPropsExA(long ptr long) EnumPropsEx32A
-0187 stdcall EnumPropsExW(long ptr long) EnumPropsEx32W
-0188 stdcall EnumPropsW(long ptr) EnumProps32W
-0189 stdcall EnumThreadWindows(long ptr long) EnumThreadWindows
+0185 stdcall EnumPropsA(long ptr) THUNK_EnumProps32A
+0186 stdcall EnumPropsExA(long ptr long) THUNK_EnumPropsEx32A
+0187 stdcall EnumPropsExW(long ptr long) THUNK_EnumPropsEx32W
+0188 stdcall EnumPropsW(long ptr) THUNK_EnumProps32W
+0189 stdcall EnumThreadWindows(long ptr long) THUNK_EnumThreadWindows
 0190 stub EnumWindowStationsA
 0191 stub EnumWindowStationsW
-0192 stdcall EnumWindows(ptr long) EnumWindows32
+0192 stdcall EnumWindows(ptr long) THUNK_EnumWindows32
 0193 stdcall EqualRect(ptr ptr) EqualRect32
 0194 stdcall ExcludeUpdateRgn(long long) ExcludeUpdateRgn
 0195 stub ExitWindowsEx
@@ -252,7 +252,7 @@ base	1
 0245 stub GetKBCodePage
 0246 stub GetKeyNameTextA
 0247 stub GetKeyNameTextW
-0248 stub GetKeyState
+0248 stdcall GetKeyState(long) GetKeyState
 0249 stub GetKeyboardLayout
 0250 stub GetKeyboardLayoutList
 0251 stub GetKeyboardLayoutNameA
@@ -281,7 +281,7 @@ base	1
 0274 stub GetNextDlgGroupItem
 0275 stub GetNextDlgTabItem
 0276 stub GetOpenClipboardWindow
-0277 stub GetParent
+0277 stdcall GetParent(long) GetParent
 0278 stub GetPriorityClipboardFormat
 0279 stub GetProcessWindowStation
 0280 stdcall GetPropA(long ptr) GetProp32A
@@ -345,9 +345,9 @@ base	1
 0338 stub IsChild
 0339 stdcall IsClipboardFormatAvailable(long) IsClipboardFormatAvailable
 0340 stub IsDialogMessage
-0341 stub IsDialogMessageA
+0341 stdcall IsDialogMessageA(long ptr) IsDialogMessage32A
 0342 stub IsDialogMessageW
-0343 stub IsDlgButtonChecked
+0343 stdcall IsDlgButtonChecked(long long) IsDlgButtonChecked
 0344 stdcall IsIconic(long) IsIconic
 0345 stub IsMenu
 0346 stdcall IsRectEmpty(ptr) IsRectEmpty32
@@ -561,7 +561,7 @@ base	1
 0554 stub TranslateMDISysAccel
 0555 stdcall TranslateMessage(ptr) USER32_TranslateMessage
 0556 stub UnhookWindowsHook
-0557 stub UnhookWindowsHookEx
+0557 stdcall UnhookWindowsHookEx(long) UnhookWindowsHookEx32
 0558 stdcall UnionRect(ptr ptr ptr) UnionRect32
 0559 stub UnloadKeyboardLayout
 0560 stub UnlockWindowStation
@@ -584,7 +584,7 @@ base	1
 0577 stub WaitMessage
 0578 stdcall WinHelpA(long ptr long long)	WIN32_WinHelpA
 0579 stub WinHelpW
-0580 stub WindowFromDC
+0580 stdcall WindowFromDC(long) WindowFromDC
 0581 stdcall WindowFromPoint(long long) WindowFromPoint32
 0582 stub keybd_event
 0583 stub mouse_event
diff --git a/if1632/wprocs.spec b/if1632/wprocs.spec
index 1f7b233dba6da15606e8ef67660fdc781b79abf5..3f33bbce5605004ba9b00c4904f39afc41c5a68c 100644
--- a/if1632/wprocs.spec
+++ b/if1632/wprocs.spec
@@ -25,8 +25,6 @@ type	win16
 27 pascal EntryAddrProc(word word) MODULE_GetEntryPoint
 28 pascal MyAlloc(word word word) MODULE_AllocateSegment
 30 pascal FormatCharDlgProc(word word word long) FormatCharDlgProc
-31 pascal16 FontStyleEnumProc(ptr ptr word long)   FontStyleEnumProc
-32 pascal16 FontFamilyEnumProc(ptr ptr word long)  FontFamilyEnumProc
  
 # Interrupt vectors 0-255 are ordinals 100-355
 # The 'word' parameter are the flags pushed on the stack by the interrupt
diff --git a/include/callback.h b/include/callback.h
index d420f76f8851c99fe6697aa890ff19e3bca3d14a..0339a89c8cf1e785a28adab2f82d00e88c70123e 100644
--- a/include/callback.h
+++ b/include/callback.h
@@ -4,13 +4,10 @@
  * Copyright 1995 Alexandre Julliard
  */
 
-#ifndef WINE_CALLBACK_H
-#define WINE_CALLBACK_H
+#ifndef __WINE_CALLBACK_H
+#define __WINE_CALLBACK_H
 
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include "stackframe.h"
+#include "wintypes.h"
 
 extern
 int CallTo32_LargeStack( int (*func)(), int nbargs, ... );
@@ -19,27 +16,27 @@ int CallTo32_LargeStack( int (*func)(), int nbargs, ... );
 /* List of the 16-bit callback functions. This list is used  */
 /* by the build program to generate the file if1632/callto16.S */
 
-                               /* func     ds    parameters */
-extern WORD CallTo16_word_     ( FARPROC16, WORD );
+                               /* func     parameters */
+extern WORD CallTo16_word_     ( FARPROC16 );
 
 #ifndef WINELIB
 
-extern WORD CallTo16_word_w    (FARPROC16, WORD, WORD);
-extern WORD CallTo16_word_ww   (FARPROC16, WORD, WORD, WORD);
-extern WORD CallTo16_word_wl   (FARPROC16, WORD, WORD, LONG);
-extern WORD CallTo16_word_ll   (FARPROC16, WORD, LONG, LONG);
-extern WORD CallTo16_word_www  (FARPROC16, WORD, WORD, WORD, WORD);
-extern WORD CallTo16_word_wwl  (FARPROC16, WORD, WORD, WORD, LONG);
-extern WORD CallTo16_word_wlw  (FARPROC16, WORD, WORD, LONG, WORD);
-extern LONG CallTo16_long_wwl  (FARPROC16, WORD, WORD, WORD, LONG);
-extern WORD CallTo16_word_llwl (FARPROC16, WORD, LONG, LONG, WORD, LONG);
-extern LONG CallTo16_long_wwwl (FARPROC16, WORD, WORD, WORD, WORD, LONG);
-extern WORD CallTo16_word_lwww (FARPROC16, WORD, LONG, WORD, WORD, WORD);
-extern WORD CallTo16_word_wwll (FARPROC16, WORD, WORD, WORD, LONG, LONG);
-extern WORD CallTo16_word_wllwl(FARPROC16, WORD, WORD, LONG, LONG, WORD, LONG);
-extern LONG CallTo16_long_lwwll(FARPROC16, WORD, LONG, WORD, WORD, LONG, LONG);
-extern WORD CallTo16_word_wwlll(FARPROC16, WORD, WORD, WORD, LONG, LONG, LONG);
-extern LONG CallTo16_long_lllllllwlwwwl( FARPROC16, WORD, LONG, LONG, LONG,
+extern WORD CallTo16_word_w    ( FARPROC16, WORD );
+extern WORD CallTo16_word_ww   ( FARPROC16, WORD, WORD );
+extern WORD CallTo16_word_wl   ( FARPROC16, WORD, LONG );
+extern WORD CallTo16_word_ll   ( FARPROC16, LONG, LONG );
+extern WORD CallTo16_word_www  ( FARPROC16, WORD, WORD, WORD );
+extern WORD CallTo16_word_wwl  ( FARPROC16, WORD, WORD, LONG );
+extern WORD CallTo16_word_wlw  ( FARPROC16, WORD, LONG, WORD );
+extern LONG CallTo16_long_wwl  ( FARPROC16, WORD, WORD, LONG );
+extern WORD CallTo16_word_llwl ( FARPROC16, LONG, LONG, WORD, LONG );
+extern LONG CallTo16_long_wwwl ( FARPROC16, WORD, WORD, WORD, LONG );
+extern WORD CallTo16_word_lwww ( FARPROC16, LONG, WORD, WORD, WORD );
+extern WORD CallTo16_word_wwll ( FARPROC16, WORD, WORD, LONG, LONG );
+extern WORD CallTo16_word_wllwl( FARPROC16, WORD, LONG, LONG, WORD, LONG );
+extern LONG CallTo16_long_lwwll( FARPROC16, LONG, WORD, WORD, LONG, LONG );
+extern WORD CallTo16_word_wwlll( FARPROC16, WORD, WORD, LONG, LONG, LONG );
+extern LONG CallTo16_long_lllllllwlwwwl( FARPROC16, LONG, LONG, LONG,
                                          LONG, LONG, LONG, LONG, WORD, LONG,
                                          WORD, WORD, WORD, LONG );
 
@@ -47,46 +44,26 @@ extern WORD CallTo16_regs_( FARPROC16 func, WORD ds, WORD es, WORD bp, WORD ax,
                             WORD bx, WORD cx, WORD dx, WORD si, WORD di );
 
 #define CallDCHookProc( func, hdc, code, data, lparam) \
-    CallTo16_word_wwll( func, CURRENT_DS, hdc, code, data, lparam )
+    CallTo16_word_wwll( func, hdc, code, data, lparam )
 #define CallDriverProc( func, dwId, msg, hdrvr, lparam1, lparam2 ) \
-    CallTo16_long_lwwll( func, CURRENT_DS, dwId, msg, hdrvr, lparam1, lparam2 )
-#define CallEnumChildProc( func, hwnd, lParam ) \
-    CallTo16_word_wl( func, CURRENT_DS, hwnd, lParam )
-#define CallEnumFontFamProc( func, lpfont, lpmetric, type, lParam ) \
-    CallTo16_word_llwl( func, CURRENT_DS, lpfont, lpmetric, type, lParam )
-#define CallEnumFontsProc( func, lpfont, lpmetric, type, lParam ) \
-    CallTo16_word_llwl( func, CURRENT_DS, lpfont, lpmetric, type, lParam )
-#define CallEnumMetafileProc( func, hdc, lptable, lprecord, objs, lParam ) \
-    CallTo16_word_wllwl(func, CURRENT_DS, hdc, lptable, lprecord, objs, lParam)
-#define CallEnumObjectsProc( func, lpobj, lParam ) \
-    CallTo16_word_ll( func, CURRENT_DS, lpobj, lParam )
-#define CallEnumPropProc16( func, hwnd, lpstr, handle ) \
-    CallTo16_word_wlw( (FARPROC16)(func), CURRENT_DS, hwnd, lpstr, handle )
-#define CallEnumTaskWndProc( func, hwnd, lParam ) \
-    CallTo16_word_wl( func, CURRENT_DS, hwnd, lParam )
-#define CallEnumWindowsProc16( func, hwnd, lParam ) \
-    CallTo16_word_wl( func, CURRENT_DS, hwnd, lParam )
-#define CallLineDDAProc( func, xPos, yPos, lParam ) \
-    CallTo16_word_wwl( func, CURRENT_DS, xPos, yPos, lParam )
-#define CallGrayStringProc( func, hdc, lParam, cch ) \
-    CallTo16_word_wlw( func, CURRENT_DS, hdc, lParam, cch )
+    CallTo16_long_lwwll( func, dwId, msg, hdrvr, lparam1, lparam2 )
 #define CallHookProc( func, code, wParam, lParam ) \
-    CallTo16_long_wwl( func, CURRENT_DS, code, wParam, lParam )
+    CallTo16_long_wwl( func, code, wParam, lParam )
 #define CallTimeFuncProc( func, id, msg, dwUser, dw1, dw2 ) \
-    CallTo16_word_wwlll( func, CURRENT_DS, id, msg, dwUser, dw1, dw2 )
+    CallTo16_word_wwlll( func, id, msg, dwUser, dw1, dw2 )
 #define CallWindowsExitProc( func, nExitType ) \
-    CallTo16_word_w( func, CURRENT_DS, nExitType )
-#define CallWndProc16( func, ds, hwnd, msg, wParam, lParam ) \
-    CallTo16_long_wwwl( (FARPROC16)(func), ds, hwnd, msg, wParam, lParam )
+    CallTo16_word_w( func, nExitType )
+#define CallWndProc16( func, hwnd, msg, wParam, lParam ) \
+    CallTo16_long_wwwl( (FARPROC16)(func), hwnd, msg, wParam, lParam )
 #define CallWordBreakProc( func, lpch, ichCurrent, cch, code ) \
-    CallTo16_word_lwww( func, CURRENT_DS, lpch, ichCurrent, cch, code )
-#define CallWndProcNCCREATE16( func, ds, exStyle, clsName, winName, style, \
+    CallTo16_word_lwww( func, lpch, ichCurrent, cch, code )
+#define CallWndProcNCCREATE16( func, exStyle, clsName, winName, style, \
                                x, y, cx, cy, hparent, hmenu, instance, \
                                params, hwnd, msg, wParam, lParam ) \
-    CallTo16_long_lllllllwlwwwl( (FARPROC16)(func), ds, exStyle, clsName, \
-                              winName, style, MAKELONG(y,x), MAKELONG(cy,cx), \
-                              MAKELONG(hmenu,hparent), instance, params, \
-                              hwnd, msg, wParam, lParam )
+    CallTo16_long_lllllllwlwwwl( (FARPROC16)(func), exStyle, clsName, winName,\
+                                 style, MAKELONG(y,x), MAKELONG(cy,cx), \
+                                 MAKELONG(hmenu,hparent), instance, params, \
+                                 hwnd, msg, wParam, lParam )
 
 /* List of the 32-bit callback functions. This list is used  */
 /* by the build program to generate the file if1632/callto32.S */
@@ -100,12 +77,6 @@ extern LONG CallTo32_4( FARPROC32, DWORD, DWORD, DWORD, DWORD );
     CallTo32_0( func )
 #define CallDLLEntryProc32( func, hmodule, a, b ) \
     CallTo32_3( func, hmodule, a, b )
-#define CallEnumPropProc32( func, hwnd, lpstr, handle ) \
-    CallTo32_3( (FARPROC32)(func), hwnd, (DWORD)(lpstr), handle )
-#define CallEnumPropProcEx32( func, hwnd, lpstr, handle, data ) \
-    CallTo32_4( (FARPROC32)(func), hwnd, (DWORD)(lpstr), handle, data )
-#define CallEnumWindowsProc32( func, hwnd, lParam ) \
-    CallTo32_2( func, hwnd, lParam )
 #define CallWndProc32( func, hwnd, msg, wParam, lParam ) \
     CallTo32_4( func, hwnd, msg, wParam, lParam )
 
@@ -116,39 +87,13 @@ extern LONG CallTo32_4( FARPROC32, DWORD, DWORD, DWORD, DWORD );
     (*func)( hdc, code, data, lparam )
 #define CallDriverProc( func, dwId, msg, hdrvr, lparam1, lparam2 ) \
     (*func)( dwId, msg, hdrvr, lparam1, lparam2 )
-#define CallEnumChildProc( func, hwnd, lParam ) \
-    (*func)( hwnd, lParam )
-#define CallEnumFontFamProc( func, lpfont, lpmetric, type, lParam ) \
-    (*func)( lpfont, lpmetric, type, lParam )
-#define CallEnumFontsProc( func, lpfont, lpmetric, type, lParam ) \
-    (*func)( lpfont, lpmetric, type, lParam )
-#define CallEnumMetafileProc( func, hdc, lptable, lprecord, objs, lParam ) \
-    (*func)( hdc, lptable, lprecord, objs, lParam)
-#define CallEnumObjectsProc( func, lpobj, lParam ) \
-    (*func)( lpobj, lParam )
-#define CallEnumPropProc16( func, hwnd, lpstr, handle ) \
-    (*func)( hwnd, lpstr, handle )
-#define CallEnumPropProc32( func, hwnd, lpstr, handle ) \
-    (*func)( hwnd, lpstr, handle )
-#define CallEnumPropProcEx32( func, hwnd, lpstr, handle, data ) \
-    (*func)( hwnd, lpstr, handle, data )
-#define CallEnumTaskWndProc( func, hwnd, lParam ) \
-    (*func)( hwnd, lParam )
-#define CallEnumWindowsProc16( func, hwnd, lParam ) \
-    (*func)( hwnd, lParam )
-#define CallEnumWindowsProc32( func, hwnd, lParam ) \
-    (*func)( hwnd, lParam )
-#define CallLineDDAProc( func, xPos, yPos, lParam ) \
-    (*func)( xPos, yPos, lParam )
-#define CallGrayStringProc( func, hdc, lParam, cch ) \
-    (*func)( hdc, lParam, cch )
 #define CallHookProc( func, code, wParam, lParam ) \
     (*func)( code, wParam, lParam )
 #define CallTimeFuncProc( func, id, msg, dwUser, dw1, dw2 ) \
     (*func)( id, msg, dwUser, dw1, dw2 )
 #define CallWindowsExitProc( func, nExitType ) \
     (*func)( nExitType )
-#define CallWndProc16( func, ds, hwnd, msg, wParam, lParam ) \
+#define CallWndProc16( func, hwnd, msg, wParam, lParam ) \
     (*func)( hwnd, msg, wParam, lParam )
 #define CallWndProc32( func, hwnd, msg, wParam, lParam ) \
     (*func)( hwnd, msg, wParam, lParam )
@@ -158,4 +103,4 @@ extern LONG CallTo32_4( FARPROC32, DWORD, DWORD, DWORD, DWORD );
 #endif  /* WINELIB */
 
 
-#endif /* WINE_CALLBACK_H */
+#endif /* __WINE_CALLBACK_H */
diff --git a/include/combo.h b/include/combo.h
index 0e177f63978ef7827ffff5f282810249971918bb..973253354cfae7433e905db45e9a945e06a692e4 100644
--- a/include/combo.h
+++ b/include/combo.h
@@ -4,6 +4,7 @@
 
 
 typedef struct {
+  WND*	  wndSelf;
   DWORD   dwStyle;
   DWORD   dwState;
   HWND    hWndEdit;
diff --git a/include/file.h b/include/file.h
index 634ca761b36457770f733e27a14aab5861cabe6d..f1533d99bc274c6786abc541d92789262cffc9cc 100644
--- a/include/file.h
+++ b/include/file.h
@@ -11,6 +11,7 @@
 
 extern void FILE_SetDosError(void);
 extern void FILE_CloseAllFiles( HANDLE hPDB );
+extern HFILE FILE_DupUnixHandle( int fd );
 extern int FILE_Stat( LPCSTR unixName, BYTE *pattr, DWORD *psize,
                       WORD *pdate, WORD *ptime );
 extern int FILE_GetDateTime( HFILE hFile, WORD *pdate, WORD *ptime,
diff --git a/include/hook.h b/include/hook.h
index 4dcd375d5154c9765e3057f2c30ef41fad42ff4e..0f499883bed1dfeea69df5e2d0f2f4332b2de76f 100644
--- a/include/hook.h
+++ b/include/hook.h
@@ -9,7 +9,6 @@
 
 #include "windows.h"
 #include "ldt.h"
-#include "callback.h"
 
 #pragma pack(1)
 
diff --git a/include/metafile.h b/include/metafile.h
index 0d2c306f0a84ca45ca1b555ade8510803709fc97..06f4e63a48be1260de4a67882e189ec803605def 100644
--- a/include/metafile.h
+++ b/include/metafile.h
@@ -14,7 +14,7 @@
 #define META_EOF 0x0000
 
 HMETAFILE MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen);
-int MF_AddHandle(HANDLETABLE *ht, WORD htlen, HANDLE hobj);
+int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HANDLE hobj);
 int MF_AddHandleInternal(HANDLE hobj);
 BOOL MF_MetaParam0(DC *dc, short func);
 BOOL MF_MetaParam1(DC *dc, short func, short param1);
@@ -31,6 +31,8 @@ BOOL MF_CreatePatternBrush(DC *dc, HBRUSH hBrush, LOGBRUSH16 *logbrush);
 BOOL MF_CreatePenIndirect(DC *dc, HPEN16 hPen, LOGPEN16 *logpen);
 BOOL MF_CreateFontIndirect(DC *dc, HFONT hFont, LOGFONT16 *logfont);
 BOOL MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count);
+BOOL MF_ExtTextOut(DC *dc, short x, short y, UINT16 flags, const RECT16 *rect,
+                   LPCSTR str, short count, const INT16 *lpDx);
 BOOL MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count);
 BOOL MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
 	       short height, HDC hdcSrc, short xSrc, short ySrc, DWORD rop);
diff --git a/include/task.h b/include/task.h
index f7c92a56e2e5145884e3ce23616640532aeaae8b..f71ce81524bafefd8d660082b101e50aa1cd0ea0 100644
--- a/include/task.h
+++ b/include/task.h
@@ -70,8 +70,8 @@ typedef struct
     HQUEUE16  hQueue;                     /* 20 Selector of task queue */
     HTASK16   hParent;                    /* 22 Selector of TDB of parent */
     WORD      signal_flags;               /* 24 Flags for signal handler */
-    DWORD     sighandler WINE_PACKED;     /* 26 Signal handler */
-    DWORD     userhandler WINE_PACKED;    /* 2a USER signal handler */
+    FARPROC16 sighandler WINE_PACKED;     /* 26 Signal handler */
+    FARPROC16 userhandler WINE_PACKED;    /* 2a USER signal handler */
     DWORD     discardhandler WINE_PACKED; /* 2e Handler for GlobalDiscard() */
     DWORD     int0 WINE_PACKED;           /* 32 int 0 (divide by 0) handler */
     DWORD     int2 WINE_PACKED;           /* 36 int 2 (NMI) handler */
@@ -81,9 +81,7 @@ typedef struct
     DWORD     int3e WINE_PACKED;          /* 46 int 3e (80x87 emu) handler */
     DWORD     int75 WINE_PACKED;          /* 4a int 75 (80x87 error) handler */
     DWORD     compat_flags WINE_PACKED;   /* 4e Compatibility flags */
-    BYTE      unused4[10];                /* 52 */
-    WORD      switchStackSS;              /* 5c Saved %ss for SwitchStackTo */
-    WORD      switchStackSP;              /* 5e Saved %sp for SwitchStackTo */
+    BYTE      unused4[14];                /* 52 */
     HANDLE16  hPDB;                       /* 60 Selector of PDB (i.e. PSP) */
     SEGPTR    dta WINE_PACKED;            /* 62 Current DTA */
     BYTE      curdrive;                   /* 66 Current drive */
diff --git a/include/winbase.h b/include/winbase.h
index f221fa209d0ea073844eaae6e82c5e3de982d496..1583f35d7657c3164caed4136f3fad06410ef981 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -133,6 +133,35 @@ typedef struct {
 
 DECL_WINELIB_TYPE_AW(OSVERSIONINFO);
 
+typedef struct
+{
+    DWORD     FileAttributes;
+    FILETIME  CreationTime;
+    FILETIME  LastAccessTime;
+    FILETIME  LastWriteTime;
+    DWORD     FileSizeHigh;
+    DWORD     FileSizeLow;
+    DWORD     reserved[2];
+    CHAR      FileName[260];
+    CHAR      AlternateName[14];
+} WIN32_FIND_DATA32A, *LPWIN32_FIND_DATA32A;
+
+typedef struct
+{
+    DWORD     FileAttributes;
+    FILETIME  CreationTime;
+    FILETIME  LastAccessTime;
+    FILETIME  LastWriteTime;
+    DWORD     FileSizeHigh;
+    DWORD     FileSizeLow;
+    DWORD     reserved[2];
+    WCHAR     FileName[260];
+    WCHAR     AlternateName[14];
+} WIN32_FIND_DATA32W, *LPWIN32_FIND_DATA32W;
+
+DECL_WINELIB_TYPE_AW(WIN32_FIND_DATA);
+DECL_WINELIB_TYPE_AW(LPWIN32_FIND_DATA);
+
 #define VER_PLATFORM_WIN32s             0
 #define VER_PLATFORM_WIN32_WINDOWS      1
 #define VER_PLATFORM_WIN32_NT           2
diff --git a/include/windows.h b/include/windows.h
index 767363a78aea3885d0fa76455dba995a683b87df..2e6fa9f731aa87cd4eb191a0c26465f947d416e2 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1053,6 +1053,11 @@ typedef struct
 DECL_WINELIB_TYPE_AW(TEXTMETRIC);
 DECL_WINELIB_TYPE_AW(LPTEXTMETRIC);
 
+typedef INT16 (*FONTENUMPROC16)(SEGPTR,SEGPTR,UINT16,LPARAM);
+typedef INT32 (*FONTENUMPROC32A)(const LOGFONT32A*,const TEXTMETRIC32A*,UINT32,LPARAM);
+typedef INT32 (*FONTENUMPROC32W)(const LOGFONT32W*,const TEXTMETRIC32W*,UINT32,LPARAM);
+DECL_WINELIB_TYPE_AW(FONTENUMPROC);
+
   /* tmPitchAndFamily values */
 #define TMPF_FIXED_PITCH    1
 #define TMPF_VECTOR	    2
@@ -2508,6 +2513,13 @@ typedef struct
 #define ESB_DISABLE_LTUP    ESB_DISABLE_LEFT
 #define ESB_DISABLE_RTDN    ESB_DISABLE_RIGHT
 
+/* Scrollbar messages (undocumented) */
+#define SBM_SETSCROLLPOS      (WM_USER+0)
+#define SBM_GETSCROLLPOS      (WM_USER+1)
+#define SBM_SETSCROLLRANGE    (WM_USER+2)
+#define SBM_REDRAW            (WM_USER+3)
+#define SBM_ENABLE            (WM_USER+4)
+
 /* Listbox styles */
 #define LBS_NOTIFY            0x0001L
 #define LBS_SORT              0x0002L
@@ -3000,12 +3012,19 @@ typedef METARECORD *PMETARECORD;
 typedef METARECORD *LPMETARECORD;
 
 /* Handle table structure */
+
+typedef struct
+{
+    HGDIOBJ16 objectHandle[1];
+} HANDLETABLE16, *LPHANDLETABLE16;
+
 typedef struct
 {
-    HANDLE16   objectHandle[1];
-} HANDLETABLE;
-typedef HANDLETABLE *PHANDLETABLE;
-typedef HANDLETABLE *LPHANDLETABLE;
+    HGDIOBJ32 objectHandle[1];
+} HANDLETABLE32, *LPHANDLETABLE32;
+
+DECL_WINELIB_TYPE(HANDLETABLE);
+DECL_WINELIB_TYPE(LPHANDLETABLE);
 
 /* Clipboard metafile picture structure */
 typedef struct
@@ -3096,6 +3115,10 @@ typedef struct
 #define META_CREATEBITMAP            0x06FE
 #define META_CREATEREGION            0x06FF
 
+typedef INT16 (*MFENUMPROC16)(HDC16,HANDLETABLE16*,METARECORD*,INT16,LPARAM);
+typedef INT32 (*MFENUMPROC32)(HDC32,HANDLETABLE32*,METARECORD*,INT32,LPARAM);
+DECL_WINELIB_TYPE(MFENUMPROC);
+
 /* Debugging support (DEBUG SYSTEM ONLY) */
 typedef struct
 {
@@ -3281,8 +3304,10 @@ INT16      GetCommError(INT16,LPCOMSTAT);
 UINT16     GetCommEventMask(INT16,UINT16);
 HTASK16    GetCurrentTask(void);
 HMODULE16  GetExePtr(HANDLE16);
+WORD       GetExeVersion(void);
 HINSTANCE16 GetTaskDS(void);
 HQUEUE16   GetTaskQueue(HTASK16);
+BOOL16     IsSharedSelector(HANDLE16);
 BOOL16     LocalInit(HANDLE16,WORD,WORD);
 DWORD      OffsetViewportOrg(HDC16,INT16,INT16);
 DWORD      OffsetWindowOrg(HDC16,INT16,INT16);
@@ -3294,6 +3319,7 @@ DWORD      ScaleWindowExt(HDC16,INT16,INT16,INT16,INT16);
 DWORD      SetBitmapDimension(HBITMAP16,INT16,INT16);
 DWORD      SetBrushOrg(HDC16,INT16,INT16);
 UINT16*    SetCommEventMask(INT16,UINT16);
+FARPROC16  SetTaskSignalProc(HTASK16,FARPROC16);
 DWORD      SetViewportExt(HDC16,INT16,INT16);
 DWORD      SetViewportOrg(HDC16,INT16,INT16);
 DWORD      SetWindowExt(HDC16,INT16,INT16);
@@ -3403,6 +3429,7 @@ INT16      SetDIBitsToDevice(HDC32,INT32,INT32,DWORD,DWORD,INT32,INT32,UINT32,UI
 VOID       SetRectRgn(HRGN32,INT32,INT32,INT32,INT32);
 WORD       SetWindowWord(HWND32,INT32,WORD);
 BOOL16     ShowCaret(HWND32);
+HWND16     WindowFromDC(HDC32);
 HFILE      _lclose(HFILE);
 HFILE      _lcreat(LPCSTR,INT32);
 HFILE      _lopen(LPCSTR,INT32);
@@ -3914,6 +3941,9 @@ HFILE      LZOpenFile32W(LPCWSTR,LPOFSTRUCT,UINT32);
 INT16      LZRead16(HFILE,SEGPTR,UINT16); 
 INT32      LZRead32(HFILE,LPVOID,UINT32); 
 #define    LZRead WINELIB_NAME(LZRead)
+VOID       LineDDA16(INT16,INT16,INT16,INT16,LINEDDAPROC16,LPARAM);
+BOOL32     LineDDA32(INT32,INT32,INT32,INT32,LINEDDAPROC32,LPARAM);
+#define    LineDDA WINELIB_NAME(LineDDA)
 HACCEL16   LoadAccelerators16(HINSTANCE16,SEGPTR);
 HACCEL32   LoadAccelerators32A(HINSTANCE32,LPCSTR);
 HACCEL32   LoadAccelerators32W(HINSTANCE32,LPCWSTR);
@@ -4359,17 +4389,9 @@ typedef HANDLE16 HWND;
 #ifdef WINELIB
 typedef LONG (*DRIVERPROC)(DWORD, HDRVR, UINT, LPARAM, LPARAM);
 typedef int (*EDITWORDBREAKPROC)(LPSTR lpch, int ichCurrent, int cch,int code);
-/*typedef int (*FONTENUMPROC)(const LOGFONT*,const TEXTMETRIC*,DWORD,LPARAM);*/
-typedef int (*FONTENUMPROC)(const void*,const void*,DWORD,LPARAM);
-typedef int (*GOBJENUMPROC)(LPVOID,LPARAM);
-/*typedef int (*MFENUMPROC)(HDC,HANDLETABLE*,METARECORD*,int,LPARAM);*/
-typedef int (*MFENUMPROC)(HDC,void*,void*,int,LPARAM);
 #else
 typedef SEGPTR DRIVERPROC;
 typedef SEGPTR EDITWORDBREAKPROC;
-typedef SEGPTR FONTENUMPROC;
-typedef SEGPTR GOBJENUMPROC;
-typedef SEGPTR MFENUMPROC;
 #endif
 
 ATOM       AddAtom(SEGPTR);
@@ -4455,10 +4477,10 @@ BOOL       EnableScrollBar(HWND,UINT,UINT);
 BOOL       EnableWindow(HWND,BOOL);
 BOOL       EndDeferWindowPos(HDWP16);
 UINT       EnumClipboardFormats(UINT);
-INT        EnumFontFamilies(HDC,LPCSTR,FONTENUMPROC,LPARAM);
-INT        EnumFonts(HDC,LPCSTR,FONTENUMPROC,LPARAM);
-BOOL       EnumMetaFile(HDC,HMETAFILE,MFENUMPROC,LPARAM);
-INT        EnumObjects(HDC,INT,GOBJENUMPROC,LPARAM);
+INT        EnumFontFamilies(HDC,LPCSTR,FONTENUMPROC16,LPARAM);
+INT        EnumFonts(HDC,LPCSTR,FONTENUMPROC16,LPARAM);
+BOOL       EnumMetaFile(HDC,HMETAFILE,MFENUMPROC16,LPARAM);
+INT        EnumObjects(HDC,INT,GOBJENUMPROC16,LPARAM);
 INT        Escape(HDC,INT,INT,LPCSTR,LPVOID);
 int        ExcludeClipRect(HDC,short,short,short,short);
 int        ExcludeVisRect(HDC,short,short,short,short);
@@ -4610,7 +4632,7 @@ WORD       GlobalPageUnlock(HGLOBAL16);
 BOOL16     GlobalUnWire(HGLOBAL16);
 void       GlobalUnfix(HGLOBAL16);
 SEGPTR     GlobalWire(HGLOBAL16);
-BOOL       GrayString(HDC,HBRUSH,FARPROC16,LPARAM,INT,INT,INT,INT,INT);
+BOOL       GrayString(HDC,HBRUSH,GRAYSTRINGPROC16,LPARAM,INT,INT,INT,INT,INT);
 BOOL       HiliteMenuItem(HWND,HMENU,UINT,UINT);
 BOOL       InSendMessage(void);
 WORD       InitAtomTable(WORD);
@@ -4638,7 +4660,6 @@ BOOL       IsWindowEnabled(HWND);
 BOOL       IsWindowVisible(HWND);
 BOOL       IsZoomed(HWND);
 void       LimitEmsPages(DWORD);
-void       LineDDA(short,short,short,short,FARPROC16,long);
 BOOL       LineTo(HDC,short,short);
 HANDLE     LoadLibrary(LPCSTR);
 HANDLE     LoadModule(LPCSTR,LPVOID);
@@ -4661,7 +4682,7 @@ BOOL       PaintRgn(HDC,HRGN);
 BOOL       PatBlt(HDC,short,short,short,short,DWORD);
 BOOL       Pie(HDC,INT,INT,INT,INT,INT,INT,INT,INT);
 BOOL       PlayMetaFile(HDC,HANDLE);
-void       PlayMetaFileRecord(HDC,LPHANDLETABLE,LPMETARECORD,WORD);
+void       PlayMetaFileRecord(HDC,LPHANDLETABLE16,LPMETARECORD,WORD);
 BOOL       PostAppMessage(HANDLE,WORD,WORD,LONG);
 void       PostEvent(HTASK);
 BOOL       PostMessage(HWND,WORD,WORD,LONG);
diff --git a/include/wintypes.h b/include/wintypes.h
index 389a9fe196d9d0aa691b51a62310931f1a79d06b..5345511cefedf0764690cf9e4b5abcf7f38d6a6e 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -168,9 +168,18 @@ DECL_WINELIB_TYPE(DLGPROC);
 typedef LRESULT (*FARPROC16)();
 typedef LRESULT (*FARPROC32)();
 DECL_WINELIB_TYPE(FARPROC);
+typedef INT16   (*GOBJENUMPROC16)(SEGPTR,LPARAM);
+typedef INT32   (*GOBJENUMPROC32)(LPVOID,LPARAM);
+DECL_WINELIB_TYPE(GOBJENUMPROC);
+typedef BOOL16  (*GRAYSTRINGPROC16)(HDC16,LPARAM,INT16);
+typedef BOOL32  (*GRAYSTRINGPROC32)(HDC32,LPARAM,INT32);
+DECL_WINELIB_TYPE(GRAYSTRINGPROC);
 typedef LRESULT (*HOOKPROC16)(INT16,WPARAM16,LPARAM);
 typedef LRESULT (*HOOKPROC32)(INT32,WPARAM32,LPARAM);
 DECL_WINELIB_TYPE(HOOKPROC);
+typedef VOID    (*LINEDDAPROC16)(INT16,INT16,LPARAM);
+typedef VOID    (*LINEDDAPROC32)(INT32,INT32,LPARAM);
+DECL_WINELIB_TYPE(LINEDDAPROC);
 typedef BOOL16  (*PROPENUMPROC16)(HWND16,SEGPTR,HANDLE16);
 typedef BOOL32  (*PROPENUMPROC32A)(HWND32,LPCSTR,HANDLE32);
 typedef BOOL32  (*PROPENUMPROC32W)(HWND32,LPCWSTR,HANDLE32);
diff --git a/library/miscstubs.c b/library/miscstubs.c
index 071b69e5a579d33a6cc08964b3d511e2d781a3c1..9bce0eeba906270c5523297586543a9a557b4486 100644
--- a/library/miscstubs.c
+++ b/library/miscstubs.c
@@ -33,16 +33,14 @@ int CallTo32_LargeStack( int (*func)(), int nbargs, ...)
                 a[7],a[8],a[9],a[10]);
   case 14: return func(a[0],a[1],a[2],a[3],a[4],a[5],a[6],
                 a[7],a[8],a[9],a[10],a[11],a[12],a[13]);
-  case 17: return func(a[0],a[1],a[2],a[3],a[4],a[5],a[6],
-                a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15],a[16]);
+  case 16: return func(a[0],a[1],a[2],a[3],a[4],a[5],a[6],
+                a[7],a[8],a[9],a[10],a[11],a[12],a[13],a[14],a[15]);
   default: fprintf(stderr,"JBP: CallTo32_LargeStack called with unsupported "
                           "number of arguments (%d).  Ignored.\n",nbargs);
            return 0;
   }
 }
 
-WORD CallTo16_word_ ( FARPROC16 func, WORD arg ) { return func(arg); }
-
 extern LRESULT AboutDlgProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT ColorDlgProc(HWND,UINT,WPARAM,LPARAM);
 extern LRESULT ComboBoxWndProc(HWND,UINT,WPARAM,LPARAM);
diff --git a/library/sup.c b/library/sup.c
index 194d7e7eed8ccdd0a24d2e8c33fe9f12b49e8dd5..934ac2befe631649fe4e0392efcef49308d8d3ca 100644
--- a/library/sup.c
+++ b/library/sup.c
@@ -1,7 +1,6 @@
 #include <stdio.h>
 #include <unistd.h>
 #include "windows.h"
-#include "callback.h"
 #include "arch.h"
 #include "neexe.h"
 
diff --git a/loader/builtin.c b/loader/builtin.c
index 4717f66a6eab1f495b8b3f536b8edc565e83d142..a7e618dea756c71ccc14f25cc54c1719134968a6 100644
--- a/loader/builtin.c
+++ b/loader/builtin.c
@@ -350,7 +350,7 @@ LPCSTR BUILTIN_GetEntryPoint32( void *relay )
     static char buffer[80];
     BUILTIN_DLL *dll;
     const void **funcs;
-    int first, i, size;
+    int i;
 
     /* First find the module */
 
@@ -365,19 +365,11 @@ LPCSTR BUILTIN_GetEntryPoint32( void *relay )
         return buffer;
     }
 
-    /* Do a binary search for the function */
+    /* Now find the function */
 
     relay = (BYTE *)relay - 11;  /* The relay entry point is 11 bytes long */
     funcs = dll->descr->u.win32.functions;
-    first = i = 0;
-    size = dll->descr->u.win32.size;
-    while (first < size)
-    {
-        i = (first + size) / 2;
-        if (funcs[i] == relay) break;
-        if (funcs[i] > relay) size = i;
-        else first = i + 1;
-    }
+    for (i = 0; i < dll->descr->u.win32.size;i++) if (*funcs++ == relay) break;
     sprintf( buffer, "%s.%d: %s",
              dll->descr->name, i, dll->descr->u.win32.names[i] );
     return buffer;
diff --git a/loader/module.c b/loader/module.c
index bf4fd5e80cce2bb6fa07486d532fc27a5277942c..82850e775533979cceda649cd87e226c815d765a 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -1100,7 +1100,7 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
 
 	if (pModule->flags & NE_FFLAGS_SELFLOAD)
 	{
-                int fd;
+                HFILE hf;
 		/* Handle self loading modules */
 		SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule);
 		SELFLOADHEADER *selfloadheader;
@@ -1166,9 +1166,9 @@ HINSTANCE LoadModule( LPCSTR name, LPVOID paramBlock )
 
 		}
                 /* FIXME: we probably need a DOS handle here */
-                fd = MODULE_OpenFile( hModule );
-		CallTo16_word_ww (selfloadheader->BootApp,
-			pModule->self_loading_sel, hModule, fd);
+                hf = FILE_DupUnixHandle( MODULE_OpenFile( hModule ) );
+		CallTo16_word_ww( selfloadheader->BootApp, hModule, hf );
+                _lclose(hf);
 		/* some BootApp procs overwrite the selector of dgroup */
 		pSegTable[pModule->dgroup - 1].selector = saved_dgroup;
 		IF1632_Saved16_ss = oldss;
@@ -1536,6 +1536,18 @@ WORD GetExpWinVer( HMODULE16 hModule )
 }
 
 
+/**********************************************************************
+ *	    IsSharedSelector    (KERNEL.345)
+ */
+BOOL16 IsSharedSelector( HANDLE16 selector )
+{
+    /* Check whether the selector belongs to a DLL */
+    NE_MODULE *pModule = MODULE_GetPtr( GetExePtr( selector ));
+    if (!pModule) return FALSE;
+    return (pModule->flags & NE_FFLAGS_LIBMODULE) != 0;
+}
+
+
 /**********************************************************************
  *	    ModuleFirst    (TOOLHELP.59)
  */
diff --git a/loader/ne_image.c b/loader/ne_image.c
index ad5af2fedbcd68157f692722b196d3037a92ad08..a32007eac0caa2524bec6679664b9d768774d276 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -67,6 +67,8 @@ BOOL NE_LoadSegment( HMODULE16 hModule, WORD segnum )
  	SELFLOADHEADER *selfloadheader;
         STACK16FRAME *stack16Top;
  	WORD oldss, oldsp, oldselector, newselector;
+        HFILE hf = FILE_DupUnixHandle( fd );
+
  	selfloadheader = (SELFLOADHEADER *)
  		PTR_SEG_OFF_TO_LIN(pSegTable->selector,0);
  	oldss = IF1632_Saved16_ss;
@@ -84,9 +86,9 @@ BOOL NE_LoadSegment( HMODULE16 hModule, WORD segnum )
         stack16Top->bp = 0;
         stack16Top->ip = 0;
         stack16Top->cs = 0;
-        /* FIXME: we probably need to pass a DOS file handle here */
- 	newselector =  CallTo16_word_www(selfloadheader->LoadAppSeg,
- 		pModule->self_loading_sel, hModule, fd, segnum);
+ 	newselector =  CallTo16_word_www( selfloadheader->LoadAppSeg,
+                                          hModule, hf, segnum );
+        _lclose( hf );
  	if (newselector != oldselector) {
  	  /* Self loaders like creating their own selectors; 
  	   * they love asking for trouble to Wine developers
diff --git a/loader/task.c b/loader/task.c
index bf327904fdc05594b6968592f57d747d90c0775d..b1bea0db8e06e0895d02935481c17b10062005dd 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -25,6 +25,7 @@
 #include "peexe.h"
 #include "pe_image.h"
 #include "queue.h"
+#include "stackframe.h"
 #include "toolhelp.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -61,9 +62,9 @@ static HANDLE hDOSEnvironment = 0;
 static FARPROC16 TASK_RescheduleProc;
 
 #ifdef WINELIB
-#define TASK_SCHEDULE()  TASK_Reschedule();
+#define TASK_SCHEDULE()  TASK_Reschedule()
 #else
-#define TASK_SCHEDULE()  CallTo16_word_(TASK_RescheduleProc,0)
+#define TASK_SCHEDULE()  CallTo16_word_(TASK_RescheduleProc)
 #endif
 
 static HANDLE TASK_CreateDOSEnvironment(void);
@@ -1066,20 +1067,33 @@ void SwitchStackTo( WORD seg, WORD ptr, WORD top )
 {
     TDB *pTask;
     STACK16FRAME *oldFrame, *newFrame;
+    INSTANCEDATA *pData;
+    UINT16 copySize;
 
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
+    if (!(pData = (INSTANCEDATA *)GlobalLock16( seg ))) return;
     dprintf_task( stddeb, "SwitchStackTo: old=%04x:%04x new=%04x:%04x\n",
                   IF1632_Saved16_ss, IF1632_Saved16_sp, seg, ptr );
+
     /* Save the old stack */
-    oldFrame = CURRENT_STACK16;
-    pTask->switchStackSS = IF1632_Saved16_ss;
-    pTask->switchStackSP = IF1632_Saved16_sp;
+
+    oldFrame           = CURRENT_STACK16;
+    pData->old_sp      = IF1632_Saved16_sp;
+    pData->old_ss      = IF1632_Saved16_ss;
+    pData->stacktop    = top;
+    pData->stackmin    = ptr;
+    pData->stackbottom = ptr;
+
     /* Switch to the new stack */
-    IF1632_Saved16_ss = seg;
-    IF1632_Saved16_sp = ptr - sizeof(STACK16FRAME);
+
+    IF1632_Saved16_ss = pTask->ss = seg;
+    IF1632_Saved16_sp = pTask->sp = ptr - sizeof(STACK16FRAME);
     newFrame = CURRENT_STACK16;
-    /* Build the stack frame on the new stack */
-    *newFrame = *oldFrame;
+
+    /* Copy the stack frame and the local variables to the new stack */
+
+    copySize = oldFrame->bp - pData->old_sp;
+    memcpy( newFrame, oldFrame, MAX( copySize, sizeof(STACK16FRAME) ));
 }
 
 
@@ -1094,22 +1108,28 @@ void SwitchStackBack(void)
 {
     TDB *pTask;
     STACK16FRAME *oldFrame, *newFrame;
+    INSTANCEDATA *pData;
 
     if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return;
-    if (!pTask->switchStackSS)
+    if (!(pData = (INSTANCEDATA *)GlobalLock16( IF1632_Saved16_ss ))) return;
+    if (!pData->old_ss)
     {
         fprintf( stderr, "SwitchStackBack: no previous SwitchStackTo\n" );
         return;
     }
     dprintf_task( stddeb, "SwitchStackBack: restoring stack %04x:%04x\n",
-                  pTask->switchStackSS, pTask->switchStackSP );
+                  pData->old_ss, pData->old_sp );
 
     oldFrame = CURRENT_STACK16;
+
     /* Switch back to the old stack */
-    IF1632_Saved16_ss = pTask->switchStackSS;
-    IF1632_Saved16_sp = pTask->switchStackSP;
-    pTask->switchStackSS = 0;
+
+    IF1632_Saved16_ss = pTask->ss = pData->old_ss;
+    IF1632_Saved16_sp = pTask->sp = pData->old_sp;
+    pData->old_ss = pData->old_sp = 0;
+
     /* Build a stack frame for the return */
+
     newFrame = CURRENT_STACK16;
     newFrame->saved_ss = oldFrame->saved_ss;
     newFrame->saved_sp = oldFrame->saved_sp;
@@ -1184,6 +1204,18 @@ int GetInstanceData( HANDLE instance, WORD buffer, int len )
 }
 
 
+/***********************************************************************
+ *           GetExeVersion   (KERNEL.105)
+ */
+WORD GetExeVersion(void)
+{
+    TDB *pTask;
+
+    if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+    return pTask->version;
+}
+
+
 /***********************************************************************
  *           SetErrorMode   (KERNEL.107)
  */
@@ -1222,6 +1254,9 @@ WORD GetNumTasks(void)
 
 /***********************************************************************
  *           GetTaskDS   (KERNEL.155)
+ *
+ * Note: this function apparently returns a DWORD with LOWORD == HIWORD.
+ * I don't think we need to bother with this.
  */
 HINSTANCE16 GetTaskDS(void)
 {
@@ -1245,6 +1280,47 @@ BOOL IsTask( HTASK hTask )
 }
 
 
+/***********************************************************************
+ *           SetTaskSignalProc   (KERNEL.38)
+ */
+FARPROC16 SetTaskSignalProc( HTASK16 hTask, FARPROC16 proc )
+{
+    TDB *pTask;
+    FARPROC16 oldProc;
+
+    if (!hTask) hTask = hCurrentTask;
+    if (!(pTask = (TDB *)GlobalLock16( hTask ))) return NULL;
+    oldProc = pTask->userhandler;
+    pTask->userhandler = proc;
+    return oldProc;
+}
+
+
+/***********************************************************************
+ *           SetSigHandler   (KERNEL.140)
+ */
+WORD SetSigHandler( FARPROC16 newhandler, FARPROC16* oldhandler,
+                    UINT16 *oldmode, UINT16 newmode, UINT16 flag )
+{
+    fprintf(stdnimp,"SetSigHandler(%p,%p,%p,%d,%d), unimplemented.\n",
+            newhandler,oldhandler,oldmode,newmode,flag );
+
+    if (flag != 1) return 0;
+    if (!newmode) newhandler = NULL;  /* Default handler */
+    if (newmode != 4)
+    {
+        TDB *pTask;
+
+        if (!(pTask = (TDB *)GlobalLock16( hCurrentTask ))) return 0;
+        if (oldmode) *oldmode = pTask->signal_flags;
+        pTask->signal_flags = newmode;
+        if (oldhandler) *oldhandler = pTask->sighandler;
+        pTask->sighandler = newhandler;
+    }
+    return 0;
+}
+
+
 /***********************************************************************
  *           GetExePtr   (KERNEL.133)
  */
@@ -1349,15 +1425,3 @@ DWORD GetAppCompatFlags( HTASK32 hTask )
     if (GlobalSize16(hTask) < sizeof(TDB)) return 0;
     return pTask->compat_flags;
 }
-
-
-/***********************************************************************
- *           SetSigHandler   (KERNEL.140)
- */
-WORD SetSigHandler( SEGPTR newhandler,SEGPTR* oldhandler,
-                    LPUINT16 *oldmode,UINT16 newmode,UINT16 flag )
-{
-    fprintf(stdnimp,"SetSigHandler(%lx,%p,%p,%d,%d), unimplemented.\n",
-            newhandler,oldhandler,oldmode,newmode,flag );
-    return 0;
-}
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 176bb5af61279ca461584e3d257df7c0372f14ac..723d577bbc9f502ae87205a417b865b3d2053b38 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -2231,13 +2231,15 @@ static BOOL CFn_HookCallChk(LPCHOOSEFONT lpcf)
 /***********************************************************************
  *                FontFamilyEnumProc                       (COMMDLG.19)
  */
-int FontFamilyEnumProc(LPLOGFONT16 lplf, LPTEXTMETRIC16 lptm, int nFontType, LPARAM lParam)
+INT16 FontFamilyEnumProc( SEGPTR logfont, SEGPTR metrics,
+                          UINT16 nFontType, LPARAM lParam )
 {
   int i;
   WORD w;
   HWND hwnd=LOWORD(lParam);
   HWND hDlg=GetParent(hwnd);
   LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
+  LOGFONT16 *lplf = (LOGFONT16 *)PTR_SEG_TO_LIN( logfont );
 
   dprintf_commdlg(stddeb,"FontFamilyEnumProc: font=%s (nFontType=%d)\n",
      			lplf->lfFaceName,nFontType);
@@ -2268,7 +2270,8 @@ int FontFamilyEnumProc(LPLOGFONT16 lplf, LPTEXTMETRIC16 lptm, int nFontType, LPA
  *
  * Fill font style information into combobox  (without using font.c directly)
  */
-static int SetFontStylesToCombo2(HWND hwnd, HDC hdc, LPLOGFONT16 lplf ,LPTEXTMETRIC16 lptm)
+static int SetFontStylesToCombo2(HWND hwnd, HDC hdc, LPLOGFONT16 lplf,
+                                 LPTEXTMETRIC16 lptm)
 {
    #define FSTYLES 4
    struct FONTSTYLE
@@ -2338,12 +2341,15 @@ static int SetFontSizesToCombo3(HWND hwnd, LPLOGFONT16 lplf, LPCHOOSEFONT lpcf)
 /***********************************************************************
  *                 FontStyleEnumProc                     (COMMDLG.18)
  */
-int FontStyleEnumProc(LPLOGFONT16 lplf ,LPTEXTMETRIC16 lptm, int nFontType, LPARAM lParam)
+INT16 FontStyleEnumProc( SEGPTR logfont, SEGPTR metrics,
+                         UINT16 nFontType, LPARAM lParam )
 {
   HWND hcmb2=LOWORD(lParam);
   HWND hcmb3=HIWORD(lParam);
   HWND hDlg=GetParent(hcmb3);
   LPCHOOSEFONT lpcf=(LPCHOOSEFONT)GetWindowLong32A(hDlg, DWL_USER); 
+  LOGFONT16 *lplf = (LOGFONT16 *)PTR_SEG_TO_LIN(logfont);
+  TEXTMETRIC16 *lptm = (TEXTMETRIC16 *)PTR_SEG_TO_LIN(metrics);
   int i;
   
   dprintf_commdlg(stddeb,"FontStyleEnumProc: (nFontType=%d)\n",nFontType);
@@ -2376,7 +2382,6 @@ LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
   HDC hdc;
   int i,j,res,init=0;
   long l;
-  FARPROC16 enumCallback = MODULE_GetWndProcEntry16("FontFamilyEnumProc");
   LPLOGFONT16 lpxx;
   HCURSOR hcursor=SetCursor(LoadCursor16(0,IDC_WAIT));
   LPCHOOSEFONT lpcf;
@@ -2422,7 +2427,7 @@ LRESULT CFn_WMInitDialog(HWND hDlg, WPARAM wParam, LPARAM lParam)
   hdc= (lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC) ? lpcf->hDC : GetDC(hDlg);
   if (hdc)
   {
-    if (!EnumFontFamilies (hdc, NULL,enumCallback,(LPARAM)GetDlgItem(hDlg,cmb1)))
+    if (!EnumFontFamilies (hdc, NULL,FontFamilyEnumProc,(LPARAM)GetDlgItem(hDlg,cmb1)))
       dprintf_commdlg(stddeb,"WM_INITDIALOG: EnumFontFamilies returns 0\n");
     if (lpcf->Flags & CF_INITTOLOGFONTSTRUCT)
     {
@@ -2610,7 +2615,6 @@ LRESULT CFn_WMCtlColor(HWND hDlg, WPARAM wParam, LPARAM lParam)
 LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
 {
   char buffer[200];
-  FARPROC16 enumCallback;
   HFONT hFont/*,hFontOld*/;
   int i,j;
   long l;
@@ -2634,8 +2638,7 @@ LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
 		        HCURSOR hcursor=SetCursor(LoadCursor16(0,IDC_WAIT));
                         SendDlgItemMessage16(hDlg,cmb1,CB_GETLBTEXT,i,(LPARAM)MAKE_SEGPTR(buffer));
 	                dprintf_commdlg(stddeb,"WM_COMMAND/cmb1 =>%s\n",buffer);
-		        enumCallback = MODULE_GetWndProcEntry16("FontStyleEnumProc");
-       		        EnumFontFamilies(hdc,buffer,enumCallback,
+       		        EnumFontFamilies(hdc,buffer,FontStyleEnumProc,
 		             MAKELONG(GetDlgItem(hDlg,cmb2),GetDlgItem(hDlg,cmb3)));
 		        SetCursor(hcursor);        
 		      }
diff --git a/misc/exec.c b/misc/exec.c
index fb67a0b5c107d3087b58bf104889995e2307df0f..6c6b8444684839081bf4ed861db5940ed0118aa3 100644
--- a/misc/exec.c
+++ b/misc/exec.c
@@ -11,7 +11,6 @@
 #include "heap.h"
 #include "neexe.h"
 #include "shell.h"
-#include "callback.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "win.h"
diff --git a/multimedia/joystick.c b/multimedia/joystick.c
index 821957b734904d5f03e299c3feaa874dc9d13ecd..301ba6c2bc3e76309d3915f4200011427bdb1995 100644
--- a/multimedia/joystick.c
+++ b/multimedia/joystick.c
@@ -12,7 +12,6 @@
 #include <sys/ioctl.h>
 #include "windows.h"
 #include "ldt.h"
-#include "callback.h"
 #include "user.h"
 #include "driver.h"
 #include "mmsystem.h"
diff --git a/multimedia/mcistring.c b/multimedia/mcistring.c
index 5abd42adceca0ebedf6155b0bfbde3c75c19342b..895a11340f8480d7d4e619d7152c5eae0019cd6d 100644
--- a/multimedia/mcistring.c
+++ b/multimedia/mcistring.c
@@ -16,7 +16,6 @@
 #include <sys/ioctl.h>
 #include "windows.h"
 #include "ldt.h"
-#include "callback.h"
 #include "user.h"
 #include "driver.h"
 #include "mmsystem.h"
diff --git a/multimedia/mmsystem.c b/multimedia/mmsystem.c
index 283c9287608bfbda3fa73ad5bd88d4f764cc22ca..e974c8b36611bfd8e787108f4bb9ed1596121532 100644
--- a/multimedia/mmsystem.c
+++ b/multimedia/mmsystem.c
@@ -17,7 +17,6 @@
 #include <sys/ioctl.h>
 #include "windows.h"
 #include "ldt.h"
-#include "callback.h"
 #include "user.h"
 #include "driver.h"
 #include "file.h"
diff --git a/multimedia/time.c b/multimedia/time.c
index b525372141f7611532c2bee2e9dd98d81960e349..299405e1ac4478f4c532419ab07ee7e470264dc2 100644
--- a/multimedia/time.c
+++ b/multimedia/time.c
@@ -72,9 +72,8 @@ static VOID TIME_MMSysTimeCallback( HWND32 hwnd, UINT32 msg,
  *          guess current implementation via SetTimer has to be improved upon.		
  */
 
-		CallTo16_word_wwlll(lpTimer->lpFunc,
-			lpTimer->hInstance, lpTimer->wTimerID, 
-			0, lpTimer->dwUser, 0, 0);
+		CallTimeFuncProc(lpTimer->lpFunc, lpTimer->wTimerID, 
+                                    0, lpTimer->dwUser, 0, 0);
 
 		dprintf_mmtime(stddeb, "MMSysTimeCallback // after CallBack16 !\n");
 		fflush(stdout);
diff --git a/objects/bitmap.c b/objects/bitmap.c
index f609f25c41dd848ef74f2fcfacf9d55ffe66cbf9..afc0b6b06f3240e35d103ecb37bd2531848861be 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -129,8 +129,12 @@ HBITMAP16 CreateCompatibleBitmap( HDC32 hdc, INT32 width, INT32 height )
 
     dprintf_gdi( stddeb, "CreateCompatibleBitmap(%04x,%d,%d) = \n", 
                  hdc, width, height );
-    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
-    
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return 0;
+    }
     hbmpRet = CreateBitmap( width, height, 1, dc->w.bitsPerPixel, NULL );
     dprintf_gdi(stddeb,"\t\t%04x\n", hbmpRet);
     return hbmpRet;
diff --git a/objects/color.c b/objects/color.c
index b7c45a2b8c3af928223d29f3443143402114bdde..308d191b4f2c7af4ee0d75782ef06fb41c90020c 100644
--- a/objects/color.c
+++ b/objects/color.c
@@ -34,10 +34,6 @@
  * http://198.105.232.5/MSDN/LIBRARY/TECHNOTE/CH3.HTM 
  */
 
-extern void BITBLT_SetAccelMode( int ); /* speed up INVERT raster ops whenever possible 
-					 * parameter is a speedup level (see bitblt.c)
-					 */
-
 typedef struct
 { 
     Colormap    colorMap;
@@ -375,9 +371,6 @@ static BOOL COLOR_BuildSharedMap(CSPACE* cs)
 
         cs->size = c_min + NB_RESERVED_COLORS;
 
-	COLOR_gapStart = cs->size/2;
-	COLOR_gapEnd = 256 - cs->size/2;
-
 	XUngrabServer(display);
 
 	dprintf_palette(stddeb,"adjusted size %i colorcells\n", cs->size);
@@ -690,7 +683,7 @@ int COLOR_PaletteLookupExactIndex( PALETTEENTRY* palPalEntry, int size,
     BYTE r = GetRValue(col), g = GetGValue(col), b = GetBValue(col);
     for( i = 0; i < size; i++ )
     {
-        if( palPalEntry[i].peFlags & PC_SYS_USED ) 	/* skip gap */
+        if( palPalEntry[i].peFlags & PC_SYS_USED ) 	/* skips gap */
             if( palPalEntry[i].peRed == r &&
                 palPalEntry[i].peGreen == g &&
                 palPalEntry[i].peBlue == b )
@@ -964,17 +957,15 @@ int COLOR_SetMapping( PALETTEOBJ* palPtr, BOOL mapOnly )
 
                     COLOR_sysPal[index] = palPtr->logpalette.palPalEntry[i];
                     COLOR_sysPal[index].peFlags = flag;
-                    if( COLOR_PaletteToPixel ) index = COLOR_PaletteToPixel[index];
-
 		    COLOR_freeList[index] = 0;
-		    palPtr->logpalette.palPalEntry[i].peFlags = PC_SYS_USED | PC_SYS_MAPPED;
+
+                    if( COLOR_PaletteToPixel ) index = COLOR_PaletteToPixel[index];
                     break;
                 }
                 else if ( cSpace.flags & COLOR_VIRTUAL ) 
                 {
                     index = COLOR_ToPhysical( NULL, 0x00ffffff &
                              *(COLORREF*)(palPtr->logpalette.palPalEntry + i));
-		    palPtr->logpalette.palPalEntry[i].peFlags = PC_SYS_USED;
                     break;     
                 }
 
@@ -983,7 +974,7 @@ int COLOR_SetMapping( PALETTEOBJ* palPtr, BOOL mapOnly )
                 index = COLOR_PaletteLookupPixel(COLOR_sysPal, 256, NULL, 
                        *(COLORREF*)(palPtr->logpalette.palPalEntry + i), TRUE);
             }
-	    palPtr->logpalette.palPalEntry[i].peFlags = PC_SYS_USED;
+	    palPtr->logpalette.palPalEntry[i].peFlags |= PC_SYS_USED;
 
             if( COLOR_PaletteToPixel ) index = COLOR_PaletteToPixel[index];
             break;
diff --git a/objects/dib.c b/objects/dib.c
index ef9f072aed7a2dc7e5d5f3b9a80bde11687e182a..e94b41767dd82d3a3224d2cdaea3e7a27a775261 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -562,13 +562,17 @@ static void DIB_SetImageBits_24( WORD lines, BYTE *bits, WORD width,
  * Helper function for SetDIBits() and SetDIBitsToDevice().
  */
 static int DIB_SetImageBits( DC *dc, WORD lines, WORD depth, LPSTR bits,
-                             DWORD infoWidth, WORD infoBpp, DWORD compression,
+                             DWORD infoWidth, WORD infoBpp,
                              BITMAPINFO *info, WORD coloruse,
 			     Drawable drawable, GC gc, int xSrc, int ySrc,
 			     int xDest, int yDest, int width, int height )
 {
     int *colorMapping;
     XImage *bmpImage;
+    DWORD compression = 0;
+
+    if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
+        compression = info->bmiHeader.biCompression;
 
       /* Build the color mapping table */
 
@@ -647,24 +651,27 @@ INT16 SetDIBits( HDC32 hdc, HBITMAP32 hbitmap, UINT32 startscan, UINT32 lines,
 {
     DC * dc;
     BITMAPOBJ * bmp;
-    DWORD width, height, compression = 0;
+    DWORD width, height;
     WORD bpp;
 
       /* Check parameters */
 
-    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return 0;
+    }
     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
 	return 0;
     if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &bpp ) == -1)
         return 0;
-    if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
-        compression = info->bmiHeader.biCompression;
     if (!lines || (startscan >= (WORD)height)) return 0;
     if (startscan + lines > height) lines = height - startscan;
 
-    return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 17,
+    return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 16,
                                 dc, lines, bmp->bitmap.bmBitsPixel,
-                                bits, width, bpp, compression, info,
+                                bits, width, bpp, info,
                                 coloruse, bmp->pixmap, BITMAP_GC(bmp), 0, 0, 0,
                                 startscan, bmp->bitmap.bmWidth, lines );
 }
@@ -679,16 +686,19 @@ INT16 SetDIBitsToDevice( HDC32 hdc, INT32 xDest, INT32 yDest, DWORD cx,
                          UINT32 coloruse )
 {
     DC * dc;
-    DWORD width, height, compression = 0;
+    DWORD width, height;
     WORD bpp;
 
       /* Check parameters */
 
-    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return 0;
+    }
     if (DIB_GetBitmapInfo( &info->bmiHeader, &width, &height, &bpp ) == -1)
         return 0;
-    if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
-        compression = info->bmiHeader.biCompression;
     if (!lines || (startscan >= height)) return 0;
     if (startscan + lines > height) lines = height - startscan;
     if (ySrc < startscan) ySrc = startscan;
@@ -700,9 +710,9 @@ INT16 SetDIBitsToDevice( HDC32 hdc, INT32 xDest, INT32 yDest, DWORD cx,
 
     DC_SetupGCForText( dc );  /* To have the correct colors */
     XSetFunction( display, dc->u.x.gc, DC_XROPfunction[dc->w.ROPmode-1] );
-    return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 17,
+    return CallTo32_LargeStack( (int(*)())DIB_SetImageBits, 16,
                                 dc, lines, dc->w.bitsPerPixel, bits, width,
-                                bpp, compression, info, coloruse,
+                                bpp, info, coloruse,
                                 dc->u.x.drawable, dc->u.x.gc,
                                 xSrc, ySrc - startscan,
                                 dc->w.DCOrgX + XLPTODP( dc, xDest ),
@@ -726,7 +736,12 @@ int GetDIBits( HDC hdc, HBITMAP hbitmap, WORD startscan, WORD lines,
     int i, x, y;
         
     if (!lines) return 0;
-    if (!(dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC ))) return 0;
+    dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return 0;
+    }
     if (!(bmp = (BITMAPOBJ *)GDI_GetObjPtr( hbitmap, BITMAP_MAGIC )))
 	return 0;
     if (!(palette = (PALETTEOBJ*)GDI_GetObjPtr( dc->w.hPalette, PALETTE_MAGIC )))
diff --git a/objects/font.c b/objects/font.c
index fb4e2346528d0524bab39b269d4934cbecbdd0cb..5cdfd38158a07afad57a86147fd27d07cabdb2d5 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -15,7 +15,6 @@
 #include <X11/Xatom.h>
 #include "font.h"
 #include "metafile.h"
-#include "callback.h"
 #include "options.h"
 #include "string32.h"
 #include "xmalloc.h"
@@ -1124,7 +1123,7 @@ void InitFontsList(void)
 /*************************************************************************
  *				EnumFonts			[GDI.70]
  */
-INT EnumFonts(HDC hDC, LPCSTR lpFaceName, FONTENUMPROC lpEnumFunc, LPARAM lpData)
+INT EnumFonts(HDC hDC, LPCSTR lpFaceName, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
 {
   HANDLE       hLog;
   HANDLE       hMet;
@@ -1178,8 +1177,8 @@ INT EnumFonts(HDC hDC, LPCSTR lpFaceName, FONTENUMPROC lpEnumFunc, LPARAM lpData
     SelectObject(hDC, hOldFont);
     DeleteObject(hFont);
     dprintf_font(stddeb,"EnumFonts // i=%d lpLogFont=%p lptm=%p\n", i, lpLogFont, lptm);
-    nRet = CallEnumFontsProc((FARPROC16)lpEnumFunc, GDI_HEAP_SEG_ADDR(hLog),
-			     GDI_HEAP_SEG_ADDR(hMet), 0, (LONG)lpData );
+    nRet = lpEnumFunc( GDI_HEAP_SEG_ADDR(hLog), GDI_HEAP_SEG_ADDR(hMet),
+                       0, (LONG)lpData );
     if (nRet == 0) {
       dprintf_font(stddeb,"EnumFonts // EnumEnd requested by application !\n");
       break;
@@ -1194,7 +1193,7 @@ INT EnumFonts(HDC hDC, LPCSTR lpFaceName, FONTENUMPROC lpEnumFunc, LPARAM lpData
 /*************************************************************************
  *				EnumFontFamilies	[GDI.330]
  */
-INT EnumFontFamilies(HDC hDC, LPCSTR lpszFamily, FONTENUMPROC lpEnumFunc, LPARAM lpData)
+INT EnumFontFamilies(HDC hDC, LPCSTR lpszFamily, FONTENUMPROC16 lpEnumFunc, LPARAM lpData)
 {
   HANDLE       	hLog;
   HANDLE       	hMet;
@@ -1248,10 +1247,8 @@ INT EnumFontFamilies(HDC hDC, LPCSTR lpszFamily, FONTENUMPROC lpEnumFunc, LPARAM
     DeleteObject(hFont);
     dprintf_font(stddeb, "EnumFontFamilies // i=%d lpLogFont=%p lptm=%p\n", i, lpEnumLogFont, lptm);
     
-    nRet = CallEnumFontFamProc( (FARPROC16)lpEnumFunc,
-			       GDI_HEAP_SEG_ADDR(hLog),
-			       GDI_HEAP_SEG_ADDR(hMet),
-			       0, lpData );
+    nRet = lpEnumFunc( GDI_HEAP_SEG_ADDR(hLog), GDI_HEAP_SEG_ADDR(hMet),
+                       0, lpData );
     if (nRet == 0) {
       dprintf_font(stddeb,"EnumFontFamilies // EnumEnd requested by application !\n");
       break;
diff --git a/objects/gdiobj.c b/objects/gdiobj.c
index 1dffd302d082a5c7ffc26d7fe066fef4535b154a..c4061406cb0ffaf6b81022e58eae02a111ab93e9 100644
--- a/objects/gdiobj.c
+++ b/objects/gdiobj.c
@@ -16,7 +16,6 @@
 #include "palette.h"
 #include "pen.h"
 #include "region.h"
-#include "callback.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
@@ -435,7 +434,8 @@ BOOL UnrealizeObject( HANDLE obj )
 /***********************************************************************
  *           EnumObjects    (GDI.71)
  */
-INT EnumObjects( HDC hdc, INT nObjType, GOBJENUMPROC lpEnumFunc, LPARAM lParam )
+INT EnumObjects( HDC hdc, INT nObjType, GOBJENUMPROC16 lpEnumFunc,
+                 LPARAM lParam )
 {
     /* Solid colors to enumerate */
     static const COLORREF solid_colors[] =
@@ -466,8 +466,7 @@ INT EnumObjects( HDC hdc, INT nObjType, GOBJENUMPROC lpEnumFunc, LPARAM lParam )
             pen->lopnWidth.x = 1;
             pen->lopnWidth.y = 0;
             pen->lopnColor   = solid_colors[i];
-            retval = CallEnumObjectsProc( (FARPROC16)lpEnumFunc,
-                                          SEGPTR_GET(pen), lParam );
+            retval = lpEnumFunc( SEGPTR_GET(pen), lParam );
             dprintf_gdi( stddeb, "EnumObject: solid pen %08lx, ret=%d\n",
                          solid_colors[i], retval);
             if (!retval) break;
@@ -483,8 +482,7 @@ INT EnumObjects( HDC hdc, INT nObjType, GOBJENUMPROC lpEnumFunc, LPARAM lParam )
             brush->lbStyle = BS_SOLID;
             brush->lbColor = solid_colors[i];
             brush->lbHatch = 0;
-            retval = CallEnumObjectsProc( (FARPROC16)lpEnumFunc,
-                                          SEGPTR_GET(brush), lParam );
+            retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
             dprintf_gdi( stddeb, "EnumObject: solid brush %08lx, ret=%d\n",
                          solid_colors[i], retval);
             if (!retval) break;
@@ -496,8 +494,7 @@ INT EnumObjects( HDC hdc, INT nObjType, GOBJENUMPROC lpEnumFunc, LPARAM lParam )
             brush->lbStyle = BS_HATCHED;
             brush->lbColor = RGB(0,0,0);
             brush->lbHatch = i;
-            retval = CallEnumObjectsProc( (FARPROC16)lpEnumFunc,
-                                          SEGPTR_GET(brush), lParam );
+            retval = lpEnumFunc( SEGPTR_GET(brush), lParam );
             dprintf_gdi( stddeb, "EnumObject: hatched brush %d, ret=%d\n",
                          i, retval);
             if (!retval) break;
diff --git a/objects/linedda.c b/objects/linedda.c
index 5ef10f294e9d94df05a82ab54e44bbe417e6056c..be9693f82477dc26950ee0456993110c4cee69db 100644
--- a/objects/linedda.c
+++ b/objects/linedda.c
@@ -2,24 +2,35 @@
  * LineDDA
  *
  * Copyright 1993 Bob Amstadt
- *
  */
 
+#define NO_TRANSITION_TYPES  /* This file is Win32-clean */
 #include <stdlib.h>
 #include "windows.h"
-#include "callback.h"
+
+
+/**********************************************************************
+ *           LineDDA16   (GDI.100)
+ */
+void LineDDA16( INT16 nXStart, INT16 nYStart, INT16 nXEnd, INT16 nYEnd,
+                LINEDDAPROC16 callback, LPARAM lParam )
+{
+    LineDDA32( nXStart, nYStart, nXEnd, nYEnd,
+               (LINEDDAPROC32)callback, lParam );
+}
+
 
 /**********************************************************************
- *		LineDDA		(GDI.100)
+ *           LineDDA32   (GDI32.248)
  */
-void LineDDA(short nXStart, short nYStart, short nXEnd, short nYEnd,
-	     FARPROC16 callback, long lParam)
+BOOL32 LineDDA32( INT32 nXStart, INT32 nYStart, INT32 nXEnd, INT32 nYEnd,
+                  LINEDDAPROC32 callback, LPARAM lParam )
 {
-    int xadd = 1, yadd = 1;
-    int err,erradd;
-    int cnt;
-    int dx = nXEnd - nXStart;
-    int dy = nYEnd - nYStart;
+    INT32 xadd = 1, yadd = 1;
+    INT32 err,erradd;
+    INT32 cnt;
+    INT32 dx = nXEnd - nXStart;
+    INT32 dy = nYEnd - nYStart;
 
     if (dx < 0)  {
       dx = -dx; xadd = -1;
@@ -30,7 +41,7 @@ void LineDDA(short nXStart, short nYStart, short nXEnd, short nYEnd,
     if (dx > dy) { /* line is "more horizontal" */
       err = 2*dy - dx; erradd = 2*dy - 2*dx;
       for(cnt = 0;cnt <= dx; cnt++) {
-	CallLineDDAProc(callback,nXStart,nYStart,lParam);
+        callback(nXStart,nYStart,lParam);
 	if (err > 0) {
 	  nYStart += yadd;
 	  err += erradd;
@@ -42,7 +53,7 @@ void LineDDA(short nXStart, short nYStart, short nXEnd, short nYEnd,
     } else  { /* line is "more vertical" */
       err = 2*dx - dy; erradd = 2*dx - 2*dy;
       for(cnt = 0;cnt <= dy; cnt++) {
-	CallLineDDAProc(callback,nXStart,nYStart,lParam);
+	callback(nXStart,nYStart,lParam);
 	if (err > 0) {
 	  nXStart += xadd;
 	  err += erradd;
@@ -52,4 +63,5 @@ void LineDDA(short nXStart, short nYStart, short nXEnd, short nYEnd,
 	nYStart += yadd;
       }
     }
+    return TRUE;
 }
diff --git a/objects/metafile.c b/objects/metafile.c
index f3fb1a737d70fa740c8f46666058f777342304f2..3c2ad1ab95af295f60dd76da6ab6fa55c41216c3 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -2,7 +2,7 @@
  * Metafile functions
  *
  * Copyright  David W. Metcalfe, 1994
- *            Niels de Carpentier, 1996
+ *            Niels de Carpentier, Albrecht Kleine 1996
  *
  */
 
@@ -12,8 +12,8 @@
 #include "bitmap.h"
 #include "file.h"
 #include "metafile.h"
+#include "stackframe.h"
 #include "stddebug.h"
-#include "callback.h"
 #include "debug.h"
 
 #define HTINCR  10      /* handle table allocation size increment */
@@ -107,7 +107,7 @@ HANDLE CreateMetaFile(LPCSTR lpFilename)
         GDI_FreeObject(handle);
 	return 0;
     }
-    
+    dc->w.bitsPerPixel    = screenDepth;
     mh = (METAHEADER *)GlobalLock16(dc->w.hMetaFile);
 
     mh->mtHeaderSize = MFHEADERSIZE / 2;
@@ -135,14 +135,13 @@ HANDLE CreateMetaFile(LPCSTR lpFilename)
     /* create the handle table */
     HTLen = HTINCR;
     hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT, 
-		      sizeof(HANDLETABLE) * HTLen);
+		      sizeof(HANDLETABLE16) * HTLen);
     
     GlobalUnlock16(dc->w.hMetaFile);
     dprintf_metafile(stddeb,"CreateMetaFile: returning %04x\n", handle);
     return handle;
 }
 
-
 /******************************************************************
  *         CopyMetafile         GDI.151 Niels de Carpentier, April 1996
  */
@@ -163,8 +162,13 @@ HMETAFILE CopyMetaFile(HMETAFILE hSrcMetaFile, LPCSTR lpFilename)
     
     if (lpFilename)          /* disk based metafile */
         {
+        int i,j;
 	hFile = _lcreat(lpFilename, 0);
-	if (_lwrite(hFile, (char *)mh, mh->mtSize * 2) == -1)
+	j=mh->mtType;
+	mh->mtType=1;        /* disk file version stores 1 here */
+	i=_lwrite(hFile, (char *)mh, mh->mtSize * 2) ;
+	mh->mtType=j;        /* restore old value  [0 or 1] */	
+	if (i == -1)
 	    {
 	    _lclose(hFile);
 	    return 0;
@@ -264,7 +268,7 @@ BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf)
 {
     METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
     METARECORD *mr;
-    HANDLETABLE *ht;
+    HANDLETABLE16 *ht;
     int offset = 0;
     WORD i;
 
@@ -272,8 +276,8 @@ BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf)
     
     /* create the handle table */
     hHT = GlobalAlloc16(GMEM_MOVEABLE|GMEM_ZEROINIT,
-		      sizeof(HANDLETABLE) * mh->mtNoObjects);
-    ht = (HANDLETABLE *)GlobalLock16(hHT);
+		      sizeof(HANDLETABLE16) * mh->mtNoObjects);
+    ht = (HANDLETABLE16 *)GlobalLock16(hHT);
 
     /* loop through metafile playing records */
     offset = mh->mtHeaderSize * 2;
@@ -303,7 +307,7 @@ BOOL PlayMetaFile(HDC hdc, HMETAFILE hmf)
  *                                    Niels de carpentier, april 1996
  */
 
-BOOL EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc,LPARAM lpData)
+BOOL EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC16 lpEnumFunc,LPARAM lpData)
 {
     METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
     METARECORD *mr;
@@ -316,7 +320,7 @@ BOOL EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc,LPARAM lpData)
     /* create the handle table */
     
     hHT = GlobalAlloc16(GMEM_MOVEABLE | GMEM_ZEROINIT,
-		     sizeof(HANDLETABLE) * mh->mtNoObjects);
+		     sizeof(HANDLETABLE16) * mh->mtNoObjects);
     ht = WIN16_GlobalLock16(hHT);
    
     offset = mh->mtHeaderSize * 2;
@@ -326,9 +330,8 @@ BOOL EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc,LPARAM lpData)
     while (offset < (mh->mtSize * 2))
     {
 	mr = (METARECORD *)((char *)mh + offset);
-        if (!CallEnumMetafileProc( (FARPROC16)lpEnumFunc, hdc, ht,
-                                   MAKE_SEGPTR(mr),  /* FIXME!! */
-                                   mh->mtNoObjects, (LONG)lpData))
+        if (!lpEnumFunc( hdc, ht, MAKE_SEGPTR(mr),  /* FIXME!! */
+                         mh->mtNoObjects, (LONG)lpData))
 	    break;
 
 	offset += (mr->rdSize * 2);
@@ -340,12 +343,53 @@ BOOL EnumMetaFile(HDC hdc, HMETAFILE hmf, MFENUMPROC lpEnumFunc,LPARAM lpData)
     return TRUE;
 }
 
+/*******************************************************************
+ *   MF_GetDIBitsPointer    [internal helper for e.g. PlayMetaFileRecord]
+ *
+ * Returns offset to DIB bits or 0 if error
+ * (perhaps should be moved to (objects/dib.c ?)
+ */
+static LPSTR MF_GetDIBitsPointer(LPBITMAPINFO info)
+{
+      int offset;
+      if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
+	{
+        if (info->bmiHeader.biClrUsed)
+	  {
+	  if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount))
+	    offset = info->bmiHeader.biClrUsed * 4;
+          else
+	    offset = (1 << info->bmiHeader.biBitCount) * 4;
+          }
+        else
+	  offset = (1 << info->bmiHeader.biBitCount) * 4;
+	}
+      else if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+	{
+	if (info->bmiHeader.biClrUsed)
+	  {
+	  if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount))
+	    offset = info->bmiHeader.biClrUsed * 3;
+          else
+	    offset = (1 << info->bmiHeader.biBitCount) * 3;
+          }
+        else
+	  offset = (1 << info->bmiHeader.biBitCount) * 3;
+	}
+      else
+	{
+	fprintf(stderr,"Unknown size for BITMAPHEADER in MetaFile!\n");
+	return NULL;
+	}
+      return (LPSTR)info + info->bmiHeader.biSize + offset; 
+}
+
 
 /******************************************************************
  *         PlayMetaFileRecord      GDI.176
  */
 
-void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr,
+void PlayMetaFileRecord(HDC hdc, HANDLETABLE16 *ht, METARECORD *mr,
 			                           WORD nHandles)
 {
     short s1;
@@ -603,76 +647,93 @@ void PlayMetaFileRecord(HDC hdc, HANDLETABLE *ht, METARECORD *mr,
 	dprintf_metafile(stddeb,"PlayMetaFileRecord: META_ESCAPE unimplemented.\n");
         break;
 
-    case META_EXTTEXTOUT: /* FIXME: don't know the exact parameters here */
-        {
-        short x,y,options,x5,x6,x7,x8;
-        y=mr->rdParam[0];  /* X position */
-        x=mr->rdParam[1];  /* Y position */
-        s1=mr->rdParam[2]; /* String length */
-        options=mr->rdParam[3];
-        x5=mr->rdParam[(s1+1)/2+4]; /* unknown meaning */
-        x6=mr->rdParam[(s1+1)/2+5]; /* unknown meaning */
-        x7=mr->rdParam[(s1+1)/2+6]; /* unknown meaning */
-        x8=mr->rdParam[(s1+1)/2+7]; /* unknown meaning */
-	ExtTextOut16( hdc, x, y, options, (LPRECT16) &mr->rdParam[(s1+1)/2+4],
-                      (char *)(mr->rdParam + 4), s1, NULL );
-	/* fprintf(stderr,"EXTTEXTOUT (len: %d) %hd : %hd %hd %hd %hd [%s].\n",
-            (mr->rdSize-s1),options,x5,x6,x7,x8,(char*) &(mr->rdParam[4]) );*/
-        }
-        break;
-        /* End new metafile operations. */
+        /* --- Begin of fixed or new metafile operations. July 1996 ----*/
+    case META_EXTTEXTOUT:
+      {
+        LPINT16 dxx;
+        s1=mr->rdParam[2];                              /* String length */
+        if (mr->rdSize-(s1+1))
+         dxx=&mr->rdParam[8+(s1+1)/2];                  /* start of array */
+        else
+         dxx=NULL;                                      /* NO array present */
+          
+	ExtTextOut16( hdc, mr->rdParam[1],              /* X position */
+	                   mr->rdParam[0],              /* Y position */
+	                   mr->rdParam[3],              /* options */
+	                   (LPRECT16) &mr->rdParam[4],  /* rectangle */
+                           (char *)(mr->rdParam + 8),   /* string */
+                           s1, dxx);                    /* length, dx array */
+        if (dxx)                      
+          dprintf_metafile(stddeb,"EXTTEXTOUT len: %ld  (%hd %hd)  [%s].\n",
+            mr->rdSize,dxx[0],dxx[1],(char*) &(mr->rdParam[8]) );
+       }
+       break;
     
     case META_STRETCHDIB:
       {
-      LPSTR bits;
-      LPBITMAPINFO info;
-      int offset;
-      info = (LPBITMAPINFO) &(mr->rdParam[11]);
-      if (info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
-	{
-        if (info->bmiHeader.biClrUsed)
-	  {
-	  if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount))
-	    offset = info->bmiHeader.biClrUsed * 4;
-          else
-	    offset = (1 << info->bmiHeader.biBitCount) * 4;
-          }
-        else
-	  offset = (1 << info->bmiHeader.biBitCount) * 4;
-	}
-      else if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
-	{
-	if (info->bmiHeader.biClrUsed)
-	  {
-	  if (info->bmiHeader.biClrUsed < (1 << info->bmiHeader.biBitCount))
-	    offset = info->bmiHeader.biClrUsed * 3;
-          else
-	    offset = (1 << info->bmiHeader.biBitCount) * 3;
-          }
-        else
-	  offset = (1 << info->bmiHeader.biBitCount) * 3;
-	}
-      else
-	{
-	fprintf(stderr,"Unknown size for BITMAPHEADER in PlayMetaRecord!\n");
-	break;
-	}
-	
-      offset += info->bmiHeader.biSize; 
-      bits = (LPSTR) info + offset;
-      StretchDIBits(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
+       LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[11]);
+       LPSTR bits = MF_GetDIBitsPointer(info);
+       if (bits)
+        StretchDIBits(hdc,mr->rdParam[10],mr->rdParam[9],mr->rdParam[8],
 		    mr->rdParam[7],mr->rdParam[6],mr->rdParam[5],
 		    mr->rdParam[4],mr->rdParam[3],bits,info,
-		    mr->rdParam[2],(DWORD)mr->rdParam[0]);
+		    mr->rdParam[2],MAKELONG(mr->rdParam[0],mr->rdParam[1]));
       }
       break;
-		    
+
+    case META_DIBSTRETCHBLT:
+      {
+       LPBITMAPINFO info = (LPBITMAPINFO) &(mr->rdParam[10]); 
+       LPSTR bits = MF_GetDIBitsPointer(info);
+       if (bits)
+         StretchDIBits(hdc,mr->rdParam[9],mr->rdParam[8],mr->rdParam[7],
+		    mr->rdParam[6],mr->rdParam[5],mr->rdParam[4],
+		    mr->rdParam[3],mr->rdParam[2],bits,info,
+		    DIB_RGB_COLORS,MAKELONG(mr->rdParam[0],mr->rdParam[1]));
+      }
+      break;		  
+
+    case META_STRETCHBLT:
+      {
+       HDC hdcSrc=CreateCompatibleDC(hdc);
+       HBITMAP16 hbitmap=CreateBitmap(mr->rdParam[10], /*Width */
+                                      mr->rdParam[11], /*Height*/
+                                      mr->rdParam[13], /*Planes*/
+                                      mr->rdParam[14], /*BitsPixel*/
+                                      (LPSTR)&mr->rdParam[15]);  /*bits*/
+       SelectObject(hdcSrc,hbitmap);
+       StretchBlt(hdc,mr->rdParam[9],mr->rdParam[8],
+                    mr->rdParam[7],mr->rdParam[6],
+		    hdcSrc,mr->rdParam[5],mr->rdParam[4],
+		    mr->rdParam[3],mr->rdParam[2],
+		    MAKELONG(mr->rdParam[0],mr->rdParam[1]));
+       DeleteDC(hdcSrc);		    
+      }
+      break;
+
+    case META_BITBLT:            /* <-- not yet debugged */
+      {
+       HDC hdcSrc=CreateCompatibleDC(hdc);
+       HBITMAP16 hbitmap=CreateBitmap(mr->rdParam[7]/*Width */,mr->rdParam[8]/*Height*/,
+                            mr->rdParam[10]/*Planes*/,mr->rdParam[11]/*BitsPixel*/,
+                            (LPSTR)&mr->rdParam[12]/*bits*/);
+       SelectObject(hdcSrc,hbitmap);
+       BitBlt(hdc,mr->rdParam[6],mr->rdParam[5],
+                    mr->rdParam[4],mr->rdParam[3],
+		    hdcSrc,
+		    mr->rdParam[2],mr->rdParam[1],
+		    MAKELONG(0,mr->rdParam[0]));
+       DeleteDC(hdcSrc);		    
+      }
+      break;
+
     default:
 	fprintf(stddeb,"PlayMetaFileRecord: Unknown record type %x\n",
 	                                      mr->rdFunction);
     }
 }
 
+
 /******************************************************************
  *         GetMetaFileBits		by William Magro, 19 Sep 1995
  *
@@ -744,7 +805,7 @@ HMETAFILE MF_WriteRecord(HMETAFILE hmf, METARECORD *mr, WORD rlen)
  *    Add a handle to an external handle table and return the index
  */
 
-int MF_AddHandle(HANDLETABLE *ht, WORD htlen, HANDLE hobj)
+int MF_AddHandle(HANDLETABLE16 *ht, WORD htlen, HANDLE hobj)
 {
     int i;
 
@@ -769,7 +830,7 @@ int MF_AddHandle(HANDLETABLE *ht, WORD htlen, HANDLE hobj)
 int MF_AddHandleInternal(HANDLE hobj)
 {
     int i;
-    HANDLETABLE *ht = (HANDLETABLE *)GlobalLock16(hHT);
+    HANDLETABLE16 *ht = (HANDLETABLE16 *)GlobalLock16(hHT);
 
     for (i = 0; i < HTLen; i++)
     {
@@ -784,7 +845,7 @@ int MF_AddHandleInternal(HANDLE hobj)
     if (!(hHT = GlobalReAlloc16(hHT, HTINCR, GMEM_MOVEABLE | GMEM_ZEROINIT)))
 	return -1;
     HTLen += HTINCR;
-    ht = (HANDLETABLE *)GlobalLock16(hHT);
+    ht = (HANDLETABLE16 *)GlobalLock16(hHT);
     *(ht->objectHandle + i) = hobj;
     GlobalUnlock16(hHT);
     return i;
@@ -1158,6 +1219,40 @@ BOOL MF_TextOut(DC *dc, short x, short y, LPCSTR str, short count)
     return handle;
 }
 
+/******************************************************************
+ *         MF_ExtTextOut
+ */
+BOOL MF_ExtTextOut(DC *dc, short x, short y, UINT16 flags, const RECT16 *rect,
+                   LPCSTR str, short count, const INT16 *lpDx)
+{
+    HMETAFILE handle;
+    DWORD len;
+    HANDLE hmr;
+    METARECORD *mr;
+
+    len = sizeof(METARECORD) + (((count + 1) >> 1) * 2) + 4 + sizeof(RECT16);
+    if (lpDx)
+     len+=count*sizeof(INT16);
+    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
+	return FALSE;
+    mr = (METARECORD *)GlobalLock16(hmr);
+    memset(mr, 0, len);
+
+    mr->rdSize = len / 2;
+    mr->rdFunction = META_EXTTEXTOUT;
+    *(mr->rdParam) = y;
+    *(mr->rdParam + 1) = x;
+    *(mr->rdParam + 2) = count;
+    *(mr->rdParam + 3) = flags;
+    memcpy(mr->rdParam + 4, rect, sizeof(RECT16));
+    memcpy(mr->rdParam + 8, str, count);
+    if (lpDx)
+     memcpy(mr->rdParam + 8+ ((count + 1) >> 1),lpDx,count*sizeof(INT16));
+    handle = MF_WriteRecord(dc->w.hMetaFile, mr, mr->rdSize * 2);
+    dc->w.hMetaFile = handle;
+    GlobalFree16(hmr);
+    return handle;
+}
 
 /******************************************************************
  *         MF_MetaPoly - implements Polygon and Polyline
@@ -1192,18 +1287,130 @@ BOOL MF_MetaPoly(DC *dc, short func, LPPOINT16 pt, short count)
 BOOL MF_BitBlt(DC *dcDest, short xDest, short yDest, short width,
 	       short height, HDC hdcSrc, short xSrc, short ySrc, DWORD rop)
 {
-    fprintf(stdnimp,"MF_BitBlt: not implemented yet\n");
-    return FALSE;
+    HMETAFILE handle;
+    DWORD len;
+    HANDLE hmr;
+    METARECORD *mr;
+    DC *dcSrc;
+    BITMAP16  BM;
+
+    if (!(dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ))) return 0;
+    GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
+    len = sizeof(METARECORD) + 12 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
+    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
+	return FALSE;
+    mr = (METARECORD *)GlobalLock16(hmr);
+    mr->rdFunction = META_BITBLT;
+    *(mr->rdParam + 7) = BM.bmWidth;
+    *(mr->rdParam + 8) = BM.bmHeight;
+    *(mr->rdParam + 9) = BM.bmWidthBytes;
+    *(mr->rdParam +10) = BM.bmPlanes;
+    *(mr->rdParam +11) = BM.bmBitsPixel;
+    dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld  rop=%lx  \n",len,rop);
+    if (GetBitmapBits(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,mr->rdParam +12))
+    {
+      mr->rdSize = len / sizeof(INT16);
+      *(mr->rdParam) = HIWORD(rop);
+      *(mr->rdParam + 1) = ySrc;
+      *(mr->rdParam + 2) = xSrc;
+      *(mr->rdParam + 3) = height;
+      *(mr->rdParam + 4) = width;
+      *(mr->rdParam + 5) = yDest;
+      *(mr->rdParam + 6) = xDest;
+      handle = MF_WriteRecord(dcDest->w.hMetaFile, mr, mr->rdSize * 2);
+    }  
+    else
+      handle = 0;  
+    dcDest->w.hMetaFile = handle;
+    GlobalFree16(hmr);
+    return handle;
 }
 
 
-/******************************************************************
- *         MF_StretchBlt
+/**********************************************************************
+ *         MF_StretchBlt         
+ * this function contains TWO ways for procesing StretchBlt in metafiles,
+ * decide between rdFunction values  META_STRETCHBLT or META_DIBSTRETCHBLT
+ * via #define STRETCH_VIA_DIB
  */
+#define STRETCH_VIA_DIB
+#undef  STRETCH_VIA_DIB
 BOOL MF_StretchBlt(DC *dcDest, short xDest, short yDest, short widthDest,
 		   short heightDest, HDC hdcSrc, short xSrc, short ySrc, 
 		   short widthSrc, short heightSrc, DWORD rop)
 {
-    fprintf(stdnimp,"MF_StretchBlt: not implemented yet\n");
-    return FALSE;
+    HMETAFILE handle;
+    DWORD len;
+    HANDLE hmr;
+    METARECORD *mr;
+    DC *dcSrc;
+    BITMAP16  BM;
+#ifdef STRETCH_VIA_DIB    
+    LPBITMAPINFOHEADER lpBMI;
+    WORD nBPP;
+#endif  
+    if (!(dcSrc = (DC *) GDI_GetObjPtr( hdcSrc, DC_MAGIC ))) return 0;
+    GetObject16(dcSrc->w.hBitmap, sizeof(BITMAP16), &BM);
+#ifdef STRETCH_VIA_DIB
+    nBPP = BM.bmPlanes * BM.bmBitsPixel;
+    len = sizeof(METARECORD) + 10 * sizeof(INT16) 
+            + sizeof(BITMAPINFOHEADER) + (nBPP != 24 ? 1 << nBPP: 0) * sizeof(RGBQUAD) 
+              + ((BM.bmWidth * nBPP + 31) / 32) * 4 * BM.bmHeight;
+    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
+	return FALSE;
+    mr = (METARECORD *)GlobalLock16(hmr);
+    mr->rdFunction = META_DIBSTRETCHBLT;
+    lpBMI=(LPBITMAPINFOHEADER)(mr->rdParam+10);
+    lpBMI->biSize      = sizeof(BITMAPINFOHEADER);
+    lpBMI->biWidth     = BM.bmWidth;
+    lpBMI->biHeight    = BM.bmHeight;
+    lpBMI->biPlanes    = 1;
+    lpBMI->biBitCount  = nBPP;                              /* 1,4,8 or 24 */
+    lpBMI->biClrUsed   = nBPP != 24 ? 1 << nBPP : 0;
+    lpBMI->biSizeImage = ((lpBMI->biWidth * nBPP + 31) / 32) * 4 * lpBMI->biHeight;
+    lpBMI->biCompression = BI_RGB;
+    lpBMI->biXPelsPerMeter = MulDiv32(GetDeviceCaps(hdcSrc,LOGPIXELSX),3937,100);
+    lpBMI->biYPelsPerMeter = MulDiv32(GetDeviceCaps(hdcSrc,LOGPIXELSY),3937,100);
+    lpBMI->biClrImportant  = 0;                          /* 1 meter  = 39.37 inch */
+
+    dprintf_metafile(stddeb,"MF_StretchBltViaDIB->len = %ld  rop=%lx  PixYPM=%ld Caps=%d\n",
+               len,rop,lpBMI->biYPelsPerMeter,GetDeviceCaps(hdcSrc,LOGPIXELSY));
+    if (GetDIBits(hdcSrc,dcSrc->w.hBitmap,0,(UINT)lpBMI->biHeight,
+              MF_GetDIBitsPointer((LPBITMAPINFO)lpBMI),    /* DIB bits */
+              (LPBITMAPINFO)lpBMI,DIB_RGB_COLORS))         /* DIB info structure */ 
+#else
+    len = sizeof(METARECORD) + 15 * sizeof(INT16) + BM.bmWidthBytes * BM.bmHeight;
+    if (!(hmr = GlobalAlloc16(GMEM_MOVEABLE, len)))
+	return FALSE;
+    mr = (METARECORD *)GlobalLock16(hmr);
+    mr->rdFunction = META_STRETCHBLT;
+    *(mr->rdParam +10) = BM.bmWidth;
+    *(mr->rdParam +11) = BM.bmHeight;
+    *(mr->rdParam +12) = BM.bmWidthBytes;
+    *(mr->rdParam +13) = BM.bmPlanes;
+    *(mr->rdParam +14) = BM.bmBitsPixel;
+    dprintf_metafile(stddeb,"MF_StretchBlt->len = %ld  rop=%lx  \n",len,rop);
+    if (GetBitmapBits(dcSrc->w.hBitmap,BM.bmWidthBytes * BM.bmHeight,mr->rdParam +15))
+#endif    
+    {
+      mr->rdSize = len / sizeof(INT16);
+      *(mr->rdParam) = LOWORD(rop);
+      *(mr->rdParam + 1) = HIWORD(rop);
+      *(mr->rdParam + 2) = heightSrc;
+      *(mr->rdParam + 3) = widthSrc;
+      *(mr->rdParam + 4) = ySrc;
+      *(mr->rdParam + 5) = xSrc;
+      *(mr->rdParam + 6) = heightDest;
+      *(mr->rdParam + 7) = widthDest;
+      *(mr->rdParam + 8) = yDest;
+      *(mr->rdParam + 9) = xDest;
+      handle = MF_WriteRecord(dcDest->w.hMetaFile, mr, mr->rdSize * 2);
+    }  
+    else
+      handle = 0;  
+    dcDest->w.hMetaFile = handle;
+    GlobalFree16(hmr);
+    return handle;
 }
+
+
diff --git a/objects/palette.c b/objects/palette.c
index 854322a544d0351b47c6c6c6b1f6331cd40b9ba3..ab8f25b703c8691facf9358b29373ef4029c3e54 100644
--- a/objects/palette.c
+++ b/objects/palette.c
@@ -15,8 +15,6 @@
 /* #define DEBUG_PALETTE */
 #include "debug.h"
 
-extern HWND 		DCE_hDC2hWnd( HDC );			/* get associated window by 
-								 * walking DCE list */
 extern int              COLOR_LookupSystemPixel(COLORREF);      /* lookup pixel among static entries 
                                                                  * of the system palette */
 extern COLORREF		COLOR_GetSystemPaletteEntry(BYTE);
@@ -389,7 +387,7 @@ HPALETTE16 SelectPalette( HDC hDC, HPALETTE16 hPal, BOOL bForceBackground )
 
     if( hPal != STOCK_DEFAULT_PALETTE )
     {
-	HWND hWnd = DCE_hDC2hWnd( hDC );
+	HWND hWnd = WindowFromDC( hDC );
 	HWND hActive = GetActiveWindow();
 	
 	/* set primary palette if it's related to current active */
@@ -417,7 +415,7 @@ UINT16 RealizePalette( HDC32 hDC )
 	/* Send palette change notification */
 
 	HWND hWnd;
- 	if( (hWnd = DCE_hDC2hWnd( hDC )) )
+ 	if( (hWnd = WindowFromDC( hDC )) )
             SendMessage16( HWND_BROADCAST, WM_PALETTECHANGED, hWnd, 0L);
     }
     return realized;
@@ -430,7 +428,7 @@ UINT16 RealizePalette( HDC32 hDC )
  */
 int UpdateColors( HDC hDC )
 {
-    HWND hWnd = DCE_hDC2hWnd( hDC );
+    HWND hWnd = WindowFromDC( hDC );
 
     /* Docs say that we have to remap current drawable pixel by pixel
      * but it would take forever given the speed of XGet/PutPixel.
diff --git a/objects/text.c b/objects/text.c
index 5c892d8cc7040947f14ec7f7bea83854a4e5dc43..bbfb6d5082b44fcc7cb1516065010c8889b6fbaf 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -331,7 +331,7 @@ BOOL16 ExtTextOut16( HDC16 hdc, INT16 x, INT16 y, UINT16 flags,
     {
 	dc = (DC *)GDI_GetObjPtr( hdc, METAFILE_DC_MAGIC );
 	if (!dc) return FALSE;
-	MF_TextOut( dc, x, y, str, count );
+	MF_ExtTextOut( dc, x, y, flags, lprect, str, count, lpDx );
 	return TRUE;
     }
 
@@ -616,16 +616,16 @@ BOOL32 TextOut32W( HDC32 hdc, INT32 x, INT32 y, LPCWSTR str, INT32 count )
 
 
 /***********************************************************************
- *		GrayString (USER.185)
+ *           GrayString   (USER.185)
  */
-BOOL GrayString(HDC hdc, HBRUSH hbr, FARPROC16 gsprc, LPARAM lParam, 
+BOOL GrayString(HDC hdc, HBRUSH hbr, GRAYSTRINGPROC16 gsprc, LPARAM lParam, 
 		INT cch, INT x, INT y, INT cx, INT cy)
 {
     BOOL ret;
     COLORREF current_color;
 
     if (!cch) cch = lstrlen16( (LPCSTR)PTR_SEG_TO_LIN(lParam) );
-    if (gsprc) return CallGrayStringProc( gsprc, hdc, lParam, cch );
+    if (gsprc) return gsprc( hdc, lParam, cch );
     current_color = GetTextColor( hdc );
     SetTextColor( hdc, GetSysColor(COLOR_GRAYTEXT) );
     ret = TextOut16( hdc, x, y, (LPCSTR)PTR_SEG_TO_LIN(lParam), cch );
diff --git a/programs/progman/ChangeLog b/programs/progman/ChangeLog
index 9345fd7b4d345e4704107aa236174fe6c95af5d8..d24c29a7fee9317844b3adee0907e350c638bb5d 100644
--- a/programs/progman/ChangeLog
+++ b/programs/progman/ChangeLog
@@ -1,3 +1,8 @@
+Mon Jul 22 20:30:11 1996  Jussi Tirkkonen <jt@modeemi.cs.tut.fi>
+
+	* [Fi.rc] (new)
+	Added Finnish language support.
+
 Sun Jun  2 13:14:55 1996  Ulrich Schmid  <uschmid@mail.hh.provi.de>
 
 	* Program icons: repaint on WM_NCPAINT or WM_PAINTICON
diff --git a/programs/progman/Fi.rc b/programs/progman/Fi.rc
new file mode 100644
index 0000000000000000000000000000000000000000..a38379c045946d50146bbc38cdfb8f4e36d68f9c
--- /dev/null
+++ b/programs/progman/Fi.rc
@@ -0,0 +1,120 @@
+/*
+ * Program Manager
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Finnish language by Jussi Tirkkonen <jt@modeemi.cs.tut.fi>
+ */
+
+#define LANGUAGE_ID                  Fi
+#define LANGUAGE_NUMBER              5
+#define LANGUAGE_MENU_ITEM           "&Suomi"
+
+/* Menu */
+
+#define MENU_FILE                    "&Tiedosto"
+#define MENU_FILE_NEW                "&Uusi..."
+#define MENU_FILE_OPEN               "&Avaa\tEnter"
+#define MENU_FILE_MOVE               "&Siirrä...\tF7"
+#define MENU_FILE_COPY               "&Kopioi...\tF8"
+#define MENU_FILE_DELETE             "&Poista\tDel"
+#define MENU_FILE_ATTRIBUTES         "&Ominaisuudet...\tAlt+Enter"
+#define MENU_FILE_EXECUTE            "Suo&rita..."
+#define MENU_FILE_EXIT               "&Lopeta..."
+
+#define MENU_OPTIONS                 "&Asetukset"
+#define MENU_OPTIONS_AUTO_ARRANGE    "&Järjestä automaattisesti"
+#define MENU_OPTIONS_MIN_ON_RUN      "&Pienennä käytettäessä"
+#define MENU_OPTIONS_SAVE_SETTINGS   "&Tallenna asetukset lopetettaessa"
+
+#define MENU_WINDOWS                 "&Ikkuna"
+#define MENU_WINDOWS_OVERLAP         "&Limittäin\tVaihto+F5"
+#define MENU_WINDOWS_SIDE_BY_SIDE    "&Vierekkäin\tVaihto+F4"
+#define MENU_WINDOWS_ARRANGE         "&Järjestä kuvakkeet"
+
+#define MENU_LANGUAGE                "&Kieli"
+
+#define MENU_HELP                    "&Ohje"
+#define MENU_HELP_CONTENTS           "&Sisällys"
+#define MENU_HELP_SEARCH             "&Etsi ohje aiheesta..."
+#define MENU_HELP_HELP_ON_HELP       "&Ohjeen käyttö"
+#define MENU_HELP_TUTORIAL           "O&petusohjelma"
+
+#define MENU_INFO                    "Ti&etoja..."
+#define MENU_INFO_LICENSE            "&Lisenssi"
+#define MENU_INFO_NO_WARRANTY        "&OMALLA VASTUULLA"
+#define MENU_INFO_ABOUT_WINE         "&Tietoja WINEstä"
+
+/* Dialogs */
+
+#define DIALOG_OK                    "OK"
+#define DIALOG_CANCEL                "Peruuta"
+#define DIALOG_BROWSE                "&Selaa"
+#define DIALOG_HELP                  "&Ohje"
+
+#define DIALOG_NEW_CAPTION           "Uusi ilmentymä"
+#define DIALOG_NEW_NEW               "Uusi"
+#define DIALOG_NEW_GROUP             "Ohjelma&ryhmä"
+#define DIALOG_NEW_PROGRAM           "Ohjelma&"
+
+#define DIALOG_MOVE_CAPTION          "Siirrä"
+#define DIALOG_MOVE_PROGRAM          "Siirrä ohjelma:"
+#define DIALOG_MOVE_FROM_GROUP       "Ryhmästä:"
+#define DIALOG_MOVE_TO_GROUP         "&Ryhmään:"
+
+#define DIALOG_COPY_CAPTION          "Kopioi"
+#define DIALOG_COPY_PROGRAM          "Kopioi ohjelma:"
+#define DIALOG_COPY_FROM_GROUP       DIALOG_MOVE_FROM_GROUP
+#define DIALOG_COPY_TO_GROUP         DIALOG_MOVE_TO_GROUP
+
+#define DIALOG_GROUP_CAPTION         "Ohjelmaryhmän ominaisuudet"
+#define DIALOG_GROUP_DESCRIPTION     "&Kuvaus:"
+#define DIALOG_GROUP_FILE            "&Ryhmätiedosto:"
+
+#define DIALOG_PROGRAM_CAPTION       "Ohjelman ominaisuudet"
+#define DIALOG_PROGRAM_DESCRIPTION   DIALOG_GROUP_DESCRIPTION
+#define DIALOG_PROGRAM_COMMAND_LINE  "K&omentorivi:"
+#define DIALOG_PROGRAM_DIRECTORY     "&Työhakemisto:"
+#define DIALOG_PROGRAM_HOT_KEY       "&Pikanäppäin:"
+#define DIALOG_PROGRAM_SYMBOL        "Suo&rita kuvakkeena"
+#define DIALOG_PROGRAM_OTHER_SYMBOL  "&Vaihda kuvaketta..."
+
+#define DIALOG_SYMBOL_CAPTION        "Valitse kuvake"
+#define DIALOG_SYMBOL_FILE           "&Nimi:"
+#define DIALOG_SYMBOL_CURRENT        "Nykyinen &kuvake:"
+
+#define DIALOG_EXECUTE_CAPTION       "Suorita ohjelma"
+#define DIALOG_EXECUTE_COMMAND_LINE  DIALOG_PROGRAM_COMMAND_LINE
+#define DIALOG_EXECUTE_SYMBOL        DIALOG_PROGRAM_SYMBOL
+
+/* Strings */
+
+#define STRING_PROGRAM_MANAGER            "Järjestemänhallinta"
+#define STRING_ERROR                      "VIRHE"
+#define STRING_WARNING                    "VAROITUS"
+#define STRING_INFO                       "Tietoja"
+#define STRING_DELETE                     "Poista"
+#define STRING_DELETE_GROUP_s             "Poista ryhmä `%s' ?"
+#define STRING_DELETE_PROGRAM_s           "Poista ohjelma `%s' ?"
+#define STRING_NOT_IMPLEMENTED            "Ei käytettävissä"
+#define STRING_FILE_READ_ERROR_s          "Virhe luettaessa `%s'"
+#define STRING_FILE_WRITE_ERROR_s         "Virhe kirjoitettaessa `%s'"
+
+#define STRING_GRPFILE_READ_ERROR_s       "\
+Ryhmätiedostoa `%s' ei voida avata.\n\
+Yritetäänkö uudestaan?"
+
+#define STRING_OUT_OF_MEMORY              "Muisti lopussa"
+#define STRING_WINHELP_ERROR              "Ohje ei käytettävissä"
+#define STRING_UNKNOWN_FEATURE_s          "Tuntematon ominaisuus %s:ssa"
+#define STRING_FILE_NOT_OVERWRITTEN_s     "Tiedosto `%s' on olemassa. Tiedostoa ei muutettu."
+#define STRING_SAVE_GROUP_AS_s            "Tallenna ryhmä nimellä `%s' alkuperäisten tiedostojen säilyttämiseksi"
+
+#define STRING_NO_HOT_KEY                 "Ei mitään"
+
+#define STRING_ALL_FILES                  "Kaikki tiedostot (*.*)"
+#define STRING_PROGRAMS                   "Ohjelmat"
+#define STRING_LIBRARIES_DLL              "Kirjastot (*.dll)"
+#define STRING_SYMBOL_FILES               "Symbolitiedostot"
+#define STRING_SYMBOLS_ICO                "Kuvakkeet (*.ico)"
+
+#include "Xx.rc"
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
index 8db65d25e19f5f6797f56cb1e5ef028312a1bdb3..63da670dc46f7b65d4a656e6d64b09df1d8a697f 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -3,7 +3,7 @@ MODULE   = none
 PROGRAMS = progman
 ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
 
-LANGUAGES   = En De Fr
+LANGUAGES   = En De Fr Fi
 LICENSELANG = En
 
 # Installation infos
diff --git a/programs/progman/main.c b/programs/progman/main.c
index 1dd5e6d0b5a774d707b246b6bca3fa700a1ea09a..e8590e24aa2319a007f25eee236faf990c6e99e7 100644
--- a/programs/progman/main.c
+++ b/programs/progman/main.c
@@ -15,6 +15,7 @@
 void LIBWINE_Register_accel();
 void LIBWINE_Register_De();
 void LIBWINE_Register_En();
+void LIBWINE_Register_Fi();
 void LIBWINE_Register_Fr();
 #endif
 
@@ -43,6 +44,7 @@ int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
   LIBWINE_Register_accel();
   LIBWINE_Register_De();
   LIBWINE_Register_En();
+  LIBWINE_Register_Fi();
   LIBWINE_Register_Fr();
 #endif
 
diff --git a/programs/winhelp/ChangeLog b/programs/winhelp/ChangeLog
index 9af4b054e1ba99d5f58563a98fb98689b1d6cd1b..aa692bcbb543e2b097c789582210110b6c90892c 100644
--- a/programs/winhelp/ChangeLog
+++ b/programs/winhelp/ChangeLog
@@ -1,3 +1,8 @@
+Mon Jul 22 20:30:11 1996  Jussi Tirkkonen <jt@modeemi.cs.tut.fi>
+
+	* [Fi.rc] (new)
+	Added Finnish language support.
+
 Sat May 18 11:06:02 1996  Pablo Saratxaga <srtxg@f2219.n293.z2.fidonet.org>
 
 	* [Fr.rc] (new)
diff --git a/programs/winhelp/Fi.rc b/programs/winhelp/Fi.rc
new file mode 100644
index 0000000000000000000000000000000000000000..8d929f3b9e0f5d3b57b3293b3833315dbd9a5eb5
--- /dev/null
+++ b/programs/winhelp/Fi.rc
@@ -0,0 +1,49 @@
+/*
+ * Help Viewer
+ *
+ * Copyright 1996 Ulrich Schmid
+ * Finnish language by Jussi Tirkkonen <jt@modeemi.cs.tut.fi>
+ */
+
+/* This file is not yet complete !! */
+
+#define LANGUAGE_ID                  Fi
+#define LANGUAGE_NUMBER              5
+
+/* Menu */
+
+#define MENU_FILE                    "&Tiedosto"
+#define MENU_FILE_OPEN               "&Avaa..."
+#define MENU_FILE_PRINT              "&Tulosta"
+#define MENU_FILE_PRINTER_SETUP      "&Kirjoittimen asetukset..."
+#define MENU_FILE_EXIT               "&Lopeta"
+
+#define MENU_EDIT                    "&Muokkaa"
+#define MENU_EDIT_COPY_DIALOG        "&Kopioi..."
+#define MENU_EDIT_ANNOTATE           "&Huomautus..."
+
+#define MENU_BOOKMARK                "&Kirjanmerkki"
+#define MENU_BOOKMARK_DEFINE         "&Aseta..."
+
+#define MENU_HELP                    "&Ohje"
+#define MENU_HELP_ON_HELP            "&Ohjeen käyttö"
+#define MENU_HELP_ON_TOP             "&Aina päällimmäisenä"
+#define MENU_HELP_INFO               "T&ietoja..."
+#define MENU_HELP_ABOUT_WINE         "&Tietoja WINEstä"
+
+/* Strings */
+
+#define STRING_WINE_HELP             "WINE Ohje"
+#define STRING_ERROR                 "VIRHE"
+#define STRING_WARNING               "VAROITUS"
+#define STRING_INFO                  "Tietoja"
+#define STRING_NOT_IMPLEMENTED       "Ei käytettävissä"
+#define STRING_HLPFILE_ERROR_s       "Virhe luettaessa ohjetiedostoa `%s'" 
+#define STRING_CONTENTS              "&Sisällys"
+#define STRING_SEARCH                "&Etsi"
+#define STRING_BACK                  "&Takaisin"
+#define STRING_HISTORY               "&Luetut"
+#define STRING_ALL_FILES             "Kaikki tiedostot (*.*)"
+#define STRING_HELP_FILES_HLP        "Ohjetiedostot (*.hlp)"
+
+#include "Xx.rc"
diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in
index 0499f9f807de973266f6e5492e56fca1bb24aaa9..5f6afa301ac2fafe23072167ef1b7d5483852859 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -3,7 +3,7 @@ MODULE   = none
 PROGRAMS = winhelp hlp2sgml
 ALL_LIBS = $(WINELIB) $(X_LIBS) $(XPM_LIB) $(XLIB) $(LDLIBS)
 
-LANGUAGES   = En De Fr
+LANGUAGES   = En De Fr Fi
 
 # Installation infos
 
diff --git a/programs/winhelp/winhelp.c b/programs/winhelp/winhelp.c
index 594efe08af33ef8c11b31b0e20758712e0b3db13..177ea49ee72f600296dc89bd6fc5c833aaa508ec 100644
--- a/programs/winhelp/winhelp.c
+++ b/programs/winhelp/winhelp.c
@@ -16,6 +16,7 @@ extern const char people[];
 
 VOID LIBWINE_Register_De(void);
 VOID LIBWINE_Register_En(void);
+VOID LIBWINE_Register_Fi(void);
 VOID LIBWINE_Register_Fr(void);
 
 static BOOL    WINHELP_RegisterWinClasses();
@@ -53,6 +54,7 @@ int PASCAL WinMain (HANDLE hInstance, HANDLE prev, LPSTR cmdline, int show)
   /* Register resources */
   LIBWINE_Register_De();
   LIBWINE_Register_En();
+  LIBWINE_Register_Fi();
   LIBWINE_Register_Fr();
 #endif
 
diff --git a/tools/build.c b/tools/build.c
index 1e0d7b62e8d10cfc2df9d232a0e229cd7020079e..3f18bdeb934c11267f038456ec43e1af4cf5b0be 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1652,17 +1652,16 @@ static void BuildCallFrom16Func( char *profile )
  *
  * Stack frame of the callback function:
  *  ...      ...
- * (ebp+24) arg2
- * (ebp+20) arg1
- * (ebp+16) 16-bit ds
+ * (ebp+20) arg2
+ * (ebp+16) arg1
  * (ebp+12) func to call
  * (ebp+8)  code selector
  * (ebp+4)  return address
  * (ebp)    previous ebp
  *
  * Prototypes for the CallTo16 functions:
- *   extern WORD CallTo16_word_xxx( FARPROC16 func, WORD ds, args... );
- *   extern LONG CallTo16_long_xxx( FARPROC16 func, WORD ds, args... );
+ *   extern WORD CallTo16_word_xxx( FARPROC16 func, args... );
+ *   extern LONG CallTo16_long_xxx( FARPROC16 func, args... );
  *   extern void CallTo16_regs_( FARPROC16 func, WORD ds, WORD es, WORD bp,
  *                               WORD ax, WORD bx, WORD cx, WORD dx,
  *                               WORD si, WORD di );
@@ -1753,10 +1752,10 @@ static void BuildCallTo16Func( char *profile )
     }
     else  /* not a register function */
     {
-        int pos = 20;  /* first argument position */
+        int pos = 16;  /* first argument position */
 
         /* Make %bp point to the previous stackframe (built by CallFrom16) */
-        printf( "\tmovw %%sp,%%bp\n" );
+        printf( "\tmovzwl %%sp,%%ebp\n" );
         printf( "\taddw $16,%%bp\n" );
 
         while (*args)
@@ -1793,8 +1792,9 @@ static void BuildCallTo16Func( char *profile )
     }
     else
     {
-        /* Set ax equal to ds for window procedures */
-        printf( "\tmovw 16(%%ebx),%%ax\n" );
+        /* Get previous ds from the 16-bit stack and */
+        /* set ax equal to ds for window procedures. */
+        printf( "\tmovw -10(%%ebp),%%ax\n" );
 #ifdef __svr4__
         printf( "\tdata16\n");
 #endif
diff --git a/win32/Makefile.in b/win32/Makefile.in
index 634e87bee4d62db138b6bff2004c84c030b2fac6..df4f9b6a891bb5b6fa79cf69bca62ff5308f5167 100644
--- a/win32/Makefile.in
+++ b/win32/Makefile.in
@@ -11,6 +11,7 @@ C_SRCS = \
 	error.c \
 	except.c \
 	file.c \
+	findfile.c \
 	init.c \
 	memory.c \
 	newfns.c \
diff --git a/win32/file.c b/win32/file.c
index 5e5ad28bd1a00955ebd39e122c962a8258497aa3..ffb0b2fb1a845bcfbd0e3b3c9b8b03978cc61ba1 100644
--- a/win32/file.c
+++ b/win32/file.c
@@ -500,3 +500,18 @@ DWORD GetFileAttributesA(LPCSTR lpFileName)
 		res |= FILE_ATTRIBUTE_READONLY;
 	return res;
 }
+
+/**************************************************************************
+ *              SetFileAttributes
+ */
+BOOL SetFileAttributes32A(LPCSTR lpFileName, DWORD attributes)
+
+{
+	struct stat buf;
+	DWORD	res=0;
+	char	*fn;
+
+	fprintf(stdnimp,"Call to stub function SetFileAttributesA(%s, %08x)\n",lpFileName, attributes);
+	return TRUE;
+}
+
diff --git a/win32/findfile.c b/win32/findfile.c
new file mode 100644
index 0000000000000000000000000000000000000000..47b9d9ec647368489f6e0ea013b7bb383c670d40
--- /dev/null
+++ b/win32/findfile.c
@@ -0,0 +1,54 @@
+#include <sys/types.h>
+#include <dirent.h>
+#include <string.h>
+#include "xmalloc.h"
+#include "windows.h"
+#include "winbase.h"
+#include "dos_fs.h"
+
+HANDLE32 FindFirstFile32A(LPCSTR lpfilename, 
+			  LPWIN32_FIND_DATA32A lpFindFileData)
+
+{
+	char *unixpath = DOSFS_GetUnixFileName(lpfilename, FALSE);
+	char *p;
+	char *path;
+	char *mask;
+	DIR *dir;
+	struct dirent *dirent;
+	int namelen;
+	char *foundname;
+
+	if (!unixpath) {
+		/* FIXME: SetLastError(??) */
+		return INVALID_HANDLE_VALUE;
+	}
+	p = strrchr(unixpath, '/');
+	if (p) {
+		*p = '\0';
+		path = unixpath;
+		mask = p + 1;
+	} else {
+		path = ".";
+		mask = unixpath;
+	}
+	dir = opendir(path);
+	if (!dir) {
+		/* FIXME: SetLastError(??) */
+		return INVALID_HANDLE_VALUE;
+	}
+	while ((dirent = readdir(dir)) != NULL) {
+		if (!DOSFS_Match(DOSFS_Hash(dirent->d_name, TRUE)))
+			continue;
+		/* FIXME: Ought to fiddle to avoid
+                   returning ./.. in drive root */
+		namelen = strlen(path) + strlen(dirent->d_name);
+		foundname = xmalloc(namelen+1);
+		strcpy(foundname, path);
+		strcat(foundname, dirent->d_name);
+		strcpy(lpFindFileData->FileName, DOSFS_GetDosTrueName(foundname, TRUE));
+		free(foundname);
+		return dir;
+	}
+	return INVALID_HANDLE_VALUE;
+}
diff --git a/win32/memory.c b/win32/memory.c
index 4b78f3d80e5f9a236587b3a225884595e7bdd9d5..952c2e270b4584911509a3d8ab546cbe29b819ce 100644
--- a/win32/memory.c
+++ b/win32/memory.c
@@ -5,7 +5,6 @@
  */
 
 #include <fcntl.h>
-#include <malloc.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/time.h>
diff --git a/win32/newfns.c b/win32/newfns.c
index 805ed2e189eb5ff3b2379daf9adcfe0a51c74e82..31d116bca667e630baba7dd750fec9e5b268d720 100644
--- a/win32/newfns.c
+++ b/win32/newfns.c
@@ -29,7 +29,15 @@ HHOOK SetWindowsHookEx32A(int HookId, HOOKPROC32 hookfn, HINSTANCE hModule,
 
 {
 	/* Stub for now */
-	fprintf(stdnimp, "WIN32_SetWindowsHookEx Stub called!\n");
+	fprintf(stdnimp, "SetWindowsHookEx32A Stub called! (hook Id %d)\n", HookId);
 	
 	return (HHOOK) NULL;
 }
+
+BOOL UnhookWindowsHookEx32(HHOOK hHook)
+
+{
+	/* Stub for now */
+	fprintf(stdnimp, "UnhookWindowsHookEx32 Stub called!\n");
+	return FALSE;
+}
diff --git a/win32/user32.c b/win32/user32.c
index 4451e2a572235d8d763b255c44999f7c4e49bfbb..594e0b63bde7f9518064c9f0082c03e55163830f 100644
--- a/win32/user32.c
+++ b/win32/user32.c
@@ -33,6 +33,16 @@ BOOL USER32_GetMessageA(MSG32* lpmsg,DWORD hwnd,DWORD min,DWORD max)
 	return ret;
 }
 
+/***********************************************************************
+ *          IsDialogMessageA     (USER32.341)
+ */
+BOOL IsDialogMessage32A(DWORD hwnd, MSG32* lpmsg)
+{
+	MSG16 msg;
+	STRUCT32_MSG32to16(lpmsg, &msg);
+	return IsDialogMessage(hwnd, &msg);
+}
+
 /***********************************************************************
  *         DispatchMessageA       (USER32.140)
  */
diff --git a/windows/dce.c b/windows/dce.c
index 97fc7f5e978bd233de685ce4c12e0d2692261413..58ada2a3a3a180978d7fe3f2c119203cc91ac852 100644
--- a/windows/dce.c
+++ b/windows/dce.c
@@ -118,11 +118,11 @@ HANDLE DCE_FindDCE(HDC hDC)
 }
 
 /**********************************************************************
- *	    DCE_hDC2hWnd
+ *          WindowFromDC   (USER.117) (USER32.580)
  */
-HWND DCE_hDC2hWnd(HDC hDC)
+HWND16 WindowFromDC( HDC32 hDC )
 {
- HANDLE hdce = DCE_FindDCE(hDC); 
+ HANDLE16 hdce = DCE_FindDCE(hDC); 
 
  if( hdce )
    {
diff --git a/windows/defdlg.c b/windows/defdlg.c
index 0ddbea88596d1e8b52a066b531196606a4be5a27..c91c6075f0a0b6fb5816bd3b071d11ffdfc9ba14 100644
--- a/windows/defdlg.c
+++ b/windows/defdlg.c
@@ -40,7 +40,6 @@ static BOOL DEFDLG_SaveFocus( HWND hwnd, DIALOGINFO *infoPtr )
     HWND hwndFocus = GetFocus();
 
     if (!hwndFocus || !IsChild( hwnd, hwndFocus )) return FALSE;
-    if (!infoPtr->hwndFocus) return FALSE;  /* Already saved */
     infoPtr->hwndFocus = hwndFocus;
       /* Remove default button */
     return TRUE;
@@ -60,7 +59,6 @@ static BOOL DEFDLG_RestoreFocus( HWND hwnd, DIALOGINFO *infoPtr )
 }
 
 
-#ifdef SUPERFLUOUS_FUNCTIONS
 /***********************************************************************
  *           DEFDLG_FindDefButton
  *
@@ -77,7 +75,6 @@ static HWND DEFDLG_FindDefButton( HWND hwndDlg )
     }
     return hwndChild;
 }
-#endif
 
 
 /***********************************************************************
@@ -117,6 +114,8 @@ static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo,
 static LRESULT DEFDLG_Proc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
                             LPARAM lParam, DIALOGINFO *dlgInfo )
 {
+    HWND hwndDefId;
+
     switch(msg)
     {
 	case WM_INITDIALOG:
@@ -177,8 +176,13 @@ static LRESULT DEFDLG_Proc( HWND32 hwnd, UINT32 msg, WPARAM32 wParam,
             return 1;
 
         case DM_GETDEFID:
-            if (dlgInfo->fEnd || !dlgInfo->msgResult) return 0;
-            return MAKELONG( dlgInfo->msgResult, DC_HASDEFID );
+            if (dlgInfo->fEnd) return 0;
+	    if (dlgInfo->msgResult)
+	      return MAKELONG( dlgInfo->msgResult, DC_HASDEFID );
+	    hwndDefId = DEFDLG_FindDefButton( hwnd );
+	    if (hwndDefId)
+	      return MAKELONG( GetDlgCtrlID( hwndDefId ), DC_HASDEFID);
+	    return 0;
 
 	case WM_NEXTDLGCTL:
 	    {
diff --git a/windows/dialog.c b/windows/dialog.c
index 9faec22acccd8003c6fde86e53bc6d5f6641a641..3fbcb141198b7aad7b5cf7964fc3c9034605770a 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -550,7 +550,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCSTR dlgTemplate,
     {
         rect.left += template.x * xUnit / 4;
         rect.top += template.y * yUnit / 8;
-        if (!(template.style & DS_ABSALIGN))
+        if ( !(template.style & DS_ABSALIGN) && !(template.style & WS_CHILD) )
             ClientToScreen16( owner, (POINT16 *)&rect );
     }
 
@@ -1160,7 +1160,7 @@ BOOL16 CheckDlgButton( HWND32 hwnd, INT32 id, UINT32 check )
  */
 WORD IsDlgButtonChecked( HWND hwnd, WORD id )
 {
-    return (WORD)SendDlgItemMessage16( hwnd, id, BM_GETCHECK16, 0, 0 );
+    return (WORD)SendDlgItemMessage32A( hwnd, id, BM_GETCHECK32, 0, 0 );
 }
 
 
diff --git a/windows/event.c b/windows/event.c
index f00cfe94b49c4282eb587320afcf6aba143b8f81..9ea4349635b408db3c3f771202e306358267ba9d 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -148,6 +148,7 @@ static void EVENT_SelectionRequest( WND *pWnd, XSelectionRequestEvent *event);
 static void EVENT_SelectionNotify( XSelectionEvent *event);
 static void EVENT_SelectionClear( WND *pWnd, XSelectionClearEvent *event);
 static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event );
+static void EVENT_MapNotify( HWND hwnd, XMapEvent *event );
 
 /* Usable only with OLVWM - compile option perhaps?
 static void EVENT_EnterNotify( WND *pWnd, XCrossingEvent *event );
@@ -238,7 +239,20 @@ void EVENT_ProcessEvent( XEvent *event )
  *       break;
  */
     case NoExpose:
-	break;   
+	break;
+
+    /* We get all these because of StructureNotifyMask. */
+    case UnmapNotify:
+    case CirculateNotify:
+    case CreateNotify:
+    case DestroyNotify:
+    case GravityNotify:
+    case ReparentNotify:
+	break;
+
+    case MapNotify:
+	EVENT_MapNotify( pWnd->hwndSelf, (XMapEvent *)event );
+	break;
 
     default:    
 	dprintf_event(stddeb, "Unprocessed event %s for hwnd %04x\n",
@@ -843,6 +857,19 @@ static void EVENT_ClientMessage( WND *pWnd, XClientMessageEvent *event )
   }
  */ 
 
+/**********************************************************************
+ *		EVENT_MapNotify
+ */
+void EVENT_MapNotify( HWND hWnd, XMapEvent *event )
+{
+    HWND hwndFocus = GetFocus();
+
+    if (hwndFocus && IsChild( hWnd, hwndFocus ))
+      FOCUS_SetXFocus(hwndFocus);
+
+    return;
+}
+
 /**********************************************************************
  *		SetCapture 	(USER.18)
  */
diff --git a/windows/focus.c b/windows/focus.c
index 1c2802587a6aaee63c209bf551923bda57000174..f2c7f20d15bed8d84165c9cd7b98e715fd2f7f17 100644
--- a/windows/focus.c
+++ b/windows/focus.c
@@ -11,6 +11,7 @@
 #include "winpos.h"
 #include "hook.h"
 #include "color.h"
+#include "message.h"
 #include "options.h"
 
 static HWND hwndFocus = 0;
@@ -21,7 +22,7 @@ static HWND hwndFocus = 0;
  * Set the X focus.
  * Explicit colormap management seems to work only with OLVWM.
  */
-static void FOCUS_SetXFocus( HWND hwnd )
+void FOCUS_SetXFocus( HWND hwnd )
 {
     XWindowAttributes win_attr;
     Window win;
@@ -47,6 +48,8 @@ static void FOCUS_SetXFocus( HWND hwnd )
     XSetInputFocus( display, win, RevertToParent, CurrentTime );
     if (COLOR_GetSystemPaletteFlags() & COLOR_PRIVATE)
         XInstallColormap( display, COLOR_GetColormap() );
+
+    EVENT_Synchronize();
 }
 
 /*****************************************************************
diff --git a/windows/graphics.c b/windows/graphics.c
index ef7806de652ea55df6b4eb9c2391338502408299..221bc0241cf66a351e49561e37efcce7f0376e8d 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -453,7 +453,10 @@ INT16 FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
 {
     HBRUSH prevBrush;
 
-    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
+    /* coordinates are logical so we cannot fast-check rectangle
+     * - do it in PatBlt() after LPtoDP().
+     */
+
     if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
     PatBlt( hdc, rect->left, rect->top,
 	    rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
@@ -469,7 +472,6 @@ INT32 FillRect32( HDC32 hdc, const RECT32 *rect, HBRUSH32 hbrush )
 {
     HBRUSH prevBrush;
 
-    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
     if (!(prevBrush = SelectObject( hdc, (HBRUSH16)hbrush ))) return 0;
     PatBlt( hdc, rect->left, rect->top,
 	    rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
@@ -483,7 +485,6 @@ INT32 FillRect32( HDC32 hdc, const RECT32 *rect, HBRUSH32 hbrush )
  */
 void InvertRect16( HDC16 hdc, const RECT16 *rect )
 {
-    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return;
     PatBlt( hdc, rect->left, rect->top,
 	    rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
 }
@@ -494,7 +495,6 @@ void InvertRect16( HDC16 hdc, const RECT16 *rect )
  */
 void InvertRect32( HDC32 hdc, const RECT32 *rect )
 {
-    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return;
     PatBlt( hdc, rect->left, rect->top,
 	    rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
 }
@@ -511,13 +511,13 @@ INT16 FrameRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) return FALSE;
 
-    if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
-    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
-    
     left   = XLPTODP( dc, rect->left );
     top    = YLPTODP( dc, rect->top );
     right  = XLPTODP( dc, rect->right );
     bottom = YLPTODP( dc, rect->bottom );
+
+    if ( (right <= left) || (bottom <= top) ) return 0;
+    if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
     
     if (DC_SetupGCForBrush( dc ))
     {
diff --git a/windows/hook.c b/windows/hook.c
index e9cb15879be1f2b7ed1f411e73425c89e25a523e..a8bc38b8ae1f1e553fe1270c2c2b977e630e7cff 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -15,6 +15,7 @@
 
 #define NO_TRANSITION_TYPES  /* This file is Win32-clean */
 #include "hook.h"
+#include "callback.h"
 #include "queue.h"
 #include "user.h"
 #include "stddebug.h"
diff --git a/windows/message.c b/windows/message.c
index ff5e6468b03b077a9ab5185fb31615f8322b93b7..82d04dd9a842f9e7d7f91df6b65f0fe1d7591be4 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -15,6 +15,7 @@
 #include "sysmetrics.h"
 #include "hook.h"
 #include "spy.h"
+#include "stackframe.h"
 #include "winpos.h"
 #include "atom.h"
 #include "dde.h"
diff --git a/windows/property.c b/windows/property.c
index e60a61c6f8d5b90d4664b107c22472b358e3db6a..22bcf989e8c8a4f945bd7aa7f8b127c33f74f64a 100644
--- a/windows/property.c
+++ b/windows/property.c
@@ -8,7 +8,6 @@
 #include <string.h>
 #include "win.h"
 #include "heap.h"
-#include "callback.h"
 #include "string32.h"
 #include "stddebug.h"
 #include "debug.h"
@@ -235,8 +234,7 @@ INT16 EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
 
         dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
                       prop->handle, prop->string );
-        ret = CallEnumPropProc16( (FARPROC16)func, hwnd,
-                                  SEGPTR_GET(prop->string), prop->handle );
+        ret = func( hwnd, SEGPTR_GET(prop->string), prop->handle );
         if (!ret) break;
     }
     return ret;
@@ -248,24 +246,7 @@ INT16 EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
  */
 INT32 EnumProps32A( HWND32 hwnd, PROPENUMPROC32A func )
 {
-    PROPERTY *prop, *next;
-    WND *pWnd;
-    INT32 ret = -1;
-
-    dprintf_prop( stddeb, "EnumProps32A: %04x %08x\n", hwnd, (UINT32)func );
-    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
-    for (prop = pWnd->pProp; (prop); prop = next)
-    {
-        /* Already get the next in case the callback */
-        /* function removes the current property.    */
-        next = prop->next;
-
-        dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
-                      prop->handle, prop->string );
-        ret = CallEnumPropProc32( func, hwnd, prop->string, prop->handle );
-        if (!ret) break;
-    }
-    return ret;
+    return EnumPropsEx32A( hwnd, (PROPENUMPROCEX32A)func, 0 );
 }
 
 
@@ -274,33 +255,7 @@ INT32 EnumProps32A( HWND32 hwnd, PROPENUMPROC32A func )
  */
 INT32 EnumProps32W( HWND32 hwnd, PROPENUMPROC32W func )
 {
-    PROPERTY *prop, *next;
-    WND *pWnd;
-    INT32 ret = -1;
-
-    dprintf_prop( stddeb, "EnumProps32W: %04x %08x\n", hwnd, (UINT32)func );
-    if (!(pWnd = WIN_FindWndPtr( hwnd ))) return -1;
-    for (prop = pWnd->pProp; (prop); prop = next)
-    {
-        /* Already get the next in case the callback */
-        /* function removes the current property.    */
-        next = prop->next;
-
-        dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
-                      prop->handle, prop->string );
-        if (HIWORD(prop->string))
-        {
-            LPWSTR str = STRING32_DupAnsiToUni( prop->string );
-            ret = CallEnumPropProc32( func, hwnd, str, prop->handle );
-            free( str );
-        }
-        else
-            ret = CallEnumPropProc32( func, hwnd,
-                                      (LPCWSTR)(UINT32)LOWORD(prop->string),
-                                      prop->handle );
-        if (!ret) break;
-    }
-    return ret;
+    return EnumPropsEx32W( hwnd, (PROPENUMPROCEX32W)func, 0 );
 }
 
 
@@ -324,8 +279,7 @@ INT32 EnumPropsEx32A( HWND32 hwnd, PROPENUMPROCEX32A func, LPARAM lParam )
 
         dprintf_prop( stddeb, "  Callback: handle=%08x str='%s'\n",
                       prop->handle, prop->string );
-        ret = CallEnumPropProcEx32( func, hwnd, prop->string,
-                                    prop->handle, lParam );
+        ret = func( hwnd, prop->string, prop->handle, lParam );
         if (!ret) break;
     }
     return ret;
@@ -355,13 +309,12 @@ INT32 EnumPropsEx32W( HWND32 hwnd, PROPENUMPROCEX32W func, LPARAM lParam )
         if (HIWORD(prop->string))
         {
             LPWSTR str = STRING32_DupAnsiToUni( prop->string );
-            ret = CallEnumPropProcEx32( func, hwnd, str, prop->handle, lParam);
+            ret = func( hwnd, str, prop->handle, lParam );
             free( str );
         }
         else
-            ret = CallEnumPropProcEx32( func, hwnd,
-                                        (LPCWSTR)(UINT32)LOWORD(prop->string),
-                                        prop->handle, lParam );
+            ret = func( hwnd, (LPCWSTR)(UINT32)LOWORD( prop->string ),
+                        prop->handle, lParam );
         if (!ret) break;
     }
     return ret;
diff --git a/windows/win.c b/windows/win.c
index 29b902f93bb4faed5aa644286bf55942d8c8c7d0..845d9ac8170aca441cbcc6ee35aa0d9d564c77f1 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -28,7 +28,6 @@
 #include "color.h"
 #include "shm_main_blk.h"
 #include "dde_proc.h"
-#include "callback.h"
 #include "clipboard.h"
 #include "winproc.h"
 #include "stddebug.h"
@@ -602,7 +601,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCT32A *cs, ATOM classAtom,
 	    win_attr.event_mask = ExposureMask | KeyPressMask |
 	                          KeyReleaseMask | PointerMotionMask |
 	                          ButtonPressMask | ButtonReleaseMask |
-	                          FocusChangeMask;
+	                          FocusChangeMask | StructureNotifyMask;
             win_attr.override_redirect = TRUE;
 	}
         win_attr.colormap      = COLOR_GetColormap();
@@ -1687,9 +1686,7 @@ BOOL16 EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
     {
         /* Make sure that the window still exists */
         if (!IsWindow((*ppWnd)->hwndSelf)) continue;
-        if (!CallEnumWindowsProc16( (FARPROC16)lpEnumFunc,
-                                    (*ppWnd)->hwndSelf, lParam ))
-            break;
+        if (!lpEnumFunc( (*ppWnd)->hwndSelf, lParam )) break;
     }
     HeapFree( SystemHeap, 0, list );
     return TRUE;
@@ -1701,25 +1698,7 @@ BOOL16 EnumWindows16( WNDENUMPROC16 lpEnumFunc, LPARAM lParam )
  */
 BOOL32 EnumWindows32( WNDENUMPROC32 lpEnumFunc, LPARAM lParam )
 {
-    WND **list, **ppWnd;
-
-    /* We have to build a list of all windows first, to avoid */
-    /* unpleasant side-effects, for instance if the callback  */
-    /* function changes the Z-order of the windows.           */
-
-    if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
-
-    /* Now call the callback function for every window */
-
-    for (ppWnd = list; *ppWnd; ppWnd++)
-    {
-        /* Make sure that the window still exists */
-        if (!IsWindow((*ppWnd)->hwndSelf)) continue;
-        if (!CallEnumWindowsProc32( lpEnumFunc, (*ppWnd)->hwndSelf, lParam ))
-            break;
-    }
-    HeapFree( SystemHeap, 0, list );
-    return TRUE;
+    return (BOOL32)EnumWindows16( (WNDENUMPROC16)lpEnumFunc, lParam );
 }
 
 
@@ -1743,9 +1722,7 @@ BOOL16 EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func, LPARAM lParam )
         /* Make sure that the window still exists */
         if (!IsWindow((*ppWnd)->hwndSelf)) continue;
         if ((*ppWnd)->hmemTaskQ != hQueue) continue;  /* Check the queue */
-        if (!CallEnumWindowsProc16( (FARPROC16)func,
-                                    (*ppWnd)->hwndSelf, lParam ))
-            break;
+        if (!func( (*ppWnd)->hwndSelf, lParam )) break;
     }
     HeapFree( SystemHeap, 0, list );
     return TRUE;
@@ -1757,33 +1734,17 @@ BOOL16 EnumTaskWindows16( HTASK16 hTask, WNDENUMPROC16 func, LPARAM lParam )
  */
 BOOL32 EnumThreadWindows( DWORD id, WNDENUMPROC32 func, LPARAM lParam )
 {
-    WND **list, **ppWnd;
-    HANDLE hQueue = GetTaskQueue( (DWORD)id );
-
-    if (!(list = WIN_BuildWinArray( pWndDesktop ))) return FALSE;
-
-    /* Now call the callback function for every window */
-
-    for (ppWnd = list; *ppWnd; ppWnd++)
-    {
-        /* Make sure that the window still exists */
-        if (!IsWindow((*ppWnd)->hwndSelf)) continue;
-        if ((*ppWnd)->hmemTaskQ != hQueue) continue;  /* Check the queue */
-        if (!CallEnumWindowsProc32( func, (*ppWnd)->hwndSelf, lParam ))
-            break;
-    }
-    HeapFree( SystemHeap, 0, list );
-    return TRUE;
+    return (BOOL16)EnumTaskWindows16((HTASK16)id, (WNDENUMPROC16)func, lParam);
 }
 
 
 /**********************************************************************
- *           WIN_EnumChildWindows16
+ *           WIN_EnumChildWindows
  *
- * Helper function for EnumChildWindows16().
+ * Helper function for EnumChildWindows().
  */
-static BOOL16 WIN_EnumChildWindows16( WND **ppWnd, WNDENUMPROC16 func,
-                                      LPARAM lParam )
+static BOOL16 WIN_EnumChildWindows( WND **ppWnd, WNDENUMPROC16 func,
+                                    LPARAM lParam )
 {
     WND **childList;
     BOOL16 ret = FALSE;
@@ -1794,37 +1755,8 @@ static BOOL16 WIN_EnumChildWindows16( WND **ppWnd, WNDENUMPROC16 func,
         if (!IsWindow((*ppWnd)->hwndSelf)) continue;
         /* Build children list first */
         if (!(childList = WIN_BuildWinArray( *ppWnd ))) return FALSE;
-        if (!CallEnumWindowsProc16((FARPROC16)func,(*ppWnd)->hwndSelf,lParam))
-            return FALSE;
-        ret = WIN_EnumChildWindows16( childList, func, lParam );
-        HeapFree( SystemHeap, 0, childList );
-        if (!ret) return FALSE;
-        ppWnd++;
-    }
-    return TRUE;
-}
-
-
-/**********************************************************************
- *           WIN_EnumChildWindows32
- *
- * Helper function for EnumChildWindows32().
- */
-static BOOL32 WIN_EnumChildWindows32( WND **ppWnd, WNDENUMPROC32 func,
-                                      LPARAM lParam )
-{
-    WND **childList;
-    BOOL32 ret = FALSE;
-
-    while (*ppWnd)
-    {
-        /* Make sure that the window still exists */
-        if (!IsWindow((*ppWnd)->hwndSelf)) continue;
-        /* Build children list first */
-        if (!(childList = WIN_BuildWinArray( *ppWnd ))) return FALSE;
-        if (!CallEnumWindowsProc32( func, (*ppWnd)->hwndSelf, lParam ))
-            return FALSE;
-        ret = WIN_EnumChildWindows32( childList, func, lParam );
+        if (!func( (*ppWnd)->hwndSelf, lParam )) return FALSE;
+        ret = WIN_EnumChildWindows( childList, func, lParam );
         HeapFree( SystemHeap, 0, childList );
         if (!ret) return FALSE;
         ppWnd++;
@@ -1842,7 +1774,7 @@ BOOL16 EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func, LPARAM lParam )
 
     if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
     if (!(list = WIN_BuildWinArray( pParent ))) return FALSE;
-    WIN_EnumChildWindows16( list, func, lParam );
+    WIN_EnumChildWindows( list, func, lParam );
     HeapFree( SystemHeap, 0, list );
     return TRUE;
 }
@@ -1853,13 +1785,8 @@ BOOL16 EnumChildWindows16( HWND16 parent, WNDENUMPROC16 func, LPARAM lParam )
  */
 BOOL32 EnumChildWindows32( HWND32 parent, WNDENUMPROC32 func, LPARAM lParam )
 {
-    WND **list, *pParent;
-
-    if (!(pParent = WIN_FindWndPtr( parent ))) return FALSE;
-    if (!(list = WIN_BuildWinArray( pParent ))) return FALSE;
-    WIN_EnumChildWindows32( list, func, lParam );
-    HeapFree( SystemHeap, 0, list );
-    return TRUE;
+    return (BOOL32)EnumChildWindows16( (HWND16)parent, (WNDENUMPROC16)func,
+                                       lParam );
 }
 
 
diff --git a/windows/winpos.c b/windows/winpos.c
index 23ab087b572304c07f6f02f9a5a384ed335e0226..9e1a9cc8bf168c5df9e8078dcd5ef302753ef53a 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -683,7 +683,8 @@ BOOL ShowWindow( HWND hwnd, int cmd )
     else
     {
         /* We can't activate a child window */
-        if (wndPtr->dwStyle & WS_CHILD) swpflags |= SWP_NOACTIVATE;
+        if (wndPtr->dwStyle & WS_CHILD)
+            swpflags |= SWP_NOACTIVATE | SWP_NOZORDER;
         SetWindowPos( hwnd, HWND_TOP, x, y, cx, cy, swpflags );
         if (!IsWindow( hwnd )) return wasVisible;
     }
diff --git a/windows/winproc.c b/windows/winproc.c
index f52a6d248a62e33ffe2476bff1ce5459d574e828..06057c0db9454e0b38014e078a03a50d62be2b5a 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -1344,11 +1344,13 @@ static LRESULT WINPROC_CallProc32ATo16( WNDPROC16 func, HWND32 hwnd,
     UINT16 msg16;
     WPARAM16 wParam16;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
-    WORD ds = wndPtr ? wndPtr->hInstance : CURRENT_DS;
+    WORD ds = CURRENT_DS;
 
     if (WINPROC_MapMsg32ATo16( msg, wParam, &msg16, &wParam16, &lParam ) == -1)
         return 0;
-    result = CallWndProc16( func, ds, hwnd, msg16, wParam16, lParam );
+    if (wndPtr) CURRENT_DS = wndPtr->hInstance;
+    result = CallWndProc16( func, hwnd, msg16, wParam16, lParam );
+    CURRENT_DS = ds;
     WINPROC_UnmapMsg32ATo16( msg16, wParam16, lParam );
     return result;
 }
@@ -1367,11 +1369,13 @@ static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
     UINT16 msg16;
     WPARAM16 wParam16;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
+    WORD ds = CURRENT_DS;
 
     if (WINPROC_MapMsg32WTo16( msg, wParam, &msg16, &wParam16, &lParam ) == -1)
         return 0;
-    result = CallWndProc16( func, wndPtr ? wndPtr->hInstance : CURRENT_DS,
-                            hwnd, msg16, wParam16, lParam );
+    if (wndPtr) CURRENT_DS = wndPtr->hInstance;
+    result = CallWndProc16( func, hwnd, msg16, wParam16, lParam );
+    CURRENT_DS = ds;
     WINPROC_UnmapMsg32WTo16( msg16, wParam16, lParam );
     return result;
 }
@@ -1383,21 +1387,26 @@ static LRESULT WINPROC_CallProc32WTo16( WNDPROC16 func, HWND32 hwnd,
 LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
                           WPARAM16 wParam, LPARAM lParam )
 {
+    LRESULT result;
     WND *wndPtr;
     WINDOWPROC *proc = WINPROC_GetPtr( func );
+    WORD ds = CURRENT_DS;
 
     if (!proc)
     {
         wndPtr = WIN_FindWndPtr( hwnd );
-        return CallWndProc16( (FARPROC16)func,
-                              wndPtr ? wndPtr->hInstance : CURRENT_DS,
-                              hwnd, msg, wParam, lParam );
+        if (wndPtr) CURRENT_DS = wndPtr->hInstance;
+        result = CallWndProc16( (FARPROC16)func, hwnd, msg, wParam, lParam );
+        CURRENT_DS = ds;
+        return result;
     }
 #if testing
     wndPtr = WIN_FindWndPtr( hwnd );
-    return CallWndProc16( WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16),
-                          wndPtr ? wndPtr->hInstance : CURRENT_DS,
-                          hwnd, msg, wParam, lParam );
+    if (wndPtr) CURRENT_DS = wndPtr->hInstance;
+    result = CallWndProc16( WINPROC_GetProc( (HWINDOWPROC)proc, WIN_PROC_16),
+                            hwnd, msg, wParam, lParam );
+    CURRENT_DS = ds;
+    return result;
 #endif
     
     switch(proc->type)
@@ -1405,6 +1414,7 @@ LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
     case WIN_PROC_16:
         if (!proc->thunk.t_from32.proc) return 0;
         wndPtr = WIN_FindWndPtr( hwnd );
+        if (wndPtr) CURRENT_DS = wndPtr->hInstance;
 #ifndef WINELIB
         if ((msg == WM_CREATE) || (msg == WM_NCCREATE))
         {
@@ -1412,18 +1422,21 @@ LRESULT CallWindowProc16( WNDPROC16 func, HWND16 hwnd, UINT16 msg,
             /* Build the CREATESTRUCT on the 16-bit stack. */
             /* This is really ugly, but some programs (notably the */
             /* "Undocumented Windows" examples) want it that way.  */
-            return CallWndProcNCCREATE16( proc->thunk.t_from32.proc,
-                      wndPtr ? wndPtr->hInstance : CURRENT_DS, cs->dwExStyle,
-                      cs->lpszClass, cs->lpszName, cs->style, cs->x, cs->y,
-                      cs->cx, cs->cy, cs->hwndParent, cs->hMenu, cs->hInstance,
-                      (LONG)cs->lpCreateParams, hwnd, msg, wParam,
-                      MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
-                                IF1632_Saved16_ss ) );
+            result = CallWndProcNCCREATE16( proc->thunk.t_from32.proc,
+                    cs->dwExStyle, cs->lpszClass, cs->lpszName, cs->style,
+                    cs->x, cs->y, cs->cx, cs->cy, cs->hwndParent, cs->hMenu,
+                    cs->hInstance, (LONG)cs->lpCreateParams, hwnd, msg, wParam,
+                    MAKELONG( IF1632_Saved16_sp-sizeof(CREATESTRUCT16),
+                              IF1632_Saved16_ss ) );
+            CURRENT_DS = ds;
+            return result;
         }
 #endif
-        return CallWndProc16( proc->thunk.t_from32.proc,
-                              wndPtr ? wndPtr->hInstance : CURRENT_DS,
-                              hwnd, msg, wParam, lParam );
+        result = CallWndProc16( proc->thunk.t_from32.proc,
+                                hwnd, msg, wParam, lParam );
+        CURRENT_DS = ds;
+        return result;
+
     case WIN_PROC_32A:
         if (!proc->thunk.t_from16.proc) return 0;
         return WINPROC_CallProc16To32A( hwnd, msg, wParam, lParam,