Release 940714

Thu Jul 14 17:50:45 1994  Bob Amstadt  (bob@pooh)

	* [Configure]
	Autodetects Linux version (if running Linux).

	* [loader/signal.c]
	New signals for Linux.

	* [loader/ldtlib.c]
	New structure field in sys call.

Sun Jul 10 19:31:34 1994  Olaf Flebbe  (olaf@dragon)

        * [load/resource.c] 
          fixed Memory (Resource) Leak.

        * [load/main.c] 
          fixed a printf.

Tue Jul 12 18:50:34 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)

	* [controls/desktop.c]
	Implemented desktop wallpaper (only 16 colors for now).

	* [controls/menu.c] [windows/nonclient.c]
	Preliminary work to allow multi-line menus.

	* [misc/main.c]
	No backing store on desktop window (not useful).

	* [objects/text.c]
	A few fixes to DrawText() to make underlines under mnemonic
	letters to look better.

	* [windows/graphics.c]
	More fixes to GRAPH_DrawArc(), and some fixes to Polygon().
	Implemented PolyPolygon() (partially working).

	* [windows/winpos.c]
	New function WINPOS_SendNCCalcSize().
	Cleaned up SetWindowPos() and added preliminary support for
	multi-line menus.

Mon Jul 11 19:15:51 1994  Miguel de Icaza  (miguel@sphinx)

	* [controls/edit.c]
	Changes to work as a library.

	* [if1632/callback.c] 
	Ifdefed module.

	* [if1632/relay.c]
	Changes to allow linking with WineLib.

	* [include/windows.h]
	Added macro WINELIB_UNIMP

	* [loader/library.c]
	When compiling WineLib, GetProcAddress is not implemented yet.

	* [loader/main.c]
	Added empty InitDLL when using WineLib.

	* [loader/ne_image.c]
	Some parts of the loader are needed for WineLib, ifdefed correctly

	* [misc/{audio.c,mcicda.c,mmaux.c,mmsystem.c]
	Disable compilation of module when compiling WineLib.

	* [toolkit/heap.c]
	Fixed small bug.  When passed an invalid handle WineLib would
	crash, now return NULL.

	* [toolkit/winmain.c]
	Call CreateNewTask in _WinMain.

Sun Jul 10 09:08:02 1994  David Metcalfe <david@prism.demon.co.uk>

	* [controls/edit.c] [controls/widget.c]
	More changes to improve compatibility with Windows' edit
	control.  Finished off tab stop support.

Mon Jul 11 21:05:02 MET DST 1994  Erik Bos <erik@hacktic.nl>

	* [if1632/relay.c]
	# of ordinals in shell.dll changed to 103.

	* [loader/signal.c]
	sti, cli will now be ignored.

	* [objects/brush.c]
	Added stub for GetSysColorBrush().
diff --git a/BUGS b/BUGS
index f006749..b05477e 100644
--- a/BUGS
+++ b/BUGS
@@ -4,3 +4,5 @@
 - MDI does not send WM_GETMINMAX message.
 - InitializeLoadedDLLs() can't init LZEXPAND.DLL. (cs:ip => 0:0)
 - LoadCursor does not correctly handle bitmap cursors
+- AllocCSToDSAlias() shouldn't alloc alias for the same segment multiple times.
+- Dialogs don't support resources which are referred to as integers.
diff --git a/ChangeLog b/ChangeLog
index adcba41..96b0bbb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,98 @@
 ----------------------------------------------------------------------
+Thu Jul 14 17:50:45 1994  Bob Amstadt  (bob@pooh)
+
+	* [Configure]
+	Autodetects Linux version (if running Linux).
+
+	* [loader/signal.c]
+	New signals for Linux.
+
+	* [loader/ldtlib.c]
+	New structure field in sys call.
+
+Sun Jul 10 19:31:34 1994  Olaf Flebbe  (olaf@dragon)
+
+        * [load/resource.c] 
+          fixed Memory (Resource) Leak.
+
+        * [load/main.c] 
+          fixed a printf.
+
+Tue Jul 12 18:50:34 1994  Alexandre Julliard  (julliard@lamisun.epfl.ch)
+
+	* [controls/desktop.c]
+	Implemented desktop wallpaper (only 16 colors for now).
+
+	* [controls/menu.c] [windows/nonclient.c]
+	Preliminary work to allow multi-line menus.
+
+	* [misc/main.c]
+	No backing store on desktop window (not useful).
+
+	* [objects/text.c]
+	A few fixes to DrawText() to make underlines under mnemonic
+	letters to look better.
+
+	* [windows/graphics.c]
+	More fixes to GRAPH_DrawArc(), and some fixes to Polygon().
+	Implemented PolyPolygon() (partially working).
+
+	* [windows/winpos.c]
+	New function WINPOS_SendNCCalcSize().
+	Cleaned up SetWindowPos() and added preliminary support for
+	multi-line menus.
+
+Mon Jul 11 19:15:51 1994  Miguel de Icaza  (miguel@sphinx)
+
+	* [controls/edit.c]
+	Changes to work as a library.
+
+	* [if1632/callback.c] 
+	Ifdefed module.
+
+	* [if1632/relay.c]
+	Changes to allow linking with WineLib.
+
+	* [include/windows.h]
+	Added macro WINELIB_UNIMP
+
+	* [loader/library.c]
+	When compiling WineLib, GetProcAddress is not implemented yet.
+
+	* [loader/main.c]
+	Added empty InitDLL when using WineLib.
+
+	* [loader/ne_image.c]
+	Some parts of the loader are needed for WineLib, ifdefed correctly
+
+	* [misc/{audio.c,mcicda.c,mmaux.c,mmsystem.c]
+	Disable compilation of module when compiling WineLib.
+
+	* [toolkit/heap.c]
+	Fixed small bug.  When passed an invalid handle WineLib would
+	crash, now return NULL.
+
+	* [toolkit/winmain.c]
+	Call CreateNewTask in _WinMain.
+
+Sun Jul 10 09:08:02 1994  David Metcalfe <david@prism.demon.co.uk>
+
+	* [controls/edit.c] [controls/widget.c]
+	More changes to improve compatibility with Windows' edit
+	control.  Finished off tab stop support.
+
+Mon Jul 11 21:05:02 MET DST 1994  Erik Bos <erik@hacktic.nl>
+
+	* [if1632/relay.c]
+	# of ordinals in shell.dll changed to 103.
+
+	* [loader/signal.c]
+	sti, cli will now be ignored.
+
+	* [objects/brush.c]
+	Added stub for GetSysColorBrush().
+
+----------------------------------------------------------------------
 Sun, 3 Jul 1994 20:15:56 +0100 (BST)  David Metcalfe <david@prism.demon.co.uk>
 
 	* [controls/edit.c]
diff --git a/Configure b/Configure
index 15c7c31..1cb4d5c 100644
--- a/Configure
+++ b/Configure
@@ -47,11 +47,25 @@
     NEWBUILD=''
 fi
 
+if [ -f /usr/include/linux/ldt.h ]
+then
+	if grep -q seg_not_present /usr/include/linux/ldt.h
+	then
+		NEWLINUXLDT='#define NewLinuxLdt -DNEW_LDT_STRUCT'
+		ALLDEFINES="$ALLDEFINES -DNEW_LDT_STRUCT"
+	else
+		NEWLINUXLDT=''
+	fi
+else
+	NEWLINUXLDT=''
+fi
+
 echo '/* autoconf.h generated automatically.  Run Configure. */' > autoconf.h
 echo $WINELIB >> autoconf.h
 echo $SHORTNAMES >> autoconf.h
 echo $NEWBUILD >> autoconf.h
 echo $WINE_INI_GLOBAL >> autoconf.h
+echo $NEWLINUXLDT >> autoconf.h
 echo "#define AutoDefines  $ALLDEFINES" >> autoconf.h
 
 xmkmf -a
diff --git a/controls/desktop.c b/controls/desktop.c
index 183b2a2..e1f5d7f 100644
--- a/controls/desktop.c
+++ b/controls/desktop.c
@@ -6,10 +6,56 @@
 
 static char Copyright[] = "Copyright  Alexandre Julliard, 1994";
 
+#include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
 #include "win.h"
 #include "desktop.h"
+#include "prototypes.h"
+
+
+/***********************************************************************
+ *           DESKTOP_LoadBitmap
+ *
+ * Load a bitmap from a file. Used by SetDeskWallPaper().
+ */
+static HBITMAP DESKTOP_LoadBitmap( HDC hdc, char *filename )
+{
+    BITMAPFILEHEADER *fileHeader;
+    BITMAPINFO *bitmapInfo;
+    HBITMAP hbitmap;
+    char *unixFileName, *buffer;
+    int file;
+    long size;
+
+      /* Read all the file into memory */
+
+    if (!(unixFileName = GetUnixFileName( filename ))) return 0;
+    if ((file = open( unixFileName, O_RDONLY )) == -1) return 0;
+    size = lseek( file, 0, SEEK_END );
+    if (!(buffer = (char *)malloc( size )))
+    {
+	close( file );
+	return 0;
+    }
+    lseek( file, 0, SEEK_SET );
+    size = read( file, buffer, size );
+    close( file );
+    fileHeader = (BITMAPFILEHEADER *)buffer;
+    bitmapInfo = (BITMAPINFO *)(buffer + sizeof(BITMAPFILEHEADER));
+    
+      /* Check header content */
+    if ((fileHeader->bfType != 0x4d42) || (size < fileHeader->bfSize))
+    {
+	free( buffer );
+	return 0;
+    }
+    hbitmap = CreateDIBitmap( hdc, &bitmapInfo->bmiHeader, CBM_INIT,
+			      buffer + fileHeader->bfOffBits,
+			      bitmapInfo, DIB_RGB_COLORS );
+    free( buffer );
+    return hbitmap;
+}
 
 
 /***********************************************************************
@@ -20,12 +66,49 @@
 static LONG DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, DESKTOPINFO *infoPtr )
 {
     RECT rect;
-
-      /* Set colors in case pattern is a monochrome bitmap */
-    SetBkColor( hdc, RGB(0,0,0) );
-    SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
     GetClientRect( hwnd, &rect );    
-    FillRect( hdc, &rect, infoPtr->hbrushPattern );
+
+    /* Paint desktop pattern (only if wall paper does not cover everything) */
+
+    if (!infoPtr->hbitmapWallPaper || 
+	(!infoPtr->fTileWallPaper && (infoPtr->bitmapSize.cx < rect.right) &&
+	 (infoPtr->bitmapSize.cy < rect.bottom)))
+    {
+	  /* Set colors in case pattern is a monochrome bitmap */
+	SetBkColor( hdc, RGB(0,0,0) );
+	SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) );
+	FillRect( hdc, &rect, infoPtr->hbrushPattern );
+    }
+
+      /* Paint wall paper */
+
+    if (infoPtr->hbitmapWallPaper)
+    {
+	int x, y;
+	HDC hdcmem;
+
+	hdcmem = CreateCompatibleDC( hdc );
+	SelectObject( hdcmem, infoPtr->hbitmapWallPaper );
+	if (infoPtr->fTileWallPaper)
+	{
+	    for (y = 0; y < rect.bottom; y += infoPtr->bitmapSize.cy)
+		for (x = 0; x < rect.right; x += infoPtr->bitmapSize.cx)
+		    BitBlt( hdc, x, y,
+			    infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy,
+			    hdcmem, 0, 0, SRCCOPY );
+	}
+	else
+	{
+	    x = (rect.left + rect.right - infoPtr->bitmapSize.cx) / 2;
+	    y = (rect.top + rect.bottom - infoPtr->bitmapSize.cy) / 2;
+	    if (x < 0) x = 0;
+	    if (y < 0) y = 0;
+	    BitBlt( hdc, x, y, infoPtr->bitmapSize.cx, infoPtr->bitmapSize.cy,
+		    hdcmem, 0, 0, SRCCOPY );
+	}
+	DeleteDC( hdcmem );
+    }
+
     return 1;
 }
 
@@ -50,6 +133,7 @@
 	infoPtr->hbrushPattern = 0;
 	infoPtr->hbitmapWallPaper = 0;
 	SetDeskPattern();
+	SetDeskWallPaper( (LPSTR)-1 );
 	break;
 	
     case WM_ERASEBKGND:
@@ -77,6 +161,30 @@
  */
 BOOL SetDeskWallPaper( LPSTR filename )
 {
+    HBITMAP hbitmap;
+    HDC hdc;
+    char buffer[256];
+    WND *wndPtr = WIN_FindWndPtr( GetDesktopWindow() );
+    DESKTOPINFO *infoPtr = (DESKTOPINFO *)wndPtr->wExtra;
+
+    if (filename == (LPSTR)-1)
+    {
+	GetProfileString( "desktop", "WallPaper", "(None)", buffer, 256 );
+	filename = buffer;
+    }
+    hdc = GetDC( 0 );
+    hbitmap = DESKTOP_LoadBitmap( hdc, filename );
+    ReleaseDC( 0, hdc );
+    if (infoPtr->hbitmapWallPaper) DeleteObject( infoPtr->hbitmapWallPaper );
+    infoPtr->hbitmapWallPaper = hbitmap;
+    infoPtr->fTileWallPaper = GetProfileInt( "desktop", "TileWallPaper", 0 );
+    if (hbitmap)
+    {
+	BITMAP bmp;
+	GetObject( hbitmap, sizeof(bmp), (LPSTR)&bmp );
+	infoPtr->bitmapSize.cx = (bmp.bmWidth != 0) ? bmp.bmWidth : 1;
+	infoPtr->bitmapSize.cy = (bmp.bmHeight != 0) ? bmp.bmHeight : 1;
+    }
     return TRUE;
 }
 
diff --git a/controls/edit.c b/controls/edit.c
index 2a1c12c..9779230 100644
--- a/controls/edit.c
+++ b/controls/edit.c
@@ -3,7 +3,7 @@
  *
  * Copyright  David W. Metcalfe, 1994
  *
- * Release 2, June 1994
+ * Release 3, July 1994
  */
 
 static char Copyright[] = "Copyright  David W. Metcalfe, 1994";
@@ -17,13 +17,19 @@
 #include "user.h"
 #include "scroll.h"
 
+#define EDIT_HEAP_ALLOC(size)          USER_HEAP_ALLOC(GMEM_MOVEABLE,size)
+#define EDIT_HEAP_REALLOC(handle,size) USER_HEAP_REALLOC(handle,size,\
+							 GMEM_MOVEABLE)
+#define EDIT_HEAP_ADDR(handle)         USER_HEAP_ADDR(handle)
+#define EDIT_HEAP_FREE(handle)         USER_HEAP_FREE(handle)
+
 /* #define DEBUG_EDIT /* */
 
 #define NOTIFY_PARENT(hWndCntrl, wNotifyCode) \
 	SendMessage(GetParent(hWndCntrl), WM_COMMAND, \
 		 GetDlgCtrlID(hWndCntrl), MAKELPARAM(hWndCntrl, wNotifyCode));
 
-#define MAXTEXTLEN 32000   /* maximum text buffer length */
+#define MAXTEXTLEN 30000   /* maximum text buffer length */
 #define EDITLEN     1024   /* starting length for multi-line control */
 #define ENTRYLEN     256   /* starting length for single line control */
 #define GROWLENGTH    64   /* buffers grow by this much */
@@ -31,11 +37,6 @@
 #define HSCROLLDIM (ClientWidth(wndPtr) / 3)
                            /* "line" dimension for horizontal scroll */
 
-#define EDIT_HEAP_ALLOC(size)          USER_HEAP_ALLOC(GMEM_MOVEABLE,size)
-#define EDIT_HEAP_REALLOC(handle,size) USER_HEAP_REALLOC(handle,size,\
-							 GMEM_MOVEABLE)
-#define EDIT_HEAP_ADDR(handle)         USER_HEAP_ADDR(handle)
-#define EDIT_HEAP_FREE(handle)         USER_HEAP_FREE(handle)
 
 typedef struct
 {
@@ -46,7 +47,6 @@
     int textwidth;           /* width of longest line in pixels */
     RECT fmtrc;              /* rectangle in which to format text */
     int txtht;               /* height of text line in pixels */
-    MDESC **localheap;       /* pointer to application's local heap */
     HANDLE hText;            /* handle to text buffer */
     HANDLE hCharWidths;      /* widths of chars in font */
     HANDLE hTextPtrs;        /* list of line offsets */
@@ -81,9 +81,9 @@
 #define CurrChar (EDIT_TextLine(hwnd, es->CurrLine) + es->CurrCol)
 #define SelMarked(es) (es->SelBegLine != 0 || es->SelBegCol != 0 || \
 		       es->SelEndLine != 0 || es->SelEndCol != 0)
-#define ROUNDUP(numer, denom) ((numer % denom) \
-			       ? (((numer + denom) / denom) * denom) \
-			       : numer)
+#define ROUNDUP(numer, denom) (((numer) % (denom)) \
+			       ? ((((numer) + (denom)) / (denom)) * (denom)) \
+			       : (numer) + (denom))
 
 /* macros to access window styles */
 #define IsAutoVScroll() (wndPtr->dwStyle & ES_AUTOVSCROLL)
@@ -109,16 +109,16 @@
 void EDIT_PaintMsg(HWND hwnd);
 HANDLE EDIT_GetTextLine(HWND hwnd, int selection);
 char *EDIT_TextLine(HWND hwnd, int sel);
-int EDIT_StrLength(EDITSTATE *es, char *str, int len, int pcol);
+int EDIT_StrLength(HWND hwnd, char *str, int len, int pcol);
 int EDIT_LineLength(HWND hwnd, int num);
 void EDIT_WriteTextLine(HWND hwnd, RECT *rc, int y);
 void EDIT_WriteText(HWND hwnd, char *lp, int off, int len, int row, 
 		    int col, RECT *rc, BOOL blank, BOOL reverse);
-HANDLE EDIT_GetStr(EDITSTATE *es, char *lp, int off, int len, int *diff);
+HANDLE EDIT_GetStr(HWND hwnd, char *lp, int off, int len, int *diff);
 void EDIT_CharMsg(HWND hwnd, WORD wParam);
 void EDIT_KeyTyped(HWND hwnd, short ch);
-int EDIT_CharWidth(EDITSTATE *es, short ch, int pcol);
-int EDIT_GetNextTabStop(EDITSTATE *es, int pcol);
+int EDIT_CharWidth(HWND hwnd, short ch, int pcol);
+int EDIT_GetNextTabStop(HWND hwnd, int pcol);
 void EDIT_Forward(HWND hwnd);
 void EDIT_Downward(HWND hwnd);
 void EDIT_Upward(HWND hwnd);
@@ -144,7 +144,7 @@
 int EDIT_PixelToChar(HWND hwnd, int row, int *pixel);
 LONG EDIT_SetTextMsg(HWND hwnd, LONG lParam);
 void EDIT_ClearText(HWND hwnd);
-void EDIT_SetSelMsg(HWND hwnd, LONG lParam);
+void EDIT_SetSelMsg(HWND hwnd, WORD wParam, LONG lParam);
 void EDIT_GetLineCol(HWND hwnd, int off, int *line, int *col);
 void EDIT_DeleteSel(HWND hwnd);
 void EDIT_ClearSel(HWND hwnd);
@@ -165,9 +165,11 @@
 			  int col);
 void EDIT_ClearDeletedText(HWND hwnd);
 LONG EDIT_UndoMsg(HWND hwnd);
-unsigned int EDIT_TextAlloc(EDITSTATE *es, int bytes);
-void *EDIT_TextAddr(EDITSTATE *es, unsigned int handle);
-unsigned int EDIT_TextReAlloc(EDITSTATE *es, unsigned int handle, int bytes);
+unsigned int EDIT_HeapAlloc(HWND hwnd, int bytes);
+void *EDIT_HeapAddr(HWND hwnd, unsigned int handle);
+unsigned int EDIT_HeapReAlloc(HWND hwnd, unsigned int handle, int bytes);
+void EDIT_HeapFree(HWND hwnd, unsigned int handle);
+unsigned int EDIT_HeapSize(HWND hwnd, unsigned int handle);
 void EDIT_SetHandleMsg(HWND hwnd, WORD wParam);
 LONG EDIT_SetTabStopsMsg(HWND hwnd, WORD wParam, LONG lParam);
 void swap(int *a, int *b);
@@ -180,7 +182,8 @@
     char *textPtr;
     int len;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     switch (uMsg) {
     case EM_CANUNDO:
@@ -244,8 +247,10 @@
     case EM_LIMITTEXT:
 	if (wParam)
 	    es->MaxTextLen = wParam;
+	else if (IsMultiLine())
+	    es->MaxTextLen = 65535;
 	else
-	    es->MaxTextLen = 65000;
+	    es->MaxTextLen = 32767;
 	break;
 
     case EM_LINEFROMCHAR:
@@ -297,7 +302,7 @@
 
     case EM_SETSEL:
 	HideCaret(hwnd);
-	EDIT_SetSelMsg(hwnd, lParam);
+	EDIT_SetSelMsg(hwnd, wParam, lParam);
 	SetCaretPos(es->WndCol, es->WndRow * es->txtht);
 	ShowCaret(hwnd);
 	break;
@@ -326,9 +331,10 @@
 	break;
 
     case WM_DESTROY:
-	EDIT_HEAP_FREE(es->hTextPtrs);
-	EDIT_HEAP_FREE(es->hCharWidths);
-	EDIT_HEAP_FREE((HANDLE)(*(wndPtr->wExtra)));
+	EDIT_HeapFree(hwnd, es->hTextPtrs);
+	EDIT_HeapFree(hwnd, es->hCharWidths);
+	EDIT_HeapFree(hwnd, es->hText);
+	EDIT_HeapFree(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 	break;
 
     case WM_ENABLE:
@@ -336,7 +342,7 @@
 	break;
 
     case WM_GETTEXT:
-	textPtr = EDIT_TextAddr(es, es->hText);
+	textPtr = EDIT_HeapAddr(hwnd, es->hText);
 	if ((int)wParam > (len = strlen(textPtr)))
 	{
 	    strcpy((char *)lParam, textPtr);
@@ -347,7 +353,7 @@
 	break;
 
     case WM_GETTEXTLENGTH:
-	textPtr = EDIT_TextAddr(es, es->hText);
+	textPtr = EDIT_HeapAddr(hwnd, es->hText);
 	lResult = (DWORD)strlen(textPtr);
 	break;
 
@@ -398,7 +404,6 @@
 	break;
 
     case WM_SETFOCUS:
-	es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
 	CreateCaret(hwnd, 0, 2, es->txtht);
 	SetCaretPos(es->WndCol, es->WndRow * es->txtht);
 	ShowCaret(hwnd);
@@ -448,22 +453,25 @@
     char *text;
     int len;
 
+    /* store pointer to local heap in window structure so that */
+    /* EDITSTATE structure itself can be stored on local heap  */
+    (MDESC **)*(LONG *)(wndPtr->wExtra + 2) = 
+	&HEAP_LocalFindHeap(createStruct->hInstance)->free_list;
+
     /* allocate space for state variable structure */
-    (HANDLE)(*(wndPtr->wExtra)) = 
-	EDIT_HEAP_ALLOC(sizeof(EDITSTATE));
-    es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    es->hTextPtrs = EDIT_HEAP_ALLOC(sizeof(int));
-    textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
-    es->hCharWidths = EDIT_HEAP_ALLOC(256 * sizeof(short));
+    (HANDLE)(*(wndPtr->wExtra)) = EDIT_HeapAlloc(hwnd, sizeof(EDITSTATE));
+    es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    es->hTextPtrs = EDIT_HeapAlloc(hwnd, sizeof(int));
+    textPtrs = (unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
+    es->hCharWidths = EDIT_HeapAlloc(hwnd, 256 * sizeof(short));
 
     /* --- text buffer */
-    es->localheap = &HEAP_LocalFindHeap(createStruct->hInstance)->free_list;
     es->MaxTextLen = MAXTEXTLEN + 1;
     if (!(createStruct->lpszName))
     {
 	es->textlen = EditBufLen(wndPtr) + 1;
-	es->hText = EDIT_TextAlloc(es, EditBufLen(wndPtr) + 2);
-	text = EDIT_TextAddr(es, es->hText);
+	es->hText = EDIT_HeapAlloc(hwnd, EditBufLen(wndPtr) + 2);
+	text = EDIT_HeapAddr(hwnd, es->hText);
 	memset(text, 0, es->textlen + 2);
 	EDIT_ClearTextPointers(hwnd);
     }
@@ -471,16 +479,17 @@
     {
 	if (strlen(createStruct->lpszName) < EditBufLen(wndPtr))
 	{
-	    es->hText = EDIT_TextAlloc(es, EditBufLen(wndPtr) + 2);
-	    text = EDIT_TextAddr(es, es->hText);
+	    es->hText = EDIT_HeapAlloc(hwnd, EditBufLen(wndPtr) + 2);
+	    text = EDIT_HeapAddr(hwnd, es->hText);
 	    strcpy(text, createStruct->lpszName);
 	    *(text + es->textlen) = '\0';
 	    es->textlen = EditBufLen(wndPtr) + 1;
 	}
 	else
 	{
-	    es->hText = EDIT_TextAlloc(es, strlen(createStruct->lpszName) + 2);
-	    text = EDIT_TextAddr(es, es->hText);
+	    es->hText = EDIT_HeapAlloc(hwnd, 
+				       strlen(createStruct->lpszName) + 2);
+	    text = EDIT_HeapAddr(hwnd, es->hText);
 	    strcpy(text, createStruct->lpszName);
 	    es->textlen = strlen(createStruct->lpszName) + 1;
 	}
@@ -491,6 +500,13 @@
     if ((createStruct->style & WS_VSCROLL) || 
 	(createStruct->style & WS_HSCROLL)) NC_CreateScrollBars(hwnd);
 
+    /* ES_AUTOVSCROLL and ES_AUTOHSCROLL are automatically applied if */
+    /* the corresponding WM_* message is set                          */
+    if (createStruct->style & WS_VSCROLL)
+	wndPtr->dwStyle |= ES_AUTOVSCROLL;
+    if (createStruct->style & WS_HSCROLL)
+	wndPtr->dwStyle |= ES_AUTOHSCROLL;
+
     /* remove the WS_CAPTION style if it has been set - this is really a  */
     /* pseudo option made from a combination of WS_BORDER and WS_DLGFRAME */
     if (wndPtr->dwStyle & WS_BORDER && wndPtr->dwStyle & WS_DLGFRAME)
@@ -508,7 +524,8 @@
 {
     HDC hdc;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
     CLASS *classPtr;
     short *charWidths;
     TEXTMETRIC tm;
@@ -517,7 +534,7 @@
     /* initialize state variable structure */
     /* --- char width array */
     hdc = GetDC(hwnd);
-    charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+    charWidths = (short *)EDIT_HeapAddr(hwnd, es->hCharWidths);
     memset(charWidths, 0, 256 * sizeof(short));
     GetCharWidth(hdc, 0, 255, charWidths);
 
@@ -536,13 +553,13 @@
     es->hDeletedText = 0;
     es->DeletedLength = 0;
     es->NumTabStops = 0;
-    es->hTabStops = EDIT_HEAP_ALLOC(sizeof(int));
+    es->hTabStops = EDIT_HeapAlloc(hwnd, sizeof(int));
 
     /* allocate space for a line full of blanks to speed up */
     /* line filling */
-    es->hBlankLine = EDIT_HEAP_ALLOC((ClientWidth(wndPtr) / 
+    es->hBlankLine = EDIT_HeapAlloc(hwnd, (ClientWidth(wndPtr) / 
 				      charWidths[32]) + 2); 
-    text = EDIT_HEAP_ADDR(es->hBlankLine);
+    text = EDIT_HeapAddr(hwnd, es->hBlankLine);
     memset(text, ' ', (ClientWidth(wndPtr) / charWidths[32]) + 2);
 
     /* set up text cursor for edit class */
@@ -567,10 +584,11 @@
 {
     unsigned int *textPtrs;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
     
-    es->hTextPtrs = EDIT_HEAP_REALLOC(es->hTextPtrs, sizeof(int));
-    textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    es->hTextPtrs = EDIT_HeapReAlloc(hwnd, es->hTextPtrs, sizeof(int));
+    textPtrs = (unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
     *textPtrs = 0;
 }
 
@@ -593,10 +611,10 @@
     unsigned int *textPtrs;
     short *charWidths;
 
-    es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    text = EDIT_TextAddr(es, es->hText);
-    textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
-    charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+    es = (EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    text = EDIT_HeapAddr(hwnd, es->hText);
+    textPtrs = (unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
+    charWidths = (short *)EDIT_HeapAddr(hwnd, es->hCharWidths);
 
     es->textwidth = es->wlines = 0;
     cp = text;
@@ -608,9 +626,9 @@
 	if (incrs == INITLINES)
 	{
 	    incrs = 0;
-	    es->hTextPtrs = EDIT_HEAP_REALLOC(es->hTextPtrs,
+	    es->hTextPtrs = EDIT_HeapReAlloc(hwnd, es->hTextPtrs,
 			      (es->wlines + INITLINES) * sizeof(int));
-	    textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+	    textPtrs = (unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 	}
 	off = (unsigned int)(cp - text);     /* offset of beginning of line */
 	*(textPtrs + es->wlines) = off;
@@ -621,7 +639,8 @@
 	/* advance through current line */
 	while (*cp && *cp != '\n')
 	{
-	    len += EDIT_CharWidth(es, *cp, len); /* width of line in pixels */
+	    len += EDIT_CharWidth(hwnd, *cp, len);
+	                                     /* width of line in pixels */
 	    cp++;
 	}
 	es->textwidth = max(es->textwidth, len);
@@ -643,8 +662,10 @@
 void EDIT_ModTextPointers(HWND hwnd, int lineno, int var)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    unsigned int *textPtrs = 
+	(unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 
     while (lineno < es->wlines)
 	*(textPtrs + lineno++) += var;
@@ -662,7 +683,8 @@
     int y;
     RECT rc;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     hdc = BeginPaint(hwnd, &ps);
     rc = ps.rcPaint;
@@ -710,8 +732,8 @@
     }
 
     /* store selected line and return handle */
-    hLine = EDIT_HEAP_ALLOC(len + 6);
-    line = (char *)EDIT_HEAP_ADDR(hLine);
+    hLine = EDIT_HeapAlloc(hwnd, len + 6);
+    line = (char *)EDIT_HeapAddr(hwnd, hLine);
     memmove(line, cp1, len);
     line[len] = '\0';
     return hLine;
@@ -727,9 +749,11 @@
 char *EDIT_TextLine(HWND hwnd, int sel)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    char *text = EDIT_TextAddr(es, es->hText);
-    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    char *text = EDIT_HeapAddr(hwnd, es->hText);
+    unsigned int *textPtrs = 
+	(unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 
     return (text + *(textPtrs + sel));
 }
@@ -743,12 +767,15 @@
  *  the width of a tab.
  */
 
-int EDIT_StrLength(EDITSTATE *es, char *str, int len, int pcol)
+int EDIT_StrLength(HWND hwnd, char *str, int len, int pcol)
 {
     int i, plen = 0;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     for (i = 0; i < len; i++)
-	plen += EDIT_CharWidth(es, *(str + i), pcol + plen);
+	plen += EDIT_CharWidth(hwnd, *(str + i), pcol + plen);
 
 #ifdef DEBUG_EDIT
     printf("EDIT_StrLength: returning %d\n", plen);
@@ -766,7 +793,8 @@
 int EDIT_LineLength(HWND hwnd, int num)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
     char *cp = EDIT_TextLine(hwnd, num);
     char *cp1;
 
@@ -791,10 +819,10 @@
     int col, off = 0;
     int sbl, sel, sbc, sec;
     RECT rc;
-
     BOOL trunc = FALSE;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     /* initialize rectangle if NULL, else copy */
     if (rect)
@@ -844,8 +872,8 @@
     /* get the text and length of line */
     if ((hLine = EDIT_GetTextLine(hwnd, y)) == 0)
 	return;
-    lp = (unsigned char *)EDIT_HEAP_ADDR(hLine);
-    lnlen = EDIT_StrLength(es, lp, strlen(lp), 0);
+    lp = (unsigned char *)EDIT_HeapAddr(hwnd, hLine);
+    lnlen = EDIT_StrLength(hwnd, lp, strlen(lp), 0);
     lnlen1 = lnlen;
 
     /* build the line to display */
@@ -885,7 +913,7 @@
 			   TRUE, TRUE);
 	else if (y == sbl)
 	{
-	    col = EDIT_StrLength(es, lp, sbc, 0);
+	    col = EDIT_StrLength(hwnd, lp, sbc, 0);
 	    if (col > (es->wleft + rc.left))
 	    {
 		len = min(col - off, rc.right - off);
@@ -895,7 +923,7 @@
 	    }
 	    if (y == sel)
 	    {
-		col = EDIT_StrLength(es, lp, sec, 0);
+		col = EDIT_StrLength(hwnd, lp, sec, 0);
 		if (col < (es->wleft + rc.right))
 		{
 		    len = min(col - off, rc.right - off);
@@ -923,7 +951,7 @@
 	}
 	else if (y == sel)
 	{
-	    col = EDIT_StrLength(es, lp, sec, 0);
+	    col = EDIT_StrLength(hwnd, lp, sec, 0);
 	    if (col < (es->wleft + rc.right))
 	    {
 		len = min(col - off, rc.right - off);
@@ -940,7 +968,7 @@
 	EDIT_WriteText(hwnd, lp, off, len, y - es->wtop, rc.left, &rc,
 		       TRUE, FALSE);
 	      
-    EDIT_HEAP_FREE(hLine);
+    EDIT_HeapFree(hwnd, hLine);
 }
 
 
@@ -969,17 +997,18 @@
     COLORREF oldTextColor, oldBkgdColor;
     HFONT oldfont;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
-    char *blanks = (char *)EDIT_HEAP_ADDR(es->hBlankLine);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    short *charWidths = (short *)EDIT_HeapAddr(hwnd, es->hCharWidths);
+    char *blanks = (char *)EDIT_HeapAddr(hwnd, es->hBlankLine);
 
 #ifdef DEBUG_EDIT
     printf("EDIT_WriteText lp=%s, off=%d, len=%d, row=%d, col=%d, reverse=%d\n", lp, off, len, row, col, reverse);
 #endif
 
     hdc = GetDC(hwnd);
-    hStr = EDIT_GetStr(es, lp, off, len, &diff);
-    str = (char *)EDIT_HEAP_ADDR(hStr);
+    hStr = EDIT_GetStr(hwnd, lp, off, len, &diff);
+    str = (char *)EDIT_HeapAddr(hwnd, hStr);
     hrgnClip = CreateRectRgnIndirect(rc);
     SelectClipRgn(hdc, hrgnClip);
 
@@ -1002,8 +1031,8 @@
     else
     {
 	TextOut(hdc, col - diff, row * es->txtht, str, (int)(cp - str));
-	scol = EDIT_StrLength(es, str, (int)(cp - str), 0);
-	tabwidth = EDIT_CharWidth(es, VK_TAB, scol);
+	scol = EDIT_StrLength(hwnd, str, (int)(cp - str), 0);
+	tabwidth = EDIT_CharWidth(hwnd, VK_TAB, scol);
 	num_spaces = tabwidth / charWidths[32] + 1;
 	TextOut(hdc, scol, row * es->txtht, blanks, num_spaces);
 	cp++;
@@ -1012,8 +1041,8 @@
 	while (cp1 = strchr(cp, VK_TAB))
 	{
 	    TextOut(hdc, scol, row * es->txtht, cp, (int)(cp1 - cp));
-	    scol = EDIT_StrLength(es, cp, (int)(cp1 - cp), scol);
-	    tabwidth = EDIT_CharWidth(es, VK_TAB, scol);
+	    scol += EDIT_StrLength(hwnd, cp, (int)(cp1 - cp), scol);
+	    tabwidth = EDIT_CharWidth(hwnd, VK_TAB, scol);
 	    num_spaces = tabwidth / charWidths[32] + 1;
 	    TextOut(hdc, scol, row * es->txtht, blanks, num_spaces);
 	    cp = ++cp1;
@@ -1042,7 +1071,7 @@
     if (es->hFont)
 	SelectObject(hdc, (HANDLE)oldfont);
 
-    EDIT_HEAP_FREE(hStr);
+    EDIT_HeapFree(hwnd, hStr);
     ReleaseDC(hwnd, hdc);
 }
 
@@ -1056,12 +1085,15 @@
  *  will be zero.
  */
 
-HANDLE EDIT_GetStr(EDITSTATE *es, char *lp, int off, int len, int *diff)
+HANDLE EDIT_GetStr(HWND hwnd, char *lp, int off, int len, int *diff)
 {
     HANDLE hStr;
     char *str;
     int ch = 0, i = 0, j, s_i;
     int ch1;
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
 #ifdef DEBUG_EDIT
     printf("EDIT_GetStr %s %d %d\n", lp, off, len);
@@ -1070,7 +1102,7 @@
     while (i < off)
     {
 	s_i = i;
-	i += EDIT_CharWidth(es, *(lp + ch), i);
+	i += EDIT_CharWidth(hwnd, *(lp + ch), i);
 	ch++;
     }
 
@@ -1085,12 +1117,12 @@
 
     while (i < len + off)
     {
-	i += EDIT_CharWidth(es, *(lp + ch), i);
+	i += EDIT_CharWidth(hwnd, *(lp + ch), i);
 	ch++;
     }
     
-    hStr = EDIT_HEAP_ALLOC(ch - ch1 + 3);
-    str = (char *)EDIT_HEAP_ADDR(hStr);
+    hStr = EDIT_HeapAlloc(hwnd, ch - ch1 + 3);
+    str = (char *)EDIT_HeapAddr(hwnd, hStr);
     for (i = ch1, j = 0; i < ch; i++, j++)
 	str[j] = lp[i];
     str[++j] = '\0';
@@ -1108,7 +1140,8 @@
 void EDIT_CharMsg(HWND hwnd, WORD wParam)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
 #ifdef DEBUG_EDIT
     printf("EDIT_CharMsg: wParam=%c\n", (char)wParam);
@@ -1124,6 +1157,12 @@
 	EDIT_KeyTyped(hwnd, wParam);
 	break;
 
+    case VK_TAB:
+	if (!IsMultiLine())
+	    break;
+	EDIT_KeyTyped(hwnd, wParam);
+	break;
+
     default:
 	if (wParam >= 20 && wParam <= 126)
 	    EDIT_KeyTyped(hwnd, wParam);
@@ -1141,8 +1180,9 @@
 void EDIT_KeyTyped(HWND hwnd, short ch)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    char *text = EDIT_TextAddr(es, es->hText);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    char *text = EDIT_HeapAddr(hwnd, es->hText);
     char *currchar = CurrChar;
     RECT rc;
     BOOL FullPaint = FALSE;
@@ -1186,10 +1226,10 @@
 	/* but not above maximum size */
 	if (es->textlen > es->MaxTextLen)
 	    es->textlen = es->MaxTextLen;
-	es->hText = EDIT_TextReAlloc(es, es->hText, es->textlen + 2);
+	es->hText = EDIT_HeapReAlloc(hwnd, es->hText, es->textlen + 2);
 	if (!es->hText)
 	    NOTIFY_PARENT(hwnd, EN_ERRSPACE);
-	text = EDIT_TextAddr(es, es->hText);
+	text = EDIT_HeapAddr(hwnd, es->hText);
 	text[es->textlen - 1] = '\0';
 	currchar = CurrChar;
     }
@@ -1205,13 +1245,13 @@
     if (IsMultiLine() && es->wlines > 1)
     {
 	es->textwidth = max(es->textwidth,
-		    EDIT_StrLength(es, EDIT_TextLine(hwnd, es->CurrLine),
+		    EDIT_StrLength(hwnd, EDIT_TextLine(hwnd, es->CurrLine),
 		    (int)(EDIT_TextLine(hwnd, es->CurrLine + 1) -
 			  EDIT_TextLine(hwnd, es->CurrLine)), 0));
     }
     else
 	es->textwidth = max(es->textwidth,
-			    EDIT_StrLength(es, text, strlen(text), 0));
+			    EDIT_StrLength(hwnd, text, strlen(text), 0));
     EDIT_WriteTextLine(hwnd, NULL, es->wtop + es->WndRow);
 
     if (ch == '\n')
@@ -1238,14 +1278,14 @@
 
     /* test end of window */
     if (es->WndCol >= ClientWidth(wndPtr) - 
-	                    EDIT_CharWidth(es, ch, es->WndCol + es->wleft))
+	                    EDIT_CharWidth(hwnd, ch, es->WndCol + es->wleft))
     {
 	/* TODO:- Word wrap to be handled here */
 
 /*	if (!(currchar == text + es->MaxTextLen - 2)) */
 	    EDIT_KeyHScroll(hwnd, SB_LINEDOWN);
     }
-    es->WndCol += EDIT_CharWidth(es, ch, es->WndCol + es->wleft);
+    es->WndCol += EDIT_CharWidth(hwnd, ch, es->WndCol + es->wleft);
     es->CurrCol++;
     SetCaretPos(es->WndCol, es->WndRow * es->txtht);
     ShowCaret(hwnd);
@@ -1261,14 +1301,17 @@
  *  the width of a tab.
  */
 
-int EDIT_CharWidth(EDITSTATE *es, short ch, int pcol)
+int EDIT_CharWidth(HWND hwnd, short ch, int pcol)
 {
-    short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    short *charWidths = (short *)EDIT_HeapAddr(hwnd, es->hCharWidths);
 
     if (ch != VK_TAB)
 	return (charWidths[ch]);
     else
-	return (EDIT_GetNextTabStop(es, pcol) - pcol);
+	return (EDIT_GetNextTabStop(hwnd, pcol) - pcol);
 }
 
 
@@ -1278,14 +1321,17 @@
  *  Return the next tab stop beyond _pcol_.
  */
 
-int EDIT_GetNextTabStop(EDITSTATE *es, int pcol)
+int EDIT_GetNextTabStop(HWND hwnd, int pcol)
 {
-    int i;
+    int i, tmp;
     int baseUnitWidth = LOWORD(GetDialogBaseUnits());
-    unsigned short *tabstops = EDIT_HEAP_ADDR(es->hTabStops);
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    unsigned short *tabstops = EDIT_HeapAddr(hwnd, es->hTabStops);
 
     if (es->NumTabStops == 0)
-	return ROUNDUP(pcol, 8);
+	return ROUNDUP(pcol, 8 * baseUnitWidth);
     else if (es->NumTabStops == 1)
 	return ROUNDUP(pcol, *tabstops * baseUnitWidth / 4);
     else
@@ -1309,8 +1355,9 @@
 void EDIT_Forward(HWND hwnd)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    char *text = EDIT_TextAddr(es, es->hText);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    char *text = EDIT_HeapAddr(hwnd, es->hText);
 
     if (*CurrChar == '\0')
 	return;
@@ -1322,7 +1369,7 @@
     }
     else
     {
-	es->WndCol += EDIT_CharWidth(es, *CurrChar, es->WndCol + es->wleft);
+	es->WndCol += EDIT_CharWidth(hwnd, *CurrChar, es->WndCol + es->wleft);
 	es->CurrCol++;
 	if (es->WndCol >= ClientWidth(wndPtr))
 	    EDIT_KeyHScroll(hwnd, SB_LINEDOWN);
@@ -1340,7 +1387,8 @@
 void EDIT_Downward(HWND hwnd)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
 #ifdef DEBUG_EDIT
     printf("EDIT_Downward: WndRow=%d, wtop=%d, wlines=%d\n", es->WndRow, es->wtop, es->wlines);
@@ -1370,7 +1418,8 @@
 void EDIT_Upward(HWND hwnd)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (IsMultiLine() && es->CurrLine != 0)
     {
@@ -1396,13 +1445,20 @@
 void EDIT_Backward(HWND hwnd)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    char *text = EDIT_TextAddr(es, es->hText);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    char *text = EDIT_HeapAddr(hwnd, es->hText);
 
     if (es->CurrCol)
     {
 	--es->CurrCol;
-	es->WndCol -= EDIT_CharWidth(es, *CurrChar, es->WndCol + es->wleft);
+	if (*CurrChar == VK_TAB)
+	    es->WndCol -= EDIT_CharWidth(hwnd, *CurrChar, 
+					 EDIT_StrLength(hwnd, 
+					 EDIT_TextLine(hwnd, es->CurrLine), 
+					 es->CurrCol, 0));
+	else
+	    es->WndCol -= EDIT_CharWidth(hwnd, *CurrChar, 0);
 	if (es->WndCol < 0)
 	    EDIT_KeyHScroll(hwnd, SB_LINEUP);
     }
@@ -1424,12 +1480,13 @@
 {
     RECT rc;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    char *text = EDIT_TextAddr(es, es->hText);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    char *text = EDIT_HeapAddr(hwnd, es->hText);
 
     while (*CurrChar && *CurrChar != '\n')
     {
-	es->WndCol += EDIT_CharWidth(es, *CurrChar, es->WndCol + es->wleft);
+	es->WndCol += EDIT_CharWidth(hwnd, *CurrChar, es->WndCol + es->wleft);
 	es->CurrCol++;
     }
 
@@ -1453,7 +1510,8 @@
 {
     RECT rc;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     es->CurrCol = es->WndCol = 0;
     if (es->wleft != 0)
@@ -1474,14 +1532,15 @@
 void EDIT_StickEnd(HWND hwnd)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
     int len = EDIT_LineLength(hwnd, es->CurrLine);
     char *cp = EDIT_TextLine(hwnd, es->CurrLine);
     char currpel;
 
     es->CurrCol = min(len, es->CurrCol);
-    es->WndCol = min(EDIT_StrLength(es, cp, len, 0) - es->wleft, es->WndCol);
-    currpel = EDIT_StrLength(es, cp, es->CurrCol, 0);
+    es->WndCol = min(EDIT_StrLength(hwnd, cp, len, 0) - es->wleft, es->WndCol);
+    currpel = EDIT_StrLength(hwnd, cp, es->CurrCol, 0);
 
     if (es->wleft > currpel)
     {
@@ -1505,7 +1564,8 @@
 void EDIT_KeyDownMsg(HWND hwnd, WORD wParam)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
 #ifdef DEBUG_EDIT
     printf("EDIT_KeyDownMsg: key=%x\n", wParam);
@@ -1610,7 +1670,8 @@
     RECT rc;
     int hscrollpos;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (opt == SB_LINEDOWN)
     {
@@ -1655,7 +1716,8 @@
     RECT rc;
     int y, vscrollpos;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (!IsMultiLine())
 	return;
@@ -1720,7 +1782,8 @@
     RECT rc;
     int vscrollpos;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (IsMultiLine())
     {
@@ -1767,7 +1830,8 @@
     RECT rc;
     int vscrollpos;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (!IsMultiLine())
 	return;
@@ -1807,7 +1871,8 @@
     int vscrollpos;
     short minpos, maxpos;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     GetScrollRange(hwnd, SB_VERT, &minpos, &maxpos);
 
@@ -1833,7 +1898,8 @@
     int hscrollpos;
     short minpos, maxpos;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     GetScrollRange(hwnd, SB_HORZ, &minpos, &maxpos);
 
@@ -1857,7 +1923,8 @@
 {
     RECT rc;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
     char *currchar = CurrChar;
     BOOL repaint = *currchar == '\n';
 
@@ -1891,7 +1958,8 @@
 void EDIT_VScrollMsg(HWND hwnd, WORD wParam, LONG lParam)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (IsMultiLine())
     {
@@ -1927,7 +1995,8 @@
     RECT rc;
     int y;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
 #ifdef DEBUG_EDIT
     printf("EDIT_VScrollLine: direction=%d\n", opt);
@@ -1986,7 +2055,8 @@
     RECT rc;
     int vscrollpos;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (opt == SB_PAGEUP)
     {
@@ -2024,7 +2094,8 @@
 void EDIT_HScrollMsg(HWND hwnd, WORD wParam, LONG lParam)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     switch (wParam)
     {
@@ -2047,7 +2118,8 @@
 {
     RECT rc;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (wParam != SIZE_MAXIMIZED && wParam != SIZE_RESTORED) return;
 
@@ -2067,7 +2139,8 @@
     int len;
     BOOL end = FALSE;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (SelMarked(es))
 	EDIT_ClearSel(hwnd);
@@ -2086,8 +2159,8 @@
     cp = EDIT_TextLine(hwnd, es->CurrLine);
     len = EDIT_LineLength(hwnd, es->CurrLine);
     es->WndCol = LOWORD(lParam);
-    if (es->WndCol > EDIT_StrLength(es, cp, len, 0) - es->wleft || end)
-	es->WndCol = EDIT_StrLength(es, cp, len, 0) - es->wleft;
+    if (es->WndCol > EDIT_StrLength(hwnd, cp, len, 0) - es->wleft || end)
+	es->WndCol = EDIT_StrLength(hwnd, cp, len, 0) - es->wleft;
     es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol));
 
     ButtonDown = TRUE;
@@ -2130,7 +2203,8 @@
     int ch = 0, i = 0, s_i;
     char *text;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
 #ifdef DEBUG_EDIT
     printf("EDIT_PixelToChar: row=%d, pixel=%d\n", row, *pixel);
@@ -2140,7 +2214,7 @@
     while (i < *pixel)
     {
 	s_i = i;
-	i += EDIT_CharWidth(es, *(text + ch), i);
+	i += EDIT_CharWidth(hwnd, *(text + ch), i);
 	ch++;
     }
 
@@ -2165,17 +2239,17 @@
     char *text;
     RECT rc;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (strlen((char *)lParam) <= es->MaxTextLen)
     {
 	len = strlen((char *)lParam);
 	EDIT_ClearText(hwnd);
 	es->textlen = len;
-	es->hText = EDIT_TextReAlloc(es, es->hText, len + 3);
-	text = EDIT_TextAddr(es, es->hText);
+	es->hText = EDIT_HeapReAlloc(hwnd, es->hText, len + 3);
+	text = EDIT_HeapAddr(hwnd, es->hText);
 	strcpy(text, (char *)lParam);
-/*	text[len] = '\n'; */ /* Removed by Bob Amstadt */
 	text[len + 1] = '\0';
 	text[len + 2] = '\0';
 	EDIT_BuildTextPointers(hwnd);
@@ -2198,12 +2272,13 @@
 void EDIT_ClearText(HWND hwnd)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
     unsigned int blen = EditBufLen(wndPtr) + 2;
     char *text;
 
-    es->hText = EDIT_TextReAlloc(es, es->hText, blen);
-    text = EDIT_TextAddr(es, es->hText);
+    es->hText = EDIT_HeapReAlloc(hwnd, es->hText, blen);
+    text = EDIT_HeapAddr(hwnd, es->hText);
     memset(text, 0, blen);
     es->textlen = 0;
     es->wlines = 0;
@@ -2220,35 +2295,90 @@
  *  EM_SETSEL message function
  */
 
-void EDIT_SetSelMsg(HWND hwnd, LONG lParam)
+void EDIT_SetSelMsg(HWND hwnd, WORD wParam, LONG lParam)
 {
     int so, eo;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     so = LOWORD(lParam);
     eo = HIWORD(lParam);
-    if (so > eo)
-	swap(&so, &eo);
 
-    EDIT_GetLineCol(hwnd, so, &(es->SelBegLine), &(es->SelBegCol));
-    EDIT_GetLineCol(hwnd, eo, &(es->SelEndLine), &(es->SelEndCol));
-
-    if (SelMarked(es))
+    if (so == -1)       /* if so == -1, clear selection */
     {
+	EDIT_ClearSel(hwnd);
+	return;
+    }
+
+    if (so == eo)       /* if so == eo, set caret only */
+    {
+	EDIT_GetLineCol(hwnd, so, &(es->CurrLine), &(es->CurrCol));
+	es->WndRow = es->CurrLine - es->wtop;
+
+	if (!wParam)
+	{
+	    if (es->WndRow < 0 || es->WndRow > ClientHeight(wndPtr, es))
+	    {
+		es->wtop = es->CurrLine;
+		es->WndRow = 0;
+	    }
+	    es->WndCol = EDIT_StrLength(hwnd, 
+					EDIT_TextLine(hwnd, es->CurrLine), 
+					es->CurrCol, 0) - es->wleft;
+	    if (es->WndCol > ClientWidth(wndPtr))
+	    {
+		es->wleft = es->WndCol;
+		es->WndCol = 0;
+	    }
+	    else if (es->WndCol < 0)
+	    {
+		es->wleft += es->WndCol;
+		es->WndCol = 0;
+	    }
+	}
+    }
+    else                /* otherwise set selection */
+    {
+	if (so > eo)
+	    swap(&so, &eo);
+
+	EDIT_GetLineCol(hwnd, so, &(es->SelBegLine), &(es->SelBegCol));
+	EDIT_GetLineCol(hwnd, eo, &(es->SelEndLine), &(es->SelEndCol));
 	es->CurrLine = es->SelEndLine;
 	es->CurrCol = es->SelEndCol;
 	es->WndRow = es->SelEndLine - es->wtop;
-	if (es->WndRow < 0)
+
+	if (!wParam)          /* don't suppress scrolling of text */
 	{
-	    es->wtop = es->SelEndLine;
-	    es->WndRow = 0;
+	    if (es->WndRow < 0)
+	    {
+		es->wtop = es->SelEndLine;
+		es->WndRow = 0;
+	    }
+	    else if (es->WndRow > ClientHeight(wndPtr, es))
+	    {
+		es->wtop += es->WndRow - ClientHeight(wndPtr, es);
+		es->WndRow = ClientHeight(wndPtr, es);
+	    }
+	    es->WndCol = EDIT_StrLength(hwnd, 
+					EDIT_TextLine(hwnd, es->SelEndLine), 
+					es->SelEndCol, 0) - es->wleft;
+	    if (es->WndCol > ClientWidth(wndPtr))
+	    {
+		es->wleft += es->WndCol - ClientWidth(wndPtr);
+		es->WndCol = ClientWidth(wndPtr);
+	    }
+	    else if (es->WndCol < 0)
+	    {
+		es->wleft += es->WndCol;
+		es->WndCol = 0;
+	    }
 	}
-	es->WndCol = EDIT_StrLength(es, EDIT_TextLine(hwnd, es->SelEndLine), 
-				     es->SelEndCol, 0) - es->wleft;
+
+	InvalidateRect(hwnd, NULL, TRUE);
+	UpdateWindow(hwnd);
     }
-    InvalidateRect(hwnd, NULL, TRUE);
-    UpdateWindow(hwnd);
 }
 
 
@@ -2263,9 +2393,11 @@
     int lineno;
     char *cp, *cp1;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    char *text = EDIT_TextAddr(es, es->hText);
-    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    char *text = EDIT_HeapAddr(hwnd, es->hText);
+    unsigned int *textPtrs = 
+	(unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 
     /* check for (0,0) */
     if (!off)
@@ -2310,8 +2442,9 @@
     char *bbl, *bel;
     int len;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    char *text = EDIT_TextAddr(es, es->hText);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    char *text = EDIT_HeapAddr(hwnd, es->hText);
 
     if (SelMarked(es))
     {
@@ -2330,7 +2463,7 @@
 	    es->wtop = es->SelBegLine;
 	    es->WndRow = 0;
 	}
-	es->WndCol = EDIT_StrLength(es, bbl - es->SelBegCol, 
+	es->WndCol = EDIT_StrLength(hwnd, bbl - es->SelBegCol, 
 				     es->SelBegCol, 0) - es->wleft;
 
 	EDIT_BuildTextPointers(hwnd);
@@ -2349,7 +2482,8 @@
 void EDIT_ClearSel(HWND hwnd)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     es->SelBegLine = es->SelBegCol = 0;
     es->SelEndLine = es->SelEndCol = 0;
@@ -2371,9 +2505,11 @@
     int lineno;
     char *cp;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    char *text = EDIT_TextAddr(es, es->hText);
-    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    char *text = EDIT_HeapAddr(hwnd, es->hText);
+    unsigned int *textPtrs = 
+	(unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 
     for (lineno = 0; lineno < es->wlines; lineno++)
     {
@@ -2397,7 +2533,8 @@
 {
     BOOL sel = FALSE;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (SelMarked(es))
 	sel = TRUE;
@@ -2425,7 +2562,8 @@
     int len;
     BOOL end = FALSE;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
 #ifdef DEBUG_EDIT
     printf("EDIT_ExtendSel: x=%d, y=%d\n", x, y);
@@ -2449,8 +2587,8 @@
     es->SelEndLine = es->CurrLine;
 
     es->WndCol = x;
-    if (es->WndCol > EDIT_StrLength(es, cp, len, 0) - es->wleft || end)
-	es->WndCol = EDIT_StrLength(es, cp, len, 0) - es->wleft;
+    if (es->WndCol > EDIT_StrLength(hwnd, cp, len, 0) - es->wleft || end)
+	es->WndCol = EDIT_StrLength(hwnd, cp, len, 0) - es->wleft;
     es->CurrCol = EDIT_PixelToChar(hwnd, es->CurrLine, &(es->WndCol));
     es->SelEndCol = es->CurrCol - 1;
 
@@ -2500,7 +2638,8 @@
     HBRUSH hbrush, holdbrush;
     int olddm;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
 #ifdef DEBUG_EDIT
     printf("EDIT_WriteSel: y=%d start=%d end=%d\n", y, start, end);
@@ -2518,10 +2657,10 @@
     if (end == -1)
 	end = EDIT_LineLength(hwnd, y);
 
-    scol = EDIT_StrLength(es, cp, start, 0);
+    scol = EDIT_StrLength(hwnd, cp, start, 0);
     if (scol > rc.right) return;
     if (scol < rc.left) scol = rc.left;
-    ecol = EDIT_StrLength(es, cp, end, 0);
+    ecol = EDIT_StrLength(hwnd, cp, end, 0);
     if (ecol < rc.left) return;
     if (ecol > rc.right) ecol = rc.right;
 
@@ -2545,7 +2684,8 @@
 void EDIT_StopMarking(HWND hwnd)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     TextMarking = FALSE;
     if (es->SelBegLine > es->SelEndLine)
@@ -2568,7 +2708,8 @@
     int len;
     char *buffer = (char *)lParam;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     cp = EDIT_TextLine(hwnd, wParam);
     cp1 = EDIT_TextLine(hwnd, wParam + 1);
@@ -2587,8 +2728,10 @@
 {
     int so, eo;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    unsigned int *textPtrs = 
+	(unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 
     so = *(textPtrs + es->SelBegLine) + es->SelBegCol;
     eo = *(textPtrs + es->SelEndLine) + es->SelEndCol;
@@ -2620,13 +2763,14 @@
 {
     int plen;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    char *text = EDIT_TextAddr(es, es->hText);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    char *text = EDIT_HeapAddr(hwnd, es->hText);
     
     plen = strlen(text) + len;
     if (plen + 1 > es->textlen)
     {
-	es->hText = EDIT_TextReAlloc(es, es->hText, es->textlen + len);
+	es->hText = EDIT_HeapReAlloc(hwnd, es->hText, es->textlen + len);
 	es->textlen = plen + 1;
     }
     memmove(CurrChar + len, CurrChar, strlen(CurrChar) + 1);
@@ -2639,7 +2783,7 @@
     EDIT_GetLineCol(hwnd, (int)((CurrChar + len) - text), &(es->CurrLine),
 		                                    &(es->CurrCol));
     es->WndRow = es->CurrLine - es->wtop;
-    es->WndCol = EDIT_StrLength(es, EDIT_TextLine(hwnd, es->CurrLine),
+    es->WndCol = EDIT_StrLength(hwnd, EDIT_TextLine(hwnd, es->CurrLine),
 				 es->CurrCol, 0) - es->wleft;
 }
 
@@ -2652,7 +2796,8 @@
 {
     int row, col;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (wParam == (WORD)-1)
 	return (LONG)(es->SelBegLine);
@@ -2670,8 +2815,10 @@
 LONG EDIT_LineIndexMsg(HWND hwnd, WORD wParam)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    unsigned int *textPtrs = 
+	(unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 
     if (wParam == (WORD)-1)
 	wParam = es->CurrLine;
@@ -2689,8 +2836,10 @@
     int row, col, len;
     int sbl, sbc, sel, sec;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    unsigned int *textPtrs = (unsigned int *)EDIT_HEAP_ADDR(es->hTextPtrs);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    unsigned int *textPtrs = 
+	(unsigned int *)EDIT_HeapAddr(hwnd, es->hTextPtrs);
 
     if (wParam == (WORD)-1)
     {
@@ -2744,8 +2893,9 @@
     TEXTMETRIC tm;
     HFONT oldfont;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
-    short *charWidths = (short *)EDIT_HEAP_ADDR(es->hCharWidths);
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
+    short *charWidths = (short *)EDIT_HeapAddr(hwnd, es->hCharWidths);
 
     es->hFont = wParam;
     hdc = GetDC(hwnd);
@@ -2757,7 +2907,7 @@
     ReleaseDC(hwnd, hdc);
 
     es->WndRow = (es->CurrLine - es->wtop) / es->txtht;
-    es->WndCol = EDIT_StrLength(es, EDIT_TextLine(hwnd, es->CurrLine),
+    es->WndCol = EDIT_StrLength(hwnd, EDIT_TextLine(hwnd, es->CurrLine),
 				 es->CurrCol, 0) - es->wleft;
 
     InvalidateRect(hwnd, NULL, TRUE);
@@ -2777,12 +2927,14 @@
 {
     char *text;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
-    es->hDeletedText = EDIT_HEAP_REALLOC(es->hDeletedText, len);
+    es->hDeletedText = GlobalReAlloc(es->hDeletedText, len, GMEM_MOVEABLE);
     if (!es->hDeletedText) return;
-    text = (char *)EDIT_HEAP_ADDR(es->hDeletedText);
+    text = (char *)GlobalLock(es->hDeletedText);
     memcpy(text, deltext, len);
+    GlobalUnlock(es->hDeletedText);
     es->DeletedLength = len;
     es->DeletedCurrLine = line;
     es->DeletedCurrCol = col;
@@ -2798,9 +2950,10 @@
 void EDIT_ClearDeletedText(HWND hwnd)
 {
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
-    EDIT_HEAP_FREE(es->hDeletedText);
+    GlobalFree(es->hDeletedText);
     es->hDeletedText = 0;
     es->DeletedLength = 0;
 }
@@ -2814,14 +2967,16 @@
 {
     char *text;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
     
     if (es->hDeletedText)
     {
-	text = (char *)EDIT_HEAP_ADDR(es->hDeletedText);
+	text = (char *)GlobalLock(es->hDeletedText);
 	es->CurrLine = es->DeletedCurrLine;
 	es->CurrCol = es->DeletedCurrCol;
 	EDIT_InsertText(hwnd, text, es->DeletedLength);
+	GlobalUnlock(es->hDeletedText);
 	EDIT_ClearDeletedText(hwnd);
 
 	es->SelBegLine = es->CurrLine;
@@ -2829,7 +2984,7 @@
 	EDIT_GetLineCol(hwnd, (int)((CurrChar + es->DeletedLength) - text), 
 			&(es->CurrLine), &(es->CurrCol));
 	es->WndRow = es->CurrLine - es->wtop;
-	es->WndCol = EDIT_StrLength(es, EDIT_TextLine(hwnd, es->CurrLine),
+	es->WndCol = EDIT_StrLength(hwnd, EDIT_TextLine(hwnd, es->CurrLine),
 				     es->CurrCol, 0) - es->wleft;
 	es->SelEndLine = es->CurrLine;
 	es->SelEndCol = es->CurrCol;
@@ -2844,46 +2999,84 @@
 
 
 /*********************************************************************
- *  EDIT_TextAlloc
+ *  EDIT_HeapAlloc
  *
- *  Allocate the text buffer.
+ *  Allocate the specified number of bytes on the specified local heap.
  */
 
-unsigned int EDIT_TextAlloc(EDITSTATE *es, int bytes)
+unsigned int EDIT_HeapAlloc(HWND hwnd, int bytes)
 {
-    return ((unsigned int)HEAP_Alloc(es->localheap, GMEM_MOVEABLE,
-				     bytes) & 0xffff);
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+    return ((unsigned int)HEAP_Alloc((MDESC **)
+				     *(LONG *)(wndPtr->wExtra + 2), 
+				     GMEM_MOVEABLE, bytes) & 0xffff);
 }
 
 
 /*********************************************************************
- *  EDIT_TextAddr
+ *  EDIT_HeapAddr
  *
- *  Return the address of the text buffer.
+ *  Return the address of the memory pointed to by the handle.
  */
 
-void *EDIT_TextAddr(EDITSTATE *es, unsigned int handle)
+void *EDIT_HeapAddr(HWND hwnd, unsigned int handle)
 {
-    return ((void *)((handle) ? ((handle) | ((unsigned int)(*(es->localheap))
-					    & 0xffff0000)) : 0));
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+    return ((void *)((handle) ? ((handle) | ((unsigned int)
+		    (*(MDESC **)*(LONG *)(wndPtr->wExtra + 2))   
+		     & 0xffff0000)) : 0));
 }
 
 
 /*********************************************************************
- *  EDIT_TextReAlloc
+ *  EDIT_HeapReAlloc
  *
- *  Reallocate the text buffer.
+ *  Reallocate the memory pointed to by the handle.
  */
 
-unsigned int EDIT_TextReAlloc(EDITSTATE *es, unsigned int handle, int bytes)
+unsigned int EDIT_HeapReAlloc(HWND hwnd, unsigned int handle, int bytes)
 {
-    return ((unsigned int)HEAP_ReAlloc(es->localheap, 
-				       EDIT_TextAddr(es, handle),
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+    return ((unsigned int)HEAP_ReAlloc((MDESC **)
+				       *(LONG *)(wndPtr->wExtra + 2), 
+				       EDIT_HeapAddr(hwnd, handle),
 				       bytes, GMEM_MOVEABLE) & 0xffff);
 }
 
 
 /*********************************************************************
+ *  EDIT_HeapFree
+ *
+ *  Frees the memory pointed to by the handle.
+ */
+
+void EDIT_HeapFree(HWND hwnd, unsigned int handle)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+    HEAP_Free((MDESC **)*(LONG *)(wndPtr->wExtra + 2), 
+	      EDIT_HeapAddr(hwnd, handle));
+}
+
+
+/*********************************************************************
+ *  EDIT_HeapSize
+ *
+ *  Return the size of the given object on the local heap.
+ */
+
+unsigned int EDIT_HeapSize(HWND hwnd, unsigned int handle)
+{
+    WND *wndPtr = WIN_FindWndPtr(hwnd);
+
+    return HEAP_LocalSize((MDESC **)*(LONG *)(wndPtr->wExtra + 2), handle);
+}
+
+
+/*********************************************************************
  *  EM_SETHANDLE message function
  */
 
@@ -2891,12 +3084,13 @@
 {
     MDESC *m;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     if (IsMultiLine())
     {
 	es->hText = wParam;
-	es->MaxTextLen = HEAP_LocalSize(es->localheap, es->hText);
+	es->MaxTextLen = EDIT_HeapSize(hwnd, es->hText);
 	es->wlines = 0;
 	es->wtop = es->wleft = 0;
 	es->CurrLine = es->CurrCol = 0;
@@ -2921,21 +3115,22 @@
 {
     unsigned short *tabstops;
     WND *wndPtr = WIN_FindWndPtr(hwnd);
-    EDITSTATE *es = (EDITSTATE *)EDIT_HEAP_ADDR((HANDLE)(*(wndPtr->wExtra)));
+    EDITSTATE *es = 
+	(EDITSTATE *)EDIT_HeapAddr(hwnd, (HANDLE)(*(wndPtr->wExtra)));
 
     es->NumTabStops = wParam;
     if (wParam == 0)
-	es->hTabStops = EDIT_HEAP_REALLOC(es->hTabStops, 1);
+	es->hTabStops = EDIT_HeapReAlloc(hwnd, es->hTabStops, 1);
     else if (wParam == 1)
     {
-	es->hTabStops = EDIT_HEAP_REALLOC(es->hTabStops, 1);
-	tabstops = (unsigned short *)EDIT_HEAP_ADDR(es->hTabStops);
+	es->hTabStops = EDIT_HeapReAlloc(hwnd, es->hTabStops, 1);
+	tabstops = (unsigned short *)EDIT_HeapAddr(hwnd, es->hTabStops);
 	*tabstops = (unsigned short)lParam;
     }
     else
     {
-	es->hTabStops = EDIT_HEAP_REALLOC(es->hTabStops, wParam);
-	tabstops = (unsigned short *)EDIT_HEAP_ADDR(es->hTabStops);
+	es->hTabStops = EDIT_HeapReAlloc(hwnd, es->hTabStops, wParam);
+	tabstops = (unsigned short *)EDIT_HeapAddr(hwnd, es->hTabStops);
 	memcpy(tabstops, (unsigned short *)lParam, wParam);
     }
     return 0L;
diff --git a/controls/menu.c b/controls/menu.c
index 7b05747..5e3dee5 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -156,7 +156,7 @@
 									hwnd, lppop->Width, lppop->Height);
 #endif
 			SetWindowPos(hwnd, 0, 0, 0, lppop->Width + 2, lppop->Height, 
-									SWP_NOZORDER | SWP_NOMOVE);
+									SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE );
 #ifdef DEBUG_MENU
 			printf("PopupMenuWndProc // End of WM_SHOWWINDOW !\n");
 #endif
@@ -1135,7 +1135,7 @@
 #endif
 	hOldFont = SelectObject(hDC, GetStockObject(SYSTEM_FONT));
 	lppop->CheckWidth = 0;
-	LineHeight = OldHeight = SYSMETRICS_CYMENU + 2;
+	LineHeight = OldHeight = SYSMETRICS_CYMENU + 1;
 	SetRect(&rect, lprect->left, lprect->top, 0, lprect->top + LineHeight);
 	lpitem2 = lppop->firstItem;
 	while (lpitem != NULL) {
@@ -1202,6 +1202,29 @@
 
 
 /***********************************************************************
+ *           MENU_GetMenuBarHeight
+ *
+ * Compute the size of the menu bar height. Used by NC_HandleNCCalcSize().
+ */
+WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth )
+{
+    HDC hdc;
+    RECT rectBar;
+    WND *wndPtr;
+    LPPOPUPMENU lppop;
+
+    if (!(lppop = PopupMenuGetWindowAndStorage( hwnd, &wndPtr ))) return 0;
+    if (!wndPtr) return 0;
+    hdc = GetDC( hwnd );
+    SetRect( &rectBar, 0, 0, menubarWidth, SYSMETRICS_CYMENU );
+    MenuBarCalcSize( hdc, &rectBar, lppop );
+    ReleaseDC( hwnd, hdc );
+    printf( "MENU_GetMenuBarHeight: returning %d\n", lppop->Height );
+    return lppop->Height;
+}
+
+
+/***********************************************************************
  *           FindMenuItem
  */
 LPMENUITEM FindMenuItem(HMENU hMenu, WORD nPos, WORD wFlags)
@@ -1844,7 +1867,7 @@
 			}
 		}
 	else {
-		ShowWindow(lppop->hWnd, SW_SHOW);
+		ShowWindow(lppop->hWnd, SW_SHOWNOACTIVATE);
 		}
 	if (!lppop->BarFlag) {
 		PopupMenuCalcSize(lppop->hWnd);
@@ -1853,7 +1876,7 @@
 			x, y, lppop->Width, lppop->Height); 
 #endif
 		SetWindowPos(lppop->hWnd, 0, x, y, lppop->Width + 2, lppop->Height, 
-			SWP_NOZORDER);
+			SWP_NOACTIVATE | SWP_NOZORDER);
 		}
 	SetFocus(lppop->hWnd);
 	if (!MenuHasFocus) {
@@ -2208,7 +2231,7 @@
 #endif
 	if (GetCapture() == hWnd) ReleaseCapture();
 	if (wndPtr->window != 0) {
-		flags = SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED;
+		flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED;
 /*		if (!IsWindowVisible(hWnd)) flags |= SWP_NOREDRAW; */
 		flags |= SWP_NOREDRAW;
 		if (hMenu == 0) {
diff --git a/controls/widgets.c b/controls/widgets.c
index 356c606..204b65f 100644
--- a/controls/widgets.c
+++ b/controls/widgets.c
@@ -34,9 +34,9 @@
       0, 0, 0, 0, NULL, "LISTBOX" },
     { CS_GLOBALCLASS, (LONG(*)())ComboBoxWndProc, 0, 8,
       0, 0, 0, 0, NULL, "COMBOBOX" },
-    { CS_GLOBALCLASS, (LONG(*)())EditWndProc, 0, 2, 
+    { CS_GLOBALCLASS, (LONG(*)())EditWndProc, 0, 4, 
       0, 0, 0, 0, NULL, "EDIT" },
-    { CS_GLOBALCLASS, (LONG(*)())PopupMenuWndProc, 0, 8,
+    { CS_GLOBALCLASS | CS_SAVEBITS, (LONG(*)())PopupMenuWndProc, 0, 8,
       0, 0, 0, 0, NULL, "POPUPMENU" },
     { CS_GLOBALCLASS, (LONG(*)())DesktopWndProc, 0, sizeof(DESKTOPINFO),
       0, 0, 0, 0, NULL, DESKTOP_CLASS_NAME },
diff --git a/if1632/Imakefile b/if1632/Imakefile
index 601424d..f686a92 100644
--- a/if1632/Imakefile
+++ b/if1632/Imakefile
@@ -3,10 +3,16 @@
 
 MODULE = if1632
 
+#ifdef WINELIB
+SRCS = \
+	callback.c \
+	relay.c
+#else
 SRCS = \
 	call.S \
 	callback.c \
 	relay.c
+#endif
 
 DLLOBJS = \
 	dll_gdi.o \
@@ -23,6 +29,10 @@
 	dll_win87em.o \
 	dll_winsock.o
 
+#ifdef WINELIB
+DLLOBJS=
+#endif
+
 OBJS1= $(SRCS:.S=.o)
 
 #ifndef NewBuild
diff --git a/if1632/callback.c b/if1632/callback.c
index 676fc7e..3d9fefc 100644
--- a/if1632/callback.c
+++ b/if1632/callback.c
@@ -1,3 +1,4 @@
+#ifndef WINELIB
 static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
 static char Copyright[] = "Copyright  Robert J. Amstadt, 1993";
 
@@ -324,3 +325,4 @@
 #endif
 	longjmp (sb -> buffer, val);
 }
+#endif /* !WINELIB */
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index bc4a231..b39fef7 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -273,7 +273,7 @@
 	   CreateRoundRectRgn(1 2 3 4 5 6)
 445 pascal CreateDIBPatternBrush(word word) CreateDIBPatternBrush(1 2)
 #449 pascal DEVICECOLORMATCH
-#450 pascal POLYPOLYGON
+450 pascal PolyPolygon(word ptr ptr word) PolyPolygon(1 2 3 4)
 451 pascal CreatePolyPolygonRgn(ptr ptr word word)
 	   CreatePolyPolygonRgn(1 2 3 4)
 #452 pascal GDISEEGDIDO
diff --git a/if1632/relay.c b/if1632/relay.c
index bfd7fcb..9de7655 100644
--- a/if1632/relay.c
+++ b/if1632/relay.c
@@ -24,24 +24,31 @@
 
 #define DEBUG_RELAY /* */
 
+#ifdef WINELIB
+#define WineLibSkip(x) 0
+#else
+#define WineLibSkip(x) x
+#endif
+
 struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] =
 {
-    { "KERNEL",  KERNEL_table, 	410, 1 },
-    { "USER",    USER_table, 	540, 2 },
-    { "GDI",     GDI_table, 	490, 3 },
-    { "UNIXLIB", UNIXLIB_table,  10, 4 },
-    { "WIN87EM", WIN87EM_table,  10, 5 },
-    { "SHELL",   SHELL_table,   256, 6 },
-    { "SOUND",   SOUND_table,    20, 7 },
-    { "KEYBOARD",KEYBOARD_table,137, 8 },
-    { "WINSOCK", WINSOCK_table, 155, 9 },
-    { "STRESS",  STRESS_table,   15, 10},
-    { "MMSYSTEM",MMSYSTEM_table,1226,11},
-    { "SYSTEM",  SYSTEM_table,   20 ,12},
-    { "TOOLHELP",TOOLHELP_table, 83, 13},
+    { "KERNEL",  WineLibSkip(KERNEL_table), 	410, 1 },
+    { "USER",    WineLibSkip(USER_table), 	540, 2 },
+    { "GDI",     WineLibSkip(GDI_table), 	490, 3 },
+    { "UNIXLIB", WineLibSkip(UNIXLIB_table),  10, 4 },
+    { "WIN87EM", WineLibSkip(WIN87EM_table),  10, 5 },
+    { "SHELL",   WineLibSkip(SHELL_table),   103, 6 },
+    { "SOUND",   WineLibSkip(SOUND_table),    20, 7 },
+    { "KEYBOARD",WineLibSkip(KEYBOARD_table),137, 8 },
+    { "WINSOCK", WineLibSkip(WINSOCK_table), 155, 9 },
+    { "STRESS",  WineLibSkip(STRESS_table),   15, 10},
+    { "MMSYSTEM",WineLibSkip(MMSYSTEM_table),1226,11},
+    { "SYSTEM",  WineLibSkip(SYSTEM_table),   20 ,12},
+    { "TOOLHELP",WineLibSkip(TOOLHELP_table), 83, 13},
 };
 /* don't forget to increase N_BUILTINS in dll.h if you add a dll */
 
+#ifndef WINELIB
 unsigned short *Stack16Frame;
 
 extern unsigned long  IF1632_Saved16_esp;
@@ -211,6 +218,7 @@
     Stack16Frame = saved_Stack16Frame;
     return ret_val;
 }
+#endif
 
 /**********************************************************************
  *					FindDLLTable
@@ -222,8 +230,11 @@
 
     for (i = 0; i < N_BUILTINS; i++)
 	if (strcasecmp(dll_builtin_table[i].dll_name, dll_name) == 0)
+#ifdef WINELIB
+	    return dll_builtin_table[i].dll_number;
+#else
 	    return dll_builtin_table[i].dll_table;
-    
+#endif
     return NULL;
 }
 
@@ -258,6 +269,7 @@
     return arg;
 }
 
+#ifndef WINELIB
 #ifdef WINESTAT
 void winestat(){
 	int i, j;
@@ -294,3 +306,4 @@
 	printf("TOTAL: %d of %d implemented (%3.1f %%)\n",timplemented, tused, perc);
 }
 #endif /* WINESTAT */
+#endif /* !WINELIB */
diff --git a/if1632/system.spec b/if1632/system.spec
index b37eb9f..e54f67f 100644
--- a/if1632/system.spec
+++ b/if1632/system.spec
@@ -1,3 +1,5 @@
 name	system
 id	12
 length	20
+
+6 pascal GetSystemmsecCount() GetTickCount()
diff --git a/if1632/toolhelp.spec b/if1632/toolhelp.spec
index fe1e180..682dec5 100644
--- a/if1632/toolhelp.spec
+++ b/if1632/toolhelp.spec
@@ -11,10 +11,10 @@
 # 56   1  090e  LOCALINFO exported, shared data
 # 57   1  095e  LOCALFIRST exported, shared data
 # 58   1  09e9  LOCALNEXT exported, shared data
-#59 pascal ModuleFirst(ptr) ModuleFirst(1)
-#60 pascal ModuleNext(ptr) ModuleNext(1)
-#61 pascal ModuleFindName(ptr ptr) ModuleFindName(1 2)
-#62 pascal ModuleFindHandle(ptr word) ModuleFindHandle(1 2)
+59 pascal ModuleFirst(ptr) ModuleFirst(1)
+60 pascal ModuleNext(ptr) ModuleNext(1)
+61 pascal ModuleFindName(ptr ptr) ModuleFindName(1 2)
+62 pascal ModuleFindHandle(ptr word) ModuleFindHandle(1 2)
 # 63   1  0caa  TASKFIRST exported, shared data
 # 64   1  0ced  TASKNEXT exported, shared data
 # 65   1  0d2e  TASKFINDHANDLE exported, shared data
diff --git a/if1632/user.spec b/if1632/user.spec
index 2023ed5..edb86b9 100644
--- a/if1632/user.spec
+++ b/if1632/user.spec
@@ -291,6 +291,7 @@
 278 pascal GetDeskTopHwnd() GetDesktopWindow()
 #279 OLDSETDESKPATTERN
 #280 SETSYSTEMMENU
+281 pascal GetSysColorBrush(word) GetSysColorBrush(1)
 282 pascal SelectPalette(word word word) SelectPalette(1 2 3)
 283 pascal RealizePalette(word) RealizePalette(1)
 284 pascal GetFreeSystemResources(word) GetFreeSystemResources(1)
diff --git a/include/desktop.h b/include/desktop.h
index 38b7868..e7667a2 100644
--- a/include/desktop.h
+++ b/include/desktop.h
@@ -13,6 +13,8 @@
 {
     HBRUSH   hbrushPattern;
     HBITMAP  hbitmapWallPaper;
+    SIZE     bitmapSize;
+    BOOL     fTileWallPaper;
 } DESKTOPINFO;
 
 extern BOOL DESKTOP_SetPattern(char *pattern );
diff --git a/include/windows.h b/include/windows.h
index c389455..3f14d8b 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -1038,6 +1038,15 @@
 typedef struct { BYTE rgbBlue, rgbGreen, rgbRed, rgbReserved; } RGBQUAD;
 typedef struct { BYTE rgbtBlue, rgbtGreen, rgbtRed; } RGBTRIPLE;
 
+typedef struct
+{
+    UINT    bfType;
+    DWORD   bfSize WINE_PACKED;
+    UINT    bfReserved1 WINE_PACKED;
+    UINT    bfReserved2 WINE_PACKED;
+    DWORD   bfOffBits WINE_PACKED;
+} BITMAPFILEHEADER;
+
 typedef struct tagBITMAPINFOHEADER
 {
     DWORD 	biSize;
@@ -2899,7 +2908,7 @@
 Fd(BOOL,GetCharWidth,HDC,a,WORD,b,WORD,c,LPINT,d)
 Fd(BOOL,HiliteMenuItem,HWND,a,HMENU,b,WORD,c,WORD,d)
 Fd(BOOL,MoveToEx,HDC,a,short,b,short,c,LPPOINT,d)
-Fd(BOOL,PolyPolygon,HDC,a,LPPOINT,b,LPINT,c,int,d)
+Fd(BOOL,PolyPolygon,HDC,a,LPPOINT,b,LPINT,c,WORD,d)
 Fd(BOOL,PostAppMessage,HANDLE,a,WORD,b,WORD,c,LONG,d)
 Fd(BOOL,RedrawWindow,HWND,a,LPRECT,b,HRGN,c,UINT,d)
 Fd(BOOL,SetBitmapDimensionEx,HBITMAP,a,short,b,short,c,LPSIZE,d)
@@ -3022,4 +3031,7 @@
 Fm(int,StretchDIBits,HDC,a,WORD,b,WORD,c,WORD,d,WORD,e,WORD,f,WORD,g,WORD,h,WORD,i,LPSTR,j,LPBITMAPINFO,k,WORD,l,DWORD,m)
 Fn(HFONT,CreateFont,int,a,int,b,int,c,int,d,int,e,BYTE,f,BYTE,g,BYTE,h,BYTE,i,BYTE,j,BYTE,k,BYTE,l,BYTE,m,LPSTR,n)
 
+#ifdef WINELIB
+#define WINELIB_UNIMP(x) fprintf (stderr, "WineLib: Unimplemented %s\n", x)
+#endif
 #endif  /* WINDOWS_H */
diff --git a/loader/ldtlib.c b/loader/ldtlib.c
index c264979..40929d6 100644
--- a/loader/ldtlib.c
+++ b/loader/ldtlib.c
@@ -64,6 +64,9 @@
     ldt_info.contents       = contents;
     ldt_info.read_exec_only = read_only_flag;
     ldt_info.limit_in_pages = limit_in_pages_flag;
+#ifdef NEW_LDT_STRUCT
+    ldt_info.seg_not_present = 0;
+#endif
 
     return modify_ldt(1, &ldt_info, sizeof(ldt_info));
 #endif
diff --git a/loader/library.c b/loader/library.c
index 8253cb5..2ceb59d 100644
--- a/loader/library.c
+++ b/loader/library.c
@@ -212,6 +212,9 @@
  */
 FARPROC GetProcAddress(HANDLE hModule, char *proc_name)
 {
+#ifdef WINELIB
+    WINELIB_UNIMP ("GetProcAddress");
+#else
     int		i, sel, addr, ret;
     register struct w_files *w = wine_files;
     int 	ordinal, len;
@@ -312,6 +315,7 @@
     sel = (ret >> 16);
     printf("GetProcAddress // ret=%08X sel=%04X addr=%04X\n", ret, sel, addr);
     return (FARPROC) ret;
+#endif /* WINELIB */
 }
 
 /* internal dlls */
diff --git a/loader/main.c b/loader/main.c
index 459e7bc..c1991d0 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -358,7 +358,7 @@
 		rv = CallTo16(cs_reg << 16 | ip_reg, ds_reg);
 		printf ("rv = %x\n", rv);
 	    } else
-		printf("%s skipped\n");
+		printf("%s skipped\n", wpnt->name);
 	}
 }
 
@@ -399,4 +399,9 @@
     for( ; wpnt != final_wpnt; wpnt = wpnt->next)
 	InitDLL(wpnt);
 }
+#else /* #ifndef WINELIB */
+void InitDLL(struct w_files *wpnt)
+{
+}
+
 #endif /* #ifndef WINELIB */
diff --git a/loader/ne_image.c b/loader/ne_image.c
index 98b3059..4247e6a 100644
--- a/loader/ne_image.c
+++ b/loader/ne_image.c
@@ -51,6 +51,7 @@
 	myerror("Unable to read NE header from file");
     }
 }
+#endif
 
 /**********************************************************************
  *			LoadNEImage
@@ -68,6 +69,7 @@
     status = lseek(wpnt->fd, wpnt->mz_header->ne_offset, SEEK_SET);
     load_ne_header (wpnt->fd, wpnt->ne_header);
 
+#ifndef WINELIB
     /*
      * Create segment selectors.
      */
@@ -83,7 +85,7 @@
     wpnt->hinstance = (wpnt->
 		       selector_table[wpnt->ne_header->auto_data_seg-1].
 		       selector);
-
+#endif
     /* Get the lookup  table.  This is used for looking up the addresses
        of functions that are exported */
 
@@ -131,6 +133,7 @@
       if (strcasecmp(buff, wpnt->name) != 0 )
 	LoadImage(buff, DLL, 0);
     }
+#ifndef WINELIB
     /* fixup references */
 
     for (segment = 0; segment < wpnt->ne_header->n_segment_tab; segment++)
@@ -139,7 +142,7 @@
 
     FixupFunctionPrologs(wpnt);
     InitializeLoadedDLLs(wpnt);
-
+#endif
     return(wpnt->hinstance);
 }
 
@@ -197,6 +200,7 @@
 }
 
 
+#ifndef WINELIB
 /**********************************************************************
  *					FixupSegment
  */
@@ -458,4 +462,4 @@
     return 0;
 }
 
-#endif
+#endif /* !WINELIB */
diff --git a/loader/resource.c b/loader/resource.c
index 7814e66..4211704 100644
--- a/loader/resource.c
+++ b/loader/resource.c
@@ -948,6 +948,7 @@
 	    GlobalFree(r->info_mem);
 	    return 0;
 	}
+	rp = r;
     }
     
     return hResData;
diff --git a/loader/signal.c b/loader/signal.c
index 861c04e..c0c52fb 100644
--- a/loader/signal.c
+++ b/loader/signal.c
@@ -90,8 +90,15 @@
 
 	/* First take care of a few preliminaries */
 #ifdef linux
-    if(signal != SIGSEGV && signal != SIGTRAP) 
+    if(signal != SIGSEGV 
+       && signal != SIGILL 
+#ifdef SIGBUS
+       && signal != SIGBUS 
+#endif
+       && signal != SIGTRAP) 
+    {
 	exit(1);
+    }
 
     /* And back up over the int3 instruction. */
     if(signal == SIGTRAP) {
@@ -151,6 +158,14 @@
 	    scp->sc_eip++;
             break;
 
+      case 0xfa: /* cli, ignored */
+	    scp->sc_eip++;
+            break;
+
+      case 0xfb: /* sti, ignored */
+	    scp->sc_eip++;
+            break;
+
       default:
 		fprintf(stderr, "Unexpected Windows program segfault"
 			" - opcode = %x\n", *instr);
@@ -191,6 +206,10 @@
 	segv_act.sa_restorer = 
 		(void (*)()) (((unsigned int)(cstack) + sizeof(cstack) - 4) & ~3);
 	wine_sigaction(SIGSEGV, &segv_act, NULL);
+	wine_sigaction(SIGILL, &segv_act, NULL);
+#ifdef SIGBUS
+	wine_sigaction(SIGBUS, &segv_act, NULL);
+#endif
 	wine_sigaction(SIGTRAP, &segv_act, NULL); /* For breakpoints */
 #endif
 #if defined(__NetBSD__) || defined(__FreeBSD__)
diff --git a/misc/audio.c b/misc/audio.c
index 153223f..dcdee0d 100644
--- a/misc/audio.c
+++ b/misc/audio.c
@@ -3,7 +3,7 @@
  *
  * Copyright 1994 Martin Ayotte
  */
-
+#ifndef WINELIB
 #define DEBUG_MCIWAVE
 
 static char Copyright[] = "Copyright  Martin Ayotte, 1994";
@@ -1507,3 +1507,4 @@
 }
 
 
+#endif /* !WINELIB */
diff --git a/misc/main.c b/misc/main.c
index 4e94a7a..4479cdc 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -287,16 +287,10 @@
 			 StructureNotifyMask;
     win_attr.cursor = XCreateFontCursor( display, XC_top_left_arrow );
 
-    if (Options.nobackingstore)
-       win_attr.backing_store = NotUseful;
-    else
-       win_attr.backing_store = Always;
-
     rootWindow = XCreateWindow( display, DefaultRootWindow(display),
 			        desktopX, desktopY, width, height, 0,
 			        CopyFromParent, InputOutput, CopyFromParent,
-			        CWEventMask | CWCursor |
-			        CWBackingStore, &win_attr );
+			        CWEventMask | CWCursor, &win_attr );
 
       /* Set window manager properties */
 
diff --git a/misc/mcicda.c b/misc/mcicda.c
index 55497be..3b49cde 100644
--- a/misc/mcicda.c
+++ b/misc/mcicda.c
@@ -3,7 +3,7 @@
  *
  * Copyright 1994 Martin Ayotte
  */
-
+#ifndef WINELIB
 static char Copyright[] = "Copyright  Martin Ayotte, 1994";
 
 /*
@@ -857,3 +857,4 @@
 
 /*-----------------------------------------------------------------------*/
 
+#endif
diff --git a/misc/mmaux.c b/misc/mmaux.c
index 64627d8..58bc85d 100644
--- a/misc/mmaux.c
+++ b/misc/mmaux.c
@@ -3,7 +3,7 @@
  *
  * Copyright 1994 Martin Ayotte
  */
-
+#ifndef WINELIB
 static char Copyright[] = "Copyright  Martin Ayotte, 1994";
 
 #include "stdio.h"
@@ -114,3 +114,4 @@
 }
 
 
+#endif /* !WINELIB */
diff --git a/misc/mmsystem.c b/misc/mmsystem.c
index da5ad6f..0e1eb91 100644
--- a/misc/mmsystem.c
+++ b/misc/mmsystem.c
@@ -3,7 +3,7 @@
  *
  * Copyright 1993 Martin Ayotte
  */
-
+#ifndef WINELIB
 static char Copyright[] = "Copyright  Martin Ayotte, 1993";
 
 #include "stdio.h"
@@ -614,9 +614,14 @@
 		printf("MCI_OPEN // wDeviceID=%04X !\n", lpParms->wDeviceID);
 		switch(dwDevTyp) {
 			case MCI_DEVTYPE_CD_AUDIO:
-				return CDAUDIO_DriverProc(0, 0, MCI_OPEN_DRIVER, 
+#ifdef WINELIB
+		    WINELIB_UNIMP ("CDAUDIO_DriverProc");
+#else
+				return CDAUDIO_DriverProc(0, 0, MCI_OPEN_DRIVER,
+
 									dwParam, (DWORD)lpParms);
-			case MCI_DEVTYPE_WAVEFORM_AUDIO:
+#endif
+		case MCI_DEVTYPE_WAVEFORM_AUDIO:
 				return WAVE_DriverProc(0, 0, MCI_OPEN_DRIVER, 
 									dwParam, (DWORD)lpParms);
 			case MCI_DEVTYPE_SEQUENCER:
@@ -646,8 +651,10 @@
 	printf("mciClose(%u, %08X, %08X)\n", wDevID, dwParam, lpParms);
 	switch(mciDrv[wDevID].wType) {
 		case MCI_DEVTYPE_CD_AUDIO:
+#ifndef WINELIB
 			dwRet = CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
 						MCI_CLOSE, dwParam, (DWORD)lpParms);
+#endif
 			break;
 		case MCI_DEVTYPE_WAVEFORM_AUDIO:
 			dwRet = WAVE_DriverProc(mciDrv[wDevID].wDeviceID, 0, 
@@ -692,8 +699,11 @@
 		default:
 			switch(mciDrv[wDevID].wType) {
 				case MCI_DEVTYPE_CD_AUDIO:
+#ifndef WINELIB
 					return CDAUDIO_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
 											wMsg, dwParam1, dwParam2);
+#endif
+					
 				case MCI_DEVTYPE_WAVEFORM_AUDIO:
 					return WAVE_DriverProc(mciDrv[wDevID].wDeviceID, hDrv, 
 											wMsg, dwParam1, dwParam2);
@@ -1984,7 +1994,9 @@
 	DWORD 	dwDevID = 0;
 	printf("DrvSendMessage(%04X, %04X, %08X, %08X);\n",
 					hDriver, msg, lParam1, lParam2);
+#ifndef WINELIB
 	return CDAUDIO_DriverProc(dwDevID, hDriver, msg, lParam1, lParam2);
+#endif
 }
 
 /**************************************************************************
@@ -2007,3 +2019,4 @@
 
 
 
+#endif
diff --git a/objects/brush.c b/objects/brush.c
index a12c455..3979836 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -143,6 +143,13 @@
     return retval;
 }
 
+/***********************************************************************
+ *           GetSysColorBrush    (USER.281)
+ */
+WORD GetSysColorBrush(WORD x)
+{
+	return GetStockObject(GRAY_BRUSH);
+}
 
 /***********************************************************************
  *           BRUSH_DeleteObject
diff --git a/objects/text.c b/objects/text.c
index 53c5bb0..0cb0686 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -74,7 +74,7 @@
 	case PREFIX:
 	    if (!(format & DT_NOPREFIX))
 	    {
-		prefix_offset = j + 1;
+		prefix_offset = j;
 		i++;
 	    }
 	    else
@@ -177,7 +177,7 @@
     SIZE size;
     char *strPtr;
     static char line[1024];
-    int len, lh, prefix_x, prefix_len;
+    int len, lh, prefix_x, prefix_end;
     TEXTMETRIC tm;
     int x = rect->left, y = rect->top;
     int width = rect->right - rect->left;
@@ -214,10 +214,10 @@
 
 	if (prefix_offset != -1)
 	{
-	    GetTextExtentPoint(hdc, line, prefix_offset - 1, &size);
+	    GetTextExtentPoint(hdc, line, prefix_offset, &size);
 	    prefix_x = size.cx;
-	    GetTextExtentPoint(hdc, line + prefix_offset, 1, &size);
-	    prefix_len = size.cx;
+	    GetTextExtentPoint(hdc, line, prefix_offset + 1, &size);
+	    prefix_end = size.cx - 1;
 	}
 
 	if (!GetTextExtentPoint(hdc, line, len, &size)) return 0;
@@ -235,8 +235,8 @@
 	    if (!TextOut(hdc, x, y, line, len)) return 0;
 	if (prefix_offset != -1)
 	{
-	    MoveTo(hdc, x + prefix_x, y + size.cy);
-	    LineTo(hdc, x + prefix_x + prefix_len, y + size.cy);
+	    MoveTo(hdc, x + prefix_x, y + tm.tmAscent + 1 );
+	    LineTo(hdc, x + prefix_end, y + tm.tmAscent + 1 );
 	}
 
 	if (strPtr)
diff --git a/toolkit/heap.c b/toolkit/heap.c
index 002257f..cc4e2d7 100644
--- a/toolkit/heap.c
+++ b/toolkit/heap.c
@@ -121,7 +121,7 @@
 #ifdef DEBUG_HEAP
     printf (">%d->%p\n", hMem, *m);
 #endif
-    return *m;
+    return m ? *m : 0;
 }
 
 HANDLE LocalReAlloc (HANDLE hMem, WORD flags, WORD bytes)
@@ -196,6 +196,16 @@
     return GlobalUnlock (hMem);
 }
 
+int HEAP_LocalSize ()
+{
+    return 0;
+}
+
+int HEAP_LocalFindHeap ()
+{
+    return 0;
+}
+
 #ifdef UNIMPLEMENTED
 void *GlobalQuickAlloc(int size)
 {
diff --git a/toolkit/winmain.c b/toolkit/winmain.c
index 3f68eb7..aa21d5e 100644
--- a/toolkit/winmain.c
+++ b/toolkit/winmain.c
@@ -8,6 +8,7 @@
 {
     int ret_val;
     char filename [4096];
+    HANDLE hTaskMain;
     
     GetPrivateProfileString("wine", "SystemResources", "sysres.dll", 
 			    filename, sizeof(filename), WINE_INI);
@@ -18,6 +19,7 @@
 	printf("System Resources Loaded // hSysRes='%04X'\n", hSysRes);
 
     USER_InitApp (hSysRes);
+    hTaskMain = CreateNewTask (1); /* This is not correct */
     ret_val = WinMain (1,		/* hInstance */
 		       0,		/* hPrevInstance */
 		       "",		/* lpszCmdParam */
diff --git a/windows/defwnd.c b/windows/defwnd.c
index e91e3a8..8ae88a0 100644
--- a/windows/defwnd.c
+++ b/windows/defwnd.c
@@ -22,6 +22,7 @@
 extern LONG NC_HandleNCLButtonDblClk( HWND hwnd, WORD wParam, LONG lParam );
 extern LONG NC_HandleSysCommand( HWND hwnd, WORD wParam, POINT pt );
 extern LONG NC_HandleSetCursor( HWND hwnd, WORD wParam, LONG lParam );
+extern LONG WINPOS_HandleWindowPosChanging( WINDOWPOS *winpos ); /* winpos.c */
 extern void NC_TrackSysMenu( HWND hwnd ); /* menu.c */
 extern BOOL ActivateMenuBarFocus(HWND hWnd); /* menu.c */
 
@@ -126,6 +127,9 @@
 	if (wParam) SetFocus( hwnd );
 	break;
 
+    case WM_WINDOWPOSCHANGING:
+	return WINPOS_HandleWindowPosChanging( (WINDOWPOS *)lParam );
+
     case WM_WINDOWPOSCHANGED:
 	{
 	    WINDOWPOS * winPos = (WINDOWPOS *)lParam;
diff --git a/windows/graphics.c b/windows/graphics.c
index c21eff3..089e3cc 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -105,8 +105,8 @@
 BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom,
 		    int xstart, int ystart, int xend, int yend, int lines )
 {
-    int xcenter, ycenter;
-    double start_angle, end_angle, diff_angle;
+    int xcenter, ycenter, istart_angle, idiff_angle;
+    double start_angle, end_angle;
     XPoint points[3];
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
     if (!dc) 
@@ -151,16 +151,15 @@
 			 (double)(xstart-xcenter)*(bottom-top) );
     end_angle   = atan2( (double)(ycenter-yend)*(right-left),
 			 (double)(xend-xcenter)*(bottom-top) );
-    diff_angle  = end_angle - start_angle;
-    if (diff_angle < 0.0) diff_angle += 2*PI;
+    istart_angle = (int)(start_angle * 180 * 64 / PI);
+    idiff_angle  = (int)((end_angle - start_angle) * 180 * 64 / PI );
+    if (idiff_angle <= 0) idiff_angle += 360 * 64;
     if (left > right) swap_int( &left, &right );
     if (top > bottom) swap_int( &top, &bottom );
 
     XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
 	      dc->w.DCOrgX + left, dc->w.DCOrgY + top,
-	      right-left-1, bottom-top-1,
-	      (int)(start_angle * 180 * 64 / PI),
-	      (int)(diff_angle * 180 * 64 / PI) );
+	      right-left-1, bottom-top-1, istart_angle, idiff_angle );
     if (!lines) return TRUE;
 
     points[0].x = dc->w.DCOrgX + xcenter + (int)(cos(start_angle) * (right-left) / 2);
@@ -656,7 +655,7 @@
 {
     register int i;
     DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
-    XPoint *points = (XPoint *) malloc (sizeof (XPoint) * count+1);
+    XPoint *points = (XPoint *) malloc (sizeof (XPoint) * (count+1));
 
     if (!dc) 
     {
@@ -666,29 +665,78 @@
 	return TRUE;
     }
 
-    if (DC_SetupGCForBrush( dc ))
+    for (i = 0; i < count; i++)
     {
-    		
-	for (i = 0; i < count; i++)
-	{
-	    points [i].x = dc->w.DCOrgX + XLPTODP(dc, pt [i].x);
-	    points [i].y = dc->w.DCOrgY + YLPTODP(dc, pt [i].y);
-	}
-	points [count] = points [0];
-		
-	XFillPolygon( display, dc->u.x.drawable, dc->u.x.gc,
-		     points, count, Complex, CoordModeOrigin);
-		
-	if (DC_SetupGCForPen ( dc ))
-	{
-	    XDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
-		       points, count, CoordModeOrigin );
-	}
+	points[i].x = dc->w.DCOrgX + XLPTODP( dc, pt[i].x );
+	points[i].y = dc->w.DCOrgY + YLPTODP( dc, pt[i].y );
     }
-    free ((void *) points);
-    return (TRUE);
+    points[count] = points[0];
+
+    if (DC_SetupGCForBrush( dc ))
+	XFillPolygon( display, dc->u.x.drawable, dc->u.x.gc,
+		     points, count+1, Complex, CoordModeOrigin);
+
+    if (DC_SetupGCForPen ( dc ))
+	XDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
+		   points, count+1, CoordModeOrigin );
+
+    free( points );
+    return TRUE;
 }
 
+
+/**********************************************************************
+ *          PolyPolygon  (GDI.450)
+ */
+BOOL PolyPolygon( HDC hdc, LPPOINT pt, LPINT counts, WORD polygons )
+{
+    int i;
+    HRGN hrgn;
+    DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
+
+    if (!dc) 
+    {
+	dc = (DC *)GDI_GetObjPtr(hdc, METAFILE_DC_MAGIC);
+	if (!dc) return FALSE;
+	/* MF_MetaPoly(dc, META_POLYGON, pt, count); */
+	return TRUE;
+    }
+      /* The points should be converted to device coords before */
+      /* creating the region. But as CreatePolyPolygonRgn is not */
+      /* really correct either, it doesn't matter much... */
+      /* At least the outline will be correct :-) */
+    hrgn = CreatePolyPolygonRgn( pt, counts, polygons, dc->w.polyFillMode );
+    PaintRgn( hdc, hrgn );
+    DeleteObject( hrgn );
+
+      /* Draw the outline of the polygons */
+
+    if (DC_SetupGCForPen ( dc ))
+    {
+	int i, j, max = 0;
+	XPoint *points;
+
+	for (i = 0; i < polygons; i++) if (counts[i] > max) max = counts[i];
+	points = (XPoint *) malloc( sizeof(XPoint) * (max+1) );
+
+	for (i = 0; i < polygons; i++)
+	{
+	    for (j = 0; j < counts[i]; j++)
+	    {
+		points[j].x = dc->w.DCOrgX + XLPTODP( dc, pt->x );
+		points[j].y = dc->w.DCOrgY + YLPTODP( dc, pt->y );
+		pt++;
+	    }
+	    points[j] = points[0];
+	    XDrawLines( display, dc->u.x.drawable, dc->u.x.gc,
+		        points, j + 1, CoordModeOrigin );
+	}
+	free( points );
+    }
+    return TRUE;
+}
+
+
 /**********************************************************************
  *          FloodFill_rec -- FloodFill helper function
  *
diff --git a/windows/icon.c b/windows/icon.c
index dc9648e..ba7d94d 100644
--- a/windows/icon.c
+++ b/windows/icon.c
@@ -26,8 +26,8 @@
 	WND *parwPtr;
 	
 #ifdef DEBUG_ICON
-#endif
 	printf("ICON_Iconify %d\n", hwnd);
+#endif
 
 	parwPtr = WIN_FindWndPtr(wndPtr->hwndParent);
 	if (parwPtr == NULL) {
@@ -40,8 +40,10 @@
 		printf("argh, couldn't find icon\n");
 		exit(1);
 	}
+#ifdef DEBUG_ICON
 	printf("parent edge values are %d, %d\n",  parwPtr->rectWindow.left,
 				parwPtr->rectWindow.bottom);
+#endif
 	wndPtr->ptIconPos.x = parwPtr->rectWindow.left + 10;
 	wndPtr->ptIconPos.y = parwPtr->rectWindow.bottom - 80;
 
@@ -68,7 +70,9 @@
 	XMapWindow(display, wndPtr->icon);
 
 	SendMessage(hwnd, WM_PAINTICON, 0, 0);
+#ifdef DEBUG_ICON
         printf("done with iconify\n");
+#endif
 }
 
 
@@ -94,7 +98,7 @@
       		iconWidth = 64;
       		iconHeight = 64;
     	}	
-#define DEBUG_ICON 1
+
 #ifdef DEBUG_ICON
         printf("icon x,y is %d,%d\n",
 		wndPtr->ptIconPos.x, wndPtr->ptIconPos.y);
@@ -124,7 +128,9 @@
             (wndPtr->dwStyle & WS_VISIBLE) &&
             !(wndPtr->dwExStyle & WS_EX_TRANSPARENT))
         {
+#ifdef DEBUG_ICON
 		printf("got a winner!\n");
+#endif
 		return 1;
         } 
  
@@ -142,10 +148,14 @@
 
         	if ( !(wndPtr=WIN_FindWndPtr(hwnd)))  return 0;
       		if (ICON_isAtPoint(hwnd, pt))  {
+#ifdef DEBUG_ICON
 			printf("returning\n");
+#endif
 			return hwndRet = hwnd;
 		} else {
+#ifdef DEBUG_ICON
 			printf("checking child\n");
+#endif
       			hwnd = wndPtr->hwndChild;
 		}
     	}
@@ -157,7 +167,9 @@
 {
 	WND *wndPtr = WIN_FindWndPtr( hwnd );
 
+#ifdef DEBUG_ICON
 	printf("deiconifying\n");
+#endif
 	XUnmapWindow(display, wndPtr->icon); 
 	wndPtr->dwStyle &= ~WS_MINIMIZE;
 /*	wndPtr->rectNormal = myrect;
diff --git a/windows/nonclient.c b/windows/nonclient.c
index f799826..edc5ac2 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -27,6 +27,7 @@
 extern void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
 			    POINT *minTrack, POINT *maxTrack );  /* winpos.c */
 extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor );   /* cursor.c */
+extern WORD MENU_GetMenuBarHeight( HWND hwnd, WORD menubarWidth ); /* menu.c */
 
 
   /* Some useful macros */
@@ -117,13 +118,17 @@
 
     if (!wndPtr) return 0;
 
-    NC_AdjustRect( &tmpRect, wndPtr->dwStyle,
-		   HAS_MENU(wndPtr), wndPtr->dwExStyle );
-    
+    NC_AdjustRect( &tmpRect, wndPtr->dwStyle, FALSE, wndPtr->dwExStyle );
     params->rgrc[0].left   -= tmpRect.left;
     params->rgrc[0].top    -= tmpRect.top;
     params->rgrc[0].right  -= tmpRect.right;
     params->rgrc[0].bottom -= tmpRect.bottom;
+
+    if (HAS_MENU(wndPtr))
+    {
+	params->rgrc[0].top += MENU_GetMenuBarHeight( hwnd,
+				params->rgrc[0].right - params->rgrc[0].left );
+    }
     return 0;
 }
 
diff --git a/windows/win.c b/windows/win.c
index d768512..f03902d 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -24,6 +24,11 @@
 extern void EVENT_RegisterWindow( Window w, HWND hwnd );  /* event.c */
 extern void CURSOR_SetWinCursor( HWND hwnd, HCURSOR hcursor );  /* cursor.c */
 extern void WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ); /*winpos.c*/
+extern LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect,
+				   RECT *newWindowRect, RECT *oldWindowRect,
+				   RECT *oldClientRect, WINDOWPOS *winpos,
+				   RECT *newClientRect );  /* winpos.c */
+
 extern HMENU CopySysMenu(); /* menu.c */
 extern LONG MDIClientWndProc(HWND hwnd, WORD message, 
 			     WORD wParam, LONG lParam); /* mdi.c */
@@ -453,19 +458,8 @@
     if (!wmcreate) wmcreate = -1;
     else
     {
-	  /* Send WM_NCCALCSIZE message */
-	NCCALCSIZE_PARAMS *params;
-	HANDLE hparams;
-	hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) );
-	if (hparams)
-	{
-	    params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
-	    params->rgrc[0] = wndPtr->rectWindow;
-	    params->lppos = NULL;
-	    SendMessage( hwnd, WM_NCCALCSIZE, FALSE, (LONG)params );
-	    wndPtr->rectClient = params->rgrc[0];
-	    USER_HEAP_FREE( hparams );
-	}	
+	WINPOS_SendNCCalcSize( hwnd, FALSE, &wndPtr->rectWindow,
+			       NULL, NULL, NULL, &wndPtr->rectClient );
 	wmcreate = SendMessage( hwnd, WM_CREATE, 0, (LONG)createStruct );
     }
 
diff --git a/windows/winpos.c b/windows/winpos.c
index a9fe9a6..f60ea4a 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -438,6 +438,234 @@
 
 
 /***********************************************************************
+ *           WINPOS_SendNCCalcSize
+ *
+ * Send a WM_NCCALCSIZE message to a window.
+ * All parameters are read-only except newClientRect.
+ * oldWindowRect, oldClientRect and winpos must be non-NULL only
+ * when calcValidRect is TRUE.
+ */
+LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect, RECT *newWindowRect,
+			    RECT *oldWindowRect, RECT *oldClientRect,
+			    WINDOWPOS *winpos, RECT *newClientRect )
+{
+    NCCALCSIZE_PARAMS *params;
+    HANDLE hparams;
+    LONG result;
+
+    if (!(hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) )))
+	return 0;
+    params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
+    params->rgrc[0] = *newWindowRect;
+    if (calcValidRect)
+    {
+	params->rgrc[1] = *oldWindowRect;
+	params->rgrc[2] = *oldClientRect;
+	params->lppos = winpos;
+    }
+    result = SendMessage( hwnd, WM_NCCALCSIZE, calcValidRect, (LONG)params);
+    *newClientRect = params->rgrc[0];
+    USER_HEAP_FREE( hparams );
+    return result;
+}
+
+
+/***********************************************************************
+ *           WINPOS_HandleWindowPosChanging
+ *
+ * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
+ */
+LONG WINPOS_HandleWindowPosChanging( WINDOWPOS *winpos )
+{
+    POINT maxSize;
+    WND *wndPtr = WIN_FindWndPtr( winpos->hwnd );
+    if (!wndPtr || (winpos->flags & SWP_NOSIZE)) return 0;
+    if ((wndPtr->dwStyle & WS_THICKFRAME) ||
+	(wndPtr->dwStyle & (WS_POPUP | WS_CHILD) == 0))
+    {
+	WINPOS_GetMinMaxInfo( winpos->hwnd, &maxSize, NULL, NULL, NULL );
+	winpos->cx = min( winpos->cx, maxSize.x );
+	winpos->cy = min( winpos->cy, maxSize.y );
+    }
+    return 0;
+}
+
+
+/***********************************************************************
+ *           WINPOS_InternalSetWindowPos
+ *
+ * Helper function for SetWindowPos.
+ */
+static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos )
+{
+    HWND hwndAfter;
+    WND *wndPtr;
+    RECT newWindowRect, newClientRect;
+    int flags, result;
+    int changeMask = 0;
+    XWindowChanges winChanges;
+
+      /* Send WM_WINDOWPOSCHANGING message */
+
+    if (!(winpos->flags & SWP_NOSENDCHANGING))
+	SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winpos );
+
+      /* Check window handle */
+
+    if (winpos->hwnd == GetDesktopWindow()) return FALSE;
+    if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE;
+
+      /* Check dimensions */
+
+    if (winpos->cx <= 0) winpos->cx = 1;
+    if (winpos->cy <= 0) winpos->cy = 1;
+
+      /* Check flags */
+
+    flags = winpos->flags;
+    if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
+	flags |= SWP_NOMOVE | SWP_NOSIZE;
+    if (winpos->hwnd == hwndActive) flags |= SWP_NOACTIVATE; /*Already active*/
+
+      /* Check hwndAfter */
+
+    hwndAfter = winpos->hwndInsertAfter;
+    if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
+    {
+	  /* Ignore TOPMOST flags when activating a window */
+          /* _and_ moving it in Z order. */
+	if ((hwndAfter == HWND_TOPMOST) || (hwndAfter == HWND_NOTOPMOST))
+	    hwndAfter = HWND_TOP;	
+    }
+      /* TOPMOST not supported yet */
+    if ((hwndAfter == HWND_TOPMOST) || (hwndAfter == HWND_NOTOPMOST))
+	hwndAfter = HWND_TOP;
+      /* hwndAfter must be a sibling of the window */
+    if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM) &&
+	(GetParent(winpos->hwnd) != GetParent(hwndAfter))) return FALSE;
+
+      /* Calculate new position and size */
+
+    newWindowRect = wndPtr->rectWindow;
+    newClientRect = wndPtr->rectClient;
+
+    if (!(flags & SWP_NOSIZE))
+    {
+	newWindowRect.right  = newWindowRect.left + winpos->cx;
+	newWindowRect.bottom = newWindowRect.top + winpos->cy;
+	winChanges.width     = winpos->cx;
+	winChanges.height    = winpos->cy;
+	changeMask |= CWWidth | CWHeight;
+    }
+    if (!(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;
+	if (wndPtr->dwStyle & WS_CHILD)
+	{
+	    WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent);
+	    winChanges.x = winpos->x + parentPtr->rectClient.left 
+		           - parentPtr->rectWindow.left;
+	    winChanges.y = winpos->y + parentPtr->rectClient.top
+		           - parentPtr->rectWindow.top;
+	}
+	else
+	{
+	    winChanges.x = winpos->x;
+	    winChanges.y = winpos->y;
+	}
+	changeMask |= CWX | CWY;
+    }
+
+      /* Reposition window in Z order */
+
+    if (!(flags & SWP_NOZORDER))
+    {
+	WIN_UnlinkWindow( winpos->hwnd );
+	WIN_LinkWindow( winpos->hwnd, hwndAfter );
+	if (hwndAfter == HWND_TOP) winChanges.stack_mode = Above;
+	else winChanges.stack_mode = Below;
+	if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM))
+	{
+	    WND * insertPtr = WIN_FindWndPtr( hwndAfter );
+	    winChanges.sibling = insertPtr->window;
+	    changeMask |= CWSibling;
+	}
+	changeMask |= CWStackMode;
+    }
+
+      /* Send WM_NCCALCSIZE message to get new client area */
+
+    result = WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect,
+				    &wndPtr->rectWindow, &wndPtr->rectClient,
+				    winpos, &newClientRect );
+    /* ....  Should handle result here */
+
+      /* Perform the moving and resizing */
+
+    if (changeMask) XConfigureWindow( display, wndPtr->window,
+				      changeMask, &winChanges );
+    wndPtr->rectWindow = newWindowRect;
+    wndPtr->rectClient = newClientRect;
+
+    if (flags & SWP_SHOWWINDOW)
+    {
+	wndPtr->dwStyle |= WS_VISIBLE;
+	XMapWindow( display, wndPtr->window );
+	MSG_Synchronize();
+	if (flags & SWP_NOREDRAW)  /* Validate the whole window */
+	    RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE );
+    }
+    else if (flags & SWP_HIDEWINDOW)
+    {
+	wndPtr->dwStyle &= ~WS_VISIBLE;
+	XUnmapWindow( display, wndPtr->window );
+	if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus()))
+	    SetFocus( GetParent(winpos->hwnd) );  /* Revert focus to parent */
+	if (winpos->hwnd == hwndActive)
+	{
+	      /* Activate previously active window if possible */
+	    HWND newActive = wndPtr->hwndPrevActive;
+	    if (!IsWindow(newActive) || (newActive == winpos->hwnd))
+	    {
+		newActive = GetTopWindow(GetDesktopWindow());
+		if (newActive == winpos->hwnd) newActive = wndPtr->hwndNext;
+	    }	    
+	    WINPOS_ChangeActiveWindow( newActive, FALSE );
+	}
+    }
+
+      /* Activate the window */
+
+    if (!(flags & SWP_NOACTIVATE))
+    {
+	if (!(wndPtr->dwStyle & WS_CHILD))
+	    WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE );
+    }
+    
+      /* Send WM_NCPAINT message if needed */
+
+    if ((flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) ||
+	(!(flags & SWP_NOSIZE)) || (!(flags & SWP_NOMOVE)) ||
+	(!(flags & SWP_NOACTIVATE)) || (!(flags & SWP_NOZORDER)))
+	    SendMessage( winpos->hwnd, WM_NCPAINT, 1, 0L );
+#if 0
+    if ((flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) &&
+	(!(flags & SWP_NOREDRAW)) && 
+	(wndPtr->dwStyle & WS_VISIBLE))
+	InvalidateRect(winpos->hwnd, NULL, TRUE);
+#endif
+
+      /* And last, send the WM_WINDOWPOSCHANGED message */
+
+    SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winpos );
+    return TRUE;
+}
+
+					
+/***********************************************************************
  *           SetWindowPos   (USER.232)
  */
 /* Note: all this code should be in the DeferWindowPos() routines,
@@ -449,23 +677,13 @@
 {
     WINDOWPOS *winPos;
     HANDLE hmem = 0;
-    RECT newWindowRect, newClientRect;
-    WND *wndPtr;
-    int calcsize_result = 0;
-    XWindowChanges winChanges;
-    int changeMask = 0;
+    BOOL res;
 
 #ifdef DEBUG_WIN
     printf( "SetWindowPos: %04X %d %d,%d %dx%d 0x%x\n",
 	    hwnd, hwndInsertAfter, x, y, cx, cy, flags );
 #endif
 
-    if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return FALSE;
-    if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
-	flags |= SWP_NOMOVE | SWP_NOSIZE;
-
-      /* Send WM_WINDOWPOSCHANGING message */
-
     if (!(hmem = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(WINDOWPOS) )))
 	return FALSE;
     winPos = (WINDOWPOS *)USER_HEAP_ADDR( hmem );
@@ -476,183 +694,9 @@
     winPos->cx = cx;
     winPos->cy = cy;
     winPos->flags = flags;
-    SendMessage( hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winPos );
-    hwndInsertAfter = winPos->hwndInsertAfter;
 
-      /* Some sanity checks */
+    res = WINPOS_InternalSetWindowPos( winPos );
 
-    if (!IsWindow( hwnd ) || (hwnd == GetDesktopWindow())) goto Abort;
-    if (flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW))
-	flags |= SWP_NOMOVE | SWP_NOSIZE;
-    if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE)))
-    {
-	if (hwnd != hwndActive) hwndInsertAfter = HWND_TOP;
-	else if ((hwndInsertAfter == HWND_TOPMOST) ||
-		 (hwndInsertAfter == HWND_NOTOPMOST))
-	    hwndInsertAfter = HWND_TOP;	
-    }
-
-      /* Calculate new position and size */
-
-    newWindowRect = wndPtr->rectWindow;
-    newClientRect = wndPtr->rectClient;
-
-    if (!(winPos->flags & SWP_NOSIZE))
-    {
-	newWindowRect.right  = newWindowRect.left + winPos->cx;
-	newWindowRect.bottom = newWindowRect.top + winPos->cy;
-    }
-
-    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;
-    }
-
-      /* Reposition window in Z order */
-
-    if (!(winPos->flags & SWP_NOZORDER))
-    {
-	  /* TOPMOST not supported yet */
-	if ((hwndInsertAfter == HWND_TOPMOST) ||
-	    (hwndInsertAfter == HWND_NOTOPMOST)) hwndInsertAfter = HWND_TOP;
-
-	  /* Make sure hwndInsertAfter is a sibling of hwnd */
-	if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
-	    if (GetParent(hwnd) != GetParent(hwndInsertAfter)) goto Abort;
-
-	WIN_UnlinkWindow( hwnd );
-	WIN_LinkWindow( hwnd, hwndInsertAfter );
-    }
-
-      /* Recalculate client area position */
-
-    if (winPos->flags & SWP_FRAMECHANGED)
-    {
-	  /* Send WM_NCCALCSIZE message */
-	NCCALCSIZE_PARAMS *params;
-	HANDLE hparams;
-	
-	if (!(hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) )))
-	    goto Abort;
-	params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams );
-	params->rgrc[0] = newWindowRect;
-	params->rgrc[1] = wndPtr->rectWindow;
-	params->rgrc[2] = wndPtr->rectClient;
-	params->lppos = winPos;
-	calcsize_result = SendMessage(hwnd, WM_NCCALCSIZE, TRUE, (LONG)params);
-	USER_HEAP_FREE( hparams );
-	newClientRect = params->rgrc[0];
-	/* Handle result here */
-    }
-    else
-    {
-	newClientRect.left   = newWindowRect.left + wndPtr->rectClient.left
-	                       - wndPtr->rectWindow.left;
-	newClientRect.top    = newWindowRect.top + wndPtr->rectClient.top
-	                       - wndPtr->rectWindow.top;
-	newClientRect.right  = newWindowRect.right + wndPtr->rectClient.right
-	                       - wndPtr->rectWindow.right;
-	newClientRect.bottom = newWindowRect.bottom + wndPtr->rectClient.bottom
-	                       - wndPtr->rectWindow.bottom;
-    }
-    
-      /* Perform the moving and resizing */
-
-    if (!(winPos->flags & SWP_NOMOVE))
-    {
-	WND * parentPtr;
-	winChanges.x = newWindowRect.left;
-	winChanges.y = newWindowRect.top;
-	if (wndPtr->dwStyle & WS_CHILD)
-	{
-	    parentPtr = WIN_FindWndPtr(wndPtr->hwndParent);
-	    winChanges.x += parentPtr->rectClient.left-parentPtr->rectWindow.left;
-	    winChanges.y += parentPtr->rectClient.top-parentPtr->rectWindow.top;
-	}
-	changeMask |= CWX | CWY;
-    }
-    if (!(winPos->flags & SWP_NOSIZE))
-    {
-	winChanges.width  = newWindowRect.right - newWindowRect.left;
-	winChanges.height = newWindowRect.bottom - newWindowRect.top;
-	changeMask |= CWWidth | CWHeight;
-    }
-    if (!(winPos->flags & SWP_NOZORDER))
-    {
-	if (hwndInsertAfter == HWND_TOP) winChanges.stack_mode = Above;
-	else winChanges.stack_mode = Below;
-	if ((hwndInsertAfter != HWND_TOP) && (hwndInsertAfter != HWND_BOTTOM))
-	{
-	    WND * insertPtr = WIN_FindWndPtr( hwndInsertAfter );
-	    winChanges.sibling = insertPtr->window;
-	    changeMask |= CWSibling;
-	}
-	changeMask |= CWStackMode;
-    }
-	if ((newWindowRect.right - newWindowRect.left) != 0 &&
-		(newWindowRect.bottom - newWindowRect.top) != 0)
-		if (changeMask) XConfigureWindow( display, wndPtr->window,
-									changeMask, &winChanges );
-
-	if ((newWindowRect.right - newWindowRect.left) != 0 &&
-		(newWindowRect.bottom - newWindowRect.top) != 0 &&
-		(winPos->flags & SWP_SHOWWINDOW))
-    {
-	wndPtr->dwStyle |= WS_VISIBLE;
-	XMapWindow( display, wndPtr->window );
-	MSG_Synchronize();
-/*	if (winPos->flags & SWP_NOREDRAW)
-	    RedrawWindow( hwnd, NULL, 0, RDW_VALIDATE ); */
-    }
-    else if (winPos->flags & SWP_HIDEWINDOW)
-    {
-	wndPtr->dwStyle &= ~WS_VISIBLE;
-	XUnmapWindow( display, wndPtr->window );
-	if ((hwnd == GetFocus()) || IsChild( hwnd, GetFocus() ))
-	    SetFocus( GetParent(hwnd) );  /* Revert focus to parent (if any) */
-	if (hwnd == hwndActive)
-	{
-	      /* Activate previously active window if possible */
-	    HWND newActive = wndPtr->hwndPrevActive;
-	    if (!IsWindow(newActive) || (newActive == hwnd))
-	    {
-		newActive = GetTopWindow(GetDesktopWindow());
-		if (newActive == hwnd) newActive = wndPtr->hwndNext;
-	    }	    
-	    WINPOS_ChangeActiveWindow( newActive, FALSE );
-	}
-    }
-
-    if (!(winPos->flags & SWP_NOACTIVATE))
-    {
-	if (!(wndPtr->dwStyle & WS_CHILD))
-	    WINPOS_ChangeActiveWindow( hwnd, FALSE );
-    }
-    
-      /* Send WM_NCPAINT message if needed */
-    if ((winPos->flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) ||
-	(!(winPos->flags & SWP_NOSIZE)) ||
-	(!(winPos->flags & SWP_NOMOVE)) ||
-	(!(winPos->flags & SWP_NOACTIVATE)) ||
-	(!(winPos->flags & SWP_NOZORDER)))
-	    SendMessage( hwnd, WM_NCPAINT, 1, 0L );
-    if ((winPos->flags & (SWP_FRAMECHANGED | SWP_SHOWWINDOW)) &&
-		(!(winPos->flags & SWP_NOREDRAW)) && 
-		(wndPtr->dwStyle & WS_VISIBLE) && IsWindowVisible(hwnd))
-		InvalidateRect(hwnd, NULL, TRUE);
-
-      /* Finally send the WM_WINDOWPOSCHANGED message */
-    wndPtr->rectWindow = newWindowRect;
-    wndPtr->rectClient = newClientRect;
-    SendMessage( hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winPos );
     USER_HEAP_FREE( hmem );
-
-    return TRUE;
-
- Abort:  /* Fatal error encountered */
-    if (hmem) USER_HEAP_FREE( hmem );
-    return FALSE;
+    return res;
 }