Release 960818

Sun Aug 18 12:17:54 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [files/drive.c]
	Added 'Filesystem' option in drives configuration.

	* [files/dos_fs.c] 
	Added handling of case-insensitive filesystems.

	* [memory/selector.c] [include/stackframe.h]
	Removed MAKE_SEGPTR.

	* [misc/commdlg.c] [multimedia/mcistring.c]
	Replaced MAKE_SEGPTR by the SEGPTR_* macros.

	* [objects/bitblt.c] [windows/graphics.c]
	Use an intermediary pixmap to avoid some BadMatch errors on
	XGetImage().

Sun Aug 18 09:21:27 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [windows/message.c]
	Added handling of WM_NC...mouse messages in JOURNALRECORD hook.

	* [misc/ver.c]
	Fixed a bad string result in VerQueryValue[16|32A|32W].

Fri Aug 16 19:55:04 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [if1632/crtdll.spec] [misc/crtdll.c]
	More additions to get win95 programs further down the road.

	* [if1632/kernel.spec] [loader/module.c]
	GetModuleName() added.
	LoadModule(): params->showCmd can be NULL.

	* [if1632/kernel32.spec] [if1632/thunk.c]
	ThunkConnect32() stub added.

	* [loader/resource.c]
	Entries include lastentry.

	* [misc/shell.c] [files/file.c]
	Made progman work again.

Fri Aug 16 09:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>
	
	* [windows/defwnd.c] [windows/winpos.c] [windows/painting.c]
	Icon painting fixes.

	* [windows/winpos.c] [windows/painting.c]
	Enforce and follow hrgnUpdate more closely to cut down on
	redundant RedrawWindow() calls.

	* [windows/event.c]
	Process ConfigureNotify only for managed windows.

	* [windows/winpos.c]
	Do not redraw parent if the window was hidden before SetWindowPos().

	* [windows/nonclient.c]
	Omit some nonclient decoration painting for managed windows.

	* [controls/menu.c] [windows/mdi.c] [windows/nonclient.c]
	Implemented WM_NEXTMENU.

	* [controls/listbox.c]
	Multicolumn listboxes return WVR_VREDRAW on WM_NCCALCSIZE.

	* [misc/shell.c]
	Added .ICO file handling to ExtractIcon().
diff --git a/ANNOUNCE b/ANNOUNCE
index 95f9f61..22055cb 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,12 @@
-This is release 960811 of Wine, the MS Windows emulator.  This is still a
+This is release 960818 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-960811: (see ChangeLog for details)
-	- Status window class.
-	- Some CRTDLL support.
-	- Fixes to scrolling code.
+WHAT'S NEW with Wine-960818: (see ChangeLog for details)
+	- Many repainting fixes.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -17,10 +15,10 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960811.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960811.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960811.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960811.tar.gz
+  ftp://sunsite.unc.edu/pub/Linux/ALPHA/wine/development/Wine-960818.tar.gz
+  ftp://tsx-11.mit.edu/pub/linux/ALPHA/Wine/development/Wine-960818.tar.gz
+  ftp://ftp.infomagic.com/pub/mirrors/linux/wine/development/Wine-960818.tar.gz
+  ftp://aris.com/pub/linux/ALPHA/Wine/development/Wine-960818.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
diff --git a/ChangeLog b/ChangeLog
index 447a6ab..b379c5b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,76 @@
 ----------------------------------------------------------------------
+Sun Aug 18 12:17:54 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [files/drive.c]
+	Added 'Filesystem' option in drives configuration.
+
+	* [files/dos_fs.c] 
+	Added handling of case-insensitive filesystems.
+
+	* [memory/selector.c] [include/stackframe.h]
+	Removed MAKE_SEGPTR.
+
+	* [misc/commdlg.c] [multimedia/mcistring.c]
+	Replaced MAKE_SEGPTR by the SEGPTR_* macros.
+
+	* [objects/bitblt.c] [windows/graphics.c]
+	Use an intermediary pixmap to avoid some BadMatch errors on
+	XGetImage().
+
+Sun Aug 18 09:21:27 1996  Albrecht Kleine  <kleine@ak.sax.de>
+
+	* [windows/message.c]
+	Added handling of WM_NC...mouse messages in JOURNALRECORD hook.
+
+	* [misc/ver.c]
+	Fixed a bad string result in VerQueryValue[16|32A|32W].
+
+Fri Aug 16 19:55:04 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
+
+	* [if1632/crtdll.spec] [misc/crtdll.c]
+	More additions to get win95 programs further down the road.
+
+	* [if1632/kernel.spec] [loader/module.c]
+	GetModuleName() added.
+	LoadModule(): params->showCmd can be NULL.
+
+	* [if1632/kernel32.spec] [if1632/thunk.c]
+	ThunkConnect32() stub added.
+
+	* [loader/resource.c]
+	Entries include lastentry.
+
+	* [misc/shell.c] [files/file.c]
+	Made progman work again.
+
+Fri Aug 16 09:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>
+	
+	* [windows/defwnd.c] [windows/winpos.c] [windows/painting.c]
+	Icon painting fixes.
+
+	* [windows/winpos.c] [windows/painting.c]
+	Enforce and follow hrgnUpdate more closely to cut down on
+	redundant RedrawWindow() calls.
+
+	* [windows/event.c]
+	Process ConfigureNotify only for managed windows.
+
+	* [windows/winpos.c]
+	Do not redraw parent if the window was hidden before SetWindowPos().
+
+	* [windows/nonclient.c]
+	Omit some nonclient decoration painting for managed windows.
+
+	* [controls/menu.c] [windows/mdi.c] [windows/nonclient.c]
+	Implemented WM_NEXTMENU.
+
+	* [controls/listbox.c]
+	Multicolumn listboxes return WVR_VREDRAW on WM_NCCALCSIZE.
+
+	* [misc/shell.c]
+	Added .ICO file handling to ExtractIcon().
+
+----------------------------------------------------------------------
 Sun Aug 11 13:00:20 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [configure.in] [include/acconfig.h] [tools/build.c]
diff --git a/DEVELOPERS-HINTS b/DEVELOPERS-HINTS
index 8a0a147..1b24ed3 100644
--- a/DEVELOPERS-HINTS
+++ b/DEVELOPERS-HINTS
@@ -12,7 +12,8 @@
 by a 16-bit selector and a 16-bit offset.  Those used by the Wine code
 are regular 32-bit linear addresses.
 
-There's three ways to obtain a segmented pointer:
+There are four ways to obtain a segmented pointer:
+  - Use the SEGPTR_* macros in include/heap.h (recommended).
   - Allocate a block of memory from the global heap and use
     WIN16_GlobalLock to get its segmented address.
   - Allocate a block of memory from a local heap, and build the
diff --git a/Make.rules.in b/Make.rules.in
index d659872..41c1430 100644
--- a/Make.rules.in
+++ b/Make.rules.in
@@ -12,6 +12,7 @@
 X_LIBS    = @X_LIBS@
 XPM_LIB	  = -lXpm
 XLIB	  = @X_PRE_LIBS@ -lXext -lX11 @X_EXTRA_LIBS@
+WINELIB   = -L$(TOPSRC) -lwine
 LDLIBS	  = @LDLIBS@
 YACC      = @YACC@
 LEX       = @LEX@
@@ -22,7 +23,6 @@
 RM        = rm -f
 BUILD     = $(TOPSRC)/tools/build
 WINERC    = $(TOPSRC)/rc/winerc
-WINELIB   = $(TOPSRC)/libwine.a
 SUBMAKE   = $(MAKE) 'CC=$(CC)' 'CFLAGS=$(CFLAGS)' 'OPTIONS=$(OPTIONS)'
 @SET_MAKE@
 
diff --git a/Makefile.in b/Makefile.in
index 714e480..c311424 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -121,8 +121,13 @@
 install_programs: dummy
 	@cd programs; $(SUBMAKE) install
 
-depend:
-	for i in $(ALLSUBDIRS); do (cd $$i; $(MAKE) depend); done
+depend: libdepend emudepend
+
+libdepend: dummy
+	for i in $(COMMONSUBDIRS) $(LIBSUBDIRS); do (cd $$i; $(MAKE) depend); done
+
+emudepend: dummy
+	for i in $(EMUSUBDIRS); do (cd $$i; $(MAKE) depend); done
 
 etags:
 	etags `find . -name '*.[chS]' -print`
diff --git a/controls/combo.c b/controls/combo.c
index 213a3e3..aac742e 100644
--- a/controls/combo.c
+++ b/controls/combo.c
@@ -17,7 +17,6 @@
 #include "sysmetrics.h"
 #include "win.h"
 #include "combo.h"
-#include "stackframe.h"
 #include "user.h"
 #include "graphics.h"
 #include "heap.h"
@@ -715,7 +714,9 @@
                   case EN_UPDATE:GetWindowText32A(lphc->hWndEdit,buffer,255);
                                  if (*buffer)
                                  {
-                                  newFocused=ListBoxFindString(lphl, -1, MAKE_SEGPTR(buffer));
+                                  char *str = SEGPTR_STRDUP(buffer);
+                                  newFocused=ListBoxFindString(lphl, -1, SEGPTR_GET(str));
+                                  SEGPTR_FREE(str);
                                   dprintf_combo(stddeb,"CBCommand: new selection #%d is= %s\n",
                                                 newFocused,buffer);
                                   if (newFocused != (WORD)LB_ERR)
@@ -1259,11 +1260,11 @@
 /***********************************************************************
  *           DlgDirListComboBox16   (USER.195)
  */
-INT16 DlgDirListComboBox16( HWND16 hDlg, LPCSTR path, INT16 idCBox,
+INT16 DlgDirListComboBox16( HWND16 hDlg, SEGPTR path, INT16 idCBox,
                             INT16 idStatic, UINT16 wType )
 {
-    dprintf_combo( stddeb,"DlgDirListComboBox16(%04x,'%s',%d,%d,%04x)\n",
-                   hDlg, path, idCBox, idStatic, wType );
+    dprintf_combo( stddeb,"DlgDirListComboBox16(%04x,%08x,%d,%d,%04x)\n",
+                   hDlg, (UINT32)path, idCBox, idStatic, wType );
     return COMBO_DlgDirList( hDlg, (LPARAM)path, idCBox,
                              idStatic, wType, FALSE );
 }
diff --git a/controls/desktop.c b/controls/desktop.c
index b9fa9dd..810dd5c 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -77,6 +77,11 @@
 static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr )
 {
     RECT16 rect;
+    WND*   Wnd = WIN_FindWndPtr( hwnd );
+
+    if( Wnd->hrgnUpdate > 1 ) DeleteObject( Wnd->hrgnUpdate );
+    Wnd->hrgnUpdate = 0;
+
     GetClientRect16( hwnd, &rect );    
 
     /* Paint desktop pattern (only if wall paper does not cover everything) */
diff --git a/controls/edit.c b/controls/edit.c
index 69507b9..ec29002 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -17,7 +17,6 @@
 #include <windows.h>
 #include "win.h"
 #include "local.h"
-#include "stackframe.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
@@ -614,13 +613,21 @@
  */
 static INT EDIT_CallWordBreakProc(WND *wndPtr, char *s, INT index, INT count, INT action)
 {
-	EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0L);
+    EDITWORDBREAKPROC wbp = (EDITWORDBREAKPROC)EDIT_EM_GetWordBreakProc(wndPtr, 0, 0L);
 
-	if (wbp) {
-		return CallWordBreakProc((FARPROC16)wbp,
-				(LONG)MAKE_SEGPTR(s), index, count, action);
-	} else
-		return EDIT_WordBreakProc(s, index, count, action);
+    if (!wbp) return EDIT_WordBreakProc(s, index, count, action);
+    else
+    {
+        /* We need a SEGPTR here */
+
+        EDITSTATE *es = EDITSTATEPTR(wndPtr);
+        SEGPTR ptr = LOCAL_LockSegptr( wndPtr->hInstance, es->hBuf ) +
+                     (UINT16)(s - EDIT_GetPointer(wndPtr));
+        INT ret = CallWordBreakProc( (FARPROC16)wbp, ptr,
+                                     index, count, action);
+        LOCAL_Unlock( wndPtr->hInstance, es->hBuf );
+        return ret;
+    }
 }
 
 
@@ -1836,7 +1843,6 @@
 	INT dx;
 	INT dy;
 	POINT16 pos;
-	HRGN hRgn;
 
 	if (nfv >= lc)
 		nfv = lc - 1;
@@ -1848,15 +1854,8 @@
 	if (dx || dy) {
 		if (wndPtr->hwndSelf == GetFocus())
 			HideCaret(wndPtr->hwndSelf);
-		if (EDIT_GetRedraw(wndPtr)) {
-			hRgn = CreateRectRgn(0, 0, 0, 0);
-			GetUpdateRgn(wndPtr->hwndSelf, hRgn, FALSE);
-			ValidateRgn(wndPtr->hwndSelf, 0);
-			OffsetRgn(hRgn, dx, dy);
-			InvalidateRgn( wndPtr->hwndSelf, hRgn, TRUE );
-			DeleteObject(hRgn);
+		if (EDIT_GetRedraw(wndPtr)) 
 			ScrollWindow(wndPtr->hwndSelf, dx, dy, NULL, NULL);
-		}
 		es->FirstVisibleLine = nfv;
 		es->XOffset = nxoff;
 		if (IsVScrollBar(wndPtr))
@@ -2580,7 +2579,7 @@
 	UINT ll = (UINT)EDIT_EM_LineLength(wndPtr, e, 0L);
 	char *text = EDIT_GetPointer(wndPtr);
 
-	s = li + EDIT_CallWordBreakProc(wndPtr, text + li, e - li, ll, WB_LEFT);
+	s = li + EDIT_CallWordBreakProc (wndPtr, text + li, e - li, ll, WB_LEFT);
 	e = li + EDIT_CallWordBreakProc(wndPtr, text + li, e - li, ll, WB_RIGHT);
 	EDIT_EM_SetSel(wndPtr, 0, MAKELPARAM(s, e));
 	return 0L;
diff --git a/controls/listbox.c b/controls/listbox.c
index 1cbb28c..7b81dea 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -29,7 +29,6 @@
 #include "drive.h"
 #include "file.h"
 #include "heap.h"
-#include "stackframe.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
@@ -274,20 +273,23 @@
   return LB_ERR;
 }
 
-BOOL lbDeleteItemNotify(LPHEADLIST lphl, LPLISTSTRUCT lpls)
+BOOL32 lbDeleteItemNotify(LPHEADLIST lphl, LPLISTSTRUCT lpls)
 {
-  /* called only for owner drawn listboxes */
+    /* called only for owner drawn listboxes */
+    BOOL32 ret;
+    DELETEITEMSTRUCT16 *delItem = SEGPTR_NEW(DELETEITEMSTRUCT16);
+    if (!delItem) return FALSE;
 
-  DELETEITEMSTRUCT16   delItem;
+    delItem->CtlType  = lphl->DrawCtlType;
+    delItem->CtlID    = lphl->CtlID;
+    delItem->itemID   = lpls->mis.itemID;
+    delItem->hwndItem = lphl->hSelf;
+    delItem->itemData = lpls->mis.itemData;
 
-  delItem.CtlType = lphl->DrawCtlType;
-  delItem.CtlID   = lphl->CtlID;
-  delItem.itemID  = lpls->mis.itemID;
-  delItem.hwndItem= lphl->hSelf;
-  delItem.itemData= lpls->mis.itemData;
-
-  return (BOOL) SendMessage16(lphl->hParent, WM_DELETEITEM, (WPARAM)lphl->CtlID,
-                                          (LPARAM)MAKE_SEGPTR(&delItem));
+    ret = SendMessage16( lphl->hParent, WM_DELETEITEM, (WPARAM)lphl->CtlID,
+                         (LPARAM)SEGPTR_GET(delItem) );
+    SEGPTR_FREE(delItem);
+    return ret;
 }
 
 void ListBoxAskMeasure(LPHEADLIST lphl, LPLISTSTRUCT lpls)  
@@ -338,7 +340,7 @@
   *  MATCH_SUBSTR  (2) - same as exact match but with strncmp for string comparision
   */
 
- COMPAREITEMSTRUCT16    itemCmp;
+ COMPAREITEMSTRUCT16   *itemCmp;
  LPLISTSTRUCT		currentItem = NULL;
  LPCSTR			matchStr = (lphl->HasStrings)?(LPCSTR)PTR_SEG_TO_LIN(matchData):NULL;
  int                    head, pos = -1, tail, loop = 1;
@@ -369,9 +371,10 @@
 
  dprintf_listbox(stddeb,"AskCompare: head = %i, tail = %i, data = %08x\n", head, tail, (unsigned)matchData );
 
- itemCmp.CtlType        = lphl->DrawCtlType;
- itemCmp.CtlID          = lphl->CtlID;
- itemCmp.hwndItem       = lphl->hSelf;
+ if (!(itemCmp = SEGPTR_NEW(COMPAREITEMSTRUCT16))) return 0;
+ itemCmp->CtlType        = lphl->DrawCtlType;
+ itemCmp->CtlID          = lphl->CtlID;
+ itemCmp->hwndItem       = lphl->hSelf;
 
  /* search from startItem */
 
@@ -384,22 +387,25 @@
 
        if( lphl->HasStrings )
 	 {
-           b = ( s_length )? strncasecmp( currentItem->itemText, matchStr, s_length)
-                           : strcasecmp( currentItem->itemText, matchStr);
+           b = ( s_length )? lstrncmpi32A( currentItem->itemText, matchStr, s_length)
+                           : lstrcmpi32A( currentItem->itemText, matchStr);
 	 }
        else
          {
-           itemCmp.itemID1      = pos;
-           itemCmp.itemData1    = currentItem->mis.itemData;
-           itemCmp.itemID2      = -1;
-           itemCmp.itemData2    = matchData;
+           itemCmp->itemID1      = pos;
+           itemCmp->itemData1    = currentItem->mis.itemData;
+           itemCmp->itemID2      = -1;
+           itemCmp->itemData2    = matchData;
 
            b = SendMessage16( lphl->hParent, WM_COMPAREITEM, (WPARAM)lphl->CtlID, 
-                                                             (LPARAM)MAKE_SEGPTR(&itemCmp) );
+                              (LPARAM)SEGPTR_GET(itemCmp) );
          }
 
-       if( b == 0 ) 
+       if( b == 0 )
+       {
+           SEGPTR_FREE(itemCmp);
            return pos;  /* found exact match */
+       }
        else
          if( b < 0 ) head = ++pos;
          else
@@ -411,6 +417,7 @@
   }
 
  dprintf_listbox(stddeb,"\t-> pos = %i\n", pos );
+ SEGPTR_FREE(itemCmp);
 
  /* if we got here match is not exact */
 
@@ -612,8 +619,8 @@
   {
     if (lphl->HasStrings) 
     {
-      if ( ( s_length )? !strncasecmp(lpls->itemText, lpMatchStr, s_length)
-                       : !strcasecmp(lpls->itemText, lpMatchStr)  ) return Count;
+      if ( ( s_length )? !lstrncmpi32A(lpls->itemText, lpMatchStr, s_length)
+                       : !lstrcmpi32A(lpls->itemText, lpMatchStr)  ) return Count;
     }
     else
       if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;
@@ -630,8 +637,8 @@
   {
     if (lphl->HasStrings) 
     {
-      if ( ( s_length )? !strncasecmp(lpls->itemText, lpMatchStr, s_length)
-                       : !strcasecmp(lpls->itemText, lpMatchStr)  ) return Count;
+      if ( ( s_length )? !lstrncmpi32A(lpls->itemText, lpMatchStr, s_length)
+                       : !lstrcmpi32A(lpls->itemText, lpMatchStr)  ) return Count;
     }
     else
       if ( lpls->mis.itemData == (DWORD)lpMatchStr ) return Count;
@@ -912,6 +919,18 @@
   return 0;
 }
 
+
+/***********************************************************************
+ *           LBNCCalcSize
+ */
+static LONG LBNCCalcSize(HWND hwnd, WORD wParam, LONG lParam)
+{
+  LONG	     ret = DefWindowProc16(hwnd, WM_NCCALCSIZE, wParam, lParam);
+
+  return (GetWindowLong32A(hwnd,GWL_STYLE) & LBS_MULTICOLUMN)? WVR_VREDRAW : ret;
+}
+
+
 /***********************************************************************
  *           LBVScroll
  */
@@ -2073,6 +2092,7 @@
      case WM_PAINT: return LBPaint(hwnd, wParam, lParam);
      case WM_SETFOCUS: return LBSetFocus(hwnd, wParam, lParam);
      case WM_KILLFOCUS: return LBKillFocus(hwnd, wParam, lParam);
+     case WM_NCCALCSIZE: return LBNCCalcSize(hwnd, wParam, lParam);
      case LB_RESETCONTENT: return LBResetContent(hwnd, wParam, lParam);
      case LB_DIR: return LBDir(hwnd, wParam, lParam);
      case LB_ADDSTRING: return LBAddString(hwnd, wParam, lParam);
diff --git a/controls/menu.c b/controls/menu.c
index fc36acb..7ac8c35 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -60,6 +60,9 @@
 
 #define MENU_MAGIC   0x554d  /* 'MU' */
 
+#define ITEM_PREV		-1
+#define ITEM_NEXT		 1
+
   /* Dimension of the menu bitmaps */
 static WORD check_bitmap_width = 0, check_bitmap_height = 0;
 static WORD arrow_bitmap_width = 0, arrow_bitmap_height = 0;
@@ -85,6 +88,7 @@
 			     MF_MENUBARBREAK | MF_MENUBREAK | MF_SEPARATOR)))
 
 extern void NC_DrawSysButton(HWND hwnd, HDC hdc, BOOL down);  /* nonclient.c */
+extern BOOL NC_GetSysPopupPos(WND* wndPtr, RECT16* rect);
 
 static HBITMAP hStdCheck = 0;
 static HBITMAP hStdMnArrow = 0;
@@ -802,10 +806,11 @@
 
     uSubPWndLevel++;
 
+    wndPtr = WIN_FindWndPtr( menu->hWnd );
+
     SetWindowPos(menu->hWnd, 0, x, y, menu->Width + 2*SYSMETRICS_CXBORDER, 
 				      menu->Height + 2*SYSMETRICS_CYBORDER,
-		  		      SWP_NOACTIVATE | SWP_NOZORDER );
-
+		  		      SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW);
       /* Display the window */
 
     SetWindowPos( menu->hWnd, HWND_TOP, 0, 0, 0, 0,
@@ -879,11 +884,12 @@
 
 
 /***********************************************************************
- *           MENU_SelectNextItem
+ *           MENU_SelectItemRel
+ *
  */
-static void MENU_SelectNextItem( HWND hwndOwner, HMENU hmenu )
+static void MENU_SelectItemRel( HWND hwndOwner, HMENU hmenu, int offset )
 {
-    int i;
+    int i, min = 0;
     POPUPMENU *menu;
 
     menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
@@ -891,7 +897,8 @@
     if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
 	(menu->FocusedItem != SYSMENU_SELECTED))
     {
-	for (i = menu->FocusedItem+1; i < menu->nItems; i++)
+	for (i = menu->FocusedItem + offset ; i >= 0 && i < menu->nItems 
+					    ; i += offset)
 	{
 	    if (!(menu->items[i].item_flags & MF_SEPARATOR))
 	    {
@@ -899,53 +906,18 @@
 		return;
 	    }
 	}
+
 	if (MENU_HasSysMenu( menu ))
 	{
 	    MENU_SelectItem( hwndOwner, hmenu, SYSMENU_SELECTED, TRUE );
 	    return;
 	}
     }
-    for (i = 0; i < menu->nItems; i++)
-    {
-	if (!(menu->items[i].item_flags & MF_SEPARATOR))
-	{
-	    MENU_SelectItem( hwndOwner, hmenu, i, TRUE );
-	    return;
-	}
-    }
-    if (MENU_HasSysMenu( menu ))
-        MENU_SelectItem( hwndOwner, hmenu, SYSMENU_SELECTED, TRUE );
-}
 
-
-/***********************************************************************
- *           MENU_SelectPrevItem
- */
-static void MENU_SelectPrevItem( HWND hwndOwner, HMENU hmenu )
-{
-    int i;
-    POPUPMENU *menu;
-
-    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
-    if (!menu->items) return;
-    if ((menu->FocusedItem != NO_SELECTED_ITEM) &&
-	(menu->FocusedItem != SYSMENU_SELECTED))
-    {
-	for (i = menu->FocusedItem - 1; i >= 0; i--)
-	{
-	    if (!(menu->items[i].item_flags & MF_SEPARATOR))
-	    {
-		MENU_SelectItem( hwndOwner, hmenu, i, TRUE );
-		return;
-	    }
-	}
-	if (MENU_HasSysMenu( menu ))
-	{
-	    MENU_SelectItem( hwndOwner, hmenu, SYSMENU_SELECTED, TRUE );
-	    return;
-	}
-    }
-    for (i = menu->nItems - 1; i > 0; i--)
+    if( offset > 0 ) { i = 0; min = -1; }
+    else i = menu->nItems - 1;
+     
+    for ( ; i > min && i < menu->nItems ; i += offset)
     {
 	if (!(menu->items[i].item_flags & MF_SEPARATOR))
 	{
@@ -1193,7 +1165,7 @@
     {
 	MENU_ShowPopup(hwndOwner, wndPtr->hSysMenu, 0, wndPtr->rectClient.left,
 		wndPtr->rectClient.top - menu->Height - 2*SYSMETRICS_CYBORDER);
-	if (selectFirst) MENU_SelectNextItem( hwndOwner, wndPtr->hSysMenu );
+	if (selectFirst) MENU_SelectItemRel( hwndOwner, wndPtr->hSysMenu, ITEM_NEXT );
 	return wndPtr->hSysMenu;
     }
     item = &menu->items[menu->FocusedItem];
@@ -1212,7 +1184,7 @@
 		        wndPtr->rectWindow.left + item->rect.left,
 		        wndPtr->rectWindow.top + item->rect.bottom );
     }
-    if (selectFirst) MENU_SelectNextItem( hwndOwner, (HMENU)item->item_id );
+    if (selectFirst) MENU_SelectItemRel( hwndOwner, (HMENU)item->item_id, ITEM_NEXT );
     return (HMENU)item->item_id;
 }
 
@@ -1373,7 +1345,7 @@
     }
       /* Select first item of sub-popup */
     MENU_SelectItem( hwndOwner, hsubmenu, NO_SELECTED_ITEM, FALSE );
-    MENU_SelectNextItem( hwndOwner, hsubmenu );
+    MENU_SelectItemRel( hwndOwner, hsubmenu, ITEM_NEXT );
     return TRUE;
 }
 
@@ -1415,6 +1387,86 @@
     return TRUE;
 }
 
+/***********************************************************************
+ *           MENU_DoNextMenu
+ */
+static LRESULT MENU_DoNextMenu( HWND* hwndOwner, HMENU* hmenu, HMENU *hmenuCurrent, UINT vk)
+{
+  POPUPMENU *menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( *hmenu );
+  UINT	     id = 0;
+
+  if(    (vk == VK_LEFT && !menu->FocusedItem)
+      || (vk == VK_RIGHT && menu->FocusedItem == menu->nItems - 1) 
+      || menu->FocusedItem == SYSMENU_SELECTED 
+      || ((menu->wFlags & (MF_POPUP | MF_SYSMENU)) == (MF_POPUP | MF_SYSMENU)) )
+  {
+    LRESULT l = SendMessage16( *hwndOwner, WM_NEXTMENU, (WPARAM)vk, 
+				(LPARAM)((menu->FocusedItem == SYSMENU_SELECTED)
+					? GetSystemMenu( *hwndOwner, 0) 
+					: *hmenu));
+
+    if( l == 0 || !IsMenu(LOWORD(l)) || !IsWindow(HIWORD(l)) ) return 0;
+
+    /* shutdown current menu -
+     * all these checks for system popup window are needed
+     * only because Wine system menu tracking is unsuitable
+     * for a lot of things (esp. when we do not have wIDmenu to fall back on). 
+     */
+
+    MENU_SelectItem( *hwndOwner, *hmenu, NO_SELECTED_ITEM, FALSE );
+
+    if( (menu->wFlags & (MF_POPUP | MF_SYSMENU)) == (MF_POPUP | MF_SYSMENU) )
+	{
+	  HDC hdc;
+
+	  ShowWindow( menu->hWnd, SW_HIDE );
+	  uSubPWndLevel = 0;
+
+	  if( !IsIconic( *hwndOwner ) )
+	  { 
+	    hdc = GetDCEx( *hwndOwner, 0, DCX_CACHE | DCX_WINDOW);
+	    NC_DrawSysButton( *hwndOwner, hdc, FALSE );
+	    ReleaseDC( *hwndOwner, hdc );
+	  }
+	}
+
+    ReleaseCapture(); 
+   *hwndOwner = HIWORD(l);
+   *hmenu = LOWORD(l);
+    SetCapture( *hwndOwner );
+
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( *hmenu );
+
+    /* init next menu */
+
+    if( (menu->wFlags & (MF_POPUP | MF_SYSMENU)) == (MF_POPUP | MF_SYSMENU) )
+	{
+	  RECT16 rect;
+	  WND*   wndPtr = WIN_FindWndPtr( *hwndOwner );
+
+	  /* stupid kludge, see above */
+
+	  if( wndPtr->wIDmenu && !(wndPtr->dwStyle & WS_CHILD) )
+	     { *hmenu = wndPtr->wIDmenu; id = SYSMENU_SELECTED; }
+	  else
+	  { 
+	     if( NC_GetSysPopupPos( wndPtr, &rect ) )
+	         MENU_ShowPopup( *hwndOwner, *hmenu, 0, rect.left, rect.bottom );
+
+             if( !IsIconic( *hwndOwner ) )
+             {
+               HDC hdc =  GetDCEx( *hwndOwner, 0, DCX_CACHE | DCX_WINDOW);
+               NC_DrawSysButton( *hwndOwner, hdc, TRUE );
+               ReleaseDC( *hwndOwner, hdc );
+             }
+	  }
+	}
+
+    MENU_SelectItem( *hwndOwner, *hmenu, id, TRUE ); 
+    return l;
+  }
+  return 0;
+}
 
 /***********************************************************************
  *           MENU_KeyLeft
@@ -1422,28 +1474,34 @@
  * Handle a VK_LEFT key event in a menu.
  * hmenuCurrent is the top-most visible popup.
  */
-static void MENU_KeyLeft( HWND hwndOwner, HMENU hmenu, HMENU *hmenuCurrent )
+static void MENU_KeyLeft( HWND* hwndOwner, HMENU* hmenu, HMENU *hmenuCurrent )
 {
     POPUPMENU *menu;
     HMENU hmenutmp, hmenuprev;
 
-    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
-    hmenuprev = hmenutmp = hmenu;
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( *hmenu );
+    hmenuprev = hmenutmp = *hmenu;
     while (hmenutmp != *hmenuCurrent)
     {
 	hmenutmp = MENU_GetSubPopup( hmenuprev );
 	if (hmenutmp != *hmenuCurrent) hmenuprev = hmenutmp;
     }
-    MENU_HideSubPopups( hwndOwner, hmenuprev, TRUE );
+    MENU_HideSubPopups( *hwndOwner, hmenuprev, TRUE );
+    hmenutmp = *hmenu;
 
-    if ((hmenuprev == hmenu) && !(menu->wFlags & MF_POPUP))
+    if ( (hmenuprev == *hmenu) && 
+         ((menu->wFlags & MF_SYSMENU) || !(menu->wFlags & MF_POPUP)) )
     {
-	  /* Select previous item on the menu bar */
-	MENU_SelectPrevItem( hwndOwner, hmenu );
-	if (*hmenuCurrent != hmenu)
+	/* send WM_NEXTMENU */
+
+	if( !MENU_DoNextMenu( hwndOwner, hmenu, hmenuCurrent, VK_LEFT) )
+	     MENU_SelectItemRel( *hwndOwner, *hmenu, ITEM_PREV );
+	else *hmenuCurrent = *hmenu;
+
+	if (*hmenuCurrent != hmenutmp)
 	{
-	      /* A popup menu was displayed -> display the next one */
-	    *hmenuCurrent = MENU_ShowSubPopup( hwndOwner, hmenu, TRUE );
+	      /* A sublevel menu was displayed -> display the next one */
+	    *hmenuCurrent = MENU_ShowSubPopup( *hwndOwner, *hmenu, TRUE );
 	}
     }
     else *hmenuCurrent = hmenuprev;
@@ -1456,17 +1514,17 @@
  * Handle a VK_RIGHT key event in a menu.
  * hmenuCurrent is the top-most visible popup.
  */
-static void MENU_KeyRight( HWND hwndOwner, HMENU hmenu, HMENU *hmenuCurrent )
+static void MENU_KeyRight( HWND* hwndOwner, HMENU* hmenu, HMENU *hmenuCurrent )
 {
     POPUPMENU *menu;
     HMENU hmenutmp;
 
-    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( *hmenu );
 
-    if ((menu->wFlags & MF_POPUP) || (*hmenuCurrent != hmenu))
+    if ((menu->wFlags & MF_POPUP) || (*hmenuCurrent != *hmenu))
     {
 	  /* If already displaying a popup, try to display sub-popup */
-	hmenutmp = MENU_ShowSubPopup( hwndOwner, *hmenuCurrent, TRUE );
+	hmenutmp = MENU_ShowSubPopup( *hwndOwner, *hmenuCurrent, TRUE );
 	if (hmenutmp != *hmenuCurrent)  /* Sub-popup displayed */
 	{
 	    *hmenuCurrent = hmenutmp;
@@ -1474,27 +1532,35 @@
 	}
     }
 
-      /* If on menu-bar, go to next item */
-    if (!(menu->wFlags & MF_POPUP))
+      /* If menu-bar tracking, go to next item */
+
+    if (!(menu->wFlags & MF_POPUP) || (menu->wFlags & MF_SYSMENU))
     {
-	MENU_HideSubPopups( hwndOwner, hmenu, FALSE );
-	MENU_SelectNextItem( hwndOwner, hmenu );
-	if (*hmenuCurrent != hmenu)
+	MENU_HideSubPopups( *hwndOwner, *hmenu, FALSE );
+	hmenutmp = *hmenu;
+
+        /* Send WM_NEXTMENU */
+
+	if( !MENU_DoNextMenu( hwndOwner, hmenu, hmenuCurrent, VK_RIGHT) )
+	     MENU_SelectItemRel( *hwndOwner, *hmenu, ITEM_NEXT );
+	else *hmenuCurrent = *hmenu;
+
+	if (*hmenuCurrent != hmenutmp)
 	{
-	      /* A popup menu was displayed -> display the next one */
-	    *hmenuCurrent = MENU_ShowSubPopup( hwndOwner, hmenu, TRUE );
+	      /* A sublevel menu was displayed -> display the next one */
+	    *hmenuCurrent = MENU_ShowSubPopup( *hwndOwner, *hmenu, TRUE );
 	}
     }
-    else if (*hmenuCurrent != hmenu)  /* Hide last level popup */
+    else if (*hmenuCurrent != *hmenu)  /* Hide last level popup */
     {
 	HMENU hmenuprev;
-	hmenuprev = hmenutmp = hmenu;
+	hmenuprev = hmenutmp = *hmenu;
 	while (hmenutmp != *hmenuCurrent)
 	{
 	    hmenutmp = MENU_GetSubPopup( hmenuprev );
 	    if (hmenutmp != *hmenuCurrent) hmenuprev = hmenutmp;
 	}
-	MENU_HideSubPopups( hwndOwner, hmenuprev, TRUE );
+	MENU_HideSubPopups( *hwndOwner, hmenuprev, TRUE );
 	*hmenuCurrent = hmenuprev;
     }
 }
@@ -1510,8 +1576,7 @@
 static BOOL MENU_TrackMenu( HMENU hmenu, UINT wFlags, int x, int y,
 			    HWND hwnd, const RECT16 *lprect )
 {
-    MSG16 *msg;
-    HLOCAL16 hMsg;
+    MSG16 msg;
     POPUPMENU *menu;
     HMENU hmenuCurrent = hmenu;
     BOOL fClosed = FALSE, fRemove;
@@ -1525,23 +1590,20 @@
 	MENU_ButtonDown( hwnd, hmenu, &hmenuCurrent, pt );
     }
     SetCapture( hwnd );
-    hMsg = USER_HEAP_ALLOC( sizeof(MSG16) );
-    msg = (MSG16 *)USER_HEAP_LIN_ADDR( hMsg );
     while (!fClosed)
     {
-	if (!MSG_InternalGetMessage( (SEGPTR)USER_HEAP_SEG_ADDR(hMsg), 0,
-                                     hwnd, MSGF_MENU, 0, TRUE ))
+	if (!MSG_InternalGetMessage( &msg, 0, hwnd, MSGF_MENU, 0, TRUE ))
 	    break;
 
-        TranslateMessage( msg );
+        TranslateMessage( &msg );
 
         fRemove = FALSE;
-	if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
+	if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
 	{
 	      /* Find the sub-popup for this mouse event (if any) */
-	    HMENU hsubmenu = MENU_FindMenuByCoords( hmenu, msg->pt );
+	    HMENU hsubmenu = MENU_FindMenuByCoords( hmenu, msg.pt );
 
-	    switch(msg->message)
+	    switch(msg.message)
 	    {
 	    case WM_RBUTTONDOWN:
 	    case WM_NCRBUTTONDOWN:
@@ -1550,7 +1612,7 @@
 	    case WM_LBUTTONDOWN:
 	    case WM_NCLBUTTONDOWN:
 		fClosed = !MENU_ButtonDown( hwnd, hsubmenu,
-					    &hmenuCurrent, msg->pt );
+					    &hmenuCurrent, msg.pt );
 		break;
 		
 	    case WM_RBUTTONUP:
@@ -1560,59 +1622,56 @@
 	    case WM_LBUTTONUP:
 	    case WM_NCLBUTTONUP:
 		  /* If outside all menus but inside lprect, ignore it */
-		if (!hsubmenu && lprect && PtInRect16(lprect, msg->pt)) break;
+		if (!hsubmenu && lprect && PtInRect16(lprect, msg.pt)) break;
 		fClosed = !MENU_ButtonUp( hwnd, hsubmenu,
-					  &hmenuCurrent, msg->pt );
+					  &hmenuCurrent, msg.pt );
                 fRemove = TRUE;  /* Remove event even if outside menu */
 		break;
 		
 	    case WM_MOUSEMOVE:
 	    case WM_NCMOUSEMOVE:
-		if ((msg->wParam & MK_LBUTTON) ||
-		    ((wFlags & TPM_RIGHTBUTTON) && (msg->wParam & MK_RBUTTON)))
+		if ((msg.wParam & MK_LBUTTON) ||
+		    ((wFlags & TPM_RIGHTBUTTON) && (msg.wParam & MK_RBUTTON)))
 		{
 		    fClosed = !MENU_MouseMove( hwnd, hsubmenu,
-					       &hmenuCurrent, msg->pt );
+					       &hmenuCurrent, msg.pt );
 		}
 		break;
 	    }
 	}
-	else if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
+	else if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST))
 	{
             fRemove = TRUE;  /* Keyboard messages are always removed */
-	    switch(msg->message)
+	    switch(msg.message)
 	    {
 	    case WM_KEYDOWN:
-		switch(msg->wParam)
+		switch(msg.wParam)
 		{
 		case VK_HOME:
-		    MENU_SelectItem( hwnd, hmenuCurrent, NO_SELECTED_ITEM, FALSE );
-		    MENU_SelectNextItem( hwnd, hmenuCurrent );
-		    break;
-
 		case VK_END:
 		    MENU_SelectItem( hwnd, hmenuCurrent, NO_SELECTED_ITEM, FALSE );
-		    MENU_SelectPrevItem( hwnd, hmenuCurrent );
-		    break;
 
+		/* fall through */
 		case VK_UP:
-		    MENU_SelectPrevItem( hwnd, hmenuCurrent );
+		    MENU_SelectItemRel( hwnd, hmenuCurrent, 
+				       (msg.wParam == VK_HOME)? ITEM_NEXT : ITEM_PREV );
 		    break;
 
-		case VK_DOWN:
-		      /* If on menu bar, pull-down the menu */
+		case VK_DOWN: /* If on menu bar, pull-down the menu */
+
+		    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
 		    if (!(menu->wFlags & MF_POPUP) && (hmenuCurrent == hmenu))
 			hmenuCurrent = MENU_ShowSubPopup( hwnd, hmenu, TRUE );
 		    else
-			MENU_SelectNextItem( hwnd, hmenuCurrent );
+			MENU_SelectItemRel( hwnd, hmenuCurrent, ITEM_NEXT );
 		    break;
 
 		case VK_LEFT:
-		    MENU_KeyLeft( hwnd, hmenu, &hmenuCurrent );
+		    MENU_KeyLeft( &hwnd, &hmenu, &hmenuCurrent );
 		    break;
 		    
 		case VK_RIGHT:
-		    MENU_KeyRight( hwnd, hmenu, &hmenuCurrent );
+		    MENU_KeyRight( &hwnd, &hmenu, &hmenuCurrent );
 		    break;
 		    
 		case VK_SPACE:
@@ -1631,7 +1690,7 @@
 		break;  /* WM_KEYDOWN */
 
 	    case WM_SYSKEYDOWN:
-		switch(msg->wParam)
+		switch(msg.wParam)
 		{
 		case VK_MENU:
 		    fClosed = TRUE;
@@ -1644,8 +1703,8 @@
 		{
 		      /* Hack to avoid control chars. */
 		      /* We will find a better way real soon... */
-		    if ((msg->wParam <= 32) || (msg->wParam >= 127)) break;
-		    pos = MENU_FindItemByKey( hwnd, hmenuCurrent, msg->wParam );
+		    if ((msg.wParam <= 32) || (msg.wParam >= 127)) break;
+		    pos = MENU_FindItemByKey( hwnd, hmenuCurrent, msg.wParam );
 		    if (pos == (UINT)-2) fClosed = TRUE;
 		    else if (pos == (UINT)-1) MessageBeep(0);
 		    else
@@ -1657,22 +1716,23 @@
 		    }
 		}		    
 		break;  /* WM_CHAR */
-	    }  /* switch(msg->message) */
+	    }  /* switch(msg.message) */
 	}
 	else
 	{
-	    DispatchMessage( msg );
+	    DispatchMessage( &msg );
 	}
 	if (fEndMenuCalled) fClosed = TRUE;
 	if (!fClosed) fRemove = TRUE;
 
         if (fRemove)  /* Remove the message from the queue */
-	    PeekMessage16( msg, 0, msg->message, msg->message, PM_REMOVE );
+	    PeekMessage16( &msg, 0, msg.message, msg.message, PM_REMOVE );
     }
-    USER_HEAP_FREE( hMsg );
+
     ReleaseCapture();
     MENU_HideSubPopups( hwnd, hmenu, FALSE );
-    if (menu->wFlags & MF_POPUP) 
+    menu = (POPUPMENU *) USER_HEAP_LIN_ADDR( hmenu );
+    if (menu && menu->wFlags & MF_POPUP) 
     {
          ShowWindow( menu->hWnd, SW_HIDE );
 	 uSubPWndLevel = 0;
@@ -1756,7 +1816,7 @@
 
     MENU_SelectItem( wndPtr->hwndSelf, hTrackMenu, uItem, TRUE );
     if( uItem == NO_SELECTED_ITEM )
-      MENU_SelectNextItem( wndPtr->hwndSelf, hTrackMenu );
+      MENU_SelectItemRel( wndPtr->hwndSelf, hTrackMenu, ITEM_NEXT );
     else
       PostMessage( wndPtr->hwndSelf, WM_KEYDOWN, VK_DOWN, 0L );
 
diff --git a/controls/static.c b/controls/static.c
index faa8241..7763ce2 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -8,7 +8,6 @@
 #include <stdio.h>
 #include <windows.h>
 #include "win.h"
-#include "user.h"
 #include "static.h"
 
 static void STATIC_PaintTextfn( WND *wndPtr, HDC hdc );
diff --git a/controls/widgets.c b/controls/widgets.c
index eccaa10..236dfe3 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -13,7 +13,6 @@
 #include "desktop.h"
 #include "mdi.h"
 #include "gdi.h"
-#include "user.h"
 #include "module.h"
 #include "heap.h"
 
diff --git a/files/dos_fs.c b/files/dos_fs.c
index e0a1e17..376368a 100644
--- a/files/dos_fs.c
+++ b/files/dos_fs.c
@@ -63,10 +63,11 @@
  * (i.e. contains only valid DOS chars, lower-case only, fits in 8.3 format).
  * File name can be terminated by '\0', '\\' or '/'.
  */
-static int DOSFS_ValidDOSName( const char *name )
+static int DOSFS_ValidDOSName( const char *name, int ignore_case )
 {
-    static const char invalid_chars[] = INVALID_DOS_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    static const char invalid_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" INVALID_DOS_CHARS;
     const char *p = name;
+    const char *invalid = ignore_case ? (invalid_chars + 26) : invalid_chars;
     int len = 0;
 
     if (*p == '.')
@@ -79,7 +80,7 @@
     }
     while (!IS_END_OF_NAME(*p))
     {
-        if (strchr( invalid_chars, *p )) return 0;  /* Invalid char */
+        if (strchr( invalid, *p )) return 0;  /* Invalid char */
         if (*p == '.') break;  /* Start of the extension */
         if (++len > 8) return 0;  /* Name too long */
         p++;
@@ -90,7 +91,7 @@
     len = 0;
     while (!IS_END_OF_NAME(*p))
     {
-        if (strchr( invalid_chars, *p )) return 0;  /* Invalid char */
+        if (strchr( invalid, *p )) return 0;  /* Invalid char */
         if (*p == '.') return 0;  /* Second extension not allowed */
         if (++len > 3) return 0;  /* Extension too long */
         p++;
@@ -280,7 +281,7 @@
  * hashed version that fits in 8.3 format.
  * File name can be terminated by '\0', '\\' or '/'.
  */
-const char *DOSFS_Hash( const char *name, int dir_format )
+const char *DOSFS_Hash( const char *name, int dir_format, int ignore_case )
 {
     static const char invalid_chars[] = INVALID_DOS_CHARS "~.";
     static const char hash_chars[32] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
@@ -293,7 +294,7 @@
 
     if (dir_format) strcpy( buffer, "           " );
 
-    if (DOSFS_ValidDOSName( name ))
+    if (DOSFS_ValidDOSName( name, ignore_case ))
     {
         /* Check for '.' and '..' */
         if (*name == '.')
@@ -322,10 +323,19 @@
         /* Compute the hash code of the file name */
         /* If you know something about hash functions, feel free to */
         /* insert a better algorithm here... */
-        for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
-            hash = (hash << 3) ^ (hash >> 5) ^ *p ^ (p[1] << 8);
-        hash = (hash << 3) ^ (hash >> 5) ^ *p;  /* Last character */
-        
+        if (ignore_case)
+        {
+            for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
+                hash = (hash << 3) ^ (hash >> 5) ^ tolower(*p) ^ (tolower(p[1]) << 8);
+            hash = (hash << 3) ^ (hash >> 5) ^ tolower(*p); /* Last character*/
+        }
+        else
+        {
+            for (p = name, hash = 0xbeef; !IS_END_OF_NAME(p[1]); p++)
+                hash = (hash << 3) ^ (hash >> 5) ^ *p ^ (p[1] << 8);
+            hash = (hash << 3) ^ (hash >> 5) ^ *p;  /* Last character */
+        }
+
         /* Find last dot for start of the extension */
         for (p = name+1, ext = NULL; !IS_END_OF_NAME(*p); p++)
             if (*p == '.') ext = p;
@@ -368,7 +378,7 @@
  * Return 1 if OK, 0 if no file name matches.
  */
 static int DOSFS_FindUnixName( const char *path, const char *name,
-                               char *buffer, int maxlen )
+                               char *buffer, int maxlen, UINT32 drive_flags )
 {
     DIR *dir;
     struct dirent *dirent;
@@ -390,12 +400,22 @@
     while ((dirent = readdir( dir )) != NULL)
     {
         /* Check against Unix name */
-        if ((len == strlen(dirent->d_name) &&
-             !memcmp( dirent->d_name, name, len ))) break;
+        if (len == strlen(dirent->d_name))
+        {
+            if (drive_flags & DRIVE_CASE_SENSITIVE)
+            {
+                if (!lstrncmp32A( dirent->d_name, name, len )) break;
+            }
+            else
+            {
+                if (!lstrncmpi32A( dirent->d_name, name, len )) break;
+            }
+        }
         if (dos_name)
         {
             /* Check against hashed DOS name */
-            const char *hash_name = DOSFS_Hash( dirent->d_name, TRUE );
+            const char *hash_name = DOSFS_Hash( dirent->d_name, TRUE,
+                                       !(drive_flags & DRIVE_CASE_SENSITIVE) );
             if (!strcmp( dos_name, hash_name )) break;
         }
     }
@@ -445,6 +465,7 @@
 {
     static char buffer[MAX_PATHNAME_LEN];
     int drive, len, found;
+    UINT32 flags;
     char *p, *root;
 
     dprintf_dosfs( stddeb, "DOSFS_GetUnixFileName: %s\n", name );
@@ -470,6 +491,7 @@
         DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
         return NULL;
     }
+    flags = DRIVE_GetFlags(drive);
     lstrcpyn32A( buffer, DRIVE_GetRoot(drive), MAX_PATHNAME_LEN );
     if (buffer[1]) root = buffer + strlen(buffer);
     else root = buffer;  /* root directory */
@@ -502,7 +524,7 @@
             DOS_ERROR( ER_PathNotFound, EC_NotFound, SA_Abort, EL_Disk );
             return NULL;
         }
-        if ((found = DOSFS_FindUnixName( buffer, name, p+1, len-1 )))
+        if ((found = DOSFS_FindUnixName( buffer, name, p+1, len-1, flags )))
         {
             *p = '/';
             len -= strlen(p);
@@ -548,6 +570,7 @@
 {
     static char buffer[MAX_PATHNAME_LEN];
     int drive, len;
+    UINT32 flags;
     char *p;
 
     dprintf_dosfs( stddeb, "DOSFS_GetDosTrueName(%s,%d)\n", name, unix_format);
@@ -589,6 +612,7 @@
     }
     *p = '\0';
     len = MAX_PATHNAME_LEN - (int)(p - buffer);
+    flags = DRIVE_GetFlags(drive);
 
     while (*name)
     {
@@ -607,7 +631,9 @@
         *p++ = '\\';
         if (unix_format)  /* Hash it into a DOS name */
         {
-            lstrcpyn32A( p, DOSFS_Hash( name, FALSE ), len );
+            lstrcpyn32A( p, DOSFS_Hash( name, FALSE,
+                                     !(flags & DRIVE_CASE_SENSITIVE) ),
+                         len );
             len -= strlen(p);
             p += strlen(p);
             while (!IS_END_OF_NAME(*name)) name++;
@@ -651,7 +677,8 @@
     static int drive_root = 0;
     char *p;
     const char *hash_name;
-    
+    UINT32 flags;
+
     if ((attr & ~(FA_UNUSED | FA_ARCHIVE | FA_RDONLY)) == FA_LABEL)
     {
         if (skip) return 0;
@@ -686,12 +713,14 @@
     strcat( buffer, "/" );
     p = buffer + strlen(buffer);
     attr |= FA_UNUSED | FA_ARCHIVE | FA_RDONLY;
+    flags = DRIVE_GetFlags( drive );
 
     while ((dirent = readdir( dir )) != NULL)
     {
         if (skip-- > 0) continue;
         count++;
-        hash_name = DOSFS_Hash( dirent->d_name, TRUE );
+        hash_name = DOSFS_Hash( dirent->d_name, TRUE,
+                                !(flags & DRIVE_CASE_SENSITIVE) );
         if (!DOSFS_Match( mask, hash_name )) continue;
         /* Don't return '.' and '..' in the root of the drive */
         if (drive_root && (dirent->d_name[0] == '.') &&
@@ -708,6 +737,7 @@
         if (entry->attr & ~attr) continue;
         strcpy( entry->name, hash_name );
         lstrcpyn32A( entry->unixname, dirent->d_name, sizeof(entry->unixname));
+        if (!(flags & DRIVE_CASE_PRESERVING)) AnsiLower( entry->unixname );
         dprintf_dosfs( stddeb, "DOSFS_FindNext: returning %s %02x %ld\n",
                        entry->name, entry->attr, entry->size );
         cur_pos += count;
@@ -730,7 +760,7 @@
     dprintf_dosfs( stddeb, "GetShortPathName32A(%s,%p,%ld)\n",
                    longpath, shortpath, shortlen );
 
-    dostruename = DOSFS_GetDosTrueName( longpath, 0 );
+    dostruename = DOSFS_GetDosTrueName( longpath, TRUE );
     lstrcpyn32A( shortpath, dostruename, shortlen );
     return strlen(dostruename);
 }
@@ -742,7 +772,7 @@
 DWORD GetShortPathName32W( LPCWSTR longpath, LPWSTR shortpath, DWORD shortlen )
 {
     LPSTR longpatha = STRING32_DupUniToAnsi( longpath );
-    LPCSTR dostruename = DOSFS_GetDosTrueName( longpatha, 0 );
+    LPCSTR dostruename = DOSFS_GetDosTrueName( longpatha, TRUE );
     free( longpatha );
     lstrcpynAtoW( shortpath, dostruename, shortlen );
     return strlen(dostruename);
diff --git a/files/drive.c b/files/drive.c
index f85c149..d6350c6 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -44,11 +44,11 @@
     char      label[12]; /* drive label */
     DWORD     serial;    /* drive serial number */
     DRIVETYPE type;      /* drive type */
-    BYTE  disabled;      /* disabled flag */
+    UINT32    flags;     /* drive flags */
 } DOSDRIVE;
 
 
-static const char *DRIVE_Types[] =
+static const char * const DRIVE_Types[] =
 {
     "floppy",   /* TYPE_FLOPPY */
     "hd",       /* TYPE_HD */
@@ -57,6 +57,26 @@
 };
 
 
+/* Known filesystem types */
+
+typedef struct
+{
+    const char *name;
+    UINT32      flags;
+} FS_DESCR;
+
+static const FS_DESCR DRIVE_Filesystems[] =
+{
+    { "unix",   DRIVE_CASE_SENSITIVE | DRIVE_CASE_PRESERVING },
+    { "msdos",  DRIVE_SHORT_NAMES },
+    { "dos",    DRIVE_SHORT_NAMES },
+    { "fat",    DRIVE_SHORT_NAMES },
+    { "vfat",   DRIVE_CASE_PRESERVING },
+    { "win95",  DRIVE_CASE_PRESERVING },
+    { NULL, 0 }
+};
+
+
 static DOSDRIVE DOSDrives[MAX_DOS_DRIVES];
 static int DRIVE_CurDrive = -1;
 
@@ -83,6 +103,21 @@
 
 
 /***********************************************************************
+ *           DRIVE_GetFSFlags
+ */
+static UINT32 DRIVE_GetFSFlags( const char *name, const char *value )
+{
+    const FS_DESCR *descr;
+
+    for (descr = DRIVE_Filesystems; descr->name; descr++)
+        if (!lstrcmpi32A( value, descr->name )) return descr->flags;
+    fprintf( stderr, "%s: unknown filesystem type '%s', defaulting to 'unix'.\n",
+             name, value );
+    return DRIVE_CASE_SENSITIVE | DRIVE_CASE_PRESERVING;
+}
+
+
+/***********************************************************************
  *           DRIVE_Init
  */
 int DRIVE_Init(void)
@@ -105,7 +140,7 @@
             drive->dos_cwd  = xstrdup( "" );
             drive->unix_cwd = xstrdup( "" );
             drive->type     = DRIVE_GetDriveType( name );
-            drive->disabled = 0;
+            drive->flags    = 0;
 
             /* Get the drive label */
             PROFILE_GetWineIniString( name, "Label", name, drive->label, 12 );
@@ -121,14 +156,19 @@
                                       buffer, sizeof(buffer) );
             drive->serial = strtoul( buffer, NULL, 16 );
 
+            /* Get the filesystem type */
+            PROFILE_GetWineIniString( name, "Filesystem", "unix",
+                                      buffer, sizeof(buffer) );
+            drive->flags = DRIVE_GetFSFlags( name, buffer );
+
             /* Make the first hard disk the current drive */
             if ((DRIVE_CurDrive == -1) && (drive->type == TYPE_HD))
                 DRIVE_CurDrive = i;
 
             count++;
-            dprintf_dosfs( stddeb, "%s: path=%s type=%s label='%s' serial=%08lx\n",
+            dprintf_dosfs( stddeb, "%s: path=%s type=%s label='%s' serial=%08lx flags=%08x\n",
                            name, path, DRIVE_Types[drive->type],
-                           drive->label, drive->serial );
+                           drive->label, drive->serial, drive->flags );
         }
         else dprintf_dosfs( stddeb, "%s: not defined\n", name );
     }
@@ -143,7 +183,7 @@
         strcpy( DOSDrives[2].label, "Drive C    " );
         DOSDrives[2].serial   = 0x12345678;
         DOSDrives[2].type     = TYPE_HD;
-        DOSDrives[2].disabled = 0;
+        DOSDrives[2].flags    = 0;
         DRIVE_CurDrive = 2;
     }
 
@@ -152,7 +192,7 @@
     {
         for (i = 0, drive = DOSDrives; i < MAX_DOS_DRIVES; i++, drive++)
         {
-            if (drive->root && !drive->disabled)
+            if (drive->root && !(drive->flags & DRIVE_DISABLED))
             {
                 DRIVE_CurDrive = i;
                 break;
@@ -170,7 +210,8 @@
 int DRIVE_IsValid( int drive )
 {
     if ((drive < 0) || (drive >= MAX_DOS_DRIVES)) return 0;
-    return (DOSDrives[drive].root && !DOSDrives[drive].disabled);
+    return (DOSDrives[drive].root &&
+            !(DOSDrives[drive].flags & DRIVE_DISABLED));
 }
 
 
@@ -221,7 +262,8 @@
     dprintf_dosfs( stddeb, "DRIVE_FindDriveRoot: searching '%s'\n", *path );
     for (drive = 0; drive < MAX_DOS_DRIVES; drive++)
     {
-        if (!DOSDrives[drive].root || DOSDrives[drive].disabled) continue;
+        if (!DOSDrives[drive].root ||
+            (DOSDrives[drive].flags & DRIVE_DISABLED)) continue;
         p1 = *path;
         p2 = DOSDrives[drive].root;
         dprintf_dosfs( stddeb, "DRIVE_FindDriveRoot: checking %c: '%s'\n",
@@ -352,6 +394,16 @@
 
 
 /***********************************************************************
+ *           DRIVE_GetFlags
+ */
+UINT32 DRIVE_GetFlags( int drive )
+{
+    if ((drive < 0) || (drive >= MAX_DOS_DRIVES)) return 0;
+    return DOSDrives[drive].flags;
+}
+
+
+/***********************************************************************
  *           DRIVE_Chdir
  */
 int DRIVE_Chdir( int drive, const char *path )
@@ -407,7 +459,7 @@
         DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
         return 0;
     }
-    DOSDrives[drive].disabled = 1;
+    DOSDrives[drive].flags |= DRIVE_DISABLED;
     return 1;
 }
 
@@ -422,7 +474,7 @@
         DOS_ERROR( ER_InvalidDrive, EC_MediaError, SA_Abort, EL_Disk );
         return 0;
     }
-    DOSDrives[drive].disabled = 0;
+    DOSDrives[drive].flags &= ~DRIVE_DISABLED;
     return 1;
 }
 
diff --git a/files/file.c b/files/file.c
index 583471b..d638140 100644
--- a/files/file.c
+++ b/files/file.c
@@ -853,8 +853,12 @@
 	strcat(testpath,name);
 	if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL) {
 	    goto found;
-	} else
+	} else {
+	    strcpy(testpath,name);
+	    if ((unixName=DOSFS_GetUnixFileName((LPCSTR)testpath,TRUE))!=NULL)
+		goto found;
 	    return 0;
+	}
     }
     if ((len=sizeof(testpath)-strlen(name)-1)<0)
     	return 0;
diff --git a/if1632/crtdll.spec b/if1632/crtdll.spec
index 8f9a2b7..0294041 100644
--- a/if1632/crtdll.spec
+++ b/if1632/crtdll.spec
@@ -199,15 +199,15 @@
 194 stub _mbctoupper
 195 stub _mbctype
 196 stub _mbsbtype
-197 stub _mbscat
+197 cdecl _mbscat(ptr ptr) CRTDLL__mbscat
 198 stub _mbschr
 199 stub _mbscmp
-200 stub _mbscpy
+200 cdecl _mbscpy(ptr ptr) CRTDLL__mbscpy
 201 stub _mbscspn
 202 stub _mbsdec
 203 stub _mbsdup
-204 stub _mbsicmp
-205 stub _mbsinc
+204 cdecl _mbsicmp(ptr ptr) CRTDLL__mbsicmp
+205 cdecl _mbsinc(ptr) CRTDLL__mbsinc
 206 stub _mbslen
 207 stub _mbslwr
 208 stub _mbsnbcat
@@ -502,7 +502,7 @@
 497 stub vfprintf
 498 stub vfwprintf
 499 stub vprintf
-500 stub vsprintf
+500 cdecl vsprintf() CRTDLL_vsprintf
 501 stub vswprintf
 502 stub vwprintf
 503 stub wcscat
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index 9765459..4e82ed1 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -58,7 +58,7 @@
 0051 stub CreateMetaFileA
 0052 stub CreateMetaFileW
 0053 stdcall CreatePalette(ptr) CreatePalette
-0054 stub CreatePatternBrush
+0054 stdcall CreatePatternBrush(long) CreatePatternBrush
 0055 stdcall CreatePen(long long long) CreatePen
 0056 stub CreatePenIndirect
 0057 stub CreatePolyPolygonRgn
diff --git a/if1632/kernel.spec b/if1632/kernel.spec
index 493754f..bc5e616 100644
--- a/if1632/kernel.spec
+++ b/if1632/kernel.spec
@@ -27,7 +27,7 @@
 24  pascal16 UnlockSegment(word) UnlockSegment16
 25  pascal GlobalCompact(long) GlobalCompact16
 26  pascal16 GlobalFreeAll(word) GlobalFreeAll
-27  stub GetModuleName
+27  pascal16 GetModuleName(word ptr word) GetModuleName
 28  stub GlobalMasterHandle
 29  pascal16 Yield() Yield
 30  pascal16 WaitEvent(word) WaitEvent
diff --git a/if1632/kernel32.spec b/if1632/kernel32.spec
index 16cf10d..95fc4a2 100644
--- a/if1632/kernel32.spec
+++ b/if1632/kernel32.spec
@@ -232,7 +232,7 @@
 0227    stdcall GetLastError() GetLastError
 0228    stdcall GetLocalTime(ptr) GetLocalTime
 0229 stdcall GetLocaleInfoA(long long ptr long) GetLocaleInfoA
-0230 stub GetLocaleInfoW
+0230 stdcall GetLocaleInfoW(long long ptr long) GetLocaleInfo32W
 0231 stdcall GetLogicalDriveStringsA(long ptr) GetLogicalDriveStrings32A
 0232 stdcall GetLogicalDriveStringsW(long ptr) GetLogicalDriveStrings32W
 0233 stdcall GetLogicalDrives() GetLogicalDrives
@@ -637,3 +637,5 @@
 0631 stub WritePrivateProfileStructA
 0632 stub WritePrivateProfileStructW
 0633 stub MakeCriticalSectionGlobal
+#extra late additions
+0634 stdcall ThunkConnect32(ptr ptr ptr ptr ptr ptr) ThunkConnect32
diff --git a/if1632/thunk.c b/if1632/thunk.c
index ae623da..7b926da 100644
--- a/if1632/thunk.c
+++ b/if1632/thunk.c
@@ -6,6 +6,8 @@
 
 #include "windows.h"
 #include "callback.h"
+#include "stddebug.h"
+#include "debug.h"
 #include "heap.h"
 
 typedef void (*RELAY)();
@@ -248,3 +250,31 @@
                            x, y, cx, cy );
 }
 
+
+struct thunkstruct
+{
+	char	magic[4];
+	DWORD	x1;
+	DWORD	x2;
+};
+
+UINT32 ThunkConnect32( struct thunkstruct *ths, LPSTR thunkfun16,
+                       LPSTR module16, LPSTR module32, HMODULE32 hmod32,
+                       DWORD dllinitarg1 )
+{
+	HINSTANCE16	hmm;
+
+	fprintf(stdnimp,"ThunkConnect32(<struct>,%s,%s,%s,%lx,%lx)\n",
+		thunkfun16,module32,module16,hmod32,dllinitarg1
+	);
+	fprintf(stdnimp,"	magic = %c%c%c%c\n",
+		ths->magic[0],
+		ths->magic[1],
+		ths->magic[2],
+		ths->magic[3]
+	);
+	fprintf(stdnimp,"	x1 = %lx\n",ths->x1);
+	fprintf(stdnimp,"	x2 = %lx\n",ths->x2);
+	hmm=LoadModule(module16,NULL);
+	return TRUE;
+}
diff --git a/if1632/user.spec b/if1632/user.spec
index 10af4d8..4819c68 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -194,7 +194,7 @@
 192 pascal16 InSendMessage() InSendMessage
 193 pascal16 IsClipboardFormatAvailable(word) IsClipboardFormatAvailable
 194 pascal16 DlgDirSelectComboBox(word ptr word) DlgDirSelectComboBox
-195 pascal16 DlgDirListComboBox(word ptr word word word) DlgDirListComboBox16
+195 pascal16 DlgDirListComboBox(word segptr word word word) DlgDirListComboBox16
 196 pascal   TabbedTextOut(word s_word s_word ptr s_word s_word ptr s_word)
              TabbedTextOut
 197 pascal   GetTabbedTextExtent(word ptr word word ptr) GetTabbedTextExtent
diff --git a/if1632/user32.spec b/if1632/user32.spec
index a277e16..02325ff 100644
--- a/if1632/user32.spec
+++ b/if1632/user32.spec
@@ -98,7 +98,7 @@
 0091 stub DdeConnect
 0092 stub DdeConnectList
 0093 stub DdeCreateDataHandle
-0094 stub DdeCreateStringHandleA
+0094 return DdeCreateStringHandleA 12 0
 0095 stub DdeCreateStringHandleW
 0096 stub DdeDisconnect
 0097 stub DdeDisconnectList
@@ -109,10 +109,10 @@
 0102 stub DdeGetLastError
 0103 stub DdeGetQualityOfService
 0104 stub DdeImpersonateClient
-0105 stub DdeInitializeA
+0105 return DdeInitializeA 16 0
 0106 stub DdeInitializeW
 0107 stub DdeKeepStringHandle
-0108 stub DdeNameService
+0108 return DdeNameService 16 0
 0109 stub DdePostAdvise
 0110 stub DdeQueryConvInfo
 0111 stub DdeQueryNextServer
@@ -145,7 +145,7 @@
 0138 stdcall DialogBoxParamA(long ptr long ptr long) DialogBoxParam32A
 0139 stdcall DialogBoxParamW(long ptr long ptr long) DialogBoxParam32W
 0140 stdcall DispatchMessageA(ptr) USER32_DispatchMessageA
-0141 stub DispatchMessageW
+0141 stdcall DispatchMessageW(ptr) USER32_DispatchMessageA
 0142 stub DlgDirListA
 0143 stdcall DlgDirListComboBoxA(long ptr long long long) DlgDirListComboBox32A
 0144 stdcall DlgDirListComboBoxW(long ptr long long long) DlgDirListComboBox32W
@@ -229,7 +229,7 @@
 0222 stub GetClipboardFormatNameA
 0223 stub GetClipboardFormatNameW
 0224 stub GetClipboardOwner
-0225 stub GetClipboardViewer
+0225 stdcall GetClipboardViewer(long) GetClipboardViewer
 0226 stub GetCursor
 0227 stub GetCursorInfo
 0228 stdcall GetCursorPos(ptr) GetCursorPos32
@@ -277,7 +277,7 @@
 0270 stub GetMessageExtraInfo
 0271 stub GetMessagePos
 0272 stub GetMessageTime
-0273 stub GetMessageW
+0273 stdcall GetMessageW(ptr long long long) USER32_GetMessageA
 0274 stub GetNextDlgGroupItem
 0275 stub GetNextDlgTabItem
 0276 stub GetOpenClipboardWindow
@@ -355,7 +355,7 @@
 0348 stdcall IsWindowEnabled(long) IsWindowEnabled
 0349 stdcall IsWindowUnicode(long) IsWindowUnicode
 0350 stdcall IsWindowVisible(long) IsWindowVisible
-0351 stub IsZoomed
+0351 stdcall IsZoomed(long) IsZoomed
 0352 stdcall KillSystemTimer(long long) KillSystemTimer32
 0353 stdcall KillTimer(long long) KillTimer32
 0354 stdcall LoadAcceleratorsA(long ptr) LoadAccelerators32A
@@ -423,7 +423,7 @@
 0416 stdcall PeekMessageW(ptr long long long long) PeekMessage32W
 0417 stub PlaySoundEvent
 0418 stdcall PostMessageA(long long long long) PostMessage
-0419 stub PostMessageW
+0419 stdcall PostMessageW(long long long long) PostMessage
 0420 stdcall PostQuitMessage(long) PostQuitMessage
 0421 stub PostThreadMessageA
 0422 stub PostThreadMessageW
@@ -474,7 +474,7 @@
 0467 stdcall SetClassLongW(long long long) SetClassLong32W
 0468 stdcall SetClassWord(long long long) SetClassWord
 0469 stub SetClipboardData
-0470 stub SetClipboardViewer
+0470 stdcall SetClipboardViewer(long) SetClipboardViewer
 0471 	stdcall SetCursor(long) SetCursor
 0472 stub SetCursorContents
 0473 stub SetCursorPos
@@ -554,9 +554,9 @@
 0547 stub ToUnicode
 0548 stdcall TrackPopupMenu(long long long long long long ptr) TrackPopupMenu32
 0549 stub TrackPopupMenuEx
-0550 stub TranslateAccelerator
+0550 stdcall TranslateAccelerator(long long ptr) TranslateAccelerator
 0551 stdcall TranslateAcceleratorA(long long ptr) TranslateAccelerator
-0552 stub TranslateAcceleratorW
+0552 stdcall TranslateAcceleratorW(long long ptr) TranslateAccelerator
 0553 stub TranslateCharsetInfo
 0554 stub TranslateMDISysAccel
 0555 stdcall TranslateMessage(ptr) USER32_TranslateMessage
diff --git a/include/drive.h b/include/drive.h
index 0f3e836..f129bed 100644
--- a/include/drive.h
+++ b/include/drive.h
@@ -20,6 +20,13 @@
     TYPE_INVALID
 } DRIVETYPE;
 
+/* Drive flags */
+
+#define DRIVE_DISABLED        0x0001  /* Drive is disabled */
+#define DRIVE_SHORT_NAMES     0x0002  /* Drive fs has 8.3 file names */
+#define DRIVE_CASE_SENSITIVE  0x0004  /* Drive fs is case sensitive */
+#define DRIVE_CASE_PRESERVING 0x0008  /* Drive fs is case preserving */
+
 extern int DRIVE_Init(void);
 extern int DRIVE_IsValid( int drive );
 extern int DRIVE_GetCurrentDrive(void);
@@ -32,6 +39,7 @@
 extern DWORD DRIVE_GetSerialNumber( int drive );
 extern int DRIVE_SetSerialNumber( int drive, DWORD serial );
 extern DRIVETYPE DRIVE_GetType( int drive );
+extern UINT32 DRIVE_GetFlags( int drive );
 extern int DRIVE_Chdir( int drive, const char *path );
 extern int DRIVE_Disable( int drive  );
 extern int DRIVE_Enable( int drive  );
diff --git a/include/local.h b/include/local.h
index 114a92f..f39677c 100644
--- a/include/local.h
+++ b/include/local.h
@@ -23,6 +23,7 @@
 extern UINT16 LOCAL_HeapSize( HANDLE16 ds );
 extern UINT16 LOCAL_CountFree( HANDLE16 ds );
 extern LPSTR LOCAL_Lock( HANDLE16 ds, HLOCAL16 handle );
+extern SEGPTR LOCAL_LockSegptr( HANDLE16 ds, HLOCAL16 handle );
 extern BOOL16 LOCAL_Unlock( HANDLE16 ds, HLOCAL16 handle );
 
 #endif  /* __WINE_LOCAL_H */
diff --git a/include/message.h b/include/message.h
index ba77b6d..0a67fbf 100644
--- a/include/message.h
+++ b/include/message.h
@@ -13,7 +13,7 @@
 extern DWORD MSG_WineStartTicks;  /* Ticks at Wine startup */
 
 /* message.c */
-extern BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner,
+extern BOOL MSG_InternalGetMessage( MSG16 *msg, HWND hwnd, HWND hwndOwner,
 				    short code, WORD flags, BOOL sendIdle );
 
 /* timer.c */
diff --git a/include/nonclient.h b/include/nonclient.h
index af2c8f9..fdf9bb5 100644
--- a/include/nonclient.h
+++ b/include/nonclient.h
@@ -13,7 +13,7 @@
                               POINT16 *minTrack, POINT16 *maxTrack );
 extern void NC_DoNCPaint( HWND hwnd, HRGN clip, BOOL suppress_menupaint );
 extern LONG NC_HandleNCPaint( HWND hwnd , HRGN clip);
-extern LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam );
+extern LONG NC_HandleNCActivate( WND *pwnd, WPARAM wParam );
 extern LONG NC_HandleNCCalcSize( WND *pWnd, RECT16 *winRect );
 extern LONG NC_HandleNCHitTest( HWND hwnd, POINT16 pt );
 extern LONG NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam );
diff --git a/include/options.h b/include/options.h
index fffbbee..9e430fc 100644
--- a/include/options.h
+++ b/include/options.h
@@ -7,6 +7,8 @@
 #ifndef OPTIONS_H
 #define OPTIONS_H
 
+#include "wintypes.h"
+
   /* Supported languages */
 typedef enum
 {
@@ -23,7 +25,13 @@
     LANG_Ko   /* Korean */
 } WINE_LANGUAGE;
 
-extern const char *langNames[];
+typedef struct
+{
+    const char *name;
+    WORD        langid;
+} WINE_LANGUAGE_DEF;
+
+extern const WINE_LANGUAGE_DEF Languages[];
 
 /* Supported modes */
 typedef enum
diff --git a/include/queue.h b/include/queue.h
index e861d85..803019a 100644
--- a/include/queue.h
+++ b/include/queue.h
@@ -68,7 +68,7 @@
 
 extern void QUEUE_DumpQueue( HQUEUE16 hQueue );
 extern void QUEUE_WalkQueues(void);
-extern HQUEUE16 QUEUE_GetDoomedQueue();
+extern BOOL32 QUEUE_IsDoomedQueue( HQUEUE16 hQueue );
 extern void QUEUE_SetDoomedQueue( HQUEUE16 hQueue );
 extern MESSAGEQUEUE *QUEUE_GetSysQueue(void);
 extern void QUEUE_SetWakeBit( MESSAGEQUEUE *queue, WORD bit );
diff --git a/include/registers.h b/include/registers.h
index bfff59a..490861d 100644
--- a/include/registers.h
+++ b/include/registers.h
@@ -82,23 +82,6 @@
 #define EDI_reg(context)     ((context)->sc_edi)
 #define EBP_reg(context)     ((context)->sc_ebp)
                             
-#define AX_reg(context)      (*(WORD*)&((context)->sc_eax))
-#define BX_reg(context)      (*(WORD*)&((context)->sc_ebx))
-#define CX_reg(context)      (*(WORD*)&((context)->sc_ecx))
-#define DX_reg(context)      (*(WORD*)&((context)->sc_edx))
-#define SI_reg(context)      (*(WORD*)&((context)->sc_esi))
-#define DI_reg(context)      (*(WORD*)&((context)->sc_edi))
-#define BP_reg(context)      (*(WORD*)&((context)->sc_ebp))
-                            
-#define AL_reg(context)      (*(BYTE*)(&(context)->sc_eax))
-#define AH_reg(context)      (*(((BYTE*)(&(context)->sc_eax)+1)))
-#define BL_reg(context)      (*(BYTE*)(&(context)->sc_ebx))
-#define BH_reg(context)      (*(((BYTE*)(&(context)->sc_ebx)+1)))
-#define CL_reg(context)      (*(BYTE*)(&(context)->sc_ecx))
-#define CH_reg(context)      (*(((BYTE*)(&(context)->sc_ecx)+1)))
-#define DL_reg(context)      (*(BYTE*)(&(context)->sc_edx))
-#define DH_reg(context)      (*(((BYTE*)(&(context)->sc_edx)+1)))
-                            
 #define CS_reg(context)      ((context)->sc_cs)
 #define DS_reg(context)      ((context)->sc_ds)
 #define ES_reg(context)      ((context)->sc_es)
@@ -112,48 +95,26 @@
                             
 #ifndef __FreeBSD__         
 #define EFL_reg(context)     ((context)->sc_eflags)
-#define FL_reg(context)      (*(WORD*)(&(context)->sc_eflags))
 #else                       
 #define EFL_reg(context)     ((context)->sc_efl)
-#define FL_reg(context)      (*(WORD*)(&(context)->sc_efl))
 #endif                      
                             
 #define EIP_reg(context)     ((context)->sc_eip)
 #define ESP_reg(context)     ((context)->sc_esp)
                             
-#define IP_reg(context)      (*(WORD*)(&(context)->sc_eip))
-#define SP_reg(context)      (*(WORD*)(&(context)->sc_esp))
-                            
 #else  /* __svr4__ || _SCO_DS */
 
 #ifdef _SCO_DS
 #define gregs regs
 #endif
 
-#define EAX_reg(context)      ((context)->uc_mcontext.gregs[EAX])
-#define EBX_reg(context)      ((context)->uc_mcontext.gregs[EBX])
-#define ECX_reg(context)      ((context)->uc_mcontext.gregs[ECX])
-#define EDX_reg(context)      ((context)->uc_mcontext.gregs[EDX])
-#define ESI_reg(context)      ((context)->uc_mcontext.gregs[ESI])
-#define EDI_reg(context)      ((context)->uc_mcontext.gregs[EDI])
-#define EBP_reg(context)      ((context)->uc_mcontext.gregs[EBP])
-                            
-#define AX_reg(context)      (*(WORD*)&((context)->uc_mcontext.gregs[EAX]))
-#define BX_reg(context)      (*(WORD*)&((context)->uc_mcontext.gregs[EBX]))
-#define CX_reg(context)      (*(WORD*)&((context)->uc_mcontext.gregs[ECX]))
-#define DX_reg(context)      (*(WORD*)&((context)->uc_mcontext.gregs[EDX]))
-#define SI_reg(context)      (*(WORD*)&((context)->uc_mcontext.gregs[ESI]))
-#define DI_reg(context)      (*(WORD*)&((context)->uc_mcontext.gregs[EDI]))
-#define BP_reg(context)      (*(WORD*)&((context)->uc_mcontext.gregs[EBP]))
-                            
-#define AL_reg(context)      (*(BYTE*)(&(context)->uc_mcontext.gregs[EAX]))
-#define AH_reg(context)      (*(((BYTE*)(&(context)->uc_mcontext.gregs[EAX])+1)))
-#define BL_reg(context)      (*(BYTE*)(&(context)->uc_mcontext.gregs[EBX]))
-#define BH_reg(context)      (*(((BYTE*)(&(context)->uc_mcontext.gregs[EBX])+1)))
-#define CL_reg(context)      (*(BYTE*)(&(context)->uc_mcontext.gregs[ECX]))
-#define CH_reg(context)      (*(((BYTE*)(&(context)->uc_mcontext.gregs[ECX])+1)))
-#define DL_reg(context)      (*(BYTE*)(&(context)->uc_mcontext.gregs[EDX]))
-#define DH_reg(context)      (*(((BYTE*)(&(context)->uc_mcontext.gregs[EDX])+1)))
+#define EAX_reg(context)     ((context)->uc_mcontext.gregs[EAX])
+#define EBX_reg(context)     ((context)->uc_mcontext.gregs[EBX])
+#define ECX_reg(context)     ((context)->uc_mcontext.gregs[ECX])
+#define EDX_reg(context)     ((context)->uc_mcontext.gregs[EDX])
+#define ESI_reg(context)     ((context)->uc_mcontext.gregs[ESI])
+#define EDI_reg(context)     ((context)->uc_mcontext.gregs[EDI])
+#define EBP_reg(context)     ((context)->uc_mcontext.gregs[EBP])
                             
 #define CS_reg(context)      ((context)->uc_mcontext.gregs[CS])
 #define DS_reg(context)      ((context)->uc_mcontext.gregs[DS])
@@ -163,27 +124,39 @@
 #define FS_reg(context)      ((context)->uc_mcontext.gregs[FS])
 #define GS_reg(context)      ((context)->uc_mcontext.gregs[GS])
 
-                            
 #define EFL_reg(context)     ((context)->uc_mcontext.gregs[EFL])
-#define FL_reg(context)      (*(WORD*)(&(context)->uc_mcontext.gregs[EFL]))
-
                             
-#define EIP_reg(context)      ((context)->uc_mcontext.gregs[EIP])
+#define EIP_reg(context)     ((context)->uc_mcontext.gregs[EIP])
 #ifdef R_ESP
 #define ESP_reg(context)     ((context)->uc_mcontext.gregs[R_ESP])
 #else
 #define ESP_reg(context)     ((context)->uc_mcontext.gregs[ESP])
 #endif
                             
-#define IP_reg(context)      (*(WORD*)(&(context)->uc_mcontext.gregs[EIP]))
-#ifdef R_ESP
-#define SP_reg(context)      (*(WORD*)(&(context)->uc_mcontext.gregs[R_ESP]))
-#else
-#define SP_reg(context)      (*(WORD*)(&(context)->uc_mcontext.gregs[ESP]))
-#endif
-                            
 #endif  /* __svr4__ || _SCO_DS */
 
+#define AX_reg(context)      (*(WORD*)&EAX_reg(context))
+#define BX_reg(context)      (*(WORD*)&EBX_reg(context))
+#define CX_reg(context)      (*(WORD*)&ECX_reg(context))
+#define DX_reg(context)      (*(WORD*)&EDX_reg(context))
+#define SI_reg(context)      (*(WORD*)&ESI_reg(context))
+#define DI_reg(context)      (*(WORD*)&EDI_reg(context))
+#define BP_reg(context)      (*(WORD*)&EBP_reg(context))
+
+#define AL_reg(context)      (*(BYTE*)&EAX_reg(context))
+#define AH_reg(context)      (*((BYTE*)&EAX_reg(context)+1))
+#define BL_reg(context)      (*(BYTE*)&EBX_reg(context))
+#define BH_reg(context)      (*((BYTE*)&EBX_reg(context)+1))
+#define CL_reg(context)      (*(BYTE*)&ECX_reg(context))
+#define CH_reg(context)      (*((BYTE*)&ECX_reg(context)+1))
+#define DL_reg(context)      (*(BYTE*)&EDX_reg(context))
+#define DH_reg(context)      (*((BYTE*)&EDX_reg(context)+1))
+                            
+#define IP_reg(context)      (*(WORD*)&EIP_reg(context))
+#define SP_reg(context)      (*(WORD*)&ESP_reg(context))
+                            
+#define FL_reg(context)      (*(WORD*)&EFL_reg(context))
+
 #define SET_CFLAG(context)   (EFL_reg(context) |= 0x0001)
 #define RESET_CFLAG(context) (EFL_reg(context) &= 0xfffffffe)
 
diff --git a/include/stackframe.h b/include/stackframe.h
index 359e288..bc46ce0 100644
--- a/include/stackframe.h
+++ b/include/stackframe.h
@@ -61,17 +61,4 @@
 
 #define CURRENT_DS   (CURRENT_STACK16->ds)
 
-#ifndef WINELIB
-  /* Make a segmented pointer from a pointer to a variable located */
-  /* on the 32-bit stack for the current task. */
-#if 0
-#define MAKE_SEGPTR(ptr) \
-     ((SEGPTR)IF1632_Stack32_base + \
-      ((DWORD)(ptr) - (DWORD)PTR_SEG_TO_LIN(IF1632_Stack32_base)))
-#endif
-SEGPTR MAKE_SEGPTR(void *ptr);
-#else
-#define MAKE_SEGPTR(ptr)   ((SEGPTR)ptr)
-#endif
-
 #endif /* __WINE_STACKFRAME_H */
diff --git a/include/win.h b/include/win.h
index 3c95981..74bde91 100644
--- a/include/win.h
+++ b/include/win.h
@@ -28,6 +28,10 @@
 #define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771)  /* WinSwitch */
 #define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772)  /* IconTitle */
 
+  /* PAINT_RedrawWindow() control flags */
+#define RDW_C_USEHRGN		0x0001
+#define RDW_C_DELETEHRGN	0x0002
+
 typedef struct tagWND
 {
     struct tagWND *next;          /* Next sibling */
@@ -84,9 +88,10 @@
 extern BOOL32 WIN_LinkWindow( HWND32 hwnd, HWND32 hwndInsertAfter );
 extern HWND32 WIN_FindWinToRepaint( HWND32 hwnd, HQUEUE16 hQueue );
 extern void WIN_SendParentNotify( HWND32 hwnd, WORD event,
-                                  WORD idChild, LONG lValue );
+                                  WORD idChild, LPARAM lValue );
 extern BOOL32 WIN_CreateDesktopWindow(void);
 extern HWND32 WIN_GetTopParent( HWND32 hwnd );
+extern BOOL32 WIN_IsWindowDrawable(WND*, BOOL32 );
 extern HINSTANCE16 WIN_GetWindowInstance( HWND32 hwnd );
 extern WND **WIN_BuildWinArray( WND *wndPtr );
 
@@ -94,6 +99,10 @@
 
 extern void PROPERTY_RemoveWindowProps( WND *pWnd );   /* windows/property.c */
 
+extern BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
+                                  HRGN32 hrgnUpdate, UINT32 flags,
+                                  UINT32 control );    /* windows/painting.c */
+
 extern Display * display;
 extern Screen * screen;
 extern Window rootWindow;
diff --git a/include/windows.h b/include/windows.h
index d1275cd..b8fb02d 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -3415,6 +3415,7 @@
 HTASK16    GetCurrentTask(void);
 HMODULE16  GetExePtr(HANDLE16);
 WORD       GetExeVersion(void);
+BOOL16     GetModuleName(HINSTANCE16,LPSTR,INT16);
 HINSTANCE16 GetTaskDS(void);
 HQUEUE16   GetTaskQueue(HTASK16);
 BOOL16     IsSharedSelector(HANDLE16);
@@ -3745,7 +3746,7 @@
 INT32      DialogBoxParam32A(HINSTANCE32,LPCSTR,HWND32,DLGPROC32,LPARAM);
 INT32      DialogBoxParam32W(HINSTANCE32,LPCWSTR,HWND32,DLGPROC32,LPARAM);
 #define    DialogBoxParam WINELIB_NAME_AW(DialogBoxParam)
-INT16      DlgDirListComboBox16(HWND16,LPCSTR,INT16,INT16,UINT16);
+INT16      DlgDirListComboBox16(HWND16,SEGPTR,INT16,INT16,UINT16);
 INT32      DlgDirListComboBox32A(HWND32,LPCSTR,INT32,INT32,UINT32);
 INT32      DlgDirListComboBox32W(HWND32,LPCWSTR,INT32,INT32,UINT32);
 #define    DlgDirListComboBox WINELIB_NAME_AW(DlgDirListComboBox)
@@ -4654,8 +4655,8 @@
 LONG       GetMessageExtraInfo(void);
 DWORD      GetMessagePos(void);
 LONG       GetMessageTime(void);
-HANDLE     GetMetaFile(LPSTR);
-HANDLE     GetMetaFileBits(HANDLE);
+HMETAFILE16 GetMetaFile(LPSTR);
+HANDLE     GetMetaFileBits(HMETAFILE16);
 int        GetModuleFileName(HANDLE,LPSTR,short);
 HMODULE16  GetModuleHandle(LPCSTR);
 int        GetModuleUsage(HANDLE);
@@ -4777,7 +4778,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);
+BOOL       PlayMetaFile(HDC,HMETAFILE16);
 void       PlayMetaFileRecord(HDC,LPHANDLETABLE16,LPMETARECORD,WORD);
 BOOL       PostAppMessage(HANDLE,WORD,WORD,LONG);
 void       PostEvent(HTASK);
@@ -4844,7 +4845,7 @@
 BOOL       SetMenu(HWND,HMENU);
 BOOL       SetMenuItemBitmaps(HMENU,UINT,UINT,HBITMAP,HBITMAP);
 BOOL       SetMessageQueue(int);
-HANDLE     SetMetaFileBits(HANDLE);
+HMETAFILE16 SetMetaFileBits(HANDLE);
 WORD       SetPaletteEntries(HPALETTE16,WORD,WORD,LPPALETTEENTRY);
 HWND       SetParent(HWND,HWND);
 COLORREF   SetPixel(HDC,short,short,COLORREF);
diff --git a/include/wintypes.h b/include/wintypes.h
index 93a6905..503bcaa 100644
--- a/include/wintypes.h
+++ b/include/wintypes.h
@@ -79,7 +79,7 @@
 typedef unsigned short  BOOL16;
 typedef int             BOOL32;
 
-/* Handles types. These are the same for emulator and library. */
+/* Integer types. These are the same for emulator and library. */
 
 typedef UINT16          HANDLE16;
 typedef UINT32          HANDLE32;
@@ -96,6 +96,8 @@
 typedef HANDLE32        HHOOK;
 typedef HANDLE32        HKEY;
 typedef HANDLE32        HMIXEROBJ;
+typedef DWORD           LCID;
+typedef DWORD           LCTYPE;
 
 /* Pointers types. These are the same for emulator and library. */
 
diff --git a/libtest/Makefile.in b/libtest/Makefile.in
index ae201ae..fe7dadb 100644
--- a/libtest/Makefile.in
+++ b/libtest/Makefile.in
@@ -16,22 +16,22 @@
 
 @MAKE_RULES@
 
-hello: hello.o $(WINELIB)
+hello: hello.o
 	$(CC) -o hello hello.o $(LDOPTIONS) $(ALL_LIBS)
 
-hello2: hello2.o $(WINELIB)
+hello2: hello2.o
 	$(CC) -o hello2 hello2.o $(LDOPTIONS) $(ALL_LIBS)
 
-hello3: hello3res.o hello3.o $(WINELIB)
+hello3: hello3res.o hello3.o
 	$(CC) -o hello3 hello3.o hello3res.o $(LDOPTIONS) $(ALL_LIBS)
 
-hello4: hello4.o $(WINELIB)
+hello4: hello4.o
 	$(CC) -o hello4 hello4.o $(LDOPTIONS) $(ALL_LIBS)
 
-new: new.o $(WINELIB)
+new: new.o
 	$(CC) -o new new.o $(LDOPTIONS) $(ALL_LIBS)
 
-rolex: rolex.o $(WINELIB)
+rolex: rolex.o
 	$(CC) -o rolex rolex.o $(LDOPTIONS) $(ALL_LIBS)
 
 clean::
diff --git a/loader/builtin.c b/loader/builtin.c
index a7e618d..e450025 100644
--- a/loader/builtin.c
+++ b/loader/builtin.c
@@ -29,10 +29,11 @@
 
 typedef struct
 {
-    int                 base;      /* Ordinal base */
-    int                 size;      /* Number of functions */
-    const void        **functions; /* Pointer to functions table */
-    const char * const *names;     /* Pointer to names table */
+    int                 base;       /* Ordinal base */
+    int                 size;       /* Number of functions */
+    const void         *code_start; /* Start of DLL code */
+    const void        **functions;  /* Pointer to functions table */
+    const char * const *names;      /* Pointer to names table */
 } WIN32_DESCRIPTOR;
 
 typedef struct
@@ -356,8 +357,8 @@
 
     for (dll = BuiltinDLLs; dll->descr; dll++)
         if ((dll->flags & DLL_FLAG_WIN32) &&
-            (dll->descr->u.win32.functions[0] <= relay) &&
-            (dll->descr->u.win32.functions[dll->descr->u.win32.size-1] >relay))
+            (dll->descr->u.win32.code_start <= relay) &&
+            ((void *)dll->descr->u.win32.functions > relay))
             break;
     if (!dll->descr)
     {
diff --git a/loader/module.c b/loader/module.c
index 82850e7..f8074df 100644
--- a/loader/module.c
+++ b/loader/module.c
@@ -1215,10 +1215,17 @@
 
     if (!(pModule->flags & NE_FFLAGS_LIBMODULE) && (paramBlock != (LPVOID)-1))
     {
+        WORD	showcmd;
+
+	/* PowerPoint passes NULL as showCmd */
+	if (params->showCmd)
+		showcmd = *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1);
+	else
+		showcmd = 0; /* FIXME: correct */
         TASK_CreateTask( hModule, hInstance, hPrevInstance,
                          params->hEnvironment,
                          (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ),
-                         *((WORD *)PTR_SEG_TO_LIN(params->showCmd)+1) );
+                         showcmd );
     }
 
     return hInstance;
@@ -1286,6 +1293,18 @@
     return strlen(lpFileName);
 }
 
+/**********************************************************************
+ *	    GetModuleName    (KERNEL.27)
+ */
+BOOL16 GetModuleName( HINSTANCE16 hinst, LPSTR buf, INT16 nSize )
+{
+    LPSTR name = MODULE_GetModuleName(hinst);
+
+    if (!name) return FALSE;
+    lstrcpyn32A( buf, name, nSize );
+    return TRUE;
+}
+
 
 /***********************************************************************
  *           LoadLibrary   (KERNEL.95)
diff --git a/loader/resource.c b/loader/resource.c
index d96398a..8017685 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -726,7 +726,7 @@
     stre = NULL;
     se = (struct _subentry*)(p+4);
     for (i=nrofentries;i--;) {
-    	if ((id>=se->firstentry) && (id<se->lastentry)) {
+    	if ((id>=se->firstentry) && (id<=se->lastentry)) {
 	    stre = (struct _stringentry*)(p+se->offset);
 	    id	-= se->firstentry;
 	    break;
diff --git a/loader/task.c b/loader/task.c
index 4eb6234..44825ac 100644
--- a/loader/task.c
+++ b/loader/task.c
@@ -35,7 +35,6 @@
 #define MIN_THUNKS  32
 
   /* 32-bit stack size for each task */
-  /* Must not be greater than 64k, or MAKE_SEGPTR won't work */
 #define STACK32_SIZE 0x10000
 
 extern void USER_AppExit( HTASK16, HINSTANCE16, HQUEUE16 );
diff --git a/memory/local.c b/memory/local.c
index 9f5c762..f207c6a 100644
--- a/memory/local.c
+++ b/memory/local.c
@@ -1224,6 +1224,16 @@
 
 
 /***********************************************************************
+ *           LOCAL_LockSegptr
+ */
+SEGPTR LOCAL_LockSegptr( HANDLE16 ds, HLOCAL16 handle )
+{
+    char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
+    return PTR_SEG_OFF_TO_SEGPTR( ds, LOCAL_InternalLock( ptr, handle ) );
+}
+
+
+/***********************************************************************
  *           LOCAL_Unlock
  */
 BOOL16 LOCAL_Unlock( HANDLE16 ds, HLOCAL16 handle )
@@ -1401,9 +1411,7 @@
  */
 SEGPTR LocalLock16( HLOCAL16 handle )
 {
-    HANDLE16 ds = CURRENT_DS;
-    char *ptr = PTR_SEG_OFF_TO_LIN( ds, 0 );
-    return PTR_SEG_OFF_TO_SEGPTR( ds, LOCAL_InternalLock( ptr, handle ) );
+    return LOCAL_LockSegptr( CURRENT_DS, handle );
 }
 
 
diff --git a/memory/selector.c b/memory/selector.c
index bec8469..98a6ea9 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -480,37 +480,3 @@
     memcpy( ((char *)GET_SEL_BASE(sel)) + offset, buffer, count );
     return count;
 }
-
-#ifndef WINELIB
-SEGPTR MAKE_SEGPTR(void * ptr)
-
-{
-    SEGPTR result;
-    int entry;
-
-    if (!ptr)
-	return ptr;
-    if (!((unsigned)ptr & 0xffff0000)) {
- 	fprintf(stderr, "Invalid pointer %p has been passed to MAKE_SEGPTR. This was\n", ptr);
-	fprintf(stderr, "probably caused by an unnecessary call to PTR_SEG_TO_LIN.\n");
-	fprintf(stderr, "Forcing call to debugger\n");
-	ptr = *(void **)0;
-    }
-    result = (SEGPTR) (IF1632_Stack32_base) +
-	     ((DWORD)(ptr) - (DWORD) PTR_SEG_TO_LIN(IF1632_Stack32_base));
-    if (PTR_SEG_TO_LIN(result) == ptr)
-	return result;
-    
-    for (entry = 0; entry < LDT_SIZE; entry++) {
-	if (ldt_copy[entry].base && 
-	    (ldt_copy[entry].limit < 0x10000) &&
-	    ((unsigned) ptr >= ldt_copy[entry].base) &&
-	    ((unsigned) ptr < (ldt_copy[entry].base + ldt_copy[entry].limit))) {
-		return ((ENTRY_TO_SELECTOR(entry) << 16) | 
-                       ((unsigned) ptr - ldt_copy[entry].base));
-	}
-    }
-    entry = SELECTOR_AllocBlock((void *)((unsigned)ptr & 0xffff0000), 0x10000, SEGMENT_DATA, 0, 0);
-    return ((entry << 16) | ((unsigned) ptr & 0xffff));
-}
-#endif
diff --git a/misc/commdlg.c b/misc/commdlg.c
index bc1a62e..43ca13d 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -9,7 +9,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "win.h"
-#include "user.h"
+#include "heap.h"
 #include "message.h"
 #include "commdlg.h"
 #include "dlgs.h"
@@ -17,7 +17,6 @@
 #include "resource.h"
 #include "dos_fs.h"
 #include "drive.h"
-#include "stackframe.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -165,15 +164,22 @@
  */
 static BOOL FILEDLG_ScanDir(HWND hWnd, LPSTR newPath)
 {
-  char str[512],str2[512];
+    BOOL32 ret = FALSE;
+    int len;
+    char *str = SEGPTR_ALLOC(512);
+    if (!str) return TRUE;
 
-  strncpy(str,newPath,511); str[511]=0;
-  GetDlgItemText32A( hWnd, edt1, str2, sizeof(str2) );
-  strncat(str,str2,511-strlen(str)); str[511]=0;
-  if (!DlgDirList(hWnd, MAKE_SEGPTR(str), lst1, 0, 0x0000)) return FALSE;
-  strcpy( str, "*.*" );
-  DlgDirList(hWnd, MAKE_SEGPTR(str), lst2, stc1, 0x8010);
-  return TRUE;
+    lstrcpyn32A( str, newPath, 512 );
+    len = strlen(str);
+    GetDlgItemText32A( hWnd, edt1, str + len, 512 - len );
+    if (DlgDirList(hWnd, SEGPTR_GET(str), lst1, 0, 0x0000))
+    {
+        strcpy( str, "*.*" );
+        DlgDirList(hWnd, SEGPTR_GET(str), lst2, stc1, 0x8010 );
+        ret = TRUE;
+    }
+    SEGPTR_FREE(str);
+    return ret;
 }
 
 /***********************************************************************
@@ -209,19 +215,20 @@
 static LONG FILEDLG_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam,int savedlg)
 {
     LPDRAWITEMSTRUCT16 lpdis = (LPDRAWITEMSTRUCT16)PTR_SEG_TO_LIN(lParam);
-    char str[512];
+    char *str;
     HBRUSH hBrush;
     HBITMAP hBitmap, hPrevBitmap;
     BITMAP16 bm;
     HDC hMemDC;
 
-    str[0]=0;
-    if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1) {
+    if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1)
+    {
+        if (!(str = SEGPTR_ALLOC(512))) return FALSE;
 	hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
 	SelectObject(lpdis->hDC, hBrush);
 	FillRect16(lpdis->hDC, &lpdis->rcItem, hBrush);
 	SendMessage16(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 
-                      (LPARAM)MAKE_SEGPTR(str));
+                      (LPARAM)SEGPTR_GET(str));
 
 	if (savedlg)       /* use _gray_ text in FileSaveDlg */
 	  if (!lpdis->itemState)
@@ -235,15 +242,18 @@
 	if (lpdis->itemState != 0) {
 	    InvertRect16(lpdis->hDC, &lpdis->rcItem);
 	}
+        SEGPTR_FREE(str);
 	return TRUE;
     }
     
-    if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2) {
+    if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2)
+    {
+        if (!(str = SEGPTR_ALLOC(512))) return FALSE;
 	hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
 	SelectObject(lpdis->hDC, hBrush);
 	FillRect16(lpdis->hDC, &lpdis->rcItem, hBrush);
 	SendMessage16(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 
-                      (LPARAM)MAKE_SEGPTR(str));
+                      (LPARAM)SEGPTR_GET(str));
 
 	hBitmap = hFolder;
 	GetObject16( hBitmap, sizeof(bm), &bm );
@@ -255,17 +265,18 @@
 	       bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
 	SelectObject(hMemDC, hPrevBitmap);
 	DeleteDC(hMemDC);
-	if (lpdis->itemState != 0) {
-	    InvertRect16(lpdis->hDC, &lpdis->rcItem);
-	}
+	if (lpdis->itemState != 0) InvertRect16(lpdis->hDC, &lpdis->rcItem);
+        SEGPTR_FREE(str);
 	return TRUE;
     }
-    if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2) {
+    if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2)
+    {
+        if (!(str = SEGPTR_ALLOC(512))) return FALSE;
 	hBrush = SelectObject(lpdis->hDC, GetStockObject(LTGRAY_BRUSH));
 	SelectObject(lpdis->hDC, hBrush);
 	FillRect16(lpdis->hDC, &lpdis->rcItem, hBrush);
 	SendMessage16(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, 
-                      (LPARAM)MAKE_SEGPTR(str));
+                      (LPARAM)SEGPTR_GET(str));
         switch(DRIVE_GetType( str[2] - 'a' ))
         {
         case TYPE_FLOPPY:  hBitmap = hFloppy; break;
@@ -283,9 +294,8 @@
 	       bm.bmWidth, bm.bmHeight, hMemDC, 0, 0, SRCCOPY);
 	SelectObject(hMemDC, hPrevBitmap);
 	DeleteDC(hMemDC);
-	if (lpdis->itemState != 0) {
-	    InvertRect16(lpdis->hDC, &lpdis->rcItem);
-	}
+	if (lpdis->itemState != 0) InvertRect16(lpdis->hDC, &lpdis->rcItem);
+        SEGPTR_FREE(str);
 	return TRUE;
     }
     return FALSE;
@@ -323,8 +333,7 @@
 
 static LONG FILEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam) 
 {
-  int n;
-  int i;
+  int i, n;
   LPOPENFILENAME lpofn;
   char tmpstr[512];
   LPSTR pstr;
@@ -335,33 +344,35 @@
   if (lpofn->lpstrCustomFilter)
     {
       pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrCustomFilter);
+      n = 0;
       dprintf_commdlg(stddeb,"lpstrCustomFilter = %p\n", pstr);
       while(*pstr)
 	{
-	  n = strlen(pstr);
-	  strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
-	  dprintf_commdlg(stddeb,"lpstrCustomFilter // add tmpstr='%s' ", tmpstr);
-          i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
-	  pstr += n + 1;
-	  n = strlen(pstr);
+	  dprintf_commdlg(stddeb,"lpstrCustomFilter // add str='%s' ",pstr);
+          i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING, 0,
+                                   (LPARAM)lpofn->lpstrCustomFilter + n );
+          n += strlen(pstr) + 1;
+	  pstr += strlen(pstr) + 1;
 	  dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
           SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
-	  pstr += n + 1;
+          n += strlen(pstr) + 1;
+	  pstr += strlen(pstr) + 1;
 	}
     }
   /* read filter information */
   pstr = (LPSTR)PTR_SEG_TO_LIN(lpofn->lpstrFilter);
+  n = 0;
   while(*pstr)
     {
-      n = strlen(pstr);
-      strncpy(tmpstr, pstr, 511); tmpstr[511]=0;
-      dprintf_commdlg(stddeb,"lpstrFilter // add tmpstr='%s' ", tmpstr);
-      i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING, 0, (LPARAM)MAKE_SEGPTR(tmpstr));
-      pstr += n + 1;
-      n = strlen(pstr);
+      dprintf_commdlg(stddeb,"lpstrFilter // add str='%s' ", pstr);
+      i = SendDlgItemMessage16(hWnd, cmb1, CB_ADDSTRING, 0,
+                               (LPARAM)lpofn->lpstrFilter + n );
+      n += strlen(pstr) + 1;
+      pstr += strlen(pstr) + 1;
       dprintf_commdlg(stddeb,"associated to '%s'\n", pstr);
       SendDlgItemMessage16(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr);
-      pstr += n + 1;
+      n += strlen(pstr) + 1;
+      pstr += strlen(pstr) + 1;
     }
   /* set default filter */
   if (lpofn->nFilterIndex == 0 && lpofn->lpstrCustomFilter == (SEGPTR)NULL)
@@ -374,8 +385,10 @@
   			lpofn->nFilterIndex, tmpstr);
   SetDlgItemText32A( hWnd, edt1, tmpstr );
   /* get drive list */
-  *tmpstr = 0;
-  DlgDirListComboBox16(hWnd, (LPSTR)MAKE_SEGPTR(tmpstr), cmb2, 0, 0xC000);
+  pstr = SEGPTR_ALLOC(1);
+  *pstr = 0;
+  DlgDirListComboBox16(hWnd, SEGPTR_GET(pstr), cmb2, 0, 0xC000);
+  SEGPTR_FREE(pstr);
   /* read initial directory */
   if (PTR_SEG_TO_LIN(lpofn->lpstrInitialDir) != NULL) 
     {
@@ -398,7 +411,7 @@
     ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); 
   if (FILEDLG_HookCallChk(lpofn))
      return (BOOL)CallWindowProc16(lpofn->lpfnHook, 
-               hWnd,  WM_INITDIALOG, wParam,(LPARAM)MAKE_SEGPTR(lpofn));
+                                   hWnd,  WM_INITDIALOG, wParam, lParam );
   else  
      return TRUE;
 }
@@ -419,7 +432,7 @@
   control = wParam;
   notification = HIWORD(lParam);
     
-  lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
+  lpofn = (LPOPENFILENAME)PTR_SEG_TO_LIN(GetWindowLong32A(hWnd, DWL_USER));
   switch (control)
     {
     case lst1: /* file list */
@@ -428,10 +441,13 @@
 	goto almost_ok;
       lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL, 0, 0);
       if (lRet == LB_ERR) return TRUE;
-      SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT, lRet,
-			 (LPARAM)MAKE_SEGPTR(tmpstr));
-      SetDlgItemText32A( hWnd, edt1, tmpstr );
-
+      if ((pstr = SEGPTR_ALLOC(512)))
+      {
+          SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT, lRet,
+                               (LPARAM)SEGPTR_GET(pstr));
+          SetDlgItemText32A( hWnd, edt1, pstr );
+          SEGPTR_FREE(pstr);
+      }
       if (FILEDLG_HookCallChk(lpofn))
        CallWindowProc16(lpofn->lpfnHook, hWnd,
                   RegisterWindowMessage32A( LBSELCHSTRING ),
@@ -444,8 +460,11 @@
 	{
 	  lRet = SendDlgItemMessage16(hWnd, lst2, LB_GETCURSEL, 0, 0);
 	  if (lRet == LB_ERR) return TRUE;
+          pstr = SEGPTR_ALLOC(512);
 	  SendDlgItemMessage16(hWnd, lst2, LB_GETTEXT, lRet,
-			     (LPARAM)MAKE_SEGPTR(tmpstr));
+			     (LPARAM)SEGPTR_GET(pstr));
+          strcpy( tmpstr, pstr );
+          SEGPTR_FREE(pstr);
 	  if (tmpstr[0] == '[')
 	    {
 	      tmpstr[strlen(tmpstr) - 1] = 0;
@@ -466,8 +485,11 @@
       FILEDLG_StripEditControl(hWnd);
       lRet = SendDlgItemMessage16(hWnd, cmb2, CB_GETCURSEL, 0, 0L);
       if (lRet == LB_ERR) return 0;
-      SendDlgItemMessage16(hWnd, cmb2, CB_GETLBTEXT, lRet, (LPARAM)MAKE_SEGPTR(tmpstr));
-      sprintf(tmpstr, "%c:", tmpstr[2]);
+      pstr = SEGPTR_ALLOC(512);
+      SendDlgItemMessage16(hWnd, cmb2, CB_GETLBTEXT, lRet,
+                           (LPARAM)SEGPTR_GET(pstr));
+      sprintf(tmpstr, "%c:", pstr[2]);
+      SEGPTR_FREE(pstr);
     reset_scan:
       lRet = SendDlgItemMessage16(hWnd, cmb1, CB_GETCURSEL, 0, 0);
       if (lRet == LB_ERR)
@@ -561,15 +583,12 @@
 	{
 	  lRet = SendDlgItemMessage16(hWnd, lst1, LB_GETCURSEL, 0, 0);
 	  SendDlgItemMessage16(hWnd, lst1, LB_GETTEXT, lRet,
-			     (LPARAM)MAKE_SEGPTR(tmpstr));
-          dprintf_commdlg(stddeb,"strcpy'ing '%s'\n",tmpstr); fflush(stdout);
-	  strcpy(PTR_SEG_TO_LIN(lpofn->lpstrFileTitle), tmpstr);
+                               lpofn->lpstrFileTitle );
 	}
       if (FILEDLG_HookCallChk(lpofn))
       {
        lRet= (BOOL)CallWindowProc16(lpofn->lpfnHook,
-               hWnd, RegisterWindowMessage32A( FILEOKSTRING ),
-               0, (LPARAM)MAKE_SEGPTR(lpofn));                        
+               hWnd, RegisterWindowMessage32A( FILEOKSTRING ), 0, lParam );
        if (lRet)       
        {
          *lpofn=ofn2; /* restore old state */
@@ -594,7 +613,7 @@
  */
 LRESULT FileOpenDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {  
- LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
+ LPOPENFILENAME lpofn = (LPOPENFILENAME)PTR_SEG_TO_LIN(GetWindowLong32A(hWnd, DWL_USER));
  
  if (wMsg!=WM_INITDIALOG)
   if (FILEDLG_HookCallChk(lpofn))
@@ -637,7 +656,7 @@
  */
 LRESULT FileSaveDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {
- LPOPENFILENAME lpofn = (LPOPENFILENAME)GetWindowLong32A(hWnd, DWL_USER);
+ LPOPENFILENAME lpofn = (LPOPENFILENAME)PTR_SEG_TO_LIN(GetWindowLong32A(hWnd, DWL_USER));
  
  if (wMsg!=WM_INITDIALOG)
   if (FILEDLG_HookCallChk(lpofn))
@@ -791,7 +810,7 @@
     int uFindReplaceMessage = RegisterWindowMessage32A( FINDMSGSTRING );
     int uHelpMessage = RegisterWindowMessage32A( HELPMSGSTRING );
 
-    lpfr = (LPFINDREPLACE)GetWindowLong32A(hWnd, DWL_USER);
+    lpfr = (LPFINDREPLACE)PTR_SEG_TO_LIN(GetWindowLong32A(hWnd, DWL_USER));
     switch (wParam) {
 	case IDOK:
 	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
@@ -806,12 +825,14 @@
 		else lpfr->Flags &= ~FR_MATCHCASE;
             lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
 	    lpfr->Flags |= FR_FINDNEXT;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+                          GetWindowLong32A(hWnd, DWL_USER) );
 	    return TRUE;
 	case IDCANCEL:
             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
 	    lpfr->Flags |= FR_DIALOGTERM;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+                          GetWindowLong32A(hWnd, DWL_USER) );
 	    DestroyWindow(hWnd);
 	    return TRUE;
 	case pshHelp:
@@ -883,7 +904,7 @@
     int uFindReplaceMessage = RegisterWindowMessage32A( FINDMSGSTRING );
     int uHelpMessage = RegisterWindowMessage32A( HELPMSGSTRING );
 
-    lpfr = (LPFINDREPLACE)GetWindowLong32A(hWnd, DWL_USER);
+    lpfr = (LPFINDREPLACE)PTR_SEG_TO_LIN(GetWindowLong32A(hWnd, DWL_USER));
     switch (wParam) {
 	case IDOK:
 	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
@@ -896,12 +917,14 @@
 		else lpfr->Flags &= ~FR_MATCHCASE;
             lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
 	    lpfr->Flags |= FR_FINDNEXT;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+                          GetWindowLong32A(hWnd, DWL_USER) );
 	    return TRUE;
 	case IDCANCEL:
             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
 	    lpfr->Flags |= FR_DIALOGTERM;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+                          GetWindowLong32A(hWnd, DWL_USER) );
 	    DestroyWindow(hWnd);
 	    return TRUE;
 	case psh1:
@@ -915,7 +938,8 @@
 		else lpfr->Flags &= ~FR_MATCHCASE;
             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
 	    lpfr->Flags |= FR_REPLACE;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+                          GetWindowLong32A(hWnd, DWL_USER) );
 	    return TRUE;
 	case psh2:
 	    GetDlgItemText16(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
@@ -928,7 +952,8 @@
 		else lpfr->Flags &= ~FR_MATCHCASE;
             lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);
 	    lpfr->Flags |= FR_REPLACEALL;
-	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    SendMessage16(lpfr->hwndOwner, uFindReplaceMessage, 0,
+                          GetWindowLong32A(hWnd, DWL_USER) );
 	    return TRUE;
 	case pshHelp:
 	    /* FIXME : should lpfr structure be passed as an argument ??? */
@@ -2254,7 +2279,8 @@
    if (!(nFontType & 0x0004))   /* this means 'TRUETYPE_FONTTYPE' */
      return 1;   
 
-  i=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(lplf->lfFaceName));
+  i=SendMessage16(hwnd,CB_ADDSTRING,0,
+                  (LPARAM)logfont + ((char *)lplf->lfFaceName - (char *)lplf));
   if (i!=CB_ERR)
   {
     w=(lplf->lfCharSet << 8) | lplf->lfPitchAndFamily;
@@ -2297,7 +2323,9 @@
      if (lptm->tmWeight==fontstyles[i].weight &&
          lptm->tmItalic==fontstyles[i].italic)    /* font successful created ? */
      {
-       j=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(fontstyles[i].stname));
+       char *str = SEGPTR_STRDUP(fontstyles[i].stname);
+       j=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)SEGPTR_GET(str) );
+       SEGPTR_FREE(str);
        if (j==CB_ERR) return 1;
        j=SendMessage16(hwnd, CB_SETITEMDATA, j, 
                                  MAKELONG(fontstyles[i].weight,fontstyles[i].italic));
@@ -2312,10 +2340,11 @@
  */
 static int SetFontSizesToCombo3(HWND hwnd, LPLOGFONT16 lplf, LPCHOOSEFONT lpcf)
 {
-  int sizes[]={8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72,0};
+  static const int sizes[]={8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72,0};
   int h,i,j;
-  char buffer[20];
+  char *buffer;
   
+  if (!(buffer = SEGPTR_ALLOC(20))) return 1;
   for (i=0;sizes[i] && !lplf->lfHeight;i++)
   {
    h=lplf->lfHeight ? lplf->lfHeight : sizes[i];
@@ -2324,16 +2353,20 @@
            ((lpcf->Flags & CF_LIMITSIZE) && (h >= lpcf->nSizeMin) && (h <= lpcf->nSizeMax)))
    {
       sprintf(buffer,"%2d",h);
-      j=SendMessage16(hwnd,CB_FINDSTRING,-1,(LPARAM)MAKE_SEGPTR(buffer));
+      j=SendMessage16(hwnd,CB_FINDSTRING,-1,(LPARAM)SEGPTR_GET(buffer));
       if (j==CB_ERR)
       {
-        j=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR(buffer));
-        if (j==CB_ERR) return 1;
-        j=SendMessage16(hwnd, CB_SETITEMDATA, j, h); 
-        if (j==CB_ERR) return 1;
+        j=SendMessage16(hwnd,CB_ADDSTRING,0,(LPARAM)SEGPTR_GET(buffer));
+        if (j!=CB_ERR) j = SendMessage16(hwnd, CB_SETITEMDATA, j, h); 
+        if (j==CB_ERR)
+        {
+            SEGPTR_FREE(buffer);
+            return 1;
+        }
       }
    }  
   }  
+  SEGPTR_FREE(buffer);
  return 0;
 }
 
@@ -2409,7 +2442,10 @@
     for (res=1,i=0;res && i<TEXT_COLORS;i++)
     {
       /* FIXME: load color name from resource:  res=LoadString(...,i+....,buffer,.....); */
-      j=SendDlgItemMessage16(hDlg,cmb4,CB_ADDSTRING,0,(LPARAM)MAKE_SEGPTR("[color name]"));
+      char *name = SEGPTR_ALLOC(20);
+      strcpy( name, "[color name]" );
+      j=SendDlgItemMessage16(hDlg,cmb4,CB_ADDSTRING,0,(LPARAM)SEGPTR_GET(name));
+      SEGPTR_FREE(name);
       SendDlgItemMessage16(hDlg,cmb4, CB_SETITEMDATA,j,textcolors[j]);
       /* look for a fitting value in color combobox */
       if (textcolors[j]==lpcf->rgbColors)
@@ -2509,7 +2545,7 @@
 LRESULT CFn_WMDrawItem(HWND hDlg, WPARAM wParam, LPARAM lParam)
 {
   HBRUSH hBrush;
-  char buffer[40];
+  char *buffer;
   BITMAP16 bm;
   COLORREF cr;
   RECT16 rect;
@@ -2534,11 +2570,12 @@
      return TRUE;	/* this should never happen */
 
    rect=lpdi->rcItem;
+   buffer = SEGPTR_ALLOC(40);
    switch (lpdi->CtlID)
    {
     case cmb1:	/* dprintf_commdlg(stddeb,"WM_Drawitem cmb1\n"); */
 		SendMessage16(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
-			(LPARAM)MAKE_SEGPTR(buffer));	          
+			(LPARAM)SEGPTR_GET(buffer));	          
 		GetObject16( hBitmapTT, sizeof(bm), &bm );
 		TextOut16(lpdi->hDC, lpdi->rcItem.left + bm.bmWidth + 10,
                           lpdi->rcItem.top, buffer, lstrlen16(buffer));
@@ -2559,14 +2596,14 @@
     case cmb2:
     case cmb3:	/* dprintf_commdlg(stddeb,"WM_DRAWITEN cmb2,cmb3\n"); */
 		SendMessage16(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
-			(LPARAM)MAKE_SEGPTR(buffer));
+			(LPARAM)SEGPTR_GET(buffer));
 		TextOut16(lpdi->hDC, lpdi->rcItem.left,
                           lpdi->rcItem.top, buffer, lstrlen16(buffer));
 		break;
 
     case cmb4:	/* dprintf_commdlg(stddeb,"WM_DRAWITEM cmb4 (=COLOR)\n"); */
 		SendMessage16(lpdi->hwndItem, CB_GETLBTEXT, lpdi->itemID,
-    		    (LPARAM)MAKE_SEGPTR(buffer));
+    		    (LPARAM)SEGPTR_GET(buffer));
 		TextOut16(lpdi->hDC, lpdi->rcItem.left +  25+5,
                           lpdi->rcItem.top, buffer, lstrlen16(buffer));
 		cr = SendMessage16(lpdi->hwndItem, CB_GETITEMDATA, lpdi->itemID,0L);
@@ -2587,6 +2624,7 @@
 
     default:	return TRUE;	/* this should never happen */
    }
+   SEGPTR_FREE(buffer);
    if (lpdi->itemState ==ODS_SELECTED)
      InvertRect16(lpdi->hDC, &rect);
  }
@@ -2614,7 +2652,6 @@
  */
 LRESULT CFn_WMCommand(HWND hDlg, WPARAM wParam, LPARAM lParam)
 {
-  char buffer[200];
   HFONT hFont/*,hFontOld*/;
   int i,j;
   long l;
@@ -2636,11 +2673,14 @@
 		      if (i!=CB_ERR)
 		      {
 		        HCURSOR16 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);
-       		        EnumFontFamilies(hdc,buffer,FontStyleEnumProc,
+                        char *str = SEGPTR_ALLOC(256);
+                        SendDlgItemMessage16(hDlg,cmb1,CB_GETLBTEXT,i,
+                                             (LPARAM)SEGPTR_GET(str));
+	                dprintf_commdlg(stddeb,"WM_COMMAND/cmb1 =>%s\n",str);
+       		        EnumFontFamilies(hdc,str,FontStyleEnumProc,
 		             MAKELONG(GetDlgItem(hDlg,cmb2),GetDlgItem(hDlg,cmb3)));
-		        SetCursor(hcursor);        
+		        SetCursor(hcursor);     
+                        SEGPTR_FREE(str);
 		      }
 		      if (!(lpcf->Flags & CF_PRINTERFONTS && lpcf->hDC))
  		        ReleaseDC(hDlg,hdc);
@@ -2657,13 +2697,15 @@
 	case cmb2:
 	case cmb3:if (HIWORD(lParam)==CBN_SELCHANGE || HIWORD(lParam)== BN_CLICKED )
 	          {
+                    char *str = SEGPTR_ALLOC(256);
                     dprintf_commdlg(stddeb,"WM_COMMAND/cmb2,3 =%08lX\n", lParam);
 		    i=SendDlgItemMessage16(hDlg,cmb1,CB_GETCURSEL,0,0);
 		    if (i==CB_ERR)
-                      i=GetDlgItemText32A( hDlg, cmb1, buffer, sizeof(buffer) );
+                      i=GetDlgItemText32A( hDlg, cmb1, str, 256 );
                     else
                     {
-		      SendDlgItemMessage16(hDlg,cmb1,CB_GETLBTEXT,i,(LPARAM)MAKE_SEGPTR(buffer));
+		      SendDlgItemMessage16(hDlg,cmb1,CB_GETLBTEXT,i,
+                                           (LPARAM)SEGPTR_GET(str));
 		      l=SendDlgItemMessage16(hDlg,cmb1,CB_GETITEMDATA,i,0);
 		      j=HIWORD(l);
 		      lpcf->nFontType = LOWORD(l);
@@ -2673,7 +2715,8 @@
 		      lpxx->lfPitchAndFamily=j&0xff;
 		      lpxx->lfCharSet=j>>8;
                     }
-                    strcpy(lpxx->lfFaceName,buffer);
+                    strcpy(lpxx->lfFaceName,str);
+                    SEGPTR_FREE(str);
 		    i=SendDlgItemMessage16(hDlg,cmb2,CB_GETCURSEL,0,0);
 		    if (i!=CB_ERR)
 		    {
@@ -2725,7 +2768,9 @@
 	             EndDialog(hDlg, TRUE);
 	          else
 	          {
-	           sprintf(buffer,"Select a font size among %d and %d points.",lpcf->nSizeMin,lpcf->nSizeMax);
+                   char buffer[80];
+	           sprintf(buffer,"Select a font size between %d and %d points.",
+                           lpcf->nSizeMin,lpcf->nSizeMax);
 	           MessageBox(hDlg,buffer,NULL,MB_OK);
 	          } 
 		  return(TRUE);
diff --git a/misc/crtdll.c b/misc/crtdll.c
index e73d8c2..9139d00 100644
--- a/misc/crtdll.c
+++ b/misc/crtdll.c
@@ -8,6 +8,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 #include <time.h>
 #include <ctype.h>
@@ -176,3 +177,44 @@
 CRTDLL_putchar(INT32 x) {
 	putchar(x);
 }
+
+int
+CRTDLL__mbsicmp(unsigned char *x,unsigned char *y)
+{
+	do {
+		if (!*x)
+			return !!*y;
+		if (!*y)
+			return !!*x;
+		/* FIXME: MBCS handling... */
+		if (*x!=*y)
+			return 1;
+                x++;
+                y++;
+	} while (1);
+}
+
+unsigned char*
+CRTDLL__mbsinc(unsigned char *x)
+{
+    /* FIXME: mbcs */
+    return x++;
+}
+
+int
+CRTDLL_vsprintf(DWORD *args)
+{
+    return vsprintf((char *)args[0],(char *)args[1],args+2);
+}
+
+unsigned char*
+CRTDLL__mbscpy(unsigned char *x,unsigned char *y)
+{
+    return strcpy(x,y);
+}
+
+unsigned char*
+CRTDLL__mbscat(unsigned char *x,unsigned char *y)
+{
+    return strcat(x,y);
+}
diff --git a/misc/lstr.c b/misc/lstr.c
index 9f2d01c..318e3da 100644
--- a/misc/lstr.c
+++ b/misc/lstr.c
@@ -14,7 +14,6 @@
 #include "windows.h"
 #include "ldt.h"
 #include "module.h"
-#include "stackframe.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
diff --git a/misc/lzexpand.c b/misc/lzexpand.c
index 45b3655..cdf314d 100644
--- a/misc/lzexpand.c
+++ b/misc/lzexpand.c
@@ -16,8 +16,8 @@
 #include <sys/stat.h>
 #include "windows.h"
 #include "file.h"
+#include "ldt.h"
 #include "lzexpand.h"
-#include "stackframe.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
diff --git a/misc/main.c b/misc/main.c
index c02aaea..e2bc1f5 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -55,10 +55,7 @@
 "Jan Willamowius, Carl Williams, Karl Guenter Wuensch, Eric Youngdale, "
 "and James Youngman. ";
 
-const struct _langentry {
-	char *name;
-	WORD langid;
-} languages[] =
+const WINE_LANGUAGE_DEF Languages[] =
 {
     {"En",0x0409},	/* LANG_En */
     {"Es",0x040A},	/* LANG_Es */
@@ -289,19 +286,20 @@
  */
 static void MAIN_ParseLanguageOption( char *arg )
 {
-    const struct _langentry *p = languages;
+    const WINE_LANGUAGE_DEF *p = Languages;
 
     Options.language = LANG_En;  /* First language */
     for (;p->name;p++)
     {
-        if (!lstrcmpi32A( p->name, arg )) {
+        if (!lstrcmpi32A( p->name, arg ))
+        {
 	    WINE_LanguageId = p->langid;
 	    return;
 	}
         Options.language++;
     }
     fprintf( stderr, "Invalid language specified '%s'. Supported languages are: ", arg );
-    for (p = languages; p->name; p++) fprintf( stderr, "%s ", p->name );
+    for (p = Languages; p->name; p++) fprintf( stderr, "%s ", p->name );
     fprintf( stderr, "\n" );
     exit(1);
 }
diff --git a/misc/ole2nls.c b/misc/ole2nls.c
index 5a59bc32..297ca18 100644
--- a/misc/ole2nls.c
+++ b/misc/ole2nls.c
@@ -73,12 +73,14 @@
     int retLen;
     dprintf_ole(stddeb,"GetLocaleInfoA(%8lX,%8lX,%p,%4X)\n",
 			lcid,LCType,buf,len);
+#if 0
 	/* Wine is supporting only the default locale */
 	if(lcid!=GetUserDefaultLCID())
 	{
 		dprintf_ole(stdnimp,"GetLocaleInfoA: Unknown locale\n");
 		return 0;
 	}
+#endif
 	/* As an option, we could obtain the value from win.ini.
 	   This would not match the Wine compile-time option.
 	   Also, not all identifiers are available from win.ini */
@@ -424,6 +426,131 @@
 /* LOCVAL(LOCALE_INEGSEPBYSPACE) */
     break; /* LANG(Da) */
 
+    case LANG_En:
+/* This definitions apply to Germany only. Users in Austria 
+   or Switzerland might want to modify them */
+LOCVAL(LOCALE_ILANGUAGE,"9")
+LOCVAL(LOCALE_SLANGUAGE,"English")
+LOCVAL(LOCALE_SENGLANGUAGE,"English")
+LOCVAL(LOCALE_SABBREVLANGNAME,"enu")
+LOCVAL(LOCALE_SNATIVELANGNAME,"English")
+LOCVAL(LOCALE_ICOUNTRY,"11")
+LOCVAL(LOCALE_SCOUNTRY,"Deutschland")
+LOCVAL(LOCALE_SENGCOUNTRY,"Deutschland")
+LOCVAL(LOCALE_SABBREVCTRYNAME,"De")
+LOCVAL(LOCALE_SNATIVECTRYNAME,"Deutschland")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9")
+LOCVAL(LOCALE_IDEFAULTCOUNTRY,"49")
+/* Dunno
+LOCVAL(LOCALE_IDEFAULTCODEPAGE)
+LOCVAL(LOCALE_IDEFAULTANSICODEPAGE)
+*/
+LOCVAL(LOCALE_SLIST,";")
+LOCVAL(LOCALE_IMEASURE,"0")
+LOCVAL(LOCALE_SDECIMAL,",")
+LOCVAL(LOCALE_STHOUSAND,".")
+/*
+LOCVAL(LOCALE_SGROUPING)
+*/
+LOCVAL(LOCALE_IDIGITS,"2")
+LOCVAL(LOCALE_ILZERO,"1")
+/*
+LOCVAL(LOCALE_INEGNUMBER)
+Is this "0123456789" ??
+LOCVAL(LOCALE_SNATIVEDIGITS)
+*/
+LOCVAL(LOCALE_SCURRENCY,"DM")
+/*
+LOCVAL(LOCALE_SINTLSYMBOL)
+LOCVAL(LOCALE_SMONDECIMALSEP)
+LOCVAL(LOCALE_SMONTHOUSANDSEP)
+LOCVAL(LOCALE_SMONGROUPING)
+*/
+LOCVAL(LOCALE_ICURRDIGITS,"2")
+/*
+LOCVAL(LOCALE_IINTLCURRDIGITS)
+*/
+LOCVAL(LOCALE_ICURRENCY,"3")
+LOCVAL(LOCALE_INEGCURR,"8")
+LOCVAL(LOCALE_SDATE,".")
+LOCVAL(LOCALE_STIME,":")
+LOCVAL(LOCALE_SSHORTDATE,"dd.MM.yyyy")
+LOCVAL(LOCALE_SLONGDATE,"ddd, d. MMMM yyyy")
+/*
+LOCVAL(LOCALE_STIMEFORMAT)
+*/
+LOCVAL(LOCALE_IDATE,"1")
+/*
+LOCVAL(LOCALE_ILDATE)
+*/
+LOCVAL(LOCALE_ITIME,"1")
+/*
+LOCVAL(LOCALE_ITIMEMARKPOSN)
+LOCVAL(LOCALE_ICENTURY)
+*/
+LOCVAL(LOCALE_ITLZERO,"1")
+/*
+LOCVAL(LOCALE_IDAYLZERO)
+LOCVAL(LOCALE_IMONLZERO)
+LOCVAL(LOCALE_S1159)
+LOCVAL(LOCALE_S2359)
+LOCVAL(LOCALE_ICALENDARTYPE)
+LOCVAL(LOCALE_IOPTIONALCALENDAR)
+LOCVAL(LOCALE_IFIRSTDAYOFWEEK)
+LOCVAL(LOCALE_IFIRSTWEEKOFYEAR)
+*/
+LOCVAL(LOCALE_SDAYNAME1,"Montag")
+LOCVAL(LOCALE_SDAYNAME2,"Dienstag")
+LOCVAL(LOCALE_SDAYNAME3,"Mittwoch")
+LOCVAL(LOCALE_SDAYNAME4,"Donnerstag")
+LOCVAL(LOCALE_SDAYNAME5,"Freitag")
+LOCVAL(LOCALE_SDAYNAME6,"Sonnabend")
+LOCVAL(LOCALE_SDAYNAME7,"Sonntag")
+LOCVAL(LOCALE_SABBREVDAYNAME1,"Mo")
+LOCVAL(LOCALE_SABBREVDAYNAME2,"Di")
+LOCVAL(LOCALE_SABBREVDAYNAME3,"Mi")
+LOCVAL(LOCALE_SABBREVDAYNAME4,"Do")
+LOCVAL(LOCALE_SABBREVDAYNAME5,"Fr")
+LOCVAL(LOCALE_SABBREVDAYNAME6,"Sa")
+LOCVAL(LOCALE_SABBREVDAYNAME7,"So")
+LOCVAL(LOCALE_SMONTHNAME1,"Januar")
+LOCVAL(LOCALE_SMONTHNAME2,"Februar")
+LOCVAL(LOCALE_SMONTHNAME3,"März")
+LOCVAL(LOCALE_SMONTHNAME4,"April")
+LOCVAL(LOCALE_SMONTHNAME5,"Mai")
+LOCVAL(LOCALE_SMONTHNAME6,"Juni")
+LOCVAL(LOCALE_SMONTHNAME7,"Juli")
+LOCVAL(LOCALE_SMONTHNAME8,"August")
+LOCVAL(LOCALE_SMONTHNAME9,"September")
+LOCVAL(LOCALE_SMONTHNAME10,"Oktober")
+LOCVAL(LOCALE_SMONTHNAME11,"November")
+LOCVAL(LOCALE_SMONTHNAME12,"Dezember")
+LOCVAL(LOCALE_SMONTHNAME13,"")
+LOCVAL(LOCALE_SABBREVMONTHNAME1,"Jan")
+LOCVAL(LOCALE_SABBREVMONTHNAME2,"Feb")
+LOCVAL(LOCALE_SABBREVMONTHNAME3,"Mär")
+LOCVAL(LOCALE_SABBREVMONTHNAME4,"Apr")
+LOCVAL(LOCALE_SABBREVMONTHNAME5,"Mai")
+LOCVAL(LOCALE_SABBREVMONTHNAME6,"Jun")
+LOCVAL(LOCALE_SABBREVMONTHNAME7,"Jul")
+LOCVAL(LOCALE_SABBREVMONTHNAME8,"Aug")
+LOCVAL(LOCALE_SABBREVMONTHNAME9,"Sep")
+LOCVAL(LOCALE_SABBREVMONTHNAME10,"Okt")
+LOCVAL(LOCALE_SABBREVMONTHNAME11,"Nov")
+LOCVAL(LOCALE_SABBREVMONTHNAME12,"Dez")
+LOCVAL(LOCALE_SABBREVMONTHNAME13,"")
+/*
+LOCVAL(LOCALE_SPOSITIVESIGN)
+LOCVAL(LOCALE_SNEGATIVESIGN)
+LOCVAL(LOCALE_IPOSSIGNPOSN)
+LOCVAL(LOCALE_INEGSIGNPOSN)
+LOCVAL(LOCALE_IPOSSYMPRECEDES)
+LOCVAL(LOCALE_IPOSSEPBYSPACE)
+LOCVAL(LOCALE_INEGSYMPRECEDES)
+LOCVAL(LOCALE_INEGSEPBYSPACE)
+*/
+    break;  /* LANG(En) */
+
     case LANG_Eo:
 /* LOCVAL(LOCALE_ILANGUAGE,"9") ISO numerical ID for language TODO */
 LOCVAL(LOCALE_SLANGUAGE,"Esperanto")
@@ -437,8 +564,8 @@
 /* LOCVAL(LOCALE_SNATIVECTRYNAME,"Deutschland") */
 /* LOCVAL(LOCALE_IDEFAULTLANGUAGE,"9") ISO ID of lang TODO */
 /* LOCVAL(LOCALE_IDEFAULTCOUNTRY,"49") */
-LOCVAL(LOCALE_IDEFAULTCODEPAGE,3) /* is this right? TODO */
-LOCVAL(LOCALE_IDEFAULTANSICODEPAGE,3) /* is this right? TODO */
+LOCVAL(LOCALE_IDEFAULTCODEPAGE,"3") /* is this right? TODO */
+LOCVAL(LOCALE_IDEFAULTANSICODEPAGE,"3") /* is this right? TODO */
 LOCVAL(LOCALE_SLIST,";")
 LOCVAL(LOCALE_IMEASURE,"0")
 LOCVAL(LOCALE_SDECIMAL,",")
@@ -772,6 +899,209 @@
 */
     break;  /* LANG(It) */
 
+    case 0x0409:
+LOCVAL(LOCALE_ILANGUAGE, "0409")
+LOCVAL(LOCALE_SLANGUAGE, "English (United States)")
+LOCVAL(LOCALE_SENGLANGUAGE, "English")
+LOCVAL(LOCALE_SABBREVLANGNAME, "ENU")
+LOCVAL(LOCALE_SNATIVELANGNAME, "English")
+LOCVAL(LOCALE_ICOUNTRY, "1")
+LOCVAL(LOCALE_SCOUNTRY, "United States")
+LOCVAL(LOCALE_SENGCOUNTRY, "United States")
+LOCVAL(LOCALE_SABBREVCTRYNAME, "USA")
+LOCVAL(LOCALE_SNATIVECTRYNAME, "United States")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0409")
+LOCVAL(LOCALE_IDEFAULTCOUNTRY, "1")
+LOCVAL(LOCALE_IDEFAULTCODEPAGE, "437")
+LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
+LOCVAL(LOCALE_SLIST, ",")
+LOCVAL(LOCALE_IMEASURE, "1")
+LOCVAL(LOCALE_SDECIMAL, ".")
+LOCVAL(LOCALE_STHOUSAND, ",")
+LOCVAL(LOCALE_SGROUPING, "3;0")
+LOCVAL(LOCALE_IDIGITS, "2")
+LOCVAL(LOCALE_ILZERO, "1")
+LOCVAL(LOCALE_INEGNUMBER, "1")
+LOCVAL(LOCALE_SNATIVEDIGITS, "0123456789")
+LOCVAL(LOCALE_SCURRENCY, "$")
+LOCVAL(LOCALE_SINTLSYMBOL, "USD")
+LOCVAL(LOCALE_SMONDECIMALSEP, ".")
+LOCVAL(LOCALE_SMONTHOUSANDSEP, ",")
+LOCVAL(LOCALE_SMONGROUPING, "3;0")
+LOCVAL(LOCALE_ICURRDIGITS, "2")
+LOCVAL(LOCALE_IINTLCURRDIGITS, "2")
+LOCVAL(LOCALE_ICURRENCY, "0")
+LOCVAL(LOCALE_INEGCURR, "0")
+LOCVAL(LOCALE_SDATE, "/")
+LOCVAL(LOCALE_STIME, ":")
+LOCVAL(LOCALE_SSHORTDATE, "M/d/yy")
+LOCVAL(LOCALE_SLONGDATE, "dddd, MMMM dd, yyyy")
+LOCVAL(LOCALE_STIMEFORMAT, "h:mm:ss tt")
+LOCVAL(LOCALE_IDATE, "0")
+LOCVAL(LOCALE_ILDATE, "0")
+LOCVAL(LOCALE_ITIME, "0")
+LOCVAL(LOCALE_ITIMEMARKPOSN, "0")
+LOCVAL(LOCALE_ICENTURY, "0")
+LOCVAL(LOCALE_ITLZERO, "0")
+LOCVAL(LOCALE_IDAYLZERO, "0")
+LOCVAL(LOCALE_IMONLZERO, "0")
+LOCVAL(LOCALE_S1159, "AM")
+LOCVAL(LOCALE_S2359, "PM")
+LOCVAL(LOCALE_ICALENDARTYPE, "1")
+LOCVAL(LOCALE_IOPTIONALCALENDAR, "0")
+LOCVAL(LOCALE_IFIRSTDAYOFWEEK, "6")
+LOCVAL(LOCALE_IFIRSTWEEKOFYEAR, "0")
+LOCVAL(LOCALE_SDAYNAME1, "Monday")
+LOCVAL(LOCALE_SDAYNAME2, "Tuesday")
+LOCVAL(LOCALE_SDAYNAME3, "Wednesday")
+LOCVAL(LOCALE_SDAYNAME4, "Thursday")
+LOCVAL(LOCALE_SDAYNAME5, "Friday")
+LOCVAL(LOCALE_SDAYNAME6, "Saturday")
+LOCVAL(LOCALE_SDAYNAME7, "Sunday")
+LOCVAL(LOCALE_SABBREVDAYNAME1, "Mon")
+LOCVAL(LOCALE_SABBREVDAYNAME2, "Tue")
+LOCVAL(LOCALE_SABBREVDAYNAME3, "Wed")
+LOCVAL(LOCALE_SABBREVDAYNAME4, "Thu")
+LOCVAL(LOCALE_SABBREVDAYNAME5, "Fri")
+LOCVAL(LOCALE_SABBREVDAYNAME6, "Sat")
+LOCVAL(LOCALE_SABBREVDAYNAME7, "Sun")
+LOCVAL(LOCALE_SMONTHNAME1, "January")
+LOCVAL(LOCALE_SMONTHNAME2, "February")
+LOCVAL(LOCALE_SMONTHNAME3, "March")
+LOCVAL(LOCALE_SMONTHNAME4, "April")
+LOCVAL(LOCALE_SMONTHNAME5, "May")
+LOCVAL(LOCALE_SMONTHNAME6, "June")
+LOCVAL(LOCALE_SMONTHNAME7, "July")
+LOCVAL(LOCALE_SMONTHNAME8, "August")
+LOCVAL(LOCALE_SMONTHNAME9, "September")
+LOCVAL(LOCALE_SMONTHNAME10, "October")
+LOCVAL(LOCALE_SMONTHNAME11, "November")
+LOCVAL(LOCALE_SMONTHNAME12, "December")
+LOCVAL(LOCALE_SMONTHNAME13, "")
+LOCVAL(LOCALE_SABBREVMONTHNAME1, "Jan")
+LOCVAL(LOCALE_SABBREVMONTHNAME2, "Feb")
+LOCVAL(LOCALE_SABBREVMONTHNAME3, "Mar")
+LOCVAL(LOCALE_SABBREVMONTHNAME4, "Apr")
+LOCVAL(LOCALE_SABBREVMONTHNAME5, "May")
+LOCVAL(LOCALE_SABBREVMONTHNAME6, "Jun")
+LOCVAL(LOCALE_SABBREVMONTHNAME7, "Jul")
+LOCVAL(LOCALE_SABBREVMONTHNAME8, "Aug")
+LOCVAL(LOCALE_SABBREVMONTHNAME9, "Sep")
+LOCVAL(LOCALE_SABBREVMONTHNAME10, "Oct")
+LOCVAL(LOCALE_SABBREVMONTHNAME11, "Nov")
+LOCVAL(LOCALE_SABBREVMONTHNAME12, "Dec")
+LOCVAL(LOCALE_SABBREVMONTHNAME13, "")
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
+LOCVAL(LOCALE_IPOSSIGNPOSN, "3")
+LOCVAL(LOCALE_INEGSIGNPOSN, "0")
+LOCVAL(LOCALE_IPOSSYMPRECEDES, "1")
+LOCVAL(LOCALE_IPOSSEPBYSPACE, "0")
+LOCVAL(LOCALE_INEGSYMPRECEDES, "1")
+LOCVAL(LOCALE_INEGSEPBYSPACE, "0")
+    break; /* LANG(0x0409) (U.S. English) */
+
+    case 0x0809:
+LOCVAL(LOCALE_ILANGUAGE, "0809")
+LOCVAL(LOCALE_SLANGUAGE, "English (United Kingdom)")
+LOCVAL(LOCALE_SENGLANGUAGE, "English")
+LOCVAL(LOCALE_SABBREVLANGNAME, "ENG")
+LOCVAL(LOCALE_SNATIVELANGNAME, "English")
+LOCVAL(LOCALE_ICOUNTRY, "44")
+LOCVAL(LOCALE_SCOUNTRY, "United Kingdom")
+LOCVAL(LOCALE_SENGCOUNTRY, "United Kingdom")
+LOCVAL(LOCALE_SABBREVCTRYNAME, "GBR")
+LOCVAL(LOCALE_SNATIVECTRYNAME, "United Kingdom")
+LOCVAL(LOCALE_IDEFAULTLANGUAGE, "0809")
+LOCVAL(LOCALE_IDEFAULTCOUNTRY, "44")
+LOCVAL(LOCALE_IDEFAULTCODEPAGE, "850")
+LOCVAL(LOCALE_IDEFAULTANSICODEPAGE, "1252")
+LOCVAL(LOCALE_SLIST, ",")
+LOCVAL(LOCALE_IMEASURE, "0")
+LOCVAL(LOCALE_SDECIMAL, ".")
+LOCVAL(LOCALE_STHOUSAND, ",")
+LOCVAL(LOCALE_SGROUPING, "3;0")
+LOCVAL(LOCALE_IDIGITS, "2")
+LOCVAL(LOCALE_ILZERO, "1")
+LOCVAL(LOCALE_INEGNUMBER, "1")
+LOCVAL(LOCALE_SNATIVEDIGITS, "0123456789")
+LOCVAL(LOCALE_SCURRENCY, "£")
+LOCVAL(LOCALE_SINTLSYMBOL, "GBP")
+LOCVAL(LOCALE_SMONDECIMALSEP, ".")
+LOCVAL(LOCALE_SMONTHOUSANDSEP, ",")
+LOCVAL(LOCALE_SMONGROUPING, "3;0")
+LOCVAL(LOCALE_ICURRDIGITS, "2")
+LOCVAL(LOCALE_IINTLCURRDIGITS, "2")
+LOCVAL(LOCALE_ICURRENCY, "0")
+LOCVAL(LOCALE_INEGCURR, "1")
+LOCVAL(LOCALE_SDATE, "/")
+LOCVAL(LOCALE_STIME, ":")
+LOCVAL(LOCALE_SSHORTDATE, "dd/MM/yy")
+LOCVAL(LOCALE_SLONGDATE, "dd MMMM yyyy")
+LOCVAL(LOCALE_STIMEFORMAT, "HH:mm:ss")
+LOCVAL(LOCALE_IDATE, "1")
+LOCVAL(LOCALE_ILDATE, "1")
+LOCVAL(LOCALE_ITIME, "1")
+LOCVAL(LOCALE_ITIMEMARKPOSN, "0")
+LOCVAL(LOCALE_ICENTURY, "0")
+LOCVAL(LOCALE_ITLZERO, "1")
+LOCVAL(LOCALE_IDAYLZERO, "1")
+LOCVAL(LOCALE_IMONLZERO, "1")
+LOCVAL(LOCALE_S1159, "")
+LOCVAL(LOCALE_S2359, "")
+LOCVAL(LOCALE_ICALENDARTYPE, "1")
+LOCVAL(LOCALE_IOPTIONALCALENDAR, "0")
+LOCVAL(LOCALE_IFIRSTDAYOFWEEK, "0")
+LOCVAL(LOCALE_IFIRSTWEEKOFYEAR, "0")
+LOCVAL(LOCALE_SDAYNAME1, "Monday")
+LOCVAL(LOCALE_SDAYNAME2, "Tuesday")
+LOCVAL(LOCALE_SDAYNAME3, "Wednesday")
+LOCVAL(LOCALE_SDAYNAME4, "Thursday")
+LOCVAL(LOCALE_SDAYNAME5, "Friday")
+LOCVAL(LOCALE_SDAYNAME6, "Saturday")
+LOCVAL(LOCALE_SDAYNAME7, "Sunday")
+LOCVAL(LOCALE_SABBREVDAYNAME1, "Mon")
+LOCVAL(LOCALE_SABBREVDAYNAME2, "Tue")
+LOCVAL(LOCALE_SABBREVDAYNAME3, "Wed")
+LOCVAL(LOCALE_SABBREVDAYNAME4, "Thu")
+LOCVAL(LOCALE_SABBREVDAYNAME5, "Fri")
+LOCVAL(LOCALE_SABBREVDAYNAME6, "Sat")
+LOCVAL(LOCALE_SABBREVDAYNAME7, "Sun")
+LOCVAL(LOCALE_SMONTHNAME1, "January")
+LOCVAL(LOCALE_SMONTHNAME2, "February")
+LOCVAL(LOCALE_SMONTHNAME3, "March")
+LOCVAL(LOCALE_SMONTHNAME4, "April")
+LOCVAL(LOCALE_SMONTHNAME5, "May")
+LOCVAL(LOCALE_SMONTHNAME6, "June")
+LOCVAL(LOCALE_SMONTHNAME7, "July")
+LOCVAL(LOCALE_SMONTHNAME8, "August")
+LOCVAL(LOCALE_SMONTHNAME9, "September")
+LOCVAL(LOCALE_SMONTHNAME10, "October")
+LOCVAL(LOCALE_SMONTHNAME11, "November")
+LOCVAL(LOCALE_SMONTHNAME12, "December")
+LOCVAL(LOCALE_SMONTHNAME13, "")
+LOCVAL(LOCALE_SABBREVMONTHNAME1, "Jan")
+LOCVAL(LOCALE_SABBREVMONTHNAME2, "Feb")
+LOCVAL(LOCALE_SABBREVMONTHNAME3, "Mar")
+LOCVAL(LOCALE_SABBREVMONTHNAME4, "Apr")
+LOCVAL(LOCALE_SABBREVMONTHNAME5, "May")
+LOCVAL(LOCALE_SABBREVMONTHNAME6, "Jun")
+LOCVAL(LOCALE_SABBREVMONTHNAME7, "Jul")
+LOCVAL(LOCALE_SABBREVMONTHNAME8, "Aug")
+LOCVAL(LOCALE_SABBREVMONTHNAME9, "Sep")
+LOCVAL(LOCALE_SABBREVMONTHNAME10, "Oct")
+LOCVAL(LOCALE_SABBREVMONTHNAME11, "Nov")
+LOCVAL(LOCALE_SABBREVMONTHNAME12, "Dec")
+LOCVAL(LOCALE_SABBREVMONTHNAME13, "")
+LOCVAL(LOCALE_SPOSITIVESIGN, "")
+LOCVAL(LOCALE_SNEGATIVESIGN, "-")
+LOCVAL(LOCALE_IPOSSIGNPOSN, "3")
+LOCVAL(LOCALE_INEGSIGNPOSN, "3")
+LOCVAL(LOCALE_IPOSSYMPRECEDES, "1")
+LOCVAL(LOCALE_IPOSSEPBYSPACE, "0")
+LOCVAL(LOCALE_INEGSYMPRECEDES, "1")
+LOCVAL(LOCALE_INEGSEPBYSPACE, "0")
+    break; /* LANG(0x0809) (U.K. English) */
 
 /*Insert other languages here*/
 
@@ -792,6 +1122,20 @@
 	return retLen;
 }
 
+/***********************************************************************
+ *         GetLocaleInfo32W             (KERNEL32.230)
+ * Is the last parameter really WORD for Win16?
+ */
+INT32 GetLocaleInfo32W(LCID lcid,LCTYPE LCType,LPWSTR wbuf,INT32 len)
+{
+	int i;
+	LPSTR abuf = (LPSTR) wbuf;
+	INT32 n = GetLocaleInfoA(lcid, LCType, abuf, len);
+	for (i = n; i > 0; --i) {
+		wbuf[i] = abuf[i];
+	}
+	return n;
+}
 
 /***********************************************************************
  *           CompareString16       (OLE2NLS.8)
diff --git a/misc/shell.c b/misc/shell.c
index 0f146e1..dd7aa3b 100644
--- a/misc/shell.c
+++ b/misc/shell.c
@@ -14,11 +14,38 @@
 #include "resource.h"
 #include "dlgs.h"
 #include "win.h"
+#include "cursoricon.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
 #include "winreg.h"
 
+/* .ICO file ICONDIR definitions */
+
+#pragma pack(1)
+
+typedef struct
+{
+    BYTE        bWidth;          /* Width, in pixels, of the image	*/
+    BYTE        bHeight;         /* Height, in pixels, of the image	*/
+    BYTE        bColorCount;     /* Number of colors in image (0 if >=8bpp) */
+    BYTE        bReserved;       /* Reserved ( must be 0)		*/
+    WORD        wPlanes;         /* Color Planes			*/
+    WORD        wBitCount;       /* Bits per pixel			*/
+    DWORD       dwBytesInRes;    /* How many bytes in this resource?	*/
+    DWORD       dwImageOffset;   /* Where in the file is this image?	*/
+} icoICONDIRENTRY, *LPicoICONDIRENTRY;
+
+typedef struct
+{
+    WORD            idReserved;   /* Reserved (must be 0)		*/
+    WORD            idType;       /* Resource Type (1 for icons)	*/
+    WORD            idCount;      /* How many images?			*/
+    icoICONDIRENTRY idEntries[1]; /* An entry for each image (idCount of 'em) */
+} icoICONDIR, *LPicoICONDIR;
+
+#pragma pack(4)
+
 extern HANDLE 	CURSORICON_LoadHandler( HANDLE, HINSTANCE, BOOL);
 extern WORD 	GetIconID( HANDLE hResource, DWORD resType );
 
@@ -124,7 +151,7 @@
     HINSTANCE retval=31;    /* default - 'No association was found' */
     char *tok;              /* token pointer */
     int i;                  /* random counter */
-    char xlpFile[256];          /* result of SearchPath */
+    char xlpFile[256];      /* result of SearchPath */
 
     dprintf_exec(stddeb, "SHELL_FindExecutable: File %s, Dir %s\n", 
 		 (lpFile != NULL?lpFile:"-"), 
@@ -140,6 +167,10 @@
     }
     if (SearchPath32A(lpDirectory,lpFile,NULL,sizeof(xlpFile),xlpFile,NULL))
     	lpFile = xlpFile;
+    else {
+    	if (SearchPath32A(lpDirectory,lpFile,".exe",sizeof(xlpFile),xlpFile,NULL))
+	    lpFile = xlpFile;
+    }
 
     /* First thing we need is the file's extension */
     extension = strrchr( xlpFile, '.' ); /* Assume last "." is the one; */
@@ -376,7 +407,7 @@
  *
  * FIXME: Implement GetPEResourceTable in w32sys.c and call it here.
  */
-BYTE* SHELL_GetResourceTable(HFILE hFile)
+static BYTE* SHELL_GetResourceTable(HFILE hFile)
 {
   struct mz_header_s mz_header;
   struct ne_header_s ne_header;
@@ -391,7 +422,7 @@
       return NULL;
 
   if (ne_header.ne_magic == PE_SIGNATURE) 
-     { fprintf(stdnimp,"Win32 FIXME: file %s line %i\n", __FILE__, __LINE__ );
+     { fprintf(stdnimp,"Win32s FIXME: file %s line %i\n", __FILE__, __LINE__ );
        return NULL; }
 
   if (ne_header.ne_magic != NE_SIGNATURE) return NULL;
@@ -417,7 +448,7 @@
 /*************************************************************************
  *			SHELL_LoadResource
  */
-HANDLE	SHELL_LoadResource(HINSTANCE hInst, HFILE hFile, NE_NAMEINFO* pNInfo, WORD sizeShift)
+static HANDLE	SHELL_LoadResource(HINSTANCE hInst, HFILE hFile, NE_NAMEINFO* pNInfo, WORD sizeShift)
 {
  BYTE*	ptr;
  HANDLE handle = DirectResAlloc( hInst, 0x10, (DWORD)pNInfo->length << sizeShift);
@@ -432,6 +463,74 @@
 }
 
 /*************************************************************************
+ *                      ICO_LoadIcon
+ */
+static HANDLE   ICO_LoadIcon(HINSTANCE hInst, HFILE hFile, LPicoICONDIRENTRY lpiIDE)
+{
+ BYTE*  ptr;
+ HANDLE handle = DirectResAlloc( hInst, 0x10, lpiIDE->dwBytesInRes);
+
+ if( (ptr = (BYTE*)GlobalLock16( handle )) )
+   {
+    _llseek( hFile, lpiIDE->dwImageOffset, SEEK_SET);
+     FILE_Read( hFile, (char*)ptr, lpiIDE->dwBytesInRes);
+     return handle;
+   }
+ return (HANDLE)0;
+}
+
+/*************************************************************************
+ *                      ICO_GetIconDirectory
+ *
+ *  Read .ico file and build phony ICONDIR struct for GetIconID
+ */
+static HANDLE ICO_GetIconDirectory(HINSTANCE hInst, HFILE hFile, LPicoICONDIR* lplpiID ) 
+{
+  WORD		id[3];	/* idReserved, idType, idCount */
+  LPicoICONDIR	lpiID;
+  int		i;
+ 
+  _llseek( hFile, 0, SEEK_SET );
+  if( FILE_Read(hFile,(char*)id,sizeof(id)) != sizeof(id) ) return 0;
+
+  /* check .ICO header 
+   *
+   * - see http://www.microsoft.com/win32dev/ui/icons.htm
+   */
+
+  if( id[0] || id[1] != 1 || !id[2] ) return 0;
+
+  i = id[2]*sizeof(icoICONDIRENTRY) + sizeof(id);
+
+  lpiID = (LPicoICONDIR)xmalloc(i);
+
+  if( FILE_Read(hFile,(char*)lpiID->idEntries,i) == i )
+  {  
+     HANDLE	handle = DirectResAlloc( hInst, 0x10,
+					 id[2]*sizeof(ICONDIRENTRY) + sizeof(id) );
+     if( handle ) 
+     {
+       CURSORICONDIR*     lpID = (CURSORICONDIR*)GlobalLock16( handle );
+       lpID->idReserved = lpiID->idReserved = id[0];
+       lpID->idType = lpiID->idType = id[1];
+       lpID->idCount = lpiID->idCount = id[2];
+       for( i=0; i < lpiID->idCount; i++ )
+         {
+	    memcpy((void*)(lpID->idEntries + i), 
+		   (void*)(lpiID->idEntries + i), sizeof(ICONDIRENTRY) - 2);
+	    lpID->idEntries[i].icon.wResId = i;
+         }
+      *lplpiID = lpiID;
+       return handle;
+     }
+  }
+  /* fail */
+
+  free(lpiID);
+  return 0;
+}
+
+/*************************************************************************
  *			InternalExtractIcon		[SHELL.39]
  *
  * This abortion is called directly by Progman
@@ -449,79 +548,87 @@
 
   if( hFile == HFILE_ERROR || !n ) return 0;
 
-  hRet = GlobalAlloc16( GMEM_FIXED, sizeof(HICON16)*n);
+  hRet = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, sizeof(HICON16)*n);
   RetPtr = (HICON16*)GlobalLock16(hRet);
 
  *RetPtr = (n == 0xFFFF)? 0: 1;				/* error return values */
 
   pData = SHELL_GetResourceTable(hFile);
   if( pData ) 
+  {
+    HICON16	 hIcon = 0;
+    BOOL	 icoFile = FALSE;
+    UINT         iconDirCount = 0;
+    UINT         iconCount = 0;
+    NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2);
+    NE_NAMEINFO* pIconStorage = NULL;
+    NE_NAMEINFO* pIconDir = NULL;
+    LPicoICONDIR lpiID = NULL;
+ 
     if( pData == (BYTE*)-1 )
       {
-	/* FIXME: possible .ICO file */
+	/* check for .ICO file */
 
-	fprintf(stddeb,"InternalExtractIcon: cannot handle file %s\n", lpszExeFileName);
+	hIcon = ICO_GetIconDirectory(hInstance, hFile, &lpiID);
+	if( hIcon )
+	  { icoFile = TRUE; iconDirCount = 1; iconCount = lpiID->idCount; }
       }
-    else						/* got resource table */
+    else while( pTInfo->type_id && !(pIconStorage && pIconDir) )
       {
-	UINT	     iconDirCount = 0;
-	UINT	     iconCount = 0;
-	NE_TYPEINFO* pTInfo = (NE_TYPEINFO*)(pData + 2);
-	NE_NAMEINFO* pIconStorage = NULL;
-	NE_NAMEINFO* pIconDir = NULL;
-
 	/* find icon directory and icon repository */
 
-        while( pTInfo->type_id && !(pIconStorage && pIconDir) )
+	if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON ) 
 	  {
-	   if( pTInfo->type_id == NE_RSCTYPE_GROUP_ICON ) 
-	       {
-		 iconDirCount = pTInfo->count;
-	         pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
-		 dprintf_reg(stddeb,"\tfound directory - %i icon families\n", iconDirCount);
-	       }
-	   if( pTInfo->type_id == NE_RSCTYPE_ICON ) 
-	       { 
-		 iconCount = pTInfo->count;
-		 pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
-		 dprintf_reg(stddeb,"\ttotal icons - %i\n", iconCount);
-	       }
-  	   pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
-          }
-
-	/* load resources and create icons */
-
-        if( pIconStorage && pIconDir )
-
-            if( nIconIndex == (UINT)-1 ) RetPtr[0] = iconDirCount;
-	    else if( nIconIndex < iconDirCount )
-	      {
-		  HICON16 hIcon;
-		  UINT   i, icon;
-
-		  if( n > iconDirCount - nIconIndex ) n = iconDirCount - nIconIndex;
-
-		  for( i = nIconIndex; i < nIconIndex + n; i++ ) 
-		     {
-		       hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + i, 
-								  *(WORD*)pData );
-		       RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 );
-		       GlobalFree16(hIcon); 
-		     }
-
-		  for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
-		     {
-		       hIcon = 0;
-		       for( i = 0; i < iconCount; i++ )
-			  if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) )
-			      hIcon = SHELL_LoadResource( hInstance, hFile, pIconStorage + i,
-									     *(WORD*)pData );
-	               RetPtr[icon-nIconIndex] = (hIcon)?CURSORICON_LoadHandler( hIcon, hInstance, FALSE ):0;
-		     }
-	      }
-	free(pData);
+	     iconDirCount = pTInfo->count;
+	     pIconDir = ((NE_NAMEINFO*)(pTInfo + 1));
+	     dprintf_reg(stddeb,"\tfound directory - %i icon families\n", iconDirCount);
+	  }
+	if( pTInfo->type_id == NE_RSCTYPE_ICON ) 
+	  { 
+	     iconCount = pTInfo->count;
+	     pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1));
+	     dprintf_reg(stddeb,"\ttotal icons - %i\n", iconCount);
+	  }
+  	pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO));
       }
 
+    /* load resources and create icons */
+
+    if( (pIconStorage && pIconDir) || icoFile )
+      if( nIconIndex == (UINT)-1 ) RetPtr[0] = iconDirCount;
+      else if( nIconIndex < iconDirCount )
+        {
+	   UINT   i, icon;
+
+	   if( n > iconDirCount - nIconIndex ) n = iconDirCount - nIconIndex;
+
+	   for( i = nIconIndex; i < nIconIndex + n; i++ ) 
+	     {
+	       /* .ICO files have only one icon directory */
+
+	       if( !icoFile )
+	         hIcon = SHELL_LoadResource( hInstance, hFile, pIconDir + i, 
+							    *(WORD*)pData );
+	       RetPtr[i-nIconIndex] = GetIconID( hIcon, 3 );
+	       GlobalFree16(hIcon); 
+             }
+
+	   for( icon = nIconIndex; icon < nIconIndex + n; icon++ )
+	     {
+	       hIcon = 0;
+	       if( icoFile )
+		 hIcon = ICO_LoadIcon( hInstance, hFile, lpiID->idEntries + RetPtr[icon-nIconIndex]);
+	       else
+	         for( i = 0; i < iconCount; i++ )
+		    if( pIconStorage[i].id == (RetPtr[icon-nIconIndex] | 0x8000) )
+		      hIcon = SHELL_LoadResource( hInstance, hFile, pIconStorage + i,
+								     *(WORD*)pData );
+	       RetPtr[icon-nIconIndex] = (hIcon)?CURSORICON_LoadHandler( hIcon, hInstance, FALSE ):0;
+	     }
+        }
+    if( icoFile ) free(lpiID);
+    else free(pData);
+ } 
  _lclose( hFile );
  
   /* return array with icon handles */
diff --git a/misc/spy.c b/misc/spy.c
index 1681c9e..1a58dd4 100644
--- a/misc/spy.c
+++ b/misc/spy.c
@@ -20,11 +20,11 @@
 
 static const char * const MessageTypeNames[SPY_MAX_MSGNUM + 1] =
 {
-    "WM_NULL",			/* 0x00 */
+    "wm_null",			/* 0x00 */
     "WM_CREATE",	
     "WM_DESTROY",    
     "WM_MOVE",
-    "WM_SIZEWAIT",
+    "wm_sizewait",
     "WM_SIZE",
     "WM_ACTIVATE",
     "WM_SETFOCUS",
@@ -43,7 +43,7 @@
     "WM_ERASEBKGND",
     "WM_SYSCOLORCHANGE",
     "WM_ENDSESSION",
-    "WM_SYSTEMERROR",
+    "wm_systemerror",
     "WM_SHOWWINDOW",
     "WM_CTLCOLOR",
     "WM_WININICHANGE",
@@ -57,11 +57,11 @@
     "WM_CHILDACTIVATE",
     "WM_QUEUESYNC",
     "WM_GETMINMAXINFO",
-    "WM_UNUSED3",
-    "WM_PAINTICON",
+    "wm_unused3",
+    "wm_painticon",
     "WM_ICONERASEBKGND",
     "WM_NEXTDLGCTL",
-    "WM_ALTTABACTIVE",
+    "wm_alttabactive",
     "WM_SPOOLERSTATUS",
     "WM_DRAWITEM",
     "WM_MEASUREITEM",
@@ -72,25 +72,27 @@
     "WM_GETFONT",
     "WM_SETHOTKEY", 
     "WM_GETHOTKEY", 
-    "WM_FILESYSCHANGE", 
-    "WM_ISACTIVEICON",
-    "WM_QUERYPARKICON",
+    "wm_filesyschange", 
+    "wm_isactiveicon",
+    "wm_queryparkicon",
     "WM_QUERYDRAGICON",
-    "WM_QUERYSAVESTATE",
+    "wm_querysavestate",
     "WM_COMPAREITEM", 
-    "WM_TESTING",
+    "wm_testing",
     NULL, 
-    "WM_OTHERWINDOWCREATED", 
-    "WM_OTHERWINDOWDESTROYED", 
-    "WM_ACTIVATESHELLWINDOW",
+    "wm_otherwindowcreated", 
+    "wm_otherwindowdestroyed", 
+    "wm_activateshellwindow",
     NULL,
 
     NULL, 		        /* 0x40 */
-    "WM_COMPACTING", NULL, NULL, 
+    "wm_compacting", NULL, NULL, 
     "WM_COMMNOTIFY", NULL, 
     "WM_WINDOWPOSCHANGING",	/* 0x0046 */
     "WM_WINDOWPOSCHANGED",	/* 0x0047 */
-    "WM_POWER", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_POWER", NULL, 
+    "WM_COPYDATA", 
+    "WM_CANCELJOURNAL", NULL, NULL, NULL, NULL,
 
     NULL, 		        /* 0x0050 */
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
@@ -112,8 +114,8 @@
     "WM_NCPAINT",          	/* 0x0085 */
     "WM_NCACTIVATE",       	/* 0x0086 */
     "WM_GETDLGCODE",		/* 0x0087 */
-    "WM_SYNCPAINT", 
-    "WM_SYNCTASK", NULL, NULL, NULL, NULL, NULL, NULL,
+    "wm_syncpaint", 
+    "wm_synctask", NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x0090 */
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -265,7 +267,7 @@
     "WM_PARENTNOTIFY",		/* 0x0210 */
     "WM_ENTERMENULOOP",         /* 0x0211 */
     "WM_EXITMENULOOP",          /* 0x0212 */
-    "WM_NEXTMENU", 		/* 0x0213 */
+    "wm_nextmenu", 		/* 0x0213 */
                             NULL, NULL, NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
@@ -292,7 +294,7 @@
     "WM_ENTERSIZEMOVE",		/* 0x0231 */
     "WM_EXITSIZEMOVE",		/* 0x0232 */
     "WM_DROPFILES", 		/* 0x0233 */
-    NULL, NULL, NULL, NULL, 
+    "WM_MDIREFRESHMENU", NULL, NULL, NULL, 
     /* 0x0238*/
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
     
@@ -350,8 +352,9 @@
     "WM_QUERYNEWPALETTE",	/* 0x030f*/
 
     "WM_PALETTEISCHANGING",
-    "WM_PALETTECHANGED", 	/* 0x0311 */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
+    "WM_PALETTECHANGED",
+    "WM_HOTKEY", 		/* 0x0312 */
+	  NULL, NULL, NULL, NULL, NULL, NULL, 
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, 
 
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -371,7 +374,13 @@
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     /* 0x0380 */
-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+    "WM_PENWINFIRST", 
+    "WM_RCRESULT", 
+    "WM_HOOKRCRESULT", 
+    "WM_GLOBALRCCHANGE", 
+    "WM_SKB", 
+    "WM_HEDITCTL", 
+					NULL, NULL,
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 
     "WM_COALESCE_FIRST", 
diff --git a/misc/ver.c b/misc/ver.c
index 5a47d12..e785cb5 100644
--- a/misc/ver.c
+++ b/misc/ver.c
@@ -674,10 +674,8 @@
 	db=(struct db*)b;
 	*buflen	= db->datalen;
 	/* let b point to data area */
-	b	= b+4+((strlen(db->name)+4)&3);
-	/* now look up what the resp. SEGPTR would be ... 
-	 * we could use MAKE_SEGPTR , but we don't need to
-	 */
+	b	= b+4+((strlen(db->name)+4)&~3);
+	/* now look up what the resp. SEGPTR would be ... */
 	*buffer	= (b-block)+segblock;
 	fprintf(stderr,"	-> %s=%s\n",subblock,b);
 	return 1;
@@ -703,7 +701,7 @@
 	db=(struct db*)b;
 	*buflen	= db->datalen;
 	/* let b point to data area */
-	b	= b+4+((strlen(db->name)+4)&3);
+	b	= b+4+((strlen(db->name)+4)&~3);
 	*buffer	= b;
 	fprintf(stderr,"	-> %s=%s\n",subblock,b);
 	return 1;
@@ -733,7 +731,7 @@
 	db=(struct db*)b;
 	*buflen	= db->datalen;
 	/* let b point to data area */
-	b	= b+4+((strlen(db->name)+4)&3);
+	b	= b+4+((strlen(db->name)+4)&~3);
 	*buffer	= b;
 	fprintf(stderr,"	-> %s=%s\n",sb,b);
 	free(sb);
diff --git a/miscemu/int21.c b/miscemu/int21.c
index 7594219..8cb3ba5 100644
--- a/miscemu/int21.c
+++ b/miscemu/int21.c
@@ -1127,8 +1127,8 @@
         break;
 
     case 0x39: /* "MKDIR" - CREATE SUBDIRECTORY */
-        if (!CreateDirectory32A( PTR_SEG_OFF_TO_LIN( DS_reg(context),
-                                                     DX_reg(context) ), NULL))
+        if (!CreateDirectory16( PTR_SEG_OFF_TO_LIN( DS_reg(context),
+                                                    DX_reg(context) ), NULL))
         {
             AX_reg(context) = DOS_ExtendedError;
             SET_CFLAG(context);
@@ -1136,8 +1136,8 @@
         break;
 	
     case 0x3a: /* "RMDIR" - REMOVE SUBDIRECTORY */
-        if (!RemoveDirectory32A( PTR_SEG_OFF_TO_LIN( DS_reg(context),
-                                                     DX_reg(context) )))
+        if (!RemoveDirectory16( PTR_SEG_OFF_TO_LIN( DS_reg(context),
+                                                    DX_reg(context) )))
         {
             AX_reg(context) = DOS_ExtendedError;
             SET_CFLAG(context);
@@ -1584,8 +1584,43 @@
         ExtendedOpenCreateFile(context);
         break;
 	
+    case 0x71: /* MS-DOS 7 (Windows95) - LONG FILENAME FUNCTIONS */
+        switch(AL_reg(context))
+        {
+        case 0x39:  /* Create directory */
+            if (!CreateDirectory32A( PTR_SEG_OFF_TO_LIN( DS_reg(context),
+                                                     DX_reg(context) ), NULL))
+            {
+                AX_reg(context) = DOS_ExtendedError;
+                SET_CFLAG(context);
+            }
+            break;
+        case 0x3a:  /* Remove directory */
+            if (!RemoveDirectory32A( PTR_SEG_OFF_TO_LIN( DS_reg(context),
+                                                         DX_reg(context) )))
+            {
+                AX_reg(context) = DOS_ExtendedError;
+                SET_CFLAG(context);
+            }
+            break;
+        case 0x3b:  /* Change directory */
+        case 0x41:  /* Delete file */
+        case 0x43:  /* Get/Set file attributes */
+        case 0x47:  /* Get current directory */
+        case 0x4e:  /* Find first file */
+        case 0x4f:  /* Find next file */
+        case 0x56:  /* Move (rename) file */
+        case 0x6c:  /* Create/Open file */
+        default:
+            fprintf( stderr, "Unimplemented int21 long file name function:\n");
+            INT_BARF( context, 0x21 );
+            SET_CFLAG(context);
+            AL_reg(context) = 0;
+            break;
+        }
+        break;
+
     case 0x70: /* MS-DOS 7 (Windows95) - ??? (country-specific?)*/
-    case 0x71: /* MS-DOS 7 (Chicago) - LONG FILENAME FUNCTIONS */
     case 0x72: /* MS-DOS 7 (Windows95) - ??? */
     case 0x73: /* MS-DOS 7 (Windows95) - DRIVE LOCKING ??? */
         dprintf_int(stddeb,"int21: windows95 function AX %04x\n",
diff --git a/multimedia/audio.c b/multimedia/audio.c
index e342cfa..196356f 100644
--- a/multimedia/audio.c
+++ b/multimedia/audio.c
@@ -22,7 +22,6 @@
 #include "driver.h"
 #include "mmsystem.h"
 #include "ldt.h"
-#include "stackframe.h"
 
 #ifdef linux
 #include <linux/soundcard.h>
diff --git a/multimedia/mcistring.c b/multimedia/mcistring.c
index 721cd1e..514f843 100644
--- a/multimedia/mcistring.c
+++ b/multimedia/mcistring.c
@@ -15,11 +15,11 @@
 #include <fcntl.h>
 #include <sys/ioctl.h>
 #include "windows.h"
+#include "heap.h"
 #include "ldt.h"
 #include "user.h"
 #include "driver.h"
 #include "mmsystem.h"
-#include "stackframe.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "xmalloc.h"
@@ -303,18 +303,19 @@
 MCISTR_Open(_MCISTR_PROTO_) {
 	int		res,i;
 	char		*s;
-	union {
+	union U {
 		MCI_OPEN_PARMS	openParams;
 		MCI_WAVE_OPEN_PARMS	waveopenParams;
 		MCI_ANIM_OPEN_PARMS	animopenParams;
 		MCI_OVLY_OPEN_PARMS	ovlyopenParams;
-	} U;
+	};
+        union U *pU = SEGPTR_NEW(union U);
 
-	U.openParams.lpstrElementName = NULL;
+	pU->openParams.lpstrElementName = NULL;
 	s=strchr(dev,'!');
 	if (s!=NULL) {
 		*s++='\0';
-		_MCI_STRDUP_TO_SEG(U.openParams.lpstrElementName,s);
+		_MCI_STRDUP_TO_SEG(pU->openParams.lpstrElementName,s);
 	}
 	if (!STRCMP(dev,"cdaudio")) {
 		uDevTyp=MCI_DEVTYPE_CD_AUDIO;
@@ -338,26 +339,26 @@
 	}
 	mciDrv[wDevID].wType		= uDevTyp;
 	mciDrv[wDevID].wDeviceID	= wDevID;
-	U.openParams.dwCallback		= 0;
-	U.openParams.wDeviceID		= wDevID;
-	U.ovlyopenParams.dwStyle	= 0; 
-	U.animopenParams.dwStyle	= 0; 
+	pU->openParams.dwCallback		= 0;
+	pU->openParams.wDeviceID		= wDevID;
+	pU->ovlyopenParams.dwStyle	= 0; 
+	pU->animopenParams.dwStyle	= 0; 
 
-	_MCI_STRDUP_TO_SEG(U.openParams.lpstrDeviceType,dev);
-	U.openParams.lpstrAlias		= NULL;
+	_MCI_STRDUP_TO_SEG(pU->openParams.lpstrDeviceType,dev);
+	pU->openParams.lpstrAlias		= NULL;
 	dwFlags |= MCI_OPEN_TYPE;
 	i=0;
 	while (i<nrofkeywords) {
 		FLAG1("shareable",MCI_OPEN_SHAREABLE);
 		if (!strcmp(keywords[i],"alias") && (i+1<nrofkeywords)) {
 			dwFlags |= MCI_OPEN_ALIAS;
-			_MCI_STRDUP_TO_SEG(U.openParams.lpstrAlias,keywords[i]);
+			_MCI_STRDUP_TO_SEG(pU->openParams.lpstrAlias,keywords[i]);
 			i+=2;
 			continue;
 		}
 		if (!strcmp(keywords[i],"element") && (i+1<nrofkeywords)) {
 			dwFlags |= MCI_OPEN_ELEMENT;
-			_MCI_STRDUP_TO_SEG(U.openParams.lpstrElementName,keywords[i]);
+			_MCI_STRDUP_TO_SEG(pU->openParams.lpstrElementName,keywords[i]);
 			i+=2;
 			continue;
 		}
@@ -367,7 +368,7 @@
 			FLAG1("nostatic",MCI_ANIM_OPEN_NOSTATIC);
 			if (!STRCMP(keywords[i],"parent") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_ANIM_OPEN_PARENT;
-				sscanf(keywords[i+1],"%hu",&(U.animopenParams.hWndParent));
+				sscanf(keywords[i+1],"%hu",&(pU->animopenParams.hWndParent));
 				i+=2;
 				continue;
 			}
@@ -376,13 +377,13 @@
 
 				dwFlags |= MCI_ANIM_OPEN_WS;
 				if (!STRCMP(keywords[i+1],"popup")) {
-					U.animopenParams.dwStyle |= WS_POPUP; 
+					pU->animopenParams.dwStyle |= WS_POPUP; 
 				} else if (!STRCMP(keywords[i+1],"overlap")) {
-					U.animopenParams.dwStyle |= WS_OVERLAPPED; 
+					pU->animopenParams.dwStyle |= WS_OVERLAPPED; 
 				} else if (!STRCMP(keywords[i+1],"child")) {
-					U.animopenParams.dwStyle |= WS_CHILD; 
+					pU->animopenParams.dwStyle |= WS_CHILD; 
 				} else if (sscanf(keywords[i+1],"%ld",&st)) {
-					U.animopenParams.dwStyle |= st; 
+					pU->animopenParams.dwStyle |= st; 
 				} else
 					fprintf(stdnimp,__FILE__":MCISTR_Open:unknown 'style' keyword %s, please report.\n",keywords[i+1]);
 				i+=2;
@@ -392,14 +393,14 @@
 		case MCI_DEVTYPE_WAVEFORM_AUDIO:
 			if (!STRCMP(keywords[i],"buffer") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_WAVE_OPEN_BUFFER;
-				sscanf(keywords[i+1],"%ld",&(U.waveopenParams.dwBufferSeconds));
+				sscanf(keywords[i+1],"%ld",&(pU->waveopenParams.dwBufferSeconds));
 			}
 			break;
 		case MCI_DEVTYPE_OVERLAY:
 			/* looks just like anim, but without NOSTATIC */
 			if (!STRCMP(keywords[i],"parent") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_OVLY_OPEN_PARENT;
-				sscanf(keywords[i+1],"%hd",&(U.ovlyopenParams.hWndParent));
+				sscanf(keywords[i+1],"%hd",&(pU->ovlyopenParams.hWndParent));
 				i+=2;
 				continue;
 			}
@@ -408,13 +409,13 @@
 
 				dwFlags |= MCI_OVLY_OPEN_WS;
 				if (!STRCMP(keywords[i+1],"popup")) {
-					U.ovlyopenParams.dwStyle |= WS_POPUP; 
+					pU->ovlyopenParams.dwStyle |= WS_POPUP; 
 				} else if (!STRCMP(keywords[i+1],"overlap")) {
-					U.ovlyopenParams.dwStyle |= WS_OVERLAPPED; 
+					pU->ovlyopenParams.dwStyle |= WS_OVERLAPPED; 
 				} else if (!STRCMP(keywords[i+1],"child")) {
-					U.ovlyopenParams.dwStyle |= WS_CHILD; 
+					pU->ovlyopenParams.dwStyle |= WS_CHILD; 
 				} else if (sscanf(keywords[i+1],"%ld",&st)) {
-					U.ovlyopenParams.dwStyle |= st; 
+					pU->ovlyopenParams.dwStyle |= st; 
 				} else
 					fprintf(stdnimp,__FILE__":MCISTR_Open:unknown 'style' keyword %s, please report.\n",keywords[i+1]);
 				i+=2;
@@ -425,9 +426,10 @@
 		fprintf(stdnimp,__FILE__":MCISTR_Open:unknown parameter passed %s, please report.\n",keywords[i]);
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_OPEN, MAKE_SEGPTR(&U) );
+	_MCI_CALL_DRIVER( MCI_OPEN, SEGPTR_GET(pU) );
 	if (res==0)
-		memcpy(&mciOpenDrv[wDevID],&U.openParams,sizeof(MCI_OPEN_PARMS));
+		memcpy(&mciOpenDrv[wDevID],&pU->openParams,sizeof(MCI_OPEN_PARMS));
+        SEGPTR_FREE(pU);
 	return res;
 }
 
@@ -435,17 +437,19 @@
  * for instance status/play/record/seek etc.
  */
 DWORD
-_MCISTR_determine_timeformat(LPCSTR dev,WORD wDevID,WORD uDevTyp,int *timef) {
-	MCI_STATUS_PARMS	statusParams;
-	DWORD			dwFlags;
-	int			res;
+_MCISTR_determine_timeformat(LPCSTR dev,WORD wDevID,WORD uDevTyp,int *timef)
+{
+    int			res;
+    DWORD dwFlags = MCI_STATUS_ITEM;
+    MCI_STATUS_PARMS *statusParams = SEGPTR_NEW(MCI_STATUS_PARMS);
 
-	dwFlags	= MCI_STATUS_ITEM;
-	statusParams.dwItem	= MCI_STATUS_TIME_FORMAT;
-	statusParams.dwReturn	= 0;
-	_MCI_CALL_DRIVER( MCI_STATUS, MAKE_SEGPTR(&statusParams) );
-	if (res==0) *timef=statusParams.dwReturn;
-	return res;
+    if (!statusParams) return 0;
+    statusParams->dwItem	= MCI_STATUS_TIME_FORMAT;
+    statusParams->dwReturn	= 0;
+    _MCI_CALL_DRIVER( MCI_STATUS, SEGPTR_GET(statusParams) );
+    if (res==0) *timef = statusParams->dwReturn;
+    SEGPTR_FREE(statusParams);
+    return res;
 }
 
 /* query status of MCI drivers
@@ -503,7 +507,7 @@
 
 #define ITEM1(str,item,xtype) \
 	if (!STRCMP(keywords[i],str)) {\
-		statusParams.dwItem = item;\
+		statusParams->dwItem = item;\
 		type = xtype;\
 		i++;\
 		continue;\
@@ -513,7 +517,7 @@
 		(i+1<nrofkeywords) &&\
 		!STRCMP(keywords[i+1],str2)\
 	) {\
-		statusParams.dwItem = item;\
+		statusParams->dwItem = item;\
 		type = xtype;\
 		i+=2;\
 		continue;\
@@ -524,28 +528,28 @@
 		!STRCMP(keywords[i+1],str2) &&\
 		!STRCMP(keywords[i+2],str3)\
 	) {\
-		statusParams.dwItem = item;\
+		statusParams->dwItem = item;\
 		type = xtype;\
 		i+=3;\
 		continue;\
 	}
 static DWORD
 MCISTR_Status(_MCISTR_PROTO_) {
-	MCI_STATUS_PARMS	statusParams;
+	MCI_STATUS_PARMS	*statusParams = SEGPTR_NEW(MCI_STATUS_PARMS);
 	int			type = 0,i,res,timef;
 
-	statusParams.dwCallback = 0;
+	statusParams->dwCallback = 0;
 	dwFlags	|= MCI_STATUS_ITEM;
 	res = _MCISTR_determine_timeformat(dev,wDevID,uDevTyp,&timef);
 	if (res) return res;
 
-	statusParams.dwReturn	= 0;
-	statusParams.dwItem	= 0;
+	statusParams->dwReturn	= 0;
+	statusParams->dwItem	= 0;
 	i = 0;
 
 	while (i<nrofkeywords) {
 		if (!STRCMP(keywords[i],"track") && (i+1<nrofkeywords)) {
-			sscanf(keywords[i+1],"%ld",&(statusParams.dwTrack));
+			sscanf(keywords[i+1],"%ld",&(statusParams->dwTrack));
 			dwFlags |= MCI_TRACK;
 			i+=2;
 			continue;
@@ -610,12 +614,13 @@
 		fprintf(stdnimp,__FILE__":MCISTR_Status:unknown keyword '%s'\n",keywords[i]);
 		i++;
 	}
-	if (!statusParams.dwItem) 
+	if (!statusParams->dwItem) 
 		return MCIERR_MISSING_STRING_ARGUMENT;
 
-	_MCI_CALL_DRIVER( MCI_STATUS, MAKE_SEGPTR(&statusParams) );
+	_MCI_CALL_DRIVER( MCI_STATUS, SEGPTR_GET(statusParams) );
 	if (res==0)
-		_MCISTR_convreturn(type,statusParams.dwReturn,lpstrReturnString,uReturnLength,uDevTyp,timef);
+		_MCISTR_convreturn(type,statusParams->dwReturn,lpstrReturnString,uReturnLength,uDevTyp,timef);
+        SEGPTR_FREE(statusParams);
 	return res;
 }
 #undef ITEM1
@@ -654,14 +659,15 @@
  */
 static DWORD
 MCISTR_Set(_MCISTR_PROTO_) {
-	union	{
+	union U {
 		MCI_SET_PARMS		setParams;
 		MCI_WAVE_SET_PARMS	wavesetParams;
 		MCI_SEQ_SET_PARMS	seqsetParams;
-	} U;
+	};
+        union U *pU = SEGPTR_NEW(union U);
 	int	i,res;
 
-	U.setParams.dwCallback = 0;
+	pU->setParams.dwCallback = 0;
 	i = 0;
 	while (i<nrofkeywords) {
 		FLAG2("door","open",MCI_SET_DOOR_OPEN);
@@ -676,38 +682,38 @@
 			/* FIXME:is this a shortcut for milliseconds or
 			 *	 minutes:seconds? */
 			if (!STRCMP(keywords[i+2],"ms"))
-				U.setParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
+				pU->setParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
 
 			if (!STRCMP(keywords[i+2],"milliseconds"))
-				U.setParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
+				pU->setParams.dwTimeFormat = MCI_FORMAT_MILLISECONDS;
 			if (!STRCMP(keywords[i+2],"msf"))
-				U.setParams.dwTimeFormat = MCI_FORMAT_MSF;
+				pU->setParams.dwTimeFormat = MCI_FORMAT_MSF;
 			if (!STRCMP(keywords[i+2],"hms"))
-				U.setParams.dwTimeFormat = MCI_FORMAT_HMS;
+				pU->setParams.dwTimeFormat = MCI_FORMAT_HMS;
 			if (!STRCMP(keywords[i+2],"frames"))
-				U.setParams.dwTimeFormat = MCI_FORMAT_FRAMES;
+				pU->setParams.dwTimeFormat = MCI_FORMAT_FRAMES;
 			if (!STRCMP(keywords[i+2],"track"))
-				U.setParams.dwTimeFormat = MCI_VD_FORMAT_TRACK;
+				pU->setParams.dwTimeFormat = MCI_VD_FORMAT_TRACK;
 			if (!STRCMP(keywords[i+2],"bytes"))
-				U.setParams.dwTimeFormat = MCI_FORMAT_BYTES;
+				pU->setParams.dwTimeFormat = MCI_FORMAT_BYTES;
 			if (!STRCMP(keywords[i+2],"samples"))
-				U.setParams.dwTimeFormat = MCI_FORMAT_SAMPLES;
+				pU->setParams.dwTimeFormat = MCI_FORMAT_SAMPLES;
 			if (!STRCMP(keywords[i+2],"tmsf"))
-				U.setParams.dwTimeFormat = MCI_FORMAT_TMSF;
+				pU->setParams.dwTimeFormat = MCI_FORMAT_TMSF;
 			if (	!STRCMP(keywords[i+2],"song") && 
 				(i+3<nrofkeywords) &&
 				!STRCMP(keywords[i+3],"pointer")
 			)
-				U.setParams.dwTimeFormat = MCI_SEQ_FORMAT_SONGPTR;
+				pU->setParams.dwTimeFormat = MCI_SEQ_FORMAT_SONGPTR;
 			if (!STRCMP(keywords[i+2],"smpte") && (i+3<nrofkeywords)) {
 				if (!STRCMP(keywords[i+3],"24"))
-					U.setParams.dwTimeFormat = MCI_FORMAT_SMPTE_24;
+					pU->setParams.dwTimeFormat = MCI_FORMAT_SMPTE_24;
 				if (!STRCMP(keywords[i+3],"25"))
-					U.setParams.dwTimeFormat = MCI_FORMAT_SMPTE_25;
+					pU->setParams.dwTimeFormat = MCI_FORMAT_SMPTE_25;
 				if (!STRCMP(keywords[i+3],"30"))
-					U.setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30;
+					pU->setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30;
 				if (!STRCMP(keywords[i+3],"drop") && (i+4<nrofkeywords) && !STRCMP(keywords[i+4],"30")) {
-					U.setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30DROP;
+					pU->setParams.dwTimeFormat = MCI_FORMAT_SMPTE_30DROP;
 					i++;
 				}
 				i++;
@@ -719,11 +725,11 @@
 		if (!STRCMP(keywords[i],"audio") && (i+1<nrofkeywords)) {
 			dwFlags |= MCI_SET_AUDIO;
 			if (!STRCMP(keywords[i+1],"all"))
-				U.setParams.dwAudio = MCI_SET_AUDIO_ALL;
+				pU->setParams.dwAudio = MCI_SET_AUDIO_ALL;
 			if (!STRCMP(keywords[i+1],"left"))
-				U.setParams.dwAudio = MCI_SET_AUDIO_LEFT;
+				pU->setParams.dwAudio = MCI_SET_AUDIO_LEFT;
 			if (!STRCMP(keywords[i+1],"right"))
-				U.setParams.dwAudio = MCI_SET_AUDIO_RIGHT;
+				pU->setParams.dwAudio = MCI_SET_AUDIO_RIGHT;
 			i+=2;
 			continue;
 		}
@@ -740,7 +746,7 @@
 				!STRCMP(keywords[i+1],"pcm")
 			) {
 				dwFlags |= MCI_WAVE_SET_FORMATTAG;
-				U.wavesetParams.wFormatTag = WAVE_FORMAT_PCM;
+				pU->wavesetParams.wFormatTag = WAVE_FORMAT_PCM;
 				i+=2;
 				continue;
 			}
@@ -748,7 +754,7 @@
 			/* <keyword> <integer> */
 #define WII(str,flag,fmt,element) \
 			if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
-				sscanf(keywords[i+1],fmt,&(U.wavesetParams. element ));\
+				sscanf(keywords[i+1],fmt,&(pU->wavesetParams. element ));\
 				dwFlags |= flag;\
 				i+=2;\
 				continue;\
@@ -767,26 +773,26 @@
 			if (!STRCMP(keywords[i],"master") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_SEQ_SET_MASTER;
 				if (!STRCMP(keywords[i+1],"midi"))
-					U.seqsetParams.dwMaster = MCI_SEQ_MIDI;
+					pU->seqsetParams.dwMaster = MCI_SEQ_MIDI;
 				if (!STRCMP(keywords[i+1],"file"))
-					U.seqsetParams.dwMaster = MCI_SEQ_FILE;
+					pU->seqsetParams.dwMaster = MCI_SEQ_FILE;
 				if (!STRCMP(keywords[i+1],"smpte"))
-					U.seqsetParams.dwMaster = MCI_SEQ_SMPTE;
+					pU->seqsetParams.dwMaster = MCI_SEQ_SMPTE;
 				if (!STRCMP(keywords[i+1],"none"))
-					U.seqsetParams.dwMaster = MCI_SEQ_NONE;
+					pU->seqsetParams.dwMaster = MCI_SEQ_NONE;
 				i+=2;
 				continue;
 			}
 			if (!STRCMP(keywords[i],"slave") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_SEQ_SET_SLAVE;
 				if (!STRCMP(keywords[i+1],"midi"))
-					U.seqsetParams.dwMaster = MCI_SEQ_MIDI;
+					pU->seqsetParams.dwMaster = MCI_SEQ_MIDI;
 				if (!STRCMP(keywords[i+1],"file"))
-					U.seqsetParams.dwMaster = MCI_SEQ_FILE;
+					pU->seqsetParams.dwMaster = MCI_SEQ_FILE;
 				if (!STRCMP(keywords[i+1],"smpte"))
-					U.seqsetParams.dwMaster = MCI_SEQ_SMPTE;
+					pU->seqsetParams.dwMaster = MCI_SEQ_SMPTE;
 				if (!STRCMP(keywords[i+1],"none"))
-					U.seqsetParams.dwMaster = MCI_SEQ_NONE;
+					pU->seqsetParams.dwMaster = MCI_SEQ_NONE;
 				i+=2;
 				continue;
 			}
@@ -794,14 +800,14 @@
 				(i+1<nrofkeywords) &&
 				!STRCMP(keywords[i+1],"mapper")
 			) {
-				U.seqsetParams.dwPort=-1;/* FIXME:not sure*/
+				pU->seqsetParams.dwPort=-1;/* FIXME:not sure*/
 				dwFlags |= MCI_SEQ_SET_PORT;
 				i+=2;
 				continue;
 			}
 #define SII(str,flag,element) \
 			if (!STRCMP(keywords[i],str) && (i+1<nrofkeywords)) {\
-				sscanf(keywords[i+1],"%ld",&(U.seqsetParams. element ));\
+				sscanf(keywords[i+1],"%ld",&(pU->seqsetParams. element ));\
 				dwFlags |= flag;\
 				i+=2;\
 				continue;\
@@ -814,7 +820,8 @@
 	}
 	if (!dwFlags)
 		return MCIERR_MISSING_STRING_ARGUMENT;
-	_MCI_CALL_DRIVER( MCI_SET, MAKE_SEGPTR(&U) );
+	_MCI_CALL_DRIVER( MCI_SET, SEGPTR_GET(pU) );
+        SEGPTR_FREE(pU);
 	return res;
 }
 
@@ -828,29 +835,32 @@
  * Returns nothing.
  */
 static DWORD
-MCISTR_Break(_MCISTR_PROTO_) {
-	MCI_BREAK_PARMS	breakParams;
-	int	res,i;
+MCISTR_Break(_MCISTR_PROTO_)
+{
+    MCI_BREAK_PARMS *breakParams = SEGPTR_NEW(MCI_BREAK_PARMS);
+    int res,i;
 
+    if (!breakParams) return 0;
 	/*breakParams.hwndBreak ? */
-	i=0;while (i<nrofkeywords) {
+    for (i = 0; i < nrofkeywords; i++)
+    {
 		FLAG1("off",MCI_BREAK_OFF);
 		if (!strcmp(keywords[i],"on") && (nrofkeywords>i+1)) {
 			dwFlags&=~MCI_BREAK_OFF;
 			dwFlags|=MCI_BREAK_KEY;
-			sscanf(keywords[i+1],"%d",&(breakParams.nVirtKey));
+			sscanf(keywords[i+1],"%d",&(breakParams->nVirtKey));
 			i+=2;
 			continue;
 		}
-		i++;
-	}
-	_MCI_CALL_DRIVER( MCI_BREAK, MAKE_SEGPTR(&breakParams) );
-	return res;
+    }
+    _MCI_CALL_DRIVER( MCI_BREAK, SEGPTR_GET(breakParams) );
+    SEGPTR_FREE(breakParams);
+    return res;
 }
 
 #define ITEM1(str,item,xtype) \
 	if (!STRCMP(keywords[i],str)) {\
-		gdcParams.dwItem = item;\
+		gdcParams->dwItem = item;\
 		type = xtype;\
 		i++;\
 		continue;\
@@ -860,7 +870,7 @@
 		(i+1<nrofkeywords) &&\
 		!STRCMP(keywords[i+1],str2)\
 	) {\
-		gdcParams.dwItem = item;\
+		gdcParams->dwItem = item;\
 		type = xtype;\
 		i+=2;\
 		continue;\
@@ -871,7 +881,7 @@
 		!STRCMP(keywords[i+1],str2) &&\
 		!STRCMP(keywords[i+2],str3)\
 	) {\
-		gdcParams.dwItem = item;\
+		gdcParams->dwItem = item;\
 		type = xtype;\
 		i+=3;\
 		continue;\
@@ -913,15 +923,15 @@
  */
 static DWORD
 MCISTR_Capability(_MCISTR_PROTO_) {
-	MCI_GETDEVCAPS_PARMS	gdcParams;
+	MCI_GETDEVCAPS_PARMS *gdcParams = SEGPTR_NEW(MCI_GETDEVCAPS_PARMS);
 	int	type=0,i,res;
 
-	gdcParams.dwCallback = 0;
+	gdcParams->dwCallback = 0;
 	if (!nrofkeywords)
 		return MCIERR_MISSING_STRING_ARGUMENT;
 	/* well , thats default */
 	dwFlags |= MCI_GETDEVCAPS_ITEM;
-	gdcParams.dwItem = 0;
+	gdcParams->dwItem = 0;
 	i=0;
 	while (i<nrofkeywords) {
 		ITEM2("device","type",MCI_GETDEVCAPS_DEVICE_TYPE,_MCISTR_devtype);
@@ -963,10 +973,12 @@
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_GETDEVCAPS, MAKE_SEGPTR(&gdcParams) );
+	_MCI_CALL_DRIVER( MCI_GETDEVCAPS, SEGPTR_GET(gdcParams) );
 	/* no timeformat needed */
 	if (res==0)
-		_MCISTR_convreturn(type,gdcParams.dwReturn,lpstrReturnString,uReturnLength,uDevTyp,0);
+            _MCISTR_convreturn( type, gdcParams->dwReturn, lpstrReturnString,
+                                uReturnLength, uDevTyp, 0 );
+        SEGPTR_FREE(gdcParams);
 	return res;
 }
 #undef ITEM1
@@ -974,33 +986,35 @@
 #undef ITEM3
 /* resumes operation of device. no arguments, no return values */
 static DWORD
-MCISTR_Resume(_MCISTR_PROTO_) {
-	MCI_GENERIC_PARMS	genParams;
-	int	res;
-
-	genParams.dwCallback=0;
-	_MCI_CALL_DRIVER( MCI_RESUME, MAKE_SEGPTR(&genParams) );
-	return res;
+MCISTR_Resume(_MCISTR_PROTO_)
+{
+    MCI_GENERIC_PARMS *genParams = SEGPTR_NEW(MCI_GENERIC_PARMS);
+    int	res;
+    genParams->dwCallback = 0;
+    _MCI_CALL_DRIVER( MCI_RESUME, SEGPTR_GET(genParams) );
+    return res;
 }
 
 /* pauses operation of device. no arguments, no return values */
 static DWORD
-MCISTR_Pause(_MCISTR_PROTO_) {
-	MCI_GENERIC_PARMS	genParams;
-	int			res;
-	genParams.dwCallback=0;
-	_MCI_CALL_DRIVER( MCI_PAUSE, MAKE_SEGPTR(&genParams) );
-	return res;
+MCISTR_Pause(_MCISTR_PROTO_)
+{
+    MCI_GENERIC_PARMS *genParams = SEGPTR_NEW(MCI_GENERIC_PARMS);
+    int res;
+    genParams->dwCallback = 0;
+    _MCI_CALL_DRIVER( MCI_PAUSE, SEGPTR_GET(genParams) );
+    return res;
 }
 
 /* stops operation of device. no arguments, no return values */
 static DWORD
-MCISTR_Stop(_MCISTR_PROTO_) {
-	MCI_GENERIC_PARMS	genParams;
-	int			res;
-	genParams.dwCallback=0;
-	_MCI_CALL_DRIVER( MCI_STOP, MAKE_SEGPTR(&genParams) );
-	return res;
+MCISTR_Stop(_MCISTR_PROTO_)
+{
+    MCI_GENERIC_PARMS *genParams = SEGPTR_NEW(MCI_GENERIC_PARMS);
+    int res;
+    genParams->dwCallback = 0;
+    _MCI_CALL_DRIVER( MCI_STOP, SEGPTR_GET(genParams) );
+    return res;
 }
 
 /* starts recording.
@@ -1014,7 +1028,7 @@
 MCISTR_Record(_MCISTR_PROTO_) {
 	int			i,res,timef,nrargs,j,k,a[4];
 	char			*parsestr;
-	MCI_RECORD_PARMS	recordParams;
+	MCI_RECORD_PARMS	*recordParams = SEGPTR_NEW(MCI_RECORD_PARMS);
 
 	res = _MCISTR_determine_timeformat(dev,wDevID,uDevTyp,&timef);
 	if (res) return res;
@@ -1041,7 +1055,7 @@
 		nrargs=1;
 		break;
 	}
-	recordParams.dwCallback = 0;
+	recordParams->dwCallback = 0;
 	i = 0;
 	while (i<nrofkeywords) {
 		if (!strcmp(keywords[i],"to") && (i+1<nrofkeywords)) {
@@ -1052,9 +1066,9 @@
 			 * shift them. (Well I should use the macros in 
 			 * mmsystem.h, right).
 			 */
-			recordParams.dwTo=0;
+			recordParams->dwTo=0;
 			for (k=0;k<j;k++)
-				recordParams.dwTo+=a[k]<<(8*(nrargs-k));
+				recordParams->dwTo+=a[k]<<(8*(nrargs-k));
 			i+=2;
 			continue;
 		}
@@ -1063,9 +1077,9 @@
 			a[0]=a[1]=a[2]=a[3]=0;
 			j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
 			/* dito. */
-			recordParams.dwFrom=0;
+			recordParams->dwFrom=0;
 			for (k=0;k<j;k++)
-				recordParams.dwFrom+=a[k]<<(8*(nrargs-k));
+				recordParams->dwFrom+=a[k]<<(8*(nrargs-k));
 			i+=2;
 			continue;
 		}
@@ -1073,7 +1087,8 @@
 		FLAG1("overwrite",MCI_RECORD_OVERWRITE);
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_RECORD, MAKE_SEGPTR(&recordParams) );
+	_MCI_CALL_DRIVER( MCI_RECORD, SEGPTR_GET(recordParams) );
+        SEGPTR_FREE(recordParams);
 	return res;
 }
 
@@ -1098,11 +1113,12 @@
 MCISTR_Play(_MCISTR_PROTO_) {
 	int			i,res,timef,nrargs,j,k,a[4];
 	char			*parsestr;
-	union {
+	union U {
 		MCI_PLAY_PARMS		playParams;
 		MCI_VD_PLAY_PARMS	vdplayParams;
 		MCI_ANIM_PLAY_PARMS	animplayParams;
-	} U;
+	};
+        union U *pU = SEGPTR_NEW(union U);
 
 	res = _MCISTR_determine_timeformat(dev,wDevID,uDevTyp,&timef);
 	if (res) return res;
@@ -1128,7 +1144,7 @@
 		nrargs=1;
 		break;
 	}
-	U.playParams.dwCallback=0;
+	pU->playParams.dwCallback=0;
 	i=0;
 	while (i<nrofkeywords) {
 		if (!strcmp(keywords[i],"to") && (i+1<nrofkeywords)) {
@@ -1139,9 +1155,9 @@
 			 * shift them. (Well I should use the macros in 
 			 * mmsystem.h, right).
 			 */
-			U.playParams.dwTo=0;
+			pU->playParams.dwTo=0;
 			for (k=0;k<j;k++)
-				U.playParams.dwTo+=a[k]<<(8*(nrargs-k));
+				pU->playParams.dwTo+=a[k]<<(8*(nrargs-k));
 			i+=2;
 			continue;
 		}
@@ -1150,9 +1166,9 @@
 			a[0]=a[1]=a[2]=a[3]=0;
 			j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
 			/* dito. */
-			U.playParams.dwFrom=0;
+			pU->playParams.dwFrom=0;
 			for (k=0;k<j;k++)
-				U.playParams.dwFrom+=a[k]<<(8*(nrargs-k));
+				pU->playParams.dwFrom+=a[k]<<(8*(nrargs-k));
 			i+=2;
 			continue;
 		}
@@ -1164,7 +1180,7 @@
 			FLAG1("reverse",MCI_VD_PLAY_REVERSE);
 			if (!STRCMP(keywords[i],"speed") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_VD_PLAY_SPEED;
-				sscanf(keywords[i+1],"%ld",&(U.vdplayParams.dwSpeed));
+				sscanf(keywords[i+1],"%ld",&(pU->vdplayParams.dwSpeed));
 				i+=2;
 				continue;
 			}
@@ -1176,7 +1192,7 @@
 			FLAG1("reverse",MCI_ANIM_PLAY_REVERSE);
 			if (!STRCMP(keywords[i],"speed") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_ANIM_PLAY_SPEED;
-				sscanf(keywords[i+1],"%ld",&(U.animplayParams.dwSpeed));
+				sscanf(keywords[i+1],"%ld",&(pU->animplayParams.dwSpeed));
 				i+=2;
 				continue;
 			}
@@ -1184,7 +1200,8 @@
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_PLAY, MAKE_SEGPTR(&U) );
+	_MCI_CALL_DRIVER( MCI_PLAY, SEGPTR_GET(pU) );
+        SEGPTR_FREE(pU);
 	return res;
 }
 
@@ -1198,7 +1215,7 @@
 MCISTR_Seek(_MCISTR_PROTO_) {
 	int		i,res,timef,nrargs,j,k,a[4];
 	char		*parsestr;
-	MCI_SEEK_PARMS	seekParams;
+	MCI_SEEK_PARMS	*seekParams = SEGPTR_NEW(MCI_SEEK_PARMS);
 
 	res = _MCISTR_determine_timeformat(dev,wDevID,uDevTyp,&timef);
 	if (res) return res;
@@ -1224,19 +1241,19 @@
 		nrargs=1;
 		break;
 	}
-	seekParams.dwCallback=0;
+	seekParams->dwCallback=0;
 	i=0;
 	while (i<nrofkeywords) {
 		if (	!STRCMP(keywords[i],"to") && (i+1<nrofkeywords)) {
 			if (!STRCMP(keywords[i+1],"start")) {
 				dwFlags|=MCI_SEEK_TO_START;
-				seekParams.dwTo=0;
+				seekParams->dwTo=0;
 				i+=2;
 				continue;
 			}
 			if (!STRCMP(keywords[i+1],"end")) {
 				dwFlags|=MCI_SEEK_TO_END;
-				seekParams.dwTo=0;
+				seekParams->dwTo=0;
 				i+=2;
 				continue;
 			}
@@ -1244,9 +1261,9 @@
 			i+=2;
 			a[0]=a[1]=a[2]=a[3]=0;
 			j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
-			seekParams.dwTo=0;
+			seekParams->dwTo=0;
 			for (k=0;k<j;k++)
-				seekParams.dwTo+=a[k]<<(8*(nrargs-k));
+				seekParams->dwTo+=a[k]<<(8*(nrargs-k));
 			continue;
 		}
 		switch (uDevTyp) {
@@ -1256,18 +1273,20 @@
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_SEEK, MAKE_SEGPTR(&seekParams) );
+	_MCI_CALL_DRIVER( MCI_SEEK, SEGPTR_GET(seekParams) );
+        SEGPTR_FREE(seekParams);
 	return res;
 }
 
 /* close media/driver */
 static DWORD
-MCISTR_Close(_MCISTR_PROTO_) {
-	MCI_GENERIC_PARMS	closeParams;
-	int			res;
-
-	_MCI_CALL_DRIVER( MCI_CLOSE, MAKE_SEGPTR(&closeParams) );
-	return res;
+MCISTR_Close(_MCISTR_PROTO_)
+{
+    MCI_GENERIC_PARMS *closeParams = SEGPTR_NEW(MCI_GENERIC_PARMS);
+    int res;
+    _MCI_CALL_DRIVER( MCI_CLOSE, SEGPTR_GET(closeParams) );
+    SEGPTR_FREE(closeParams);
+    return res;
 }
 
 /* return information.
@@ -1280,8 +1299,9 @@
  *	"text"		returns text?
  */
 static DWORD
-MCISTR_Info(_MCISTR_PROTO_) {
-	MCI_INFO_PARMS	infoParams;
+MCISTR_Info(_MCISTR_PROTO_)
+{
+	MCI_INFO_PARMS	*infoParams = SEGPTR_NEW(MCI_INFO_PARMS);
 	DWORD		sflags;
 	int		i,res;
 
@@ -1304,9 +1324,10 @@
 	/* MCI driver will fill in lpstrReturn, dwRetSize.
 	 * FIXME: I don't know if this is correct behaviour
 	 */
-	_MCI_CALL_DRIVER( MCI_INFO, MAKE_SEGPTR(&infoParams) );
+	_MCI_CALL_DRIVER( MCI_INFO, SEGPTR_GET(infoParams) );
 	if (res==0)
-		_MCI_STR(infoParams.lpstrReturn);
+		_MCI_STR(infoParams->lpstrReturn);
+        SEGPTR_FREE(infoParams);
 	return res;
 }
 
@@ -1360,13 +1381,13 @@
  */
 static DWORD
 MCISTR_Load(_MCISTR_PROTO_) {
-	union {
+	union U {
 		MCI_LOAD_PARMS	loadParams;
 		MCI_OVLY_LOAD_PARMS	ovlyloadParams;
-	} U;
+	};
+        union U *pU = SEGPTR_NEW(union U);
 	int		i,len,res;
 	char		*s;
-	HANDLE		x;
 
 	i=0;len=0;
 	while (i<nrofkeywords) {
@@ -1374,10 +1395,10 @@
 		case MCI_DEVTYPE_OVERLAY:
 			if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
 				dwFlags |= MCI_OVLY_RECT;
-				sscanf(keywords[i+1],"%hd",&(U.ovlyloadParams.rc.left));
-				sscanf(keywords[i+2],"%hd",&(U.ovlyloadParams.rc.top));
-				sscanf(keywords[i+3],"%hd",&(U.ovlyloadParams.rc.right));
-				sscanf(keywords[i+4],"%hd",&(U.ovlyloadParams.rc.bottom));
+				sscanf(keywords[i+1],"%hd",&(pU->ovlyloadParams.rc.left));
+				sscanf(keywords[i+2],"%hd",&(pU->ovlyloadParams.rc.top));
+				sscanf(keywords[i+3],"%hd",&(pU->ovlyloadParams.rc.right));
+				sscanf(keywords[i+4],"%hd",&(pU->ovlyloadParams.rc.bottom));
 				memcpy(keywords+i,keywords+(i+5),nrofkeywords-(i+5));
 				continue;
 			}
@@ -1386,23 +1407,18 @@
 		len+=strlen(keywords[i])+1;
 		i++;
 	}
-	s=(char*)xmalloc(len);
+	s=(char*)SEGPTR_ALLOC(len);
 	*s='\0';
 	while (i<nrofkeywords) {
 		strcat(s,keywords[i]);
 		i++;
 		if (i<nrofkeywords) strcat(s," ");
 	}
-	/* FIXME: messy, but I strongly suspect we have to use a 
-	 * segmented pointer, so I am doing that
-	 */
-	x=USER_HEAP_ALLOC(len);
-	U.loadParams.lpfilename=(LPSTR)MAKELONG(x,USER_HeapSel);
-	strcpy(PTR_SEG_TO_LIN(U.loadParams.lpfilename),s);
-	free(s);
+	pU->loadParams.lpfilename=(LPSTR)SEGPTR_GET(s);
 	dwFlags |= MCI_LOAD_FILE;
-	_MCI_CALL_DRIVER( MCI_LOAD, MAKE_SEGPTR(&U) );
-	USER_HEAP_FREE(x);
+	_MCI_CALL_DRIVER( MCI_LOAD, SEGPTR_GET(pU) );
+	SEGPTR_FREE(s);
+        SEGPTR_FREE(pU);
 	return res;
 }
 
@@ -1412,13 +1428,13 @@
  */
 static DWORD
 MCISTR_Save(_MCISTR_PROTO_) {
-	union {
+	union U {
 		MCI_SAVE_PARMS	saveParams;
 		MCI_OVLY_SAVE_PARMS	ovlysaveParams;
-	} U;
+	};
+        union U *pU = SEGPTR_NEW(union U);
 	int		i,len,res;
 	char		*s;
-	HANDLE		x;
 
 	i=0;len=0;
 	while (i<nrofkeywords) {
@@ -1426,10 +1442,10 @@
 		case MCI_DEVTYPE_OVERLAY:
 			if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
 				dwFlags |= MCI_OVLY_RECT;
-				sscanf(keywords[i+1],"%hd",&(U.ovlysaveParams.rc.left));
-				sscanf(keywords[i+2],"%hd",&(U.ovlysaveParams.rc.top));
-				sscanf(keywords[i+3],"%hd",&(U.ovlysaveParams.rc.right));
-				sscanf(keywords[i+4],"%hd",&(U.ovlysaveParams.rc.bottom));
+				sscanf(keywords[i+1],"%hd",&(pU->ovlysaveParams.rc.left));
+				sscanf(keywords[i+2],"%hd",&(pU->ovlysaveParams.rc.top));
+				sscanf(keywords[i+3],"%hd",&(pU->ovlysaveParams.rc.right));
+				sscanf(keywords[i+4],"%hd",&(pU->ovlysaveParams.rc.bottom));
 				memcpy(keywords+i,keywords+(i+5),nrofkeywords-(i+5));
 				continue;
 			}
@@ -1438,23 +1454,18 @@
 		len+=strlen(keywords[i])+1;
 		i++;
 	}
-	s=(char*)xmalloc(len);
+	s=(char*)SEGPTR_ALLOC(len);
 	*s='\0';
 	while (i<nrofkeywords) {
 		strcat(s,keywords[i]);
 		i++;
 		if (i<nrofkeywords) strcat(s," ");
 	}
-	/* FIXME: messy, but I strongly suspect we have to use a 
-	 * segmented pointer, so I am doing that
-	 */
-	x=USER_HEAP_ALLOC(len);
-	U.saveParams.lpfilename=(LPSTR)MAKELONG(x,USER_HeapSel);
-	strcpy(PTR_SEG_TO_LIN(U.saveParams.lpfilename),s);
-	free(s);
+	pU->saveParams.lpfilename=(LPSTR)SEGPTR_GET(s);
 	dwFlags |= MCI_LOAD_FILE;
-	_MCI_CALL_DRIVER( MCI_SAVE, MAKE_SEGPTR(&U) );
-	USER_HEAP_FREE(x);
+	_MCI_CALL_DRIVER( MCI_SAVE, SEGPTR_GET(pU) );
+	SEGPTR_FREE(s);
+        SEGPTR_FREE(pU);
 	return res;
 }
 
@@ -1463,7 +1474,7 @@
  */
 static DWORD
 MCISTR_Cue(_MCISTR_PROTO_) {
-	MCI_GENERIC_PARMS	cueParams;
+	MCI_GENERIC_PARMS	*cueParams = SEGPTR_NEW(MCI_GENERIC_PARMS);
 	int			i,res;
 
 	i=0;
@@ -1476,7 +1487,8 @@
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_CUE, MAKE_SEGPTR(&cueParams) );
+	_MCI_CALL_DRIVER( MCI_CUE, SEGPTR_GET(cueParams) );
+        SEGPTR_FREE(cueParams);
 	return res;
 }
 
@@ -1485,7 +1497,7 @@
 MCISTR_Delete(_MCISTR_PROTO_) {
 	int	timef,nrargs,i,j,k,a[4],res;
 	char	*parsestr;
-	MCI_WAVE_DELETE_PARMS	deleteParams;
+	MCI_WAVE_DELETE_PARMS *deleteParams = SEGPTR_NEW(MCI_WAVE_DELETE_PARMS);
 
 	/* only implemented for waveform audio */
 	if (uDevTyp != MCI_DEVTYPE_WAVEFORM_AUDIO)
@@ -1524,9 +1536,9 @@
 			 * shift them. (Well I should use the macros in 
 			 * mmsystem.h, right).
 			 */
-			deleteParams.dwTo=0;
+			deleteParams->dwTo=0;
 			for (k=0;k<j;k++)
-				deleteParams.dwTo+=a[k]<<(8*(nrargs-k));
+				deleteParams->dwTo+=a[k]<<(8*(nrargs-k));
 			i+=2;
 			continue;
 		}
@@ -1535,25 +1547,26 @@
 			a[0]=a[1]=a[2]=a[3]=0;
 			j=sscanf(keywords[i+1],parsestr,&a[0],&a[1],&a[2],&a[3]);
 			/* dito. */
-			deleteParams.dwFrom=0;
+			deleteParams->dwFrom=0;
 			for (k=0;k<j;k++)
-				deleteParams.dwFrom+=a[k]<<(8*(nrargs-k));
+				deleteParams->dwFrom+=a[k]<<(8*(nrargs-k));
 			i+=2;
 			continue;
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_DELETE, MAKE_SEGPTR(&deleteParams) );
+	_MCI_CALL_DRIVER( MCI_DELETE, SEGPTR_GET(deleteParams) );
+        SEGPTR_FREE(deleteParams);
 	return res;
 }
 
 /* send command to device. only applies to videodisc */
 static DWORD
-MCISTR_Escape(_MCISTR_PROTO_) {
-	MCI_VD_ESCAPE_PARMS	escapeParams;
+MCISTR_Escape(_MCISTR_PROTO_)
+{
+	MCI_VD_ESCAPE_PARMS *escapeParams = SEGPTR_NEW(MCI_VD_ESCAPE_PARMS);
 	int			i,len,res;
 	char		*s;
-	HANDLE		x;
 
 	if (uDevTyp != MCI_DEVTYPE_VIDEODISC)
 		return MCIERR_UNSUPPORTED_FUNCTION;
@@ -1562,23 +1575,18 @@
 		len+=strlen(keywords[i])+1;
 		i++;
 	}
-	s=(char*)xmalloc(len);
+	s=(char*)SEGPTR_ALLOC(len);
 	*s='\0';
 	while (i<nrofkeywords) {
 		strcat(s,keywords[i]);
 		i++;
 		if (i<nrofkeywords) strcat(s," ");
 	}
-	/* FIXME: messy, but I strongly suspect we have to use a 
-	 * segmented pointer, so I am doing that
-	 */
-	x=USER_HEAP_ALLOC(len);
-	escapeParams.lpstrCommand=(LPSTR)MAKELONG(x,USER_HeapSel);
-	strcpy(PTR_SEG_TO_LIN(escapeParams.lpstrCommand),s);
-	free(s);
+	escapeParams->lpstrCommand = (LPSTR)SEGPTR_GET(s);
 	dwFlags |= MCI_VD_ESCAPE_STRING;
-	_MCI_CALL_DRIVER( MCI_ESCAPE, MAKE_SEGPTR(&escapeParams) );
-	USER_HEAP_FREE(x);
+	_MCI_CALL_DRIVER( MCI_ESCAPE, SEGPTR_GET(escapeParams) );
+        SEGPTR_FREE(s);
+        SEGPTR_FREE(escapeParams);
 	return res;
 }
 
@@ -1586,50 +1594,54 @@
  * only applyable to Overlay devices
  */
 static DWORD
-MCISTR_Unfreeze(_MCISTR_PROTO_) {
-	MCI_OVLY_RECT_PARMS	unfreezeParams;
+MCISTR_Unfreeze(_MCISTR_PROTO_)
+{
+	MCI_OVLY_RECT_PARMS *unfreezeParams = SEGPTR_NEW(MCI_OVLY_RECT_PARMS);
 	int			i,res;
 
 	if (uDevTyp != MCI_DEVTYPE_OVERLAY)
 		return MCIERR_UNSUPPORTED_FUNCTION;
 	i=0;while (i<nrofkeywords) {
 		if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
-			sscanf(keywords[i+1],"%hd",&(unfreezeParams.rc.left));
-			sscanf(keywords[i+2],"%hd",&(unfreezeParams.rc.top));
-			sscanf(keywords[i+3],"%hd",&(unfreezeParams.rc.right));
-			sscanf(keywords[i+4],"%hd",&(unfreezeParams.rc.bottom));
+			sscanf(keywords[i+1],"%hd",&(unfreezeParams->rc.left));
+			sscanf(keywords[i+2],"%hd",&(unfreezeParams->rc.top));
+			sscanf(keywords[i+3],"%hd",&(unfreezeParams->rc.right));
+			sscanf(keywords[i+4],"%hd",&(unfreezeParams->rc.bottom));
 			dwFlags |= MCI_OVLY_RECT;
 			i+=5;
 			continue;
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_UNFREEZE, MAKE_SEGPTR(&unfreezeParams) );
+	_MCI_CALL_DRIVER( MCI_UNFREEZE, SEGPTR_GET(unfreezeParams) );
+        SEGPTR_FREE(unfreezeParams);
 	return res;
 }
 /* freeze [part of] the overlayed video 
  * only applyable to Overlay devices
  */
 static DWORD
-MCISTR_Freeze(_MCISTR_PROTO_) {
-	MCI_OVLY_RECT_PARMS	freezeParams;
+MCISTR_Freeze(_MCISTR_PROTO_)
+{
+	MCI_OVLY_RECT_PARMS *freezeParams = SEGPTR_NEW(MCI_OVLY_RECT_PARMS);
 	int			i,res;
 
 	if (uDevTyp != MCI_DEVTYPE_OVERLAY)
 		return MCIERR_UNSUPPORTED_FUNCTION;
 	i=0;while (i<nrofkeywords) {
 		if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
-			sscanf(keywords[i+1],"%hd",&(freezeParams.rc.left));
-			sscanf(keywords[i+2],"%hd",&(freezeParams.rc.top));
-			sscanf(keywords[i+3],"%hd",&(freezeParams.rc.right));
-			sscanf(keywords[i+4],"%hd",&(freezeParams.rc.bottom));
+			sscanf(keywords[i+1],"%hd",&(freezeParams->rc.left));
+			sscanf(keywords[i+2],"%hd",&(freezeParams->rc.top));
+			sscanf(keywords[i+3],"%hd",&(freezeParams->rc.right));
+			sscanf(keywords[i+4],"%hd",&(freezeParams->rc.bottom));
 			dwFlags |= MCI_OVLY_RECT;
 			i+=5;
 			continue;
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_FREEZE, MAKE_SEGPTR(&freezeParams) );
+	_MCI_CALL_DRIVER( MCI_FREEZE, SEGPTR_GET(freezeParams) );
+        SEGPTR_FREE(freezeParams);
 	return res;
 }
 
@@ -1649,10 +1661,11 @@
  */
 static DWORD
 MCISTR_Put(_MCISTR_PROTO_) {
-	union {
+	union U {
 		MCI_OVLY_RECT_PARMS	ovlyputParams;
 		MCI_ANIM_RECT_PARMS	animputParams;
-	} U;
+	};
+        union U *pU = SEGPTR_NEW(union U);
 	int	i,res;
 	i=0;while (i<nrofkeywords) {
 		switch (uDevTyp) {
@@ -1660,10 +1673,10 @@
 			FLAG1("source",MCI_ANIM_PUT_SOURCE);
 			FLAG1("destination",MCI_ANIM_PUT_DESTINATION);
 			if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
-				sscanf(keywords[i+1],"%hd",&(U.animputParams.rc.left));
-				sscanf(keywords[i+2],"%hd",&(U.animputParams.rc.top));
-				sscanf(keywords[i+3],"%hd",&(U.animputParams.rc.right));
-				sscanf(keywords[i+4],"%hd",&(U.animputParams.rc.bottom));
+				sscanf(keywords[i+1],"%hd",&(pU->animputParams.rc.left));
+				sscanf(keywords[i+2],"%hd",&(pU->animputParams.rc.top));
+				sscanf(keywords[i+3],"%hd",&(pU->animputParams.rc.right));
+				sscanf(keywords[i+4],"%hd",&(pU->animputParams.rc.bottom));
 				dwFlags |= MCI_ANIM_RECT;
 				i+=5;
 				continue;
@@ -1675,10 +1688,10 @@
 			FLAG1("video",MCI_OVLY_PUT_VIDEO);
 			FLAG1("frame",MCI_OVLY_PUT_FRAME);
 			if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
-				sscanf(keywords[i+1],"%hd",&(U.ovlyputParams.rc.left));
-				sscanf(keywords[i+2],"%hd",&(U.ovlyputParams.rc.top));
-				sscanf(keywords[i+3],"%hd",&(U.ovlyputParams.rc.right));
-				sscanf(keywords[i+4],"%hd",&(U.ovlyputParams.rc.bottom));
+				sscanf(keywords[i+1],"%hd",&(pU->ovlyputParams.rc.left));
+				sscanf(keywords[i+2],"%hd",&(pU->ovlyputParams.rc.top));
+				sscanf(keywords[i+3],"%hd",&(pU->ovlyputParams.rc.right));
+				sscanf(keywords[i+4],"%hd",&(pU->ovlyputParams.rc.bottom));
 				dwFlags |= MCI_OVLY_RECT;
 				i+=5;
 				continue;
@@ -1687,7 +1700,8 @@
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_PUT, MAKE_SEGPTR(&U) );
+	_MCI_CALL_DRIVER( MCI_PUT, SEGPTR_GET(pU) );
+        SEGPTR_FREE(pU);
 	return res;
 }
 
@@ -1697,8 +1711,9 @@
  * 	"background"	realize the palette as background palette
  */
 static DWORD
-MCISTR_Realize(_MCISTR_PROTO_) {
-	MCI_GENERIC_PARMS	realizeParams;
+MCISTR_Realize(_MCISTR_PROTO_)
+{
+	MCI_GENERIC_PARMS	*realizeParams = SEGPTR_NEW(MCI_GENERIC_PARMS);
 	int			i,res;
 
 	if (uDevTyp != MCI_DEVTYPE_ANIMATION)
@@ -1709,7 +1724,8 @@
 		FLAG1("normal",MCI_ANIM_REALIZE_NORM);
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_REALIZE, MAKE_SEGPTR(&realizeParams) );
+	_MCI_CALL_DRIVER( MCI_REALIZE, SEGPTR_GET(realizeParams) );
+        SEGPTR_FREE(realizeParams);
 	return res;
 }
 
@@ -1718,8 +1734,9 @@
  *	"down"
  */
 static DWORD
-MCISTR_Spin(_MCISTR_PROTO_) {
-	MCI_GENERIC_PARMS	spinParams;
+MCISTR_Spin(_MCISTR_PROTO_)
+{
+	MCI_GENERIC_PARMS	*spinParams = SEGPTR_NEW(MCI_GENERIC_PARMS);
 	int			i,res;
 
 	if (uDevTyp != MCI_DEVTYPE_VIDEODISC)
@@ -1730,7 +1747,8 @@
 		FLAG1("down",MCI_VD_SPIN_UP);
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_SPIN, MAKE_SEGPTR(&spinParams) );
+	_MCI_CALL_DRIVER( MCI_SPIN, SEGPTR_GET(spinParams) );
+        SEGPTR_FREE(spinParams);
 	return res;
 }
 
@@ -1740,10 +1758,11 @@
  */
 static DWORD
 MCISTR_Step(_MCISTR_PROTO_) {
-	union	{
+	union U {
 		MCI_ANIM_STEP_PARMS	animstepParams;
 		MCI_VD_STEP_PARMS	vdstepParams;
-	} U;
+	};
+        union U *pU = SEGPTR_NEW(union U);
 	int	i,res;
 
 	i=0;
@@ -1752,7 +1771,7 @@
 		case MCI_DEVTYPE_ANIMATION:
 			FLAG1("reverse",MCI_ANIM_STEP_REVERSE);
 			if (!STRCMP(keywords[i],"by") && (i+1<nrofkeywords)) {
-				sscanf(keywords[i+1],"%ld",&(U.animstepParams.dwFrames));
+				sscanf(keywords[i+1],"%ld",&(pU->animstepParams.dwFrames));
 				dwFlags |= MCI_ANIM_STEP_FRAMES;
 				i+=2;
 				continue;
@@ -1761,7 +1780,7 @@
 		case MCI_DEVTYPE_VIDEODISC:
 			FLAG1("reverse",MCI_VD_STEP_REVERSE);
 			if (!STRCMP(keywords[i],"by") && (i+1<nrofkeywords)) {
-				sscanf(keywords[i+1],"%ld",&(U.vdstepParams.dwFrames));
+				sscanf(keywords[i+1],"%ld",&(pU->vdstepParams.dwFrames));
 				dwFlags |= MCI_VD_STEP_FRAMES;
 				i+=2;
 				continue;
@@ -1770,7 +1789,8 @@
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_STEP, MAKE_SEGPTR(&U) );
+	_MCI_CALL_DRIVER( MCI_STEP, SEGPTR_GET(pU) );
+        SEGPTR_FREE(pU);
 	return res;
 }
 
@@ -1782,28 +1802,29 @@
 static DWORD
 MCISTR_Update(_MCISTR_PROTO_) {
 	int		i,res;
-	MCI_ANIM_UPDATE_PARMS	updateParams;
+	MCI_ANIM_UPDATE_PARMS *updateParams = SEGPTR_NEW(MCI_ANIM_UPDATE_PARMS);
 
 	i=0;
 	while (i<nrofkeywords) {
 		if (!STRCMP(keywords[i],"at") && (i+4<nrofkeywords)) {
-			sscanf(keywords[i+1],"%hd",&(updateParams.rc.left));
-			sscanf(keywords[i+2],"%hd",&(updateParams.rc.top));
-			sscanf(keywords[i+3],"%hd",&(updateParams.rc.right));
-			sscanf(keywords[i+4],"%hd",&(updateParams.rc.bottom));
+			sscanf(keywords[i+1],"%hd",&(updateParams->rc.left));
+			sscanf(keywords[i+2],"%hd",&(updateParams->rc.top));
+			sscanf(keywords[i+3],"%hd",&(updateParams->rc.right));
+			sscanf(keywords[i+4],"%hd",&(updateParams->rc.bottom));
 			dwFlags |= MCI_ANIM_RECT;
 			i+=5;
 			continue;
 		}
 		if (!STRCMP(keywords[i],"hdc") && (i+1<nrofkeywords)) {
 			dwFlags |= MCI_ANIM_UPDATE_HDC;
-			sscanf(keywords[i+1],"%hd",&(updateParams.hDC));
+			sscanf(keywords[i+1],"%hd",&(updateParams->hDC));
 			i+=2;
 			continue;
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_UPDATE, MAKE_SEGPTR(&updateParams) );
+	_MCI_CALL_DRIVER( MCI_UPDATE, SEGPTR_GET(updateParams) );
+        SEGPTR_FREE(updateParams);
 	return res;
 }
 
@@ -1818,10 +1839,11 @@
  */
 static DWORD
 MCISTR_Where(_MCISTR_PROTO_) {
-	union {
+	union U {
 		MCI_ANIM_RECT_PARMS	animwhereParams;
 		MCI_OVLY_RECT_PARMS	ovlywhereParams;
-	} U;
+	};
+        union U *pU = SEGPTR_NEW(union U);
 	int	i,res;
 
 	i=0;
@@ -1840,30 +1862,31 @@
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_WHERE, MAKE_SEGPTR(&U) );
+	_MCI_CALL_DRIVER( MCI_WHERE, SEGPTR_GET(pU) );
 	if (res==0) {
 		char	buf[100];
 		switch (uDevTyp) {
 		case MCI_DEVTYPE_ANIMATION:
 			sprintf(buf,"%d %d %d %d",
-				U.animwhereParams.rc.left,
-				U.animwhereParams.rc.top,
-				U.animwhereParams.rc.right,
-				U.animwhereParams.rc.bottom
+				pU->animwhereParams.rc.left,
+				pU->animwhereParams.rc.top,
+				pU->animwhereParams.rc.right,
+				pU->animwhereParams.rc.bottom
 			);
 			break;
 		case MCI_DEVTYPE_OVERLAY:
 			sprintf(buf,"%d %d %d %d",
-				U.ovlywhereParams.rc.left,
-				U.ovlywhereParams.rc.top,
-				U.ovlywhereParams.rc.right,
-				U.ovlywhereParams.rc.bottom
+				pU->ovlywhereParams.rc.left,
+				pU->ovlywhereParams.rc.top,
+				pU->ovlywhereParams.rc.right,
+				pU->ovlywhereParams.rc.bottom
 			);
 			break;
 		default:strcpy(buf,"0 0 0 0");break;
 		}
 		_MCI_STR(buf);
 	}
+        SEGPTR_FREE(pU);
 	return	res;
 }
 
@@ -1871,10 +1894,11 @@
 MCISTR_Window(_MCISTR_PROTO_) {
 	int	i,res;
 	char	*s;
-	union 	{
+	union U {
 		MCI_ANIM_WINDOW_PARMS	animwindowParams;
 		MCI_OVLY_WINDOW_PARMS	ovlywindowParams;
-	} U;
+	};
+        union U *pU = SEGPTR_NEW(union U);
 
 	s=NULL;
 	i=0;
@@ -1884,33 +1908,33 @@
 			if (!STRCMP(keywords[i],"handle") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_ANIM_WINDOW_HWND;
 				if (!STRCMP(keywords[i+1],"default")) 
-					U.animwindowParams.hWnd = MCI_OVLY_WINDOW_DEFAULT;
+					pU->animwindowParams.hWnd = MCI_OVLY_WINDOW_DEFAULT;
 				else
-					sscanf(keywords[i+1],"%hd",&(U.animwindowParams.hWnd));
+					sscanf(keywords[i+1],"%hd",&(pU->animwindowParams.hWnd));
 				i+=2;
 				continue;
 			}
 			if (!STRCMP(keywords[i],"state") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_ANIM_WINDOW_STATE;
 				if (!STRCMP(keywords[i+1],"hide"))
-					U.animwindowParams.nCmdShow = SW_HIDE;
+					pU->animwindowParams.nCmdShow = SW_HIDE;
 				if (!STRCMP(keywords[i+1],"iconic"))
-					U.animwindowParams.nCmdShow = SW_SHOWMINNOACTIVE; /* correct? */
+					pU->animwindowParams.nCmdShow = SW_SHOWMINNOACTIVE; /* correct? */
 				if (!STRCMP(keywords[i+1],"minimized"))
-					U.animwindowParams.nCmdShow = SW_SHOWMINIMIZED;
+					pU->animwindowParams.nCmdShow = SW_SHOWMINIMIZED;
 				if (!STRCMP(keywords[i+1],"maximized"))
-					U.animwindowParams.nCmdShow = SW_SHOWMAXIMIZED;
+					pU->animwindowParams.nCmdShow = SW_SHOWMAXIMIZED;
 				if (!STRCMP(keywords[i+1],"minimize"))
-					U.animwindowParams.nCmdShow = SW_MINIMIZE;
+					pU->animwindowParams.nCmdShow = SW_MINIMIZE;
 				if (!STRCMP(keywords[i+1],"normal"))
-					U.animwindowParams.nCmdShow = SW_NORMAL;
+					pU->animwindowParams.nCmdShow = SW_NORMAL;
 				if (!STRCMP(keywords[i+1],"show"))
-					U.animwindowParams.nCmdShow = SW_SHOW;
+					pU->animwindowParams.nCmdShow = SW_SHOW;
 				if (!STRCMP(keywords[i+1],"no") && (i+2<nrofkeywords)) {
 					if (!STRCMP(keywords[i+2],"active"))
-						U.animwindowParams.nCmdShow = SW_SHOWNOACTIVATE;
+						pU->animwindowParams.nCmdShow = SW_SHOWNOACTIVATE;
 					if (!STRCMP(keywords[i+2],"action"))
-						U.animwindowParams.nCmdShow = SW_SHOWNA;/* correct?*/
+						pU->animwindowParams.nCmdShow = SW_SHOWNA;/* correct?*/
 					i++;
 				}
 				i+=2;
@@ -1943,7 +1967,7 @@
 				}
 				if ((t=strchr(s,'"'))) *t='\0';
 				/* FIXME: segmented pointer? */
-				U.animwindowParams.lpstrText = s;
+				pU->animwindowParams.lpstrText = s;
 				i=k+1;
 				continue;
 			}
@@ -1953,33 +1977,33 @@
 			if (!STRCMP(keywords[i],"handle") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_OVLY_WINDOW_HWND;
 				if (!STRCMP(keywords[i+1],"default")) 
-					U.ovlywindowParams.hWnd = MCI_OVLY_WINDOW_DEFAULT;
+					pU->ovlywindowParams.hWnd = MCI_OVLY_WINDOW_DEFAULT;
 				else
-					sscanf(keywords[i+1],"%hd",&(U.ovlywindowParams.hWnd));
+					sscanf(keywords[i+1],"%hd",&(pU->ovlywindowParams.hWnd));
 				i+=2;
 				continue;
 			}
 			if (!STRCMP(keywords[i],"state") && (i+1<nrofkeywords)) {
 				dwFlags |= MCI_OVLY_WINDOW_STATE;
 				if (!STRCMP(keywords[i+1],"hide"))
-					U.ovlywindowParams.nCmdShow = SW_HIDE;
+					pU->ovlywindowParams.nCmdShow = SW_HIDE;
 				if (!STRCMP(keywords[i+1],"iconic"))
-					U.ovlywindowParams.nCmdShow = SW_SHOWMINNOACTIVE; /* correct? */
+					pU->ovlywindowParams.nCmdShow = SW_SHOWMINNOACTIVE; /* correct? */
 				if (!STRCMP(keywords[i+1],"minimized"))
-					U.ovlywindowParams.nCmdShow = SW_SHOWMINIMIZED;
+					pU->ovlywindowParams.nCmdShow = SW_SHOWMINIMIZED;
 				if (!STRCMP(keywords[i+1],"maximized"))
-					U.ovlywindowParams.nCmdShow = SW_SHOWMAXIMIZED;
+					pU->ovlywindowParams.nCmdShow = SW_SHOWMAXIMIZED;
 				if (!STRCMP(keywords[i+1],"minimize"))
-					U.ovlywindowParams.nCmdShow = SW_MINIMIZE;
+					pU->ovlywindowParams.nCmdShow = SW_MINIMIZE;
 				if (!STRCMP(keywords[i+1],"normal"))
-					U.ovlywindowParams.nCmdShow = SW_NORMAL;
+					pU->ovlywindowParams.nCmdShow = SW_NORMAL;
 				if (!STRCMP(keywords[i+1],"show"))
-					U.ovlywindowParams.nCmdShow = SW_SHOW;
+					pU->ovlywindowParams.nCmdShow = SW_SHOW;
 				if (!STRCMP(keywords[i+1],"no") && (i+2<nrofkeywords)) {
 					if (!STRCMP(keywords[i+2],"active"))
-						U.ovlywindowParams.nCmdShow = SW_SHOWNOACTIVATE;
+						pU->ovlywindowParams.nCmdShow = SW_SHOWNOACTIVATE;
 					if (!STRCMP(keywords[i+2],"action"))
-						U.ovlywindowParams.nCmdShow = SW_SHOWNA;/* correct?*/
+						pU->ovlywindowParams.nCmdShow = SW_SHOWNA;/* correct?*/
 					i++;
 				}
 				i+=2;
@@ -2012,7 +2036,7 @@
 				}
 				if ((t=strchr(s,'"'))) *t='\0';
 				/* FIXME: segmented pointer? */
-				U.ovlywindowParams.lpstrText = s;
+				pU->ovlywindowParams.lpstrText = s;
 				i=k+1;
 				continue;
 			}
@@ -2021,8 +2045,9 @@
 		}
 		i++;
 	}
-	_MCI_CALL_DRIVER( MCI_WINDOW, MAKE_SEGPTR(&U) );
+	_MCI_CALL_DRIVER( MCI_WINDOW, SEGPTR_GET(pU) );
 	if (s) free(s);
+        SEGPTR_FREE(pU);
 	return res;
 }
 
diff --git a/objects/bitblt.c b/objects/bitblt.c
index 4a9489c..469b329 100644
--- a/objects/bitblt.c
+++ b/objects/bitblt.c
@@ -786,6 +786,7 @@
     RECT16 rectDst = *visRectDst;
     OffsetRect16( &rectSrc, -xSrc, -ySrc );
     OffsetRect16( &rectDst, -xDst, -yDst );
+    /* FIXME: avoid BadMatch errors */
     imageSrc = XGetImage( display, dcSrc->u.x.drawable,
                           visRectSrc->left, visRectSrc->top,
                           visRectSrc->right - visRectSrc->left,
@@ -830,9 +831,19 @@
         }
         else  /* color -> color */
         {
-            imageSrc = XGetImage( display, dcSrc->u.x.drawable,
-                                  visRectSrc->left, visRectSrc->top,
-                                  width, height, AllPlanes, ZPixmap );
+            if (dcSrc->w.flags & DC_MEMORY)
+                imageSrc = XGetImage( display, dcSrc->u.x.drawable,
+                                      visRectSrc->left, visRectSrc->top,
+                                      width, height, AllPlanes, ZPixmap );
+            else
+            {
+                /* Make sure we don't get a BadMatch error */
+                XCopyArea( display, dcSrc->u.x.drawable, pixmap, gc,
+                           visRectSrc->left, visRectSrc->top,
+                           width, height, 0, 0);
+                imageSrc = XGetImage( display, pixmap, 0, 0, width, height,
+                                      AllPlanes, ZPixmap );
+            }
             for (y = 0; y < height; y++)
                 for (x = 0; x < width; x++)
                     XPutPixel(imageSrc, x, y,
@@ -864,6 +875,7 @@
         }
         else  /* color -> monochrome */
         {
+            /* FIXME: avoid BadMatch error */
             imageSrc = XGetImage( display, dcSrc->u.x.drawable,
                                   visRectSrc->left, visRectSrc->top,
                                   width, height, AllPlanes, ZPixmap );
@@ -901,9 +913,20 @@
     else
     {
         register short x, y;
-        XImage *image = XGetImage( display, dc->u.x.drawable,
-                                   visRectDst->left, visRectDst->top,
-                                   width, height, AllPlanes, ZPixmap );
+        XImage *image;
+
+        if (dc->w.flags & DC_MEMORY)
+            image = XGetImage( display, dc->u.x.drawable,
+                               visRectDst->left, visRectDst->top,
+                               width, height, AllPlanes, ZPixmap );
+        else
+        {
+            /* Make sure we don't get a BadMatch error */
+            XCopyArea( display, dc->u.x.drawable, pixmap, gc,
+                       visRectDst->left, visRectDst->top, width, height, 0, 0);
+            image = XGetImage( display, pixmap, 0, 0, width, height,
+                               AllPlanes, ZPixmap );
+        }
         for (y = 0; y < height; y++)
             for (x = 0; x < width; x++)
                 XPutPixel( image, x, y,
diff --git a/objects/dib.c b/objects/dib.c
index e94b417..8d2907d 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -12,7 +12,6 @@
 #include "bitmap.h"
 #include "callback.h"
 #include "palette.h"
-#include "stackframe.h"
 #include "stddebug.h"
 #include "color.h"
 #include "debug.h"
diff --git a/objects/metafile.c b/objects/metafile.c
index d3e21e3..37d0b56 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -12,7 +12,6 @@
 #include "bitmap.h"
 #include "file.h"
 #include "metafile.h"
-#include "stackframe.h"
 #include "stddebug.h"
 #include "debug.h"
 
@@ -327,7 +326,7 @@
 {
     METAHEADER *mh = (METAHEADER *)GlobalLock16(hmf);
     METARECORD *mr;
-    SEGPTR ht;
+    SEGPTR ht, spRecord;
     int offset = 0;
   
     dprintf_metafile(stddeb,"EnumMetaFile(%04x, %04x, %08lx, %08lx)\n",
@@ -343,10 +342,12 @@
     
     /* loop through metafile records */
     
+    spRecord = WIN16_GlobalLock16(hmf);
     while (offset < (mh->mtSize * 2))
     {
 	mr = (METARECORD *)((char *)mh + offset);
-        if (!lpEnumFunc( hdc, ht, MAKE_SEGPTR(mr),  /* FIXME!! */
+        if (!lpEnumFunc( hdc, (HANDLETABLE16 *)ht,
+                         (METARECORD *)((UINT32)spRecord + offset),
                          mh->mtNoObjects, (LONG)lpData))
 	    break;
 
diff --git a/programs/progman/Makefile.in b/programs/progman/Makefile.in
index 63da670..c319479 100644
--- a/programs/progman/Makefile.in
+++ b/programs/progman/Makefile.in
@@ -40,7 +40,7 @@
 @MAKE_RULES@
 
 # Some strings need addresses >= 0x10000
-progman: $(MOSTOBJS) $(STRINGOBJS) $(WINELIB)
+progman: $(MOSTOBJS) $(STRINGOBJS)
 	$(CC) -o progman $(MOSTOBJS) $(LDOPTIONS) $(ALL_LIBS) $(STRINGOBJS)
 
 install: dummy
diff --git a/programs/progman/main.c b/programs/progman/main.c
index e8590e2..779eb37 100644
--- a/programs/progman/main.c
+++ b/programs/progman/main.c
@@ -71,7 +71,7 @@
 
   /* Select Language */
 #ifdef WINELIB
-  Globals.lpszLanguage = langNames[Options.language];
+  Globals.lpszLanguage = Languages[Options.language].name;
 #else
   Globals.lpszLanguage = "En";
 #endif
diff --git a/programs/progman/string.c b/programs/progman/string.c
index f33941b..07dbf3d 100644
--- a/programs/progman/string.c
+++ b/programs/progman/string.c
@@ -122,8 +122,8 @@
 
 #ifdef WINELIB
   /* Update system menus */
-  for (i = 0; langNames[i] && lstrcmp(lang, langNames[i]);) i++;
-  if (langNames[i]) Options.language = i;
+  for (i = 0; Languages[i].name && lstrcmp(lang, Languages[i].name);) i++;
+  if (Languages[i].name) Options.language = i;
 
   GetSystemMenu(Globals.hMainWnd, TRUE);
   for (hGroup = GROUP_FirstGroup(); hGroup;
diff --git a/programs/winhelp/Makefile.in b/programs/winhelp/Makefile.in
index 5f6afa3..219e42e 100644
--- a/programs/winhelp/Makefile.in
+++ b/programs/winhelp/Makefile.in
@@ -36,7 +36,7 @@
 @MAKE_RULES@
 
 # Some strings need addresses >= 0x10000
-winhelp: $(MOSTOBJS) $(STRINGOBJS) $(WINELIB)
+winhelp: $(MOSTOBJS) $(STRINGOBJS)
 	$(CC) -o winhelp $(MOSTOBJS) $(LDOPTIONS) $(ALL_LIBS) $(STRINGOBJS)
 
 hlp2sgml: hlp2sgml.o hlpfile.o
diff --git a/programs/winhelp/winhelp.c b/programs/winhelp/winhelp.c
index 177ea49..aefda90 100644
--- a/programs/winhelp/winhelp.c
+++ b/programs/winhelp/winhelp.c
@@ -92,7 +92,7 @@
     }
 
 #ifdef WINELIB
-  opt_lang = langNames[Options.language];
+  opt_lang = Languages[Options.language].name;
 #endif
 
   /* Find language specific string table */
diff --git a/tools/build.c b/tools/build.c
index 554f9ec..cdd1544 100644
--- a/tools/build.c
+++ b/tools/build.c
@@ -1089,7 +1089,8 @@
     printf( "\t.long Module_Start\n" );     /* Module start */
     printf( "\t.long %d\n", module_size );  /* Module size */
     printf( "\t.long %d\n", Base );         /* Base */
-    printf( "\t.long %d\n", Limit );        /* Limit */
+    printf( "\t.long %d\n", Limit+1 );      /* Size */
+    printf( "\t.long Code_Start\n" );       /* Code start */
     printf( "\t.long Functions\n" );        /* Functions */
     printf( "\t.long FuncNames\n" );        /* Function names */
 }
diff --git a/win32/findfile.c b/win32/findfile.c
index f0a672b..83b23a4 100644
--- a/win32/findfile.c
+++ b/win32/findfile.c
@@ -18,7 +18,7 @@
 
 typedef struct FindFileContext32 FindFileContext32;
 
-const char *DOSFS_Hash(const char *, int);
+const char *DOSFS_Hash(const char *, int, int);
 
 /* example D:\*.dbs */
 
@@ -70,7 +70,7 @@
 	    strcmp(dirent->d_name, ".") == 0)
 	    continue;
 
-	strcpy(dosname, DOSFS_Hash(dirent->d_name, FALSE));
+	strcpy(dosname, DOSFS_Hash(dirent->d_name, FALSE, FALSE));
 
 	if (MatchWildCard(dirent->d_name, context->mask)) {
 	    /* Full file name - is this a long file name?
diff --git a/win32/user32.c b/win32/user32.c
index 594e0b63..afb5bce 100644
--- a/win32/user32.c
+++ b/win32/user32.c
@@ -12,7 +12,7 @@
 #include <stdarg.h>
 #include "windows.h"
 #include "winerror.h"
-#include "stackframe.h"
+#include "heap.h"
 #include "xmalloc.h"
 #include "handle32.h"
 #include "struct32.h"
@@ -27,9 +27,11 @@
 BOOL USER32_GetMessageA(MSG32* lpmsg,DWORD hwnd,DWORD min,DWORD max)
 {
 	BOOL ret;
-	MSG16 msg;
-	ret=GetMessage(MAKE_SEGPTR(&msg),(HWND)hwnd,min,max);
-	STRUCT32_MSG16to32(&msg,lpmsg);
+	MSG16 *msg = SEGPTR_NEW(MSG16);
+        if (!msg) return 0;
+        ret=GetMessage(SEGPTR_GET(msg),(HWND)hwnd,min,max);
+	STRUCT32_MSG16to32(msg,lpmsg);
+        SEGPTR_FREE(msg);
 	return ret;
 }
 
diff --git a/windows/defwnd.c b/windows/defwnd.c
index 43b4ddc..f67c44c 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -14,6 +14,7 @@
 #include "winpos.h"
 #include "string32.h"
 #include "syscolor.h"
+#include "sysmetrics.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "spy.h"
@@ -101,7 +102,6 @@
 {
     switch(msg)
     {
-    case WM_PAINTICON: 
     case WM_NCPAINT:
 	return NC_HandleNCPaint( wndPtr->hwndSelf, (HRGN)wParam );
 
@@ -116,7 +116,7 @@
 	return NC_HandleNCLButtonDblClk( wndPtr, wParam, lParam );
 
     case WM_NCACTIVATE:
-	return NC_HandleNCActivate( wndPtr->hwndSelf, wParam );
+	return NC_HandleNCActivate( wndPtr, wParam );
 
     case WM_NCDESTROY:
 	if (wndPtr->text) HeapFree( SystemHeap, 0, wndPtr->text );
@@ -125,12 +125,26 @@
 	if (wndPtr->pHScroll) HeapFree( SystemHeap, 0, wndPtr->pHScroll );
         wndPtr->pVScroll = wndPtr->pHScroll = NULL;
 	return 0;
-	
+
+    case WM_PAINTICON:
     case WM_PAINT:
 	{
-	    PAINTSTRUCT16 paintstruct;
-	    BeginPaint16( wndPtr->hwndSelf, &paintstruct );
-	    EndPaint16( wndPtr->hwndSelf, &paintstruct );
+	    PAINTSTRUCT16 ps;
+	    HDC		  hdc = BeginPaint16( wndPtr->hwndSelf, &ps );
+	    if( hdc ) 
+	    {
+	      if( (wndPtr->dwStyle & WS_MINIMIZE) && wndPtr->class->hIcon )
+	      {
+	        int x = (wndPtr->rectWindow.right - wndPtr->rectWindow.left -
+			SYSMETRICS_CXICON)/2;
+	        int y = (wndPtr->rectWindow.bottom - wndPtr->rectWindow.top -
+			SYSMETRICS_CYICON)/2;
+		dprintf_win(stddeb,"Painting class icon: vis rect=(%i,%i - %i,%i)\n",
+		ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom );
+	        DrawIcon( hdc, x, y, wndPtr->class->hIcon );
+	      }
+	      EndPaint16( wndPtr->hwndSelf, &ps );
+	    }
 	    return 0;
 	}
 
@@ -164,18 +178,33 @@
     case WM_ICONERASEBKGND:
 	{
 	    if (!wndPtr->class->hbrBackground) return 0;
-            if (wndPtr->class->hbrBackground <= (HBRUSH)(COLOR_MAX+1))
+
+	    /* FIXME: should fill icon text with hbrushActiveCaption 
+		      instead of this */
+
+	    if (wndPtr->dwStyle & WS_MINIMIZE )
+	    {
+		 if( wndPtr->flags & WIN_NCACTIVATED )
+		 {
+		   FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
+                               (HDC)wParam, sysColorObjects.hbrushActiveCaption );
+		   return 1;
+		 }
+
+		 /* FIXME: should draw parent' background somehow
+			     (e.g for textured desktop) ? */
+	    }
+
+	    if (wndPtr->class->hbrBackground <= (HBRUSH)(COLOR_MAX+1))
             {
-                 HBRUSH hbrush;
-                 hbrush = CreateSolidBrush(
-                     GetSysColor(((DWORD)wndPtr->class->hbrBackground)-1));
+                HBRUSH hbrush = CreateSolidBrush( 
+			        GetSysColor(((DWORD)wndPtr->class->hbrBackground)-1));
                  FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
                              (HDC)wParam, hbrush);
                  DeleteObject (hbrush);
             }
-            else
-	         FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
-                             (HDC)wParam, wndPtr->class->hbrBackground );
+            else FillWindow( GetParent(wndPtr->hwndSelf), wndPtr->hwndSelf,
+                                  (HDC)wParam, wndPtr->class->hbrBackground );
 	    return 1;
 	}
 
diff --git a/windows/dialog.c b/windows/dialog.c
index 21ff837..3f3bace 100644
--- a/windows/dialog.c
+++ b/windows/dialog.c
@@ -12,7 +12,6 @@
 #include "heap.h"
 #include "win.h"
 #include "ldt.h"
-#include "stackframe.h"
 #include "string32.h"
 #include "user.h"
 #include "winproc.h"
@@ -724,33 +723,28 @@
 {
     WND * wndPtr;
     DIALOGINFO * dlgInfo;
-    HANDLE msgHandle;
-    MSG16* lpmsg;
+    MSG16 msg;
     INT32 retval;
 
       /* Owner must be a top-level window */
     owner = WIN_GetTopParent( owner );
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return -1;
-    if (!(msgHandle = USER_HEAP_ALLOC( sizeof(MSG16) ))) return -1;
-    lpmsg = (MSG16 *) USER_HEAP_LIN_ADDR( msgHandle );
     dlgInfo = (DIALOGINFO *)wndPtr->wExtra;
     EnableWindow( owner, FALSE );
     ShowWindow( hwnd, SW_SHOW );
 
-    while (MSG_InternalGetMessage( (SEGPTR)USER_HEAP_SEG_ADDR(msgHandle), hwnd, owner,
-                                   MSGF_DIALOGBOX, PM_REMOVE,
-                                   !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
+    while (MSG_InternalGetMessage(&msg, hwnd, owner, MSGF_DIALOGBOX, PM_REMOVE,
+                                  !(wndPtr->dwStyle & DS_NOIDLEMSG) ))
     {
-	if (!IsDialogMessage( hwnd, lpmsg))
+	if (!IsDialogMessage( hwnd, &msg))
 	{
-	    TranslateMessage( lpmsg );
-	    DispatchMessage( lpmsg );
+	    TranslateMessage( &msg );
+	    DispatchMessage( &msg );
 	}
 	if (dlgInfo->fEnd) break;
     }
     retval = dlgInfo->msgResult;
     DestroyWindow( hwnd );
-    USER_HEAP_FREE( msgHandle );
     EnableWindow( owner, TRUE );
     return retval;
 }
diff --git a/windows/event.c b/windows/event.c
index 9ea4349..c59b378 100644
--- a/windows/event.c
+++ b/windows/event.c
@@ -398,9 +398,9 @@
     rect.right  = rect.left + event->width;
     rect.bottom = rect.top + event->height;
 
-    RedrawWindow32( pWnd->hwndSelf, &rect, 0,
-                    RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
-                    (event->count ? 0 : RDW_ERASENOW) );
+    PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
+                        RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE |
+                        (event->count ? 0 : RDW_ERASENOW), 0 );
 }
 
 
@@ -420,9 +420,9 @@
     rect.right  = rect.left + event->width;
     rect.bottom = rect.top + event->height;
 
-    RedrawWindow32( pWnd->hwndSelf, &rect, 0,
-                    RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE |
-                    (event->count ? 0 : RDW_ERASENOW) );
+    PAINT_RedrawWindow( pWnd->hwndSelf, &rect, 0,
+                        RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE |
+                        (event->count ? 0 : RDW_ERASENOW), 0 );
 }
 
 
@@ -683,26 +683,17 @@
     }
     else
     {
-      /* Managed window; most of this code is shamelessly
-       * stolen from SetWindowPos - FIXME: outdated
-       */
-      
         WND *wndPtr;
 	WINDOWPOS16 *winpos;
 	RECT16 newWindowRect, newClientRect;
         HRGN hrgnOldPos, hrgnNewPos;
 
-	if (!(wndPtr = WIN_FindWndPtr( hwnd )))
-	{
-	    dprintf_event(stddeb,"ConfigureNotify: invalid HWND %04x\n",hwnd);
+	if (!(wndPtr = WIN_FindWndPtr( hwnd )) ||
+	    !(wndPtr->flags & WIN_MANAGED) )
 	    return;
-	}
 	
         if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return;
 
-        /* Artificial messages - what is this for? */
-	SendMessage16(hwnd, WM_ENTERSIZEMOVE, 0, 0);
-	SendMessage16(hwnd, WM_EXITSIZEMOVE, 0, 0);
 
 	/* Fill WINDOWPOS struct */
 	winpos->flags = SWP_NOACTIVATE | SWP_NOZORDER;
@@ -744,8 +735,9 @@
         SEGPTR_FREE(winpos);
 
         /* full window drag leaves unrepainted garbage without this */
-        RedrawWindow32( 0, NULL, hrgnOldPos, RDW_INVALIDATE |
-                        RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW );
+        PAINT_RedrawWindow( 0, NULL, hrgnOldPos, RDW_INVALIDATE |
+                            RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW,
+                            RDW_C_USEHRGN );
         DeleteObject(hrgnOldPos);
         DeleteObject(hrgnNewPos);
     }
diff --git a/windows/graphics.c b/windows/graphics.c
index 221bc02..e64aa2f 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -581,6 +581,7 @@
  */
 COLORREF GetPixel( HDC hdc, short x, short y )
 {
+    static Pixmap pixmap = 0;
     XImage * image;
     int pixel;
 
@@ -595,8 +596,21 @@
 
     x = dc->w.DCOrgX + XLPTODP( dc, x );
     y = dc->w.DCOrgY + YLPTODP( dc, y );
-    image = XGetImage( display, dc->u.x.drawable, x, y,
-		       1, 1, AllPlanes, ZPixmap );
+    if (dc->w.flags & DC_MEMORY)
+    {
+        image = XGetImage( display, dc->u.x.drawable, x, y, 1, 1,
+                           AllPlanes, ZPixmap );
+    }
+    else
+    {
+        /* If we are reading from the screen, use a temporary copy */
+        /* to avoid a BadMatch error */
+        if (!pixmap) pixmap = XCreatePixmap( display, rootWindow,
+                                             1, 1, dc->w.bitsPerPixel );
+        XCopyArea( display, dc->u.x.drawable, pixmap, BITMAP_colorGC,
+                   x, y, 1, 1, 0, 0 );
+        image = XGetImage( display, pixmap, 0, 0, 1, 1, AllPlanes, ZPixmap );
+    }
     pixel = XGetPixel( image, 0, 0 );
     XDestroyImage( image );
     
diff --git a/windows/mdi.c b/windows/mdi.c
index 3d1984c..96307bf 100644
--- a/windows/mdi.c
+++ b/windows/mdi.c
@@ -25,7 +25,6 @@
 #include "user.h"
 #include "menu.h"
 #include "resource.h"
-#include "stackframe.h"
 #include "struct32.h"
 #include "sysmetrics.h"
 #include "stddebug.h"
@@ -129,8 +128,7 @@
  DeleteMenu(clientInfo->hWindowMenu,id,MF_BYCOMMAND);
 
  /* walk the rest of MDI children to prevent gaps in the id 
-  * sequence and in the menu child list 
-  */
+  * sequence and in the menu child list */
 
  for( index = id+1; index <= clientInfo->nActiveChildren + 
                              clientInfo->idFirstChild; index++ )
@@ -1223,6 +1221,29 @@
 	    MoveWindow(hwndMDIClient, 0, 0, 
 		       LOWORD(lParam), HIWORD(lParam), TRUE);
 	    break;
+
+	  case WM_NEXTMENU:
+
+            wndPtr = WIN_FindWndPtr(hwndMDIClient);
+            ci     = (MDICLIENTINFO*)wndPtr->wExtra;
+
+	    if( !(wndPtr->parent->dwStyle & WS_MINIMIZE) 
+		&& ci->hwndActiveChild && !ci->hwndChildMaximized )
+	      {
+		/* control menu is between the frame system menu and 
+		 * the first entry of menu bar */
+
+		if( wParam == VK_LEFT ) 
+		  { if( wndPtr->parent->wIDmenu != LOWORD(lParam) ) break; }
+		else if( wParam == VK_RIGHT )
+		  { if( GetSystemMenu( wndPtr->parent->hwndSelf, 0) 
+				       != LOWORD(lParam) ) break; }
+		else break;
+		
+		return MAKELONG( GetSystemMenu(ci->hwndActiveChild, 0), 
+				 ci->hwndActiveChild );
+	      }
+	    break;
 	}
     }
     
@@ -1420,13 +1441,19 @@
 
       case WM_MENUCHAR:
 
-	/* MDI children don't have menus */
+	/* MDI children don't have menu bars */
 	PostMessage( clientWnd->parent->hwndSelf, WM_SYSCOMMAND, 
 				          (WPARAM)SC_KEYMENU, (LPARAM)wParam);
 	return 0x00010000L;
 
       case WM_NEXTMENU:
-	   /* set current menu to child system menu */
+
+	if( wParam == VK_LEFT )		/* switch to frame system menu */
+	  return MAKELONG( GetSystemMenu(clientWnd->parent->hwndSelf, 0), 
+			   clientWnd->parent->hwndSelf );
+	if( wParam == VK_RIGHT )	/* to frame menu bar */
+	  return MAKELONG( clientWnd->parent->wIDmenu,
+			   clientWnd->parent->hwndSelf );
 
 	break;	
     }
@@ -1468,7 +1495,7 @@
 
       case WM_MENUCHAR:
 
-	/* MDI children don't have menus */
+	/* MDI children don't have menu bars */
 	PostMessage( clientWnd->parent->hwndSelf, WM_SYSCOMMAND, 
                      (WPARAM)SC_KEYMENU, (LPARAM)LOWORD(wParam) );
 	return 0x00010000L;
diff --git a/windows/message.c b/windows/message.c
index 82870e4..4d5b558 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -16,7 +16,6 @@
 #include "heap.h"
 #include "hook.h"
 #include "spy.h"
-#include "stackframe.h"
 #include "winpos.h"
 #include "atom.h"
 #include "dde.h"
@@ -59,11 +58,12 @@
     WND *pWnd;
     BOOL eatMsg = FALSE;
     INT16 hittest;
+    MOUSEHOOKSTRUCT16 *hook;
+    BOOL32 ret;
     static DWORD lastClickTime = 0;
     static WORD  lastClickMsg = 0;
     static POINT16 lastClickPos = { 0, 0 };
     POINT16 pt = msg->pt;
-    MOUSEHOOKSTRUCT16 hook = { msg->pt, 0, HTCLIENT, 0 };
 
     BOOL mouseClick = ((msg->message == WM_LBUTTONDOWN) ||
 		       (msg->message == WM_RBUTTONDOWN) ||
@@ -73,12 +73,23 @@
 
     if ((msg->hwnd = GetCapture()) != 0)
     {
+        BOOL32 ret;
+
 	ScreenToClient16( msg->hwnd, &pt );
 	msg->lParam = MAKELONG( pt.x, pt.y );
         /* No need to further process the message */
-        hook.hwnd = msg->hwnd;
-        return !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
-                                msg->message, (LPARAM)MAKE_SEGPTR(&hook));
+
+        if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
+            !(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
+            return TRUE;
+        hook->pt           = msg->pt;
+        hook->hwnd         = msg->hwnd;
+        hook->wHitTestCode = HTCLIENT;
+        hook->dwExtraInfo  = 0;
+        ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
+                               msg->message, (LPARAM)SEGPTR_GET(hook));
+        SEGPTR_FREE(hook);
+        return ret;
     }
    
     hittest = WINPOS_WindowFromPoint( msg->pt, &pWnd );
@@ -100,7 +111,7 @@
         /* Send the WM_PARENTNOTIFY message */
 
         WIN_SendParentNotify( msg->hwnd, msg->message, 0,
-                              MAKELONG( msg->pt.x, msg->pt.y ) );
+                              MAKELPARAM( msg->pt.x, msg->pt.y ) );
 
         /* Activate the window if needed */
 
@@ -167,11 +178,21 @@
 	msg->message += WM_NCLBUTTONDOWN - WM_LBUTTONDOWN;
     }
     msg->lParam = MAKELONG( pt.x, pt.y );
-    
-    hook.hwnd = msg->hwnd;
-    hook.wHitTestCode = hittest;
-    return !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
-                            msg->message, (LPARAM)MAKE_SEGPTR(&hook));
+
+    /* Call the WH_MOUSE hook */
+
+    if (!HOOK_GetHook( WH_MOUSE, GetTaskQueue(0)) ||
+        !(hook = SEGPTR_NEW(MOUSEHOOKSTRUCT16)))
+        return TRUE;
+
+    hook->pt           = msg->pt;
+    hook->hwnd         = msg->hwnd;
+    hook->wHitTestCode = hittest;
+    hook->dwExtraInfo  = 0;
+    ret = !HOOK_CallHooks( WH_MOUSE, remove ? HC_ACTION : HC_NOREMOVE,
+                           msg->message, (LPARAM)SEGPTR_GET(hook) );
+    SEGPTR_FREE(hook);
+    return ret;
 }
 
 
@@ -214,6 +235,46 @@
                             msg->wParam, msg->lParam );
 }
 
+/***********************************************************************
+ *           MSG_JournalRecordMsg
+ *
+ * Build an EVENTMSG structure and call JOURNALRECORD hook
+ */
+static void MSG_JournalRecordMsg( MSG16 *msg )
+{
+    EVENTMSG16 *event = SEGPTR_NEW(EVENTMSG16);
+    if (!event) return;
+    event->message = msg->message;
+    event->time = msg->time;
+    if ((msg->message >= WM_KEYFIRST) && (msg->message <= WM_KEYLAST))
+    {
+        event->paramL = (msg->wParam & 0xFF) | (HIWORD(msg->lParam) << 8);
+        event->paramH = msg->lParam & 0x7FFF;  
+        if (HIWORD(msg->lParam) & 0x0100)
+            event->paramH |= 0x8000;               /* special_key - bit */
+        HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0,
+                        (LPARAM)SEGPTR_GET(event) );
+    }
+    else if ((msg->message >= WM_MOUSEFIRST) && (msg->message <= WM_MOUSELAST))
+    {
+        event->paramL = LOWORD(msg->lParam);       /* X pos */
+        event->paramH = HIWORD(msg->lParam);       /* Y pos */ 
+        ClientToScreen16( msg->hwnd, (LPPOINT16)&event->paramL );
+        HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0,
+                        (LPARAM)SEGPTR_GET(event) );
+    }
+    else if ((msg->message >= WM_NCMOUSEMOVE) &&
+             (msg->message <= WM_NCMBUTTONDBLCLK))
+    {
+        event->paramL = LOWORD(msg->lParam);       /* X pos */
+        event->paramH = HIWORD(msg->lParam);       /* Y pos */ 
+        event->message += WM_MOUSEMOVE-WM_NCMOUSEMOVE;/* give no info about NC area */
+        HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION, 0,
+                        (LPARAM)SEGPTR_GET(event) );
+    }
+    SEGPTR_FREE(event);
+}
+
 
 /***********************************************************************
  *           MSG_PeekHardwareMsg
@@ -246,10 +307,20 @@
         }
         else  /* Non-standard hardware event */
         {
-            HARDWAREHOOKSTRUCT16 hook = { msg->hwnd, msg->message,
-                                          msg->wParam, msg->lParam };
-            if (HOOK_CallHooks( WH_HARDWARE, remove ? HC_ACTION : HC_NOREMOVE,
-                                0, (LPARAM)MAKE_SEGPTR(&hook) )) continue;
+            HARDWAREHOOKSTRUCT16 *hook;
+            if ((hook = SEGPTR_NEW(HARDWAREHOOKSTRUCT16)))
+            {
+                BOOL32 ret;
+                hook->hWnd     = msg->hwnd;
+                hook->wMessage = msg->message;
+                hook->wParam   = msg->wParam;
+                hook->lParam   = msg->lParam;
+                ret = HOOK_CallHooks( WH_HARDWARE,
+                                      remove ? HC_ACTION : HC_NOREMOVE,
+                                      0, (LPARAM)SEGPTR_GET(hook) );
+                SEGPTR_FREE(hook);
+                if (ret) continue;
+            }
         }
 
           /* Check message against filters */
@@ -261,35 +332,7 @@
             (GetWindowTask16(msg->hwnd) != GetCurrentTask()))
             continue;  /* Not for this task */
         if (remove && HOOK_GetHook( WH_JOURNALRECORD, GetTaskQueue(0) ))
-        {
-            EVENTMSG16 *event = SEGPTR_NEW(EVENTMSG16);
-            if (event)
-            {
-                event->message = msg->message;
-                event->time = msg->time;
-                if ((msg->message >= WM_KEYFIRST) &&
-                    (msg->message <= WM_KEYLAST))
-                {
-                    event->paramL = (msg->wParam & 0xFF) |
-                                    (HIWORD(msg->lParam) << 8);
-                    event->paramH = msg->lParam & 0x7FFF;  
-                    if (HIWORD(msg->lParam) & 0x0100)
-                        event->paramH |= 0x8000;  /* special_key - bit */
-                    HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION,
-                                    0, (LPARAM)SEGPTR_GET(event) );
-                }
-                else if ((msg->message >= WM_MOUSEFIRST) &&
-                         (msg->message <= WM_MOUSELAST))
-                {
-                    event->paramL = LOWORD(msg->lParam);       /* X pos */
-                    event->paramH = HIWORD(msg->lParam);       /* Y pos */ 
-                    ClientToScreen16( msg->hwnd, (LPPOINT16)&event->paramL );
-                    HOOK_CallHooks( WH_JOURNALRECORD, HC_ACTION,
-                                    0, (LPARAM)SEGPTR_GET(event) );
-                }
-                SEGPTR_FREE(event);
-            }
-        }
+            MSG_JournalRecordMsg( msg );
         if (remove) QUEUE_RemoveMsg( sysMsgQueue, pos );
         return TRUE;
     }
@@ -336,7 +379,7 @@
 
     if (queue->hWnd)
     {
-        fprintf( stderr, "Nested SendMessage() not supported\n" );
+        fprintf( stderr, "Nested SendMessage(), msg %04x skipped\n", msg );
         return 0;
     }
     queue->hWnd   = hwnd;
@@ -479,24 +522,31 @@
 
 	if ((msgQueue->wakeBits & mask) & QS_PAINT)
 	{
+	    WND* wndPtr;
 	    msg->hwnd = WIN_FindWinToRepaint( hwnd , hQueue );
 	    msg->message = WM_PAINT;
 	    msg->wParam = 0;
 	    msg->lParam = 0;
-            if( msg->hwnd &&
-              (!hwnd || msg->hwnd == hwnd || IsChild(hwnd,msg->hwnd)) )
-              {
-                WND* wndPtr = WIN_FindWndPtr(msg->hwnd);
 
-	        /* FIXME: WM_PAINTICON should be sent sometimes */
+	    if ((wndPtr = WIN_FindWndPtr(msg->hwnd)))
+	    {
+                if( wndPtr->dwStyle & WS_MINIMIZE &&
+                    wndPtr->class->hIcon )
+                {
+                    msg->message = WM_PAINTICON;
+                    msg->wParam = 1;
+                }
 
-                if( wndPtr->flags & WIN_INTERNAL_PAINT && !wndPtr->hrgnUpdate)
-                  {
-                    wndPtr->flags &= ~WIN_INTERNAL_PAINT;
-                    QUEUE_DecPaintCount( hQueue );
-                  }
-                break;
-              }
+                if( !hwnd || msg->hwnd == hwnd || IsChild(hwnd,msg->hwnd) )
+                {
+                    if( wndPtr->flags & WIN_INTERNAL_PAINT && !wndPtr->hrgnUpdate)
+                    {
+                        wndPtr->flags &= ~WIN_INTERNAL_PAINT;
+                        QUEUE_DecPaintCount( hQueue );
+                    }
+                    break;
+                }
+	    }
 	}
 
         /* Check for timer messages, but yield first */
@@ -535,36 +585,52 @@
  * 'hwnd' must be the handle of the dialog or menu window.
  * 'code' is the message filter value (MSGF_??? codes).
  */
-BOOL MSG_InternalGetMessage( SEGPTR msg, HWND hwnd, HWND hwndOwner, short code,
+BOOL MSG_InternalGetMessage( MSG16 *msg, HWND hwnd, HWND hwndOwner, short code,
 			     WORD flags, BOOL sendIdle ) 
 {
     for (;;)
     {
 	if (sendIdle)
 	{
-	    if (!MSG_PeekMessage( (MSG16 *)PTR_SEG_TO_LIN(msg),
-                                  0, 0, 0, flags, TRUE ))
+	    if (!MSG_PeekMessage( msg, 0, 0, 0, flags, TRUE ))
 	    {
 		  /* No message present -> send ENTERIDLE and wait */
                 if (IsWindow(hwndOwner))
                     SendMessage16( hwndOwner, WM_ENTERIDLE,
                                    code, (LPARAM)hwnd );
-		MSG_PeekMessage( (MSG16 *)PTR_SEG_TO_LIN(msg),
-                                 0, 0, 0, flags, FALSE );
+		MSG_PeekMessage( msg, 0, 0, 0, flags, FALSE );
 	    }
 	}
 	else  /* Always wait for a message */
-	    MSG_PeekMessage( (MSG16 *)PTR_SEG_TO_LIN(msg),
-                             0, 0, 0, flags, FALSE );
+	    MSG_PeekMessage( msg, 0, 0, 0, flags, FALSE );
 
-	if (!CallMsgFilter( msg, code ))
-            return (((MSG16 *)PTR_SEG_TO_LIN(msg))->message != WM_QUIT);
+        /* Call message filters */
 
-	  /* Message filtered -> remove it from the queue */
-	  /* if it's still there. */
-	if (!(flags & PM_REMOVE))
-	    MSG_PeekMessage( (MSG16 *)PTR_SEG_TO_LIN(msg),
-                             0, 0, 0, PM_REMOVE, TRUE );
+        if (HOOK_GetHook( WH_SYSMSGFILTER, GetTaskQueue(0) ) ||
+            HOOK_GetHook( WH_MSGFILTER, GetTaskQueue(0) ))
+        {
+            MSG16 *pmsg = SEGPTR_NEW(MSG16);
+            if (pmsg)
+            {
+                BOOL32 ret;
+                *pmsg = *msg;
+                ret = (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0,
+                                       (LPARAM)SEGPTR_GET(pmsg) ) ||
+                       HOOK_CallHooks( WH_MSGFILTER, code, 0,
+                                       (LPARAM)SEGPTR_GET(pmsg) ));
+                SEGPTR_FREE(pmsg);
+                if (ret)
+                {
+                    /* Message filtered -> remove it from the queue */
+                    /* if it's still there. */
+                    if (!(flags & PM_REMOVE))
+                        MSG_PeekMessage( msg, 0, 0, 0, PM_REMOVE, TRUE );
+                    continue;
+                }
+            }
+        }
+
+        return (msg->message != WM_QUIT);
     }
 }
 
@@ -665,13 +731,6 @@
 {
     WND * wndPtr;
     LRESULT ret;
-    struct
-    {
-	LPARAM   lParam;
-	WPARAM16 wParam;
-	UINT16   wMsg;
-	HWND16   hWnd;
-    } msgstruct = { lParam, wParam, msg, hwnd };
 
 #ifdef CONFIG_IPC
     MSG16 DDE_msg = { hwnd, msg, wParam, lParam };
@@ -694,19 +753,37 @@
         return TRUE;
     }
 
-    HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1,
-                    (LPARAM)MAKE_SEGPTR(&msgstruct) );
-    hwnd   = msgstruct.hWnd;
-    msg    = msgstruct.wMsg;
-    wParam = msgstruct.wParam;
-    lParam = msgstruct.lParam;
+    if (HOOK_GetHook( WH_CALLWNDPROC, GetTaskQueue(0) ))
+    { 
+        struct msgstruct
+        {
+            LPARAM   lParam;
+            WPARAM16 wParam;
+            UINT16   wMsg;
+            HWND16   hWnd;
+        } *pmsg;
+        
+        if ((pmsg = SEGPTR_NEW(struct msgstruct)))
+        {
+            pmsg->hWnd   = hwnd;
+            pmsg->wMsg   = msg;
+            pmsg->wParam = wParam;
+            pmsg->lParam = lParam;
+            HOOK_CallHooks( WH_CALLWNDPROC, HC_ACTION, 1,
+                            (LPARAM)SEGPTR_GET(pmsg) );
+            hwnd   = pmsg->hWnd;
+            msg    = pmsg->wMsg;
+            wParam = pmsg->wParam;
+            lParam = pmsg->lParam;
+        }
+    }
 
     if (!(wndPtr = WIN_FindWndPtr( hwnd )))
     {
         fprintf( stderr, "SendMessage16: invalid hwnd %04x\n", hwnd );
         return 0;
     }
-    if (wndPtr->hmemTaskQ == QUEUE_GetDoomedQueue())
+    if (QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))
         return 0;  /* Don't send anything if the task is dying */
     if (wndPtr->hmemTaskQ != GetTaskQueue(0))
         return MSG_SendMessage( wndPtr->hmemTaskQ, hwnd, msg, wParam, lParam );
@@ -758,8 +835,9 @@
         return ret;
     }
 
-    if (wndPtr->hmemTaskQ == QUEUE_GetDoomedQueue())
+    if (QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))
         return 0;  /* Don't send anything if the task is dying */
+
     if (wndPtr->hmemTaskQ != GetTaskQueue(0))
     {
         fprintf( stderr, "SendMessage32A: intertask message not supported\n" );
@@ -800,7 +878,7 @@
         fprintf( stderr, "SendMessage32W: invalid hwnd %08x\n", hwnd );
         return 0;
     }
-    if (wndPtr->hmemTaskQ == QUEUE_GetDoomedQueue())
+    if (QUEUE_IsDoomedQueue(wndPtr->hmemTaskQ))
         return 0;  /* Don't send anything if the task is dying */
     if (wndPtr->hmemTaskQ != GetTaskQueue(0))
     {
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 0846325..64de6c0 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -16,7 +16,6 @@
 #include "menu.h"
 #include "winpos.h"
 #include "scroll.h"
-#include "stackframe.h"
 #include "nonclient.h"
 #include "graphics.h"
 #include "queue.h"
@@ -235,17 +234,20 @@
 {
     RECT16 tmpRect = { 0, 0, 0, 0 };
 
-    NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
-    winRect->left   -= tmpRect.left;
-    winRect->top    -= tmpRect.top;
-    winRect->right  -= tmpRect.right;
-    winRect->bottom -= tmpRect.bottom;
-
-    if (HAS_MENU(pWnd))
+    if( !( pWnd->dwStyle & WS_MINIMIZE ) )
     {
+      NC_AdjustRect( &tmpRect, pWnd->dwStyle, FALSE, pWnd->dwExStyle );
+      winRect->left   -= tmpRect.left;
+      winRect->top    -= tmpRect.top;
+      winRect->right  -= tmpRect.right;
+      winRect->bottom -= tmpRect.bottom;
+
+      if (HAS_MENU(pWnd))
+      {
 	winRect->top += MENU_GetMenuBarHeight( pWnd->hwndSelf,
                                                winRect->right - winRect->left,
-                                             -tmpRect.left, -tmpRect.top ) + 1;
+                                              -tmpRect.left, -tmpRect.top ) + 1;
+      }
     }
     return 0;
 }
@@ -430,14 +432,17 @@
     HBITMAP hbitmap;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-    NC_GetInsideRect( hwnd, &rect );
-    hdcMem = CreateCompatibleDC( hdc );
-    hbitmap = SelectObject( hdcMem, hbitmapClose );
-    BitBlt( hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
-            hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
-            down ? NOTSRCCOPY : SRCCOPY );
-    SelectObject( hdcMem, hbitmap );
-    DeleteDC( hdcMem );
+    if( !(wndPtr->flags & WIN_MANAGED) )
+    {
+      NC_GetInsideRect( hwnd, &rect );
+      hdcMem = CreateCompatibleDC( hdc );
+      hbitmap = SelectObject( hdcMem, hbitmapClose );
+      BitBlt( hdc, rect.left, rect.top, SYSMETRICS_CXSIZE, SYSMETRICS_CYSIZE,
+              hdcMem, (wndPtr->dwStyle & WS_CHILD) ? SYSMETRICS_CXSIZE : 0, 0,
+              down ? NOTSRCCOPY : SRCCOPY );
+      SelectObject( hdcMem, hbitmap );
+      DeleteDC( hdcMem );
+    }
 }
 
 
@@ -447,12 +452,17 @@
 static void NC_DrawMaxButton( HWND hwnd, HDC hdc, BOOL down )
 {
     RECT16 rect;
-    NC_GetInsideRect( hwnd, &rect );
-    GRAPH_DrawBitmap( hdc, (IsZoomed(hwnd) ?
-			    (down ? hbitmapRestoreD : hbitmapRestore) :
-			    (down ? hbitmapMaximizeD : hbitmapMaximize)),
-		     rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
-		     0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE );
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+
+    if( !(wndPtr->flags & WIN_MANAGED) )
+    {
+      NC_GetInsideRect( hwnd, &rect );
+      GRAPH_DrawBitmap( hdc, (IsZoomed(hwnd) ?
+			     (down ? hbitmapRestoreD : hbitmapRestore) :
+			     (down ? hbitmapMaximizeD : hbitmapMaximize)),
+		        rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
+		        0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE );
+    }
 }
 
 
@@ -463,11 +473,15 @@
 {
     RECT16 rect;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
-    NC_GetInsideRect( hwnd, &rect );
-    if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE + 1;
-    GRAPH_DrawBitmap( hdc, (down ? hbitmapMinimizeD : hbitmapMinimize),
-		     rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
-		     0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE );
+
+    if( !(wndPtr->flags & WIN_MANAGED) )
+    {
+      NC_GetInsideRect( hwnd, &rect );
+      if (wndPtr->dwStyle & WS_MAXIMIZEBOX) rect.right -= SYSMETRICS_CXSIZE + 1;
+      GRAPH_DrawBitmap( hdc, (down ? hbitmapMinimizeD : hbitmapMinimize),
+		        rect.right - SYSMETRICS_CXSIZE - 1, rect.top,
+		        0, 0, SYSMETRICS_CXSIZE+1, SYSMETRICS_CYSIZE );
+    }
 }
 
 
@@ -587,6 +601,8 @@
     WND * wndPtr = WIN_FindWndPtr( hwnd );
     char buffer[256];
 
+    if (wndPtr->flags & WIN_MANAGED) return;
+
     if (!hbitmapClose)
     {
 	if (!(hbitmapClose = LoadBitmap16( 0, MAKEINTRESOURCE(OBM_CLOSE) )))
@@ -658,7 +674,8 @@
 
     WND *wndPtr = WIN_FindWndPtr( hwnd );
 
-    if (!wndPtr || !(wndPtr->dwStyle & WS_VISIBLE)) return; /* Nothing to do */
+    if (!wndPtr || wndPtr->dwStyle & WS_MINIMIZE ||
+	!WIN_IsWindowDrawable( wndPtr, 0 )) return; /* Nothing to do */
 
     active  = wndPtr->flags & WIN_NCACTIVATED;
 
@@ -666,29 +683,6 @@
 
     if (!(hdc = GetDCEx( hwnd, 0, DCX_USESTYLE | DCX_WINDOW ))) return;
 
-    /*
-     * If this is an icon, we don't want to do any more nonclient painting
-     * of the window manager.
-     * If there is a class icon to draw, draw it
-     */
-    if (IsIconic(hwnd))
-    {
-        if (wndPtr->class->hIcon)
-        {
-            SendMessage16(hwnd, WM_ICONERASEBKGND, (WPARAM)hdc, 0);
-            DrawIcon( hdc, 0, 0, wndPtr->class->hIcon );
-        }
-        ReleaseDC(hwnd, hdc);
-        wndPtr->flags &= ~WIN_INTERNAL_PAINT;
-        if( wndPtr->hrgnUpdate )
-          {
-            DeleteObject( wndPtr->hrgnUpdate );
-            QUEUE_DecPaintCount( wndPtr->hmemTaskQ );
-            wndPtr->hrgnUpdate = 0;
-          }
-        return;
-    }
-
     if (ExcludeVisRect( hdc, wndPtr->rectClient.left-wndPtr->rectWindow.left,
 		        wndPtr->rectClient.top-wndPtr->rectWindow.top,
 		        wndPtr->rectClient.right-wndPtr->rectWindow.left,
@@ -776,14 +770,23 @@
  *
  * Handle a WM_NCACTIVATE message. Called from DefWindowProc().
  */
-LONG NC_HandleNCActivate( HWND hwnd, WPARAM wParam )
+LONG NC_HandleNCActivate( WND *wndPtr, WPARAM wParam )
 {
-    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    WORD wStateChange;
 
-    if (wParam != 0) wndPtr->flags |= WIN_NCACTIVATED;
-    else wndPtr->flags &= ~WIN_NCACTIVATED;
+    if( wParam ) wStateChange = !(wndPtr->flags & WIN_NCACTIVATED);
+    else wStateChange = wndPtr->flags & WIN_NCACTIVATED;
 
-    NC_DoNCPaint( hwnd, (HRGN)1, FALSE );
+    if( wStateChange )
+    {
+      if (wParam) wndPtr->flags |= WIN_NCACTIVATED;
+      else wndPtr->flags &= ~WIN_NCACTIVATED;
+
+      if( wndPtr->dwStyle & WS_MINIMIZE )
+	PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW, 0 );
+      else
+	NC_DoNCPaint( wndPtr->hwndSelf, (HRGN)1, FALSE );
+    }
     return TRUE;
 }
 
@@ -841,6 +844,21 @@
     return (LONG)SetCursor( LoadCursor16( 0, IDC_ARROW ) );
 }
 
+/***********************************************************************
+ *           NC_GetSysPopupPos
+ */
+BOOL NC_GetSysPopupPos( WND* wndPtr, RECT16* rect )
+{
+  if( !wndPtr->hSysMenu ) return FALSE;
+
+  NC_GetInsideRect( wndPtr->hwndSelf, rect );
+  OffsetRect16( rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top );
+  if (wndPtr->dwStyle & WS_CHILD)
+     ClientToScreen16( wndPtr->parent->hwndSelf, (POINT16 *)rect );
+  rect->right = rect->left + SYSMETRICS_CXSIZE;
+  rect->bottom = rect->top + SYSMETRICS_CYSIZE;
+  return TRUE;
+}
 
 /***********************************************************************
  *           NC_TrackSysMenu
@@ -854,19 +872,16 @@
     int iconic = wndPtr->dwStyle & WS_MINIMIZE;
 
     if (!(wndPtr->dwStyle & WS_SYSMENU)) return;
+
     /* If window has a menu, track the menu bar normally if it not minimized */
     if (HAS_MENU(wndPtr) && !iconic) MENU_TrackMouseMenuBar( hwnd, pt );
     else
     {
 	  /* Otherwise track the system menu like a normal popup menu */
-	NC_GetInsideRect( hwnd, &rect );
-	OffsetRect16( &rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top );
-	if (wndPtr->dwStyle & WS_CHILD)
-	    ClientToScreen16( wndPtr->parent->hwndSelf, (POINT16 *)&rect );
-	rect.right = rect.left + SYSMETRICS_CXSIZE;
-	rect.bottom = rect.top + SYSMETRICS_CYSIZE;
+
+	NC_GetSysPopupPos( wndPtr, &rect );
 	if (!iconic) NC_DrawSysButton( hwnd, hdc, TRUE );
-	TrackPopupMenu16( wndPtr->hSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
+	TrackPopupMenu16( GetSystemMenu(hwnd, 0), TPM_LEFTALIGN | TPM_LEFTBUTTON,
                           rect.left, rect.bottom, 0, hwnd, &rect );
 	if (!iconic) NC_DrawSysButton( hwnd, hdc, FALSE );
     }
@@ -908,8 +923,7 @@
 	SetCapture(hwnd);
 	while(!hittest)
 	{
-            MSG_InternalGetMessage( MAKE_SEGPTR(&msg), 0, 0, MSGF_SIZE,
-                                    PM_REMOVE, FALSE );
+            MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
 	    switch(msg.message)
 	    {
 	    case WM_MOUSEMOVE:
@@ -1048,8 +1062,7 @@
     {
         int dx = 0, dy = 0;
 
-        MSG_InternalGetMessage( MAKE_SEGPTR(&msg), 0, 0, MSGF_SIZE,
-                                PM_REMOVE, FALSE );
+        MSG_InternalGetMessage( &msg, 0, 0, MSGF_SIZE, PM_REMOVE, FALSE );
 
 	  /* Exit on button-up, Return, or Esc */
 	if ((msg.message == WM_LBUTTONUP) ||
@@ -1151,7 +1164,7 @@
     do
     {
 	BOOL oldstate = pressed;
-        MSG_InternalGetMessage( MAKE_SEGPTR(&msg), 0, 0, 0, PM_REMOVE, FALSE );
+        MSG_InternalGetMessage( &msg, 0, 0, 0, PM_REMOVE, FALSE );
 
 	pressed = (NC_HandleNCHitTest( hwnd, msg.pt ) == wParam);
 	if (pressed != oldstate)
diff --git a/windows/painting.c b/windows/painting.c
index 29a58cb..40f5dff 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -88,10 +88,13 @@
  */
 HDC16 BeginPaint16( HWND16 hwnd, LPPAINTSTRUCT16 lps ) 
 {
+    BOOL32 bIcon;
     HRGN hrgnUpdate;
-    WND * wndPtr = WIN_FindWndPtr( hwnd );
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr) return 0;
 
+    bIcon = (wndPtr->dwStyle & WS_MINIMIZE && wndPtr->class->hIcon);
+
     wndPtr->flags &= ~WIN_NEEDS_BEGINPAINT;
 
     if (wndPtr->flags & WIN_NEEDS_NCPAINT) WIN_UpdateNCArea( wndPtr, TRUE );
@@ -107,13 +110,15 @@
 
     dprintf_win(stddeb,"hrgnUpdate = %04x, ", hrgnUpdate);
 
-    lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_WINDOWPAINT | DCX_USESTYLE );
+    /* When bIcon is TRUE hrgnUpdate is automatically in window coordinates
+     * (because rectClient == rectWindow for WS_MINIMIZE windows).
+     */
+
+    lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_WINDOWPAINT |
+                        DCX_USESTYLE | (bIcon ? DCX_WINDOW : 0) );
 
     dprintf_win(stddeb,"hdc = %04x\n", lps->hdc);
 
-    /* pseudocode from "Internals" doesn't delete hrgnUpdate - yet another clue
-       that ReleaseDC should take care of it (hence DCX_KEEPCLIPRGN) */
-
     if (!lps->hdc)
     {
         fprintf(stderr, "GetDCEx() failed in BeginPaint(), hwnd=%04x\n", hwnd);
@@ -126,7 +131,9 @@
     if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
     {
         wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
-        lps->fErase = !SendMessage16(hwnd, WM_ERASEBKGND, (WPARAM)lps->hdc, 0);
+        lps->fErase = !SendMessage16(hwnd, (bIcon) ? WM_ICONERASEBKGND
+                                                   : WM_ERASEBKGND,
+                                     (WPARAM)lps->hdc, 0 );
     }
     else lps->fErase = TRUE;
 
@@ -218,20 +225,32 @@
 
 
 /***********************************************************************
- *           RedrawWindow32    (USER32.425)
+ *           PAINT_RedrawWindow
+ *
+ * Note: Windows uses WM_SYNCPAINT to cut down the number of intertask
+ * SendMessage() calls. From SDK:
+ *   This message avoids lots of inter-app message traffic
+ *   by switching to the other task and continuing the
+ *   recursion there.
+ * 
+ * wParam         = flags
+ * LOWORD(lParam) = hrgnClip
+ * HIWORD(lParam) = hwndSkip  (not used; always NULL)
  */
-BOOL32 RedrawWindow32( HWND32 hwnd, const RECT32 *rectUpdate,
-                       HRGN32 hrgnUpdate, UINT32 flags )
+BOOL32 PAINT_RedrawWindow( HWND32 hwnd, const RECT32 *rectUpdate,
+                         HRGN32 hrgnUpdate, UINT32 flags, UINT32 control )
 {
+    BOOL32 bIcon;
     HRGN hrgn;
     RECT32 rectClient;
-    WND * wndPtr;
+    WND* wndPtr;
 
     if (!hwnd) hwnd = GetDesktopWindow();
     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
     if (!IsWindowVisible(hwnd) || (wndPtr->flags & WIN_NO_REDRAW))
         return TRUE;  /* No redraw needed */
 
+    bIcon = (wndPtr->dwStyle & WS_MINIMIZE && wndPtr->class->hIcon);
     if (rectUpdate)
     {
         dprintf_win(stddeb, "RedrawWindow: %04x %d,%d-%d,%d %04x flags=%04x\n",
@@ -283,7 +302,7 @@
 	   }
 	else
              if (flags & RDW_ERASE) wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
-	flags |= RDW_FRAME;  /* Force invalidating the frame of children */
+	flags |= RDW_FRAME;  /* Force children frame invalidation */
     }
     else if (flags & RDW_VALIDATE)  /* Validate */
     {
@@ -335,7 +354,8 @@
 
     if (flags & RDW_UPDATENOW)
     {
-        if (wndPtr->hrgnUpdate) SendMessage16( hwnd, WM_PAINT, 0, 0 );
+        if (wndPtr->hrgnUpdate) /* wm_painticon wparam is 1 */
+            SendMessage16( hwnd, (bIcon) ? WM_PAINTICON : WM_PAINT, bIcon, 0 );
     }
     else if (flags & RDW_ERASENOW)
     {
@@ -345,18 +365,16 @@
         if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
         {
             HDC hdc = GetDCEx( hwnd, wndPtr->hrgnUpdate,
-                               DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN | DCX_WINDOWPAINT);
+                               DCX_INTERSECTRGN | DCX_USESTYLE |
+                               DCX_KEEPCLIPRGN | DCX_WINDOWPAINT |
+                               (bIcon ? DCX_WINDOW : 0) );
             if (hdc)
             {
-              /* Don't send WM_ERASEBKGND to icons */
-              /* (WM_ICONERASEBKGND is sent during processing of WM_NCPAINT) */
-                if (!(wndPtr->dwStyle & WS_MINIMIZE) ||
-                    !wndPtr->class->hIcon)
-                {
-                    if (SendMessage16( hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0 ))
-                        wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
-                }
-                ReleaseDC( hwnd, hdc );
+               if (SendMessage16( hwnd, (bIcon) ? WM_ICONERASEBKGND
+						: WM_ERASEBKGND,
+                                  (WPARAM)hdc, 0 ))
+                  wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
+               ReleaseDC( hwnd, hdc );
             }
         }
     }
@@ -364,42 +382,65 @@
       /* Recursively process children */
 
     if (!(flags & RDW_NOCHILDREN) &&
-	((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)))
+        ((flags & RDW_ALLCHILDREN) || !(wndPtr->dwStyle & WS_CLIPCHILDREN)) &&
+	!(wndPtr->dwStyle & WS_MINIMIZE) )
     {
-	if (hrgnUpdate)
+        if ( hrgnUpdate || rectUpdate )
 	{
-	    HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
-	    if (!hrgn) return TRUE;
-	    for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
-	    {
-		CombineRgn( hrgn, hrgnUpdate, 0, RGN_COPY );
-		OffsetRgn( hrgn, -wndPtr->rectClient.left,
-			         -wndPtr->rectClient.top );
-		RedrawWindow32( wndPtr->hwndSelf, NULL, hrgn, flags );
-	    }
-	    DeleteObject( hrgn );
+	   if( !(hrgn = CreateRectRgn( 0, 0, 0, 0 )) ) return TRUE;
+	   if( !hrgnUpdate )
+	     {
+	        control |= (RDW_C_DELETEHRGN | RDW_C_USEHRGN);
+ 	        if( !(hrgnUpdate = CreateRectRgnIndirect32( rectUpdate )) )
+                {
+                    DeleteObject( hrgn );
+                    return TRUE;
+                }
+	     }
+           for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
+	     if( wndPtr->dwStyle & WS_VISIBLE )
+	       {
+                 SetRectRgn( hrgn, wndPtr->rectWindow.left, wndPtr->rectWindow.top,
+                                   wndPtr->rectWindow.right, wndPtr->rectWindow.bottom);
+                 if( CombineRgn( hrgn, hrgn, hrgnUpdate, RGN_AND ) != NULLREGION )
+                 {
+		   if( control & RDW_C_USEHRGN &&
+		       wndPtr->dwStyle & WS_CLIPSIBLINGS ) 
+		       CombineRgn( hrgnUpdate, hrgnUpdate, hrgn, RGN_DIFF );
+
+                   OffsetRgn( hrgn, -wndPtr->rectClient.left,
+                                 -wndPtr->rectClient.top );
+                   PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, hrgn, flags, RDW_C_USEHRGN );
+                 }
+               }
+	   DeleteObject( hrgn );
+	   if( control & RDW_C_DELETEHRGN ) DeleteObject( hrgnUpdate );
 	}
-	else
-	{
-	    RECT32 rect;
-	    for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
-	    {
-		if (rectUpdate)
-		{
-		    rect = *rectUpdate;
-		    OffsetRect32( &rect, -wndPtr->rectClient.left,
-                                         -wndPtr->rectClient.top );
-		    RedrawWindow32( wndPtr->hwndSelf, &rect, 0, flags );
-		}
-		else RedrawWindow32( wndPtr->hwndSelf, NULL, 0, flags );
-	    }
-	}
+	else for (wndPtr = wndPtr->child; wndPtr; wndPtr = wndPtr->next)
+		  PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, flags, 0 );
+
     }
     return TRUE;
 }
 
 
 /***********************************************************************
+ *           RedrawWindow32    (USER32.425)
+ */
+BOOL32 RedrawWindow32( HWND32 hwnd, const RECT32 *rectUpdate,
+                       HRGN32 hrgnUpdate, UINT32 flags )
+{
+    WND* wnd = WIN_FindWndPtr( hwnd );
+
+    /* check if there is something to redraw */
+
+    return ( wnd && WIN_IsWindowDrawable( wnd, !(flags & RDW_FRAME) ) )
+           ? PAINT_RedrawWindow( hwnd, rectUpdate, hrgnUpdate, flags, 0 )
+	   : 1;
+}
+
+
+/***********************************************************************
  *           RedrawWindow16    (USER.290)
  */
 BOOL16 RedrawWindow16( HWND16 hwnd, const RECT16 *rectUpdate,
@@ -429,7 +470,7 @@
  */
 void InvalidateRgn( HWND32 hwnd, HRGN32 hrgn, BOOL32 erase )
 {
-    RedrawWindow32(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0));
+    RedrawWindow32(hwnd, NULL, hrgn, RDW_INVALIDATE | (erase ? RDW_ERASE : 0) );
 }
 
 
diff --git a/windows/queue.c b/windows/queue.c
index 3ae6306..b827727 100644
--- a/windows/queue.c
+++ b/windows/queue.c
@@ -84,11 +84,11 @@
 
 
 /***********************************************************************
- *	     QUEUE_GetDoomedQueue/QUEUE_SetDoomedQueue
+ *	     QUEUE_IsDoomedQueue
  */
-HQUEUE16 QUEUE_GetDoomedQueue()
+BOOL32 QUEUE_IsDoomedQueue( HQUEUE16 hQueue )
 {
-    return hDoomedQueue;
+    return (hDoomedQueue && (hQueue == hDoomedQueue));
 }
 
 
diff --git a/windows/scroll.c b/windows/scroll.c
index 7c11953..9b8d699 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -41,6 +41,8 @@
                                 (int)((clipRect)?clipRect->right:0), 
                                 (int)((clipRect)?clipRect->bottom:0));
 
+    if ( !wndScroll || !WIN_IsWindowDrawable( wndScroll, TRUE ) ) return;
+
     if ( !rect ) /* do not clip children */
        {
 	  GetClientRect16(hwnd, &rc);
@@ -87,10 +89,8 @@
                      SWP_DEFERERASE );
     }
 
-    /* RDW_ALLCHILDREN is to account for dialog controls */
-
-    RedrawWindow32( hwnd, NULL, hrgnUpdate, RDW_ALLCHILDREN |
-					    RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW);
+    PAINT_RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_ALLCHILDREN |
+			    RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW, RDW_C_USEHRGN );
 
     DeleteObject(hrgnUpdate);
     if( hCaretWnd ) ShowCaret(hCaretWnd);
@@ -250,8 +250,8 @@
 
     if (flags | SW_INVALIDATE)
     {
-	RedrawWindow32( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
-                        ((flags & SW_ERASE) ? RDW_ERASENOW : 0));
+	PAINT_RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE |
+                        ((flags & SW_ERASE) ? RDW_ERASENOW : 0), 0 );
     }
 
     ReleaseDC(hwnd, hdc);
diff --git a/windows/win.c b/windows/win.c
index 63e8564..95e7923 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -224,7 +224,11 @@
     HWND hwndRet;
     WND *pWnd = pWndDesktop;
 
-    /* Note: the desktop window never gets WM_PAINT messages */
+    /* Note: the desktop window never gets WM_PAINT messages 
+     * The real reason why is because Windows DesktopWndProc
+     * does ValidateRgn inside WM_ERASEBKGND handler.
+     */
+
     pWnd = hwnd ? WIN_FindWndPtr( hwnd ) : pWndDesktop->child;
 
     for ( ; pWnd ; pWnd = pWnd->next )
@@ -265,7 +269,7 @@
  * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless
  * the window has the WS_EX_NOPARENTNOTIFY style.
  */
-void WIN_SendParentNotify( HWND32 hwnd, WORD event, WORD idChild, LONG lValue )
+void WIN_SendParentNotify(HWND32 hwnd, WORD event, WORD idChild, LPARAM lValue)
 {
     LPPOINT16 lppt = (LPPOINT16)&lValue;
     WND     *wndPtr = WIN_FindWndPtr( hwnd );
@@ -274,10 +278,7 @@
     /* if lValue contains cursor coordinates they have to be
      * mapped to the client area of parent window */
 
-    if (bMouse) MapWindowPoints16(0, hwnd, lppt, 1);
-#ifndef WINELIB32
-    else lValue = MAKELONG( LOWORD(lValue), idChild );
-#endif
+    if (bMouse) MapWindowPoints16( 0, hwnd, lppt, 1 );
 
     while (wndPtr)
     {
@@ -291,12 +292,8 @@
         }
 
         wndPtr = wndPtr->parent;
-#ifdef WINELIB32
 	SendMessage32A( wndPtr->hwndSelf, WM_PARENTNOTIFY, 
                         MAKEWPARAM( event, idChild ), lValue );
-#else
-	SendMessage16( wndPtr->hwndSelf, WM_PARENTNOTIFY, event, (LPARAM)lValue);
-#endif
     }
 }
 
@@ -364,7 +361,6 @@
 BOOL32 WIN_CreateDesktopWindow(void)
 {
     CLASS *class;
-    HDC hdc;
     HWND hwndDesktop;
 
     dprintf_win(stddeb,"Creating desktop window\n");
@@ -415,11 +411,7 @@
     WINPROC_SetProc( &pWndDesktop->winproc, (WNDPROC16)class->winproc, 0 );
     EVENT_RegisterWindow( pWndDesktop );
     SendMessage32A( hwndDesktop, WM_NCCREATE, 0, 0 );
-    if ((hdc = GetDC( hwndDesktop )) != 0)
-    {
-        SendMessage32A( hwndDesktop, WM_ERASEBKGND, hdc, 0 );
-        ReleaseDC( hwndDesktop, hdc );
-    }
+    pWndDesktop->flags |= WIN_NEEDS_ERASEBKGND;
     return TRUE;
 }
 
@@ -705,7 +697,7 @@
                                                    wndPtr->rectClient.top ));
     } 
 
-    WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LONG)hwnd );
+    WIN_SendParentNotify( hwnd, WM_CREATE, wndPtr->wIDmenu, (LPARAM)hwnd );
     if (!IsWindow(hwnd)) return 0;
 
     /* Show the window, maximizing or minimizing if needed */
@@ -904,7 +896,7 @@
 		      SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE );
     if ((hwnd == GetCapture()) || IsChild( hwnd, GetCapture() ))
 	ReleaseCapture();
-    WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LONG)hwnd );
+    WIN_SendParentNotify( hwnd, WM_DESTROY, wndPtr->wIDmenu, (LPARAM)hwnd );
 
     CLIPBOARD_DisOwn( hwnd );
 
@@ -1543,8 +1535,29 @@
     return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
 }
 
- 
- 
+/***********************************************************************
+ *           WIN_IsWindowDrawable
+ * 
+ * hwnd is drawable when it is visible, all parents are not 
+ * minimized, and it is itself not minimized unless we are 
+ * trying to draw icon and the default class icon is set.
+ */
+BOOL32 WIN_IsWindowDrawable( WND* wnd , BOOL32 icon )
+{
+  HWND   hwnd= wnd->hwndSelf;
+  BOOL32 yes = TRUE;
+
+  while(wnd && yes)
+  { 
+    if( wnd->dwStyle & WS_MINIMIZE )
+	if( wnd->hwndSelf != hwnd ) break;
+	else if( icon && wnd->class->hIcon ) break;
+
+    yes = yes && (wnd->dwStyle & WS_VISIBLE);
+    wnd = wnd->parent; }      
+  return (!wnd && yes);
+}
+
 /*******************************************************************
  *         GetTopWindow    (USER.229)
  */
@@ -1824,8 +1837,8 @@
         }
         else
         {
-            RedrawWindow32( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
-                            RDW_UPDATENOW | RDW_FRAME );
+            PAINT_RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
+					  RDW_UPDATENOW | RDW_FRAME, 0 );
             wndPtr->flags &= ~WIN_NCACTIVATED;
         }
         return TRUE;
diff --git a/windows/winpos.c b/windows/winpos.c
index c6132bb..cfbb72e 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -16,7 +16,6 @@
 #include "hook.h"
 #include "message.h"
 #include "queue.h"
-#include "stackframe.h"
 #include "options.h"
 #include "winpos.h"
 #include "dce.h"
@@ -32,6 +31,11 @@
 #define  SWP_AGG_STATUSFLAGS \
     (SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
 
+#define SMC_NOCOPY		0x0001
+#define SMC_NOPARENTERASE	0x0002
+#define SMC_DRAWFRAME		0x0004
+#define SMC_SETXPOS		0x0008
+
 /* ----- external functions ----- */
 
 extern void 	FOCUS_SwitchFocus( HWND , HWND );
@@ -574,6 +578,7 @@
                 y  = wndPtr->ptIconPos.y;
                 cx = SYSMETRICS_CXICON;
                 cy = SYSMETRICS_CYICON;
+		swpflags |= SWP_NOCOPYBITS;
             }
             else swpflags |= SWP_NOSIZE | SWP_NOMOVE;
 	    break;
@@ -597,6 +602,7 @@
 		         swpflags |= SWP_NOSIZE | SWP_NOMOVE;
 			 break;
 			}
+		    else swpflags |= SWP_NOCOPYBITS;
 
                 cx = maxSize.x;
                 cy = maxSize.y;
@@ -650,6 +656,7 @@
                     cx = wndPtr->rectNormal.right - wndPtr->rectNormal.left;
                     cy = wndPtr->rectNormal.bottom - wndPtr->rectNormal.top;
                 }
+		swpflags |= SWP_NOCOPYBITS;
             }
             else if (wndPtr->dwStyle & WS_MAXIMIZE)
             {
@@ -1179,11 +1186,14 @@
         pWndCur = wndPtr->next;
         while (pWndCur != pWndPrevAfter)
         {
-            RECT16 rect = pWndCur->rectWindow;
-            OffsetRect16( &rect, -wndPtr->rectClient.left,
+            RECT32 rect = { pWndCur->rectWindow.left,
+			    pWndCur->rectWindow.top,
+			    pWndCur->rectWindow.right,
+			    pWndCur->rectWindow.bottom };
+            OffsetRect32( &rect, -wndPtr->rectClient.left,
                           -wndPtr->rectClient.top );
-            RedrawWindow16( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
-                            RDW_FRAME | RDW_ERASE );
+            PAINT_RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN |
+                              RDW_FRAME | RDW_ERASE, 0 );
             pWndCur = pWndCur->next;
         }
     }
@@ -1194,11 +1204,14 @@
         WIN_LinkWindow( hwnd, hwndAfter );
         while (pWndCur != wndPtr)
         {
-            RECT16 rect = wndPtr->rectWindow;
-            OffsetRect16( &rect, -pWndCur->rectClient.left,
+            RECT32 rect = { pWndCur->rectWindow.left,
+                            pWndCur->rectWindow.top,
+                            pWndCur->rectWindow.right,
+                            pWndCur->rectWindow.bottom };
+            OffsetRect32( &rect, -pWndCur->rectClient.left,
                           -pWndCur->rectClient.top );
-            RedrawWindow16( pWndCur->hwndSelf, &rect, 0, RDW_INVALIDATE |
-                            RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE );
+            PAINT_RedrawWindow( pWndCur->hwndSelf, &rect, 0, RDW_INVALIDATE |
+                              RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE, 0 );
             pWndCur = pWndCur->next;
         }
     }
@@ -1288,7 +1301,7 @@
  * update regions are in window client coordinates
  * client and window rectangles are in parent client coordinates
  */
-static void WINPOS_SizeMoveClean(WND* Wnd, HRGN oldVisRgn, LPRECT16 lpOldWndRect, LPRECT16 lpOldClientRect, BOOL bNoCopy )
+static UINT WINPOS_SizeMoveClean(WND* Wnd, HRGN oldVisRgn, LPRECT16 lpOldWndRect, LPRECT16 lpOldClientRect, UINT uFlags )
 {
  HRGN newVisRgn    = DCE_GetVisRgn(Wnd->hwndSelf, DCX_WINDOW | DCX_CLIPSIBLINGS );
  HRGN dirtyRgn     = CreateRectRgn(0,0,0,0);
@@ -1301,16 +1314,14 @@
 		   Wnd->rectClient.left,Wnd->rectClient.top,Wnd->rectClient.right,Wnd->rectClient.bottom,
 		   lpOldClientRect->left,lpOldClientRect->top,lpOldClientRect->right,lpOldClientRect->bottom);
 
+ if( (lpOldWndRect->right - lpOldWndRect->left) != (Wnd->rectWindow.right - Wnd->rectWindow.left) ||
+     (lpOldWndRect->bottom - lpOldWndRect->top) != (Wnd->rectWindow.bottom - Wnd->rectWindow.top) )
+     uFlags |= SMC_DRAWFRAME;
+
  CombineRgn( dirtyRgn, newVisRgn, 0, RGN_COPY);
 
- if( !bNoCopy )
-   {
-     HRGN hRgn = CreateRectRgn( lpOldClientRect->left - lpOldWndRect->left, lpOldClientRect->top - lpOldWndRect->top,
-				lpOldClientRect->right - lpOldWndRect->left, lpOldClientRect->bottom - lpOldWndRect->top);
-     CombineRgn( newVisRgn, newVisRgn, oldVisRgn, RGN_AND ); 
-     CombineRgn( newVisRgn, newVisRgn, hRgn, RGN_AND );
-     DeleteObject(hRgn);
-   }
+ if( !(uFlags & SMC_NOCOPY) )
+   CombineRgn( newVisRgn, newVisRgn, oldVisRgn, RGN_AND ); 
 
  /* map regions to the parent client area */
  
@@ -1331,72 +1342,78 @@
  my =  (Wnd->hrgnUpdate > 1)? CombineRgn( newVisRgn, newVisRgn, Wnd->hrgnUpdate, RGN_DIFF)
                             : COMPLEXREGION;
 
- if( bNoCopy )		/* invalidate Wnd visible region */
+ if( uFlags & SMC_NOCOPY )	/* invalidate Wnd visible region */
    {
-     if (my != NULLREGION)  RedrawWindow32( Wnd->hwndSelf, NULL, newVisRgn, RDW_INVALIDATE |
-		            RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
+     if (my != NULLREGION)  PAINT_RedrawWindow( Wnd->hwndSelf, NULL, newVisRgn, RDW_INVALIDATE |
+		            RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
    } 
  else			/* bitblt old client area */
    { 
      HDC   hDC;
      int   update;
      HRGN  updateRgn;
+     int   xfrom,yfrom,xto,yto,width,height;
 
-     /* client rect */
+     if( uFlags & SMC_DRAWFRAME )
+       {
+	 /* copy only client area, frame will be redrawn anyway */
 
-     updateRgn = CreateRectRgn( 0,0, Wnd->rectClient.right - Wnd->rectClient.left,
-				Wnd->rectClient.bottom - Wnd->rectClient.top );
+         xfrom = lpOldClientRect->left; yfrom = lpOldClientRect->top;
+         xto = Wnd->rectClient.left; yto = Wnd->rectClient.top;
+         width = lpOldClientRect->right - xfrom; height = lpOldClientRect->bottom - yfrom;
+	 updateRgn = CreateRectRgn( 0, 0, width, height );
+	 CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND );
+	 SetRectRgn( updateRgn, 0, 0, Wnd->rectClient.right - xto, Wnd->rectClient.bottom - yto );
+       }
+     else
+       {
+         xfrom = lpOldWndRect->left; yfrom = lpOldWndRect->top;
+         xto = Wnd->rectWindow.left; yto = Wnd->rectWindow.top;
+         width = lpOldWndRect->right - xfrom; height = lpOldWndRect->bottom - yfrom;
+	 updateRgn = CreateRectRgn( xto - Wnd->rectClient.left,
+				    yto - Wnd->rectClient.top,
+				    Wnd->rectWindow.right - Wnd->rectClient.left,
+				    Wnd->rectWindow.bottom - Wnd->rectClient.top );
+       }
 
-     /* clip visible region with client rect */
+     CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND );
 
-     my = CombineRgn( newVisRgn, newVisRgn, updateRgn, RGN_AND );
-
-     /* substract result from client rect to get region that won't be copied */
+     /* substract new visRgn from target rect to get a region that won't be copied */
 
      update = CombineRgn( updateRgn, updateRgn, newVisRgn, RGN_DIFF );
 
      /* Blt valid bits using parent window DC */
 
-     if( my != NULLREGION )
+     if( my != NULLREGION && (xfrom != xto || yfrom != yto) )
        {
-	 int xfrom = lpOldClientRect->left;
-	 int yfrom = lpOldClientRect->top;
-	 int xto = Wnd->rectClient.left;
-	 int yto = Wnd->rectClient.top;
+	 
+	 /* compute clipping region in parent client coordinates */
 
-	 /* check if we can skip copying */
+	 OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top);
+	 CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
 
-	 if( xfrom != xto || yfrom != yto )
-	   {
-	     /* compute clipping region in parent client coordinates */
+         hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS);
 
-	     OffsetRgn( newVisRgn, Wnd->rectClient.left, Wnd->rectClient.top);
-	     CombineRgn( oldVisRgn, oldVisRgn, newVisRgn, RGN_OR );
-
-             hDC = GetDCEx( Wnd->parent->hwndSelf, oldVisRgn, DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CACHE | DCX_CLIPSIBLINGS);
-
-             BitBlt(hDC, xto, yto, lpOldClientRect->right - lpOldClientRect->left, 
-				   lpOldClientRect->bottom - lpOldClientRect->top,
-				   hDC, xfrom, yfrom, SRCCOPY );
+         BitBlt( hDC, xto, yto, width, height, hDC, xfrom, yfrom, SRCCOPY );
     
-             ReleaseDC( Wnd->parent->hwndSelf, hDC); 
-	  }
+	 ReleaseDC( Wnd->parent->hwndSelf, hDC); 
        }
 
      if( update != NULLREGION )
-         RedrawWindow32( Wnd->hwndSelf, NULL, updateRgn, RDW_INVALIDATE |
-                         RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE );
+         PAINT_RedrawWindow( Wnd->hwndSelf, NULL, updateRgn, RDW_INVALIDATE |
+                         RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
+     else if( uFlags & SMC_DRAWFRAME ) Wnd->flags |= WIN_NEEDS_NCPAINT;
      DeleteObject( updateRgn );
    }
 
  /* erase uncovered areas */
 
- if( other != NULLREGION )
-     RedrawWindow32( Wnd->parent->hwndSelf, NULL, dirtyRgn,
-                     RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
-
+ if( !(uFlags & SMC_NOPARENTERASE) && (other != NULLREGION ) )
+      PAINT_RedrawWindow( Wnd->parent->hwndSelf, NULL, dirtyRgn,
+                        RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE, RDW_C_USEHRGN );
  DeleteObject(dirtyRgn);
  DeleteObject(newVisRgn);
+ return uFlags;
 }
 
 
@@ -1510,11 +1527,13 @@
 BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y,
 		   INT cx, INT cy, WORD flags )
 {
-    WINDOWPOS16 winpos;
+    WINDOWPOS16 *winpos;
     WND *	wndPtr;
-    RECT16 	newWindowRect, newClientRect;
+    RECT16 	newWindowRect, newClientRect, oldWindowRect;
     HRGN	visRgn = 0;
+    HWND	tempInsertAfter= 0;
     int 	result = 0;
+    UINT 	uFlags = 0;
 
     dprintf_win(stddeb,"SetWindowPos: hwnd %04x, (%i,%i)-(%i,%i) flags %08x\n", 
 						 hwnd, x, y, x+cx, y+cy, flags);  
@@ -1526,15 +1545,16 @@
     if (wndPtr->dwStyle & WS_VISIBLE) flags &= ~SWP_SHOWWINDOW;
     else
     {
+	uFlags |= SMC_NOPARENTERASE; 
 	flags &= ~SWP_HIDEWINDOW;
 	if (!(flags & SWP_SHOWWINDOW)) flags |= SWP_NOREDRAW;
     }
 
 /*     Check for windows that may not be resized 
        FIXME: this should be done only for Windows 3.0 programs 
- */    if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) )
+       if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW ) )
            flags |= SWP_NOSIZE | SWP_NOMOVE;
-
+*/
       /* Check dimensions */
 
     if (cx <= 0) cx = 1;
@@ -1578,45 +1598,48 @@
 
       /* Fill the WINDOWPOS structure */
 
-    winpos.hwnd = hwnd;
-    winpos.hwndInsertAfter = hwndInsertAfter;
-    winpos.x = x;
-    winpos.y = y;
-    winpos.cx = cx;
-    winpos.cy = cy;
-    winpos.flags = flags;
+    if (!(winpos = SEGPTR_NEW(WINDOWPOS16))) return FALSE;
+    winpos->hwnd = hwnd;
+    winpos->hwndInsertAfter = hwndInsertAfter;
+    winpos->x = x;
+    winpos->y = y;
+    winpos->cx = cx;
+    winpos->cy = cy;
+    winpos->flags = flags;
     
       /* Send WM_WINDOWPOSCHANGING message */
 
     if (!(flags & SWP_NOSENDCHANGING))
-	SendMessage16( hwnd, WM_WINDOWPOSCHANGING, 0, (LPARAM)MAKE_SEGPTR(&winpos) );
+	SendMessage16( hwnd, WM_WINDOWPOSCHANGING, 0,
+                       (LPARAM)SEGPTR_GET(winpos) );
 
       /* Calculate new position and size */
 
     newWindowRect = wndPtr->rectWindow;
-    newClientRect = wndPtr->rectClient;
+    newClientRect = (wndPtr->dwStyle & WS_MINIMIZE) ? wndPtr->rectWindow
+						    : wndPtr->rectClient;
 
-    if (!(winpos.flags & SWP_NOSIZE))
+    if (!(winpos->flags & SWP_NOSIZE))
     {
-        newWindowRect.right  = newWindowRect.left + winpos.cx;
-        newWindowRect.bottom = newWindowRect.top + winpos.cy;
+        newWindowRect.right  = newWindowRect.left + winpos->cx;
+        newWindowRect.bottom = newWindowRect.top + winpos->cy;
     }
-    if (!(winpos.flags & SWP_NOMOVE))
+    if (!(winpos->flags & SWP_NOMOVE))
     {
-        newWindowRect.left    = winpos.x;
-        newWindowRect.top     = winpos.y;
-        newWindowRect.right  += winpos.x - wndPtr->rectWindow.left;
-        newWindowRect.bottom += winpos.y - wndPtr->rectWindow.top;
+        newWindowRect.left    = winpos->x;
+        newWindowRect.top     = winpos->y;
+        newWindowRect.right  += winpos->x - wndPtr->rectWindow.left;
+        newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top;
 
-	OffsetRect16( &newClientRect, winpos.x - wndPtr->rectWindow.left, 
-                                      winpos.y - wndPtr->rectWindow.top );
+	OffsetRect16( &newClientRect, winpos->x - wndPtr->rectWindow.left, 
+                                      winpos->y - wndPtr->rectWindow.top );
     }
 
-    winpos.flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
+    winpos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
 
       /* Reposition window in Z order */
 
-    if (!(winpos.flags & SWP_NOZORDER))
+    if (!(winpos->flags & SWP_NOZORDER))
     {
 	/* reorder owned popups if hwnd is top-level window 
          */
@@ -1626,10 +1649,10 @@
 
         if (wndPtr->window)
         {
-            WIN_UnlinkWindow( winpos.hwnd );
-            WIN_LinkWindow( winpos.hwnd, hwndInsertAfter );
+            WIN_UnlinkWindow( winpos->hwnd );
+            WIN_LinkWindow( winpos->hwnd, hwndInsertAfter );
         }
-        else WINPOS_MoveWindowZOrder( winpos.hwnd, hwndInsertAfter );
+        else WINPOS_MoveWindowZOrder( winpos->hwnd, hwndInsertAfter );
     }
 
     if ( !wndPtr->window && !(flags & SWP_NOREDRAW) && 
@@ -1640,26 +1663,26 @@
       /* Send WM_NCCALCSIZE message to get new client area */
     if( (flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
       {
-         result = WINPOS_SendNCCalcSize( winpos.hwnd, TRUE, &newWindowRect,
+         result = WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
 				    &wndPtr->rectWindow, &wndPtr->rectClient,
-				    MAKE_SEGPTR(&winpos), &newClientRect );
+				    SEGPTR_GET(winpos), &newClientRect );
 
          /* FIXME: WVR_ALIGNxxx */
 
          if( newClientRect.left != wndPtr->rectClient.left ||
              newClientRect.top != wndPtr->rectClient.top )
-             winpos.flags &= ~SWP_NOCLIENTMOVE;
+             winpos->flags &= ~SWP_NOCLIENTMOVE;
 
          if( (newClientRect.right - newClientRect.left !=
              wndPtr->rectClient.right - wndPtr->rectClient.left) ||
   	    (newClientRect.bottom - newClientRect.top !=
 	     wndPtr->rectClient.bottom - wndPtr->rectClient.top) )
-	     winpos.flags &= ~SWP_NOCLIENTSIZE;
+	     winpos->flags &= ~SWP_NOCLIENTSIZE;
       }
     else
       if( !(flags & SWP_NOMOVE) && (newClientRect.left != wndPtr->rectClient.left ||
 				    newClientRect.top != wndPtr->rectClient.top) )
-	    winpos.flags &= ~SWP_NOCLIENTMOVE;
+	    winpos->flags &= ~SWP_NOCLIENTMOVE;
 
     /* Update active DCEs */
 
@@ -1673,33 +1696,40 @@
         DCE_InvalidateDCE(wndPtr->parent, &rect);
       }
 
-    /* Perform the moving and resizing */
+    /* change geometry */
+
+    oldWindowRect = wndPtr->rectWindow;
 
     if (wndPtr->window)
     {
-        RECT16 oldWindowRect = wndPtr->rectWindow;
         RECT16 oldClientRect = wndPtr->rectClient;
 
-        HWND bogusInsertAfter = winpos.hwndInsertAfter;
+        tempInsertAfter = winpos->hwndInsertAfter;
 
-        winpos.hwndInsertAfter = hwndInsertAfter;
-        WINPOS_SetXWindowPos( &winpos );
+        winpos->hwndInsertAfter = hwndInsertAfter;
+
+	/* postpone geometry change */
+
+	if( !(flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) )
+	  {
+              WINPOS_SetXWindowPos( winpos );
+	      winpos->hwndInsertAfter = tempInsertAfter;
+	  }
+	else  uFlags |= SMC_SETXPOS;
 
         wndPtr->rectWindow = newWindowRect;
         wndPtr->rectClient = newClientRect;
-        winpos.hwndInsertAfter = bogusInsertAfter;
 
-	/*  FIXME: should do something like WINPOS_SizeMoveClean */
+	if( !(flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW)) )
+	  if( (oldClientRect.left - oldWindowRect.left !=
+	       newClientRect.left - newWindowRect.left) ||
+	      (oldClientRect.top - oldWindowRect.top !=
+	       newClientRect.top - newWindowRect.top) || winpos->flags & SWP_NOCOPYBITS )
 
-	if( (oldClientRect.left - oldWindowRect.left !=
-	     newClientRect.left - newWindowRect.left) ||
-	    (oldClientRect.top - oldWindowRect.top !=
-	     newClientRect.top - newWindowRect.top) )
-
-	    RedrawWindow32( wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE |
-                            RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE );
-	else
-	    if( winpos.flags & SWP_FRAMECHANGED )
+	      PAINT_RedrawWindow( wndPtr->hwndSelf, NULL, 0, RDW_INVALIDATE |
+                              RDW_ALLCHILDREN | RDW_FRAME | RDW_ERASE, 0 );
+	  else
+	      if( winpos->flags & SWP_FRAMECHANGED )
 	      {
 		WORD wErase = 0;
 		RECT32 rect;
@@ -1709,8 +1739,8 @@
 		    rect.left = newClientRect.right; rect.top = newClientRect.top;
 		    rect.right = oldClientRect.right; rect.bottom = newClientRect.bottom;
 		    wErase = 1;
-		    RedrawWindow32( wndPtr->hwndSelf, &rect, 0,
-                                RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN );
+		    PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0,
+                                      RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN, 0 );
                 }
 		if( oldClientRect.bottom > newClientRect.bottom )
                 {
@@ -1718,33 +1748,41 @@
 		    rect.right = (wErase)?oldClientRect.right:newClientRect.right;
 		    rect.bottom = oldClientRect.bottom;
 		    wErase = 1;
-		    RedrawWindow32( wndPtr->hwndSelf, &rect, 0,
-                                RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN );
+		    PAINT_RedrawWindow( wndPtr->hwndSelf, &rect, 0,
+                                      RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN, 0 );
                 }
 		if( !wErase ) wndPtr->flags |= WIN_NEEDS_NCPAINT;
 	      }
     }
     else
     {
-        RECT16 oldWindowRect = wndPtr->rectWindow;
 	RECT16 oldClientRect = wndPtr->rectClient;
 
         wndPtr->rectWindow = newWindowRect;
         wndPtr->rectClient = newClientRect;
 
-        if( !(flags & SWP_NOREDRAW) )
+	if( oldClientRect.bottom - oldClientRect.top ==
+	    newClientRect.bottom - newClientRect.top ) result &= ~WVR_VREDRAW;
+
+	if( oldClientRect.right - oldClientRect.left ==
+	    newClientRect.right - newClientRect.left ) result &= ~WVR_HREDRAW;
+
+        if( !(flags & (SWP_NOREDRAW | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) )
 	  {
-	    BOOL bNoCopy = (flags & SWP_NOCOPYBITS) || 
-			   (result >= WVR_HREDRAW && result < WVR_VALIDRECTS);
+	    uFlags |=  ((winpos->flags & SWP_NOCOPYBITS) || 
+			(result >= WVR_HREDRAW && result < WVR_VALIDRECTS)) ? SMC_NOCOPY : 0;
+	    uFlags |=  (winpos->flags & SWP_FRAMECHANGED) ? SMC_DRAWFRAME : 0;
 
-	    if( (winpos.flags & SWP_AGG_NOGEOMETRYCHANGE) != SWP_AGG_NOGEOMETRYCHANGE )
-	        /* optimize cleanup by BitBlt'ing where possible */
-
-	        WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect, &oldClientRect, bNoCopy);
+	    if( (winpos->flags & SWP_AGG_NOGEOMETRYCHANGE) != SWP_AGG_NOGEOMETRYCHANGE )
+		uFlags = WINPOS_SizeMoveClean(wndPtr, visRgn, &oldWindowRect, 
+							      &oldClientRect, uFlags);
 	    else
-	       if( winpos.flags & SWP_FRAMECHANGED )
-        	  RedrawWindow32( winpos.hwnd, NULL, 0, RDW_NOCHILDREN | RDW_FRAME ); 
+	      { 
+		/* adjust frame and do not erase parent */
 
+		if( winpos->flags & SWP_FRAMECHANGED ) wndPtr->flags |= WIN_NEEDS_NCPAINT;
+		if( winpos->flags & SWP_NOZORDER ) uFlags |= SMC_NOPARENTERASE;
+	      }
 	  }
         DeleteObject(visRgn);
     }
@@ -1754,14 +1792,19 @@
 	wndPtr->dwStyle |= WS_VISIBLE;
         if (wndPtr->window)
         {
+	    if( uFlags & SMC_SETXPOS )
+	    {
+              WINPOS_SetXWindowPos( winpos );
+              winpos->hwndInsertAfter = tempInsertAfter;
+	    }
             XMapWindow( display, wndPtr->window );
         }
         else
         {
             if (!(flags & SWP_NOREDRAW))
-                RedrawWindow32( winpos.hwnd, NULL, 0,
+                PAINT_RedrawWindow( winpos->hwnd, NULL, 0,
                                 RDW_INVALIDATE | RDW_ALLCHILDREN |
-                                RDW_FRAME | RDW_ERASE );
+                                RDW_FRAME | RDW_ERASENOW | RDW_ERASE, 0 );
         }
     }
     else if (flags & SWP_HIDEWINDOW)
@@ -1770,25 +1813,35 @@
         if (wndPtr->window)
         {
             XUnmapWindow( display, wndPtr->window );
+	    if( uFlags & SMC_SETXPOS )
+	    {
+              WINPOS_SetXWindowPos( winpos );
+              winpos->hwndInsertAfter = tempInsertAfter;
+	    }
         }
         else
         {
             if (!(flags & SWP_NOREDRAW))
-                RedrawWindow16( wndPtr->parent->hwndSelf, &wndPtr->rectWindow, 0,
-                                RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE );
+	    {
+	        RECT32 rect = { oldWindowRect.left, oldWindowRect.top,
+				oldWindowRect.right, oldWindowRect.bottom };
+                PAINT_RedrawWindow( wndPtr->parent->hwndSelf, &rect, 0, 
+			RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASE | RDW_ERASENOW, 0);
+	    }
+	    uFlags |= SMC_NOPARENTERASE;
         }
 
-        if ((winpos.hwnd == GetFocus()) || IsChild(winpos.hwnd, GetFocus()))
-            SetFocus( GetParent(winpos.hwnd) );  /* Revert focus to parent */
+        if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus()))
+            SetFocus( GetParent(winpos->hwnd) );  /* Revert focus to parent */
 
-	if (winpos.hwnd == hwndActive)
+	if (winpos->hwnd == hwndActive)
 	{
 	      /* Activate previously active window if possible */
 	    HWND newActive = hwndPrevActive;
-	    if (!IsWindow(newActive) || (newActive == winpos.hwnd))
+	    if (!IsWindow(newActive) || (newActive == winpos->hwnd))
 	    {
 		newActive = GetTopWindow( GetDesktopWindow() );
-		if (newActive == winpos.hwnd)
+		if (newActive == winpos->hwnd)
                     newActive = wndPtr->next ? wndPtr->next->hwndSelf : 0;
 	    }	    
 	    WINPOS_ChangeActiveWindow( newActive, FALSE );
@@ -1798,7 +1851,7 @@
       /* Activate the window */
 
     if (!(flags & SWP_NOACTIVATE))
-	    WINPOS_ChangeActiveWindow( winpos.hwnd, FALSE );
+	    WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
     
       /* Repaint the window */
 
@@ -1806,19 +1859,21 @@
 
     EVENT_DummyMotionNotify(); /* Simulate a mouse event to set the cursor */
 
-    if (!(flags & SWP_DEFERERASE))
-        RedrawWindow32( wndPtr->parent->hwndSelf, NULL, 0,
-                        RDW_ALLCHILDREN | RDW_ERASENOW );
+    if (!(flags & SWP_DEFERERASE) && !(uFlags & SMC_NOPARENTERASE) )
+        PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW, 0 );
+    else if( wndPtr->parent == WIN_GetDesktop() && wndPtr->parent->flags & WIN_NEEDS_ERASEBKGND )
+	PAINT_RedrawWindow( wndPtr->parent->hwndSelf, NULL, 0, RDW_NOCHILDREN | RDW_ERASENOW, 0 );
 
       /* And last, send the WM_WINDOWPOSCHANGED message */
 
-    dprintf_win(stddeb,"\tstatus flags = %04x\n", winpos.flags & SWP_AGG_STATUSFLAGS);
+    dprintf_win(stddeb,"\tstatus flags = %04x\n", winpos->flags & SWP_AGG_STATUSFLAGS);
 
-    if ( ((winpos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) && 
-	!(winpos.flags & SWP_NOSENDCHANGING))
-        SendMessage16( winpos.hwnd, WM_WINDOWPOSCHANGED,
-                       0, (LPARAM)MAKE_SEGPTR(&winpos) );
+    if ( ((winpos->flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE) && 
+	!(winpos->flags & SWP_NOSENDCHANGING))
+        SendMessage16( winpos->hwnd, WM_WINDOWPOSCHANGED,
+                       0, (LPARAM)SEGPTR_GET(winpos) );
 
+    SEGPTR_FREE(winpos);
     return TRUE;
 }
 
diff --git a/windows/winproc.c b/windows/winproc.c
index 79f99c4..d1c89d7 100644
--- a/windows/winproc.c
+++ b/windows/winproc.c
@@ -679,10 +679,6 @@
             *pwparam32 = MAKEWPARAM( wParam16, HIWORD(*plparam) );
             *plparam   = (LPARAM)(HWND32)LOWORD(*plparam);
         }
-        else
-        {
-            *pwparam32 = MAKEWPARAM( wParam16, 0  /* FIXME? */ );
-        }
         return 0;
     case WM_SETTEXT:
         *plparam = (LPARAM)PTR_SEG_TO_LIN(*plparam);
diff --git a/wine.ini b/wine.ini
index 28ffd4d..b121e27 100644
--- a/wine.ini
+++ b/wine.ini
@@ -3,10 +3,11 @@
 ;;
 ;; Each section has the following format:
 ;; [Drive X]
-;; Path=xxx    (Unix path for drive root)
-;; Type=xxx    (supported types are 'floppy', 'hd', 'cdrom' and 'network')
-;; Label=xxx   (drive label, at most 11 characters)
-;; Serial=xxx  (serial number, 8 characters hexadecimal number)
+;; Path=xxx       (Unix path for drive root)
+;; Type=xxx       (supported types are 'floppy', 'hd', 'cdrom' and 'network')
+;; Label=xxx      (drive label, at most 11 characters)
+;; Serial=xxx     (serial number, 8 characters hexadecimal number)
+;; Filesystem=xxx (supported types are 'msdos','win95','unix')
 ;;
 [Drive A]
 Path=/mnt/fd0
@@ -18,6 +19,7 @@
 Path=/c
 Type=hd
 Label=MS-DOS
+Filesystem=msdos
 
 [Drive D]
 Path=/cdrom
diff --git a/wine.man b/wine.man
index 9220dc0..d4c66bf 100644
--- a/wine.man
+++ b/wine.man
@@ -205,6 +205,14 @@
 Used to specify the drive serial number, as an 8-character hexadecimal
 number.
 .PP
+.I format: Filesystem = <fstype>
+.br
+default: unix
+.br
+Used to specify the type of the filesystem on which the drive resides;
+supported types are msdos (or fat), win95 (or vfat), unix. If the
+drive spans several different filesystems, say unix.
+.PP
 .B [wine]
 .br
 .I format: windows = <directory>