Release 960225

Sat Feb 24 16:17:05 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [files/profile.c]
	Added \r when writing profile files, for DOS compatibility.

	* [memory/global.c]
	Fixed bug in GlobalReAlloc() that caused a discarded block not to
 	be reallocated if its size was not changed.

	* [memory/selector.c]
	Avoid setting a valid LDT entry with base and limit set to 0, as
 	this causes the kernel to clear the entry. This fixes a crash when
 	exiting Windows program manager.

	* [objects/metafile.c]
	Removed call to creat() instead of _lcreat() for WINELIB.

Fri Feb 23 00:35:54 1996  Thomas Sandford <tdgsandf@prds-grn.demon.co.uk>

	* [if1632/gdi32.spec]
	GetTextExtentPointA now has win32 specific implementation.

	* [include/struct32.h]
	Define new structure tagSIZE32 and typedef SIZE32 to it.
	Define prototype for function PARAM32_SIZE16to32

	* [win32/param32.c]
	New functions PARAM32_SIZE16to32 and WIN32_GetTextExtentPointA

	* [win32/memory.c]
	Added missing file pointer parameter to fprintf.

Thu Feb 22 01:14:21 1996  Eric Warnke <ew2193@csc.albany.edu>

	* [windows/nonclient.c]
	Added more familiar icon activity, ie single click brings up
 	system menu.

Wed Feb 21 13:07:04 1996  Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl>

	* [controls/menu.c]
	Added calls to HideCaret() and ShowCaret() from within
 	TrackPopupMenu(), MENU_TrackMouseMenuBar() and
 	MENU_TrackKbdMenuBar().  Are there any more places where this
 	should be done?

	* [controls/static.c]
	Fixed a FIXME in STATIC_SetIcon(), which now returns a handle to
 	the previous icon.  Added a new FIXME at the point where
 	WM_SETTEXT is handled for a SS_ICON static control.

	* [misc/commdlg.c]
	Implemented FindText() and ReplaceText()
	Still missing : Templates and Hooks handling / error checking

	* [resources/sysres_En.c]
	Redesigned FIND_TEXT and REPLACE_TEXT dialogs, so they now work.
	Languages other than En should update these too, though, as well
 	as redimension the controls because some of the text doesn't fit.
  	Created file resources/TODO to explain this.

	* [windows/caret.c]
	Re-written.  It now uses the correct R2_XORPEN.  It resets the
 	blink timer on SetCaretPos().  It does its own hide/show scheme
 	when SetCaretPos() is called (should be faster).

Mon Feb 19 21:50:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [controls/listbox.c]
	Miscellaneous changes for better LBS_EXTENDEDSEL support.
	Removed several superfluous redrawals of item list.

	* [controls/scroll.c]
	WM_GETDLGCODE return value.

	* [windows/win.c]
	FlashWindow function.

	* [windows/painting.c] [windows/scroll.c]
	Added HideCaret/ShowCaret calls.

	* [objects/font.c]
	Added GetCharABCWidths stub.

	* [include/windows.h]
	"#define"s needed for changes mentioned above.

Mon Feb 19 20:12:03 1996  Hans de Graaff  <Hans.deGraaff@twi72.twi.tudelft.nl>

	* [include/winsock.h]
	Change order of includes to get in_addr struct defined in time.
	(Note: Linux 1.3.66, libc 5.2.18)

	* [misc/main.c] [include/options.h] [miscemu/int2f.c]
	Changed the -enhanced option into a -mode option, which can be
	either 'standard' or 'enhanced'. 'enhanced' is the default.
diff --git a/ANNOUNCE b/ANNOUNCE
index f46d240..8ba1e3b 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,14 +1,15 @@
-This is release 960218 of Wine the MS Windows emulator.  This is still a
+This is release 960225 of Wine the MS Windows emulator.  This is still a
 developer's only release.  There are many bugs and many unimplemented API
 features.  Most applications still do not work.
 
 Patches should be submitted to "julliard@lrc.epfl.ch".  Please don't
 forget to include a ChangeLog entry.
 
-WHAT'S NEW with Wine-960218: (see ChangeLog for details)
-	- Lots of edit control fixes.
-	- Czech language support.
-	- As usual, more Win32 code.
+WHAT'S NEW with Wine-960225: (see ChangeLog for details)
+	- Many caret fixes.
+	- New -mode option to replace -enhanced.
+	- Many listboxes improvements.
+	- Find and Replace dialogs in built-in COMMDLG fixed.
 	- Lots of bug fixes.
 
 See the README file in the distribution for installation instructions.
@@ -17,19 +18,21 @@
 the release is available at the ftp sites.  The sources will be available
 from the following locations:
 
-    sunsite.unc.edu:/pub/Linux/ALPHA/wine/Wine-960218.tar.gz
-    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960218.tar.gz
-    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960218.tar.gz
-    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960218.tar.gz
+    sunsite.unc.edu:/pub/Linux/ALPHA/wine/development/Wine-960225.tar.gz
+    tsx-11.mit.edu:/pub/linux/ALPHA/Wine/development/Wine-960225.tar.gz
+    ftp.infomagic.com:/pub/mirrors/linux/wine/development/Wine-960225.tar.gz
+    aris.com:/pub/linux/ALPHA/Wine/development/Wine-960225.tar.gz
 
 It should also be available from any site that mirrors tsx-11 or sunsite.
 
 If you submitted a patch, please check to make sure it has been
 included in the new release.
 
-New developers should read the info files available from the ftp sites.
-The files NEWBIE-PROJECTS, DEVELOPERS-HINTS and Wine.FAQ are required
-reading for new developers.
+If you want to get the new releases faster, you can subscribe to the
+wine-patches mailing list by sending a mail containing 'subscribe
+wine-patches your_address' to majordomo@tiger.informatik.hu-berlin.de.
+To avoid overloading the mail host, please subscribe only if you
+really intend to test the new releases as soon as they're out.
 
 Wine is available thanks to the work of Bob Amstadt, Dag Asheim,
 Martin Ayotte, Ross Biro, Erik Bos, Fons Botman, John Brezak,
diff --git a/ChangeLog b/ChangeLog
index 315a1ca..42953b0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,102 @@
 ----------------------------------------------------------------------
+Sat Feb 24 16:17:05 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
+
+	* [files/profile.c]
+	Added \r when writing profile files, for DOS compatibility.
+
+	* [memory/global.c]
+	Fixed bug in GlobalReAlloc() that caused a discarded block not to
+ 	be reallocated if its size was not changed.
+
+	* [memory/selector.c]
+	Avoid setting a valid LDT entry with base and limit set to 0, as
+ 	this causes the kernel to clear the entry. This fixes a crash when
+ 	exiting Windows program manager.
+
+	* [objects/metafile.c]
+	Removed call to creat() instead of _lcreat() for WINELIB.
+
+Fri Feb 23 00:35:54 1996  Thomas Sandford <tdgsandf@prds-grn.demon.co.uk>
+
+	* [if1632/gdi32.spec]
+	GetTextExtentPointA now has win32 specific implementation.
+
+	* [include/struct32.h]
+	Define new structure tagSIZE32 and typedef SIZE32 to it.
+	Define prototype for function PARAM32_SIZE16to32
+
+	* [win32/param32.c]
+	New functions PARAM32_SIZE16to32 and WIN32_GetTextExtentPointA
+
+	* [win32/memory.c]
+	Added missing file pointer parameter to fprintf.
+
+Thu Feb 22 01:14:21 1996  Eric Warnke <ew2193@csc.albany.edu>
+
+	* [windows/nonclient.c]
+	Added more familiar icon activity, ie single click brings up
+ 	system menu.
+
+Wed Feb 21 13:07:04 1996  Frans van Dorsselaer <dorssel@rulhm1.leidenuniv.nl>
+
+	* [controls/menu.c]
+	Added calls to HideCaret() and ShowCaret() from within
+ 	TrackPopupMenu(), MENU_TrackMouseMenuBar() and
+ 	MENU_TrackKbdMenuBar().  Are there any more places where this
+ 	should be done?
+
+	* [controls/static.c]
+	Fixed a FIXME in STATIC_SetIcon(), which now returns a handle to
+ 	the previous icon.  Added a new FIXME at the point where
+ 	WM_SETTEXT is handled for a SS_ICON static control.
+
+	* [misc/commdlg.c]
+	Implemented FindText() and ReplaceText()
+	Still missing : Templates and Hooks handling / error checking
+
+	* [resources/sysres_En.c]
+	Redesigned FIND_TEXT and REPLACE_TEXT dialogs, so they now work.
+	Languages other than En should update these too, though, as well
+ 	as redimension the controls because some of the text doesn't fit.
+  	Created file resources/TODO to explain this.
+
+	* [windows/caret.c]
+	Re-written.  It now uses the correct R2_XORPEN.  It resets the
+ 	blink timer on SetCaretPos().  It does its own hide/show scheme
+ 	when SetCaretPos() is called (should be faster).
+
+Mon Feb 19 21:50:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>
+
+	* [controls/listbox.c]
+	Miscellaneous changes for better LBS_EXTENDEDSEL support.
+	Removed several superfluous redrawals of item list.
+
+	* [controls/scroll.c]
+	WM_GETDLGCODE return value.
+
+	* [windows/win.c]
+	FlashWindow function.
+
+	* [windows/painting.c] [windows/scroll.c]
+	Added HideCaret/ShowCaret calls.
+
+	* [objects/font.c]
+	Added GetCharABCWidths stub.
+
+	* [include/windows.h]
+	"#define"s needed for changes mentioned above.
+
+Mon Feb 19 20:12:03 1996  Hans de Graaff  <Hans.deGraaff@twi72.twi.tudelft.nl>
+
+	* [include/winsock.h]
+	Change order of includes to get in_addr struct defined in time.
+	(Note: Linux 1.3.66, libc 5.2.18)
+
+	* [misc/main.c] [include/options.h] [miscemu/int2f.c]
+	Changed the -enhanced option into a -mode option, which can be
+	either 'standard' or 'enhanced'. 'enhanced' is the default.
+
+----------------------------------------------------------------------
 Sun Feb 18 16:35:54 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>
 
 	* [controls/desktop.c]
diff --git a/controls/listbox.c b/controls/listbox.c
index b9cd547..3d24874 100644
--- a/controls/listbox.c
+++ b/controls/listbox.c
@@ -10,8 +10,8 @@
  /*
   * FIXME: 
   * - check if multi-column listboxes work
-  * - implement more messages and styles (LB_EXTENDEDSEL for instance)
-  * - exterminate evil InvalidateRect(whole listbox) where possible!!!!
+  * - implement more messages and styles 
+  * - implement caret for LBS_EXTENDEDSEL
   */
 
 #include <stdio.h>
@@ -21,6 +21,7 @@
 #include "windows.h"
 #include "user.h"
 #include "win.h"
+#include "gdi.h"
 #include "msdos.h"
 #include "listbox.h"
 #include "dos_fs.h"
@@ -574,13 +575,9 @@
   DWORD	       dwStyle = GetWindowWord(lphl->hSelf,GWL_STYLE);
 
   /* use ListBoxSetSel instead */
-  if (dwStyle & LBS_MULTIPLESEL ) return 0;
+  if (dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) ) return 0;
 
-  /* unselect all previously selected */
-  if (dwStyle & LBS_EXTENDEDSEL )
-      ListBoxSetSel(lphl,-1,0);
-  else 
-      /* unselect previous item */
+  /* unselect previous item */
   if (lphl->ItemFocused != -1) {
     lpls = ListBoxGetItem(lphl, lphl->ItemFocused);
     if (lpls == 0) return LB_ERR;
@@ -602,23 +599,27 @@
 
 int ListBoxSetSel(LPHEADLIST lphl, WORD wIndex, WORD state)
 {
-  LPLISTSTRUCT lpls;
+  LPLISTSTRUCT  lpls;
+  int           n = 0;
 
   if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & 
        (LBS_MULTIPLESEL | LBS_EXTENDEDSEL)  )) 
-        return 0;
+        return LB_ERR;
 
   if (wIndex == (UINT)-1) {
     for (lpls = lphl->lpFirst; lpls != NULL; lpls = lpls->lpNext) {
-      lpls->itemState = state;
+      if( lpls->itemState & ODS_SELECTED) n++;
+      lpls->itemState = state? lpls->itemState |  ODS_SELECTED
+                             : lpls->itemState & ~ODS_SELECTED;
     }
-    return 0;
+    return n;
   }
 
   if (wIndex >= lphl->ItemsCount) return LB_ERR;
 
   lpls = ListBoxGetItem(lphl, wIndex);
-  lpls->itemState = state;
+  lpls->itemState = state? lpls->itemState |  ODS_SELECTED
+                         : lpls->itemState & ~ODS_SELECTED;
 
   return 0;
 }
@@ -629,7 +630,7 @@
   LPLISTSTRUCT lpls = ListBoxGetItem(lphl, wIndex);
 
   if (lpls == NULL) return LB_ERR;
-  return lpls->itemState;
+  return lpls->itemState & ODS_SELECTED;
 }
 
 /* ------------------------- dir listing ------------------------ */
@@ -902,7 +903,7 @@
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
   WORD       wRet;
-  int        y;
+  int        y,n;
   RECT       rectsel;
   LONG	     dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
   POINT      tmpPOINT;
@@ -914,31 +915,62 @@
   lphl->PrevFocused = lphl->ItemFocused;
 
   y = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
-  if (y == -1)
-    return 0;
 
-  if (dwStyle & LBS_MULTIPLESEL) {
-    lphl->ItemFocused = y;
-    wRet = ListBoxGetSel(lphl, y);
-    ListBoxSetSel(lphl, y, !wRet);
+  if (y == -1) return 0;
 
-    InvalidateRect(hwnd, NULL, TRUE);
-  } else {
-    ListBoxSetCurSel(lphl, y);
+  if (dwStyle & LBS_NOTIFY && y!= LB_ERR )
+     if( SendMessage(lphl->hParent, WM_LBTRACKPOINT, y, lParam) )
+         return 0;
 
-  ListBoxGetItemRect(lphl, y, &rectsel);
-    InvalidateRect(hwnd, &rectsel, TRUE);
-    if(lphl->PrevFocused) {
-        ListBoxGetItemRect(lphl, lphl->PrevFocused, &rectsel);
-	InvalidateRect(hwnd, &rectsel, TRUE);
-    } 
-  }
 
-  if (dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL))
-    ListBoxSendNotification(lphl, LBN_SELCHANGE);
+  switch( dwStyle & (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )
+   {
+        case LBS_MULTIPLESEL:
+                lphl->ItemFocused = y;
+                wRet = ListBoxGetSel(lphl, y);
+                ListBoxSetSel(lphl, y, !wRet);
+                break;
+        case LBS_EXTENDEDSEL:
+                /* should handle extended mode here and in kbd handler 
+                 */ 
 
-  if (dwStyle & LBS_NOTIFY)
-    SendMessage(lphl->hParent, WM_LBTRACKPOINT, y, lParam);
+                if ( lphl->PrevFocused != y && y!= LB_ERR)
+                 {
+                   LPLISTSTRUCT lpls = ListBoxGetItem( lphl, lphl->ItemFocused = y );
+                   n = ListBoxSetSel(lphl,-1,FALSE);
+
+                   lpls->itemState = ODS_FOCUS | ODS_SELECTED;
+
+                   if( n > 1 && n != LB_ERR )
+                     InvalidateRect(hwnd,NULL,TRUE);
+                 }
+                else
+                       return 0;
+
+                break;
+        case 0:
+                if( y!=lphl->ItemFocused )
+                  ListBoxSetCurSel(lphl, y);
+                else
+                  return 0;
+                break;
+        default:
+                fprintf(stdnimp,"Listbox: LBS_MULTIPLESEL and LBS_EXTENDEDSEL are on!\n");
+                return 0;
+   }
+
+ /* invalidate changed items */
+ if( dwStyle & LBS_MULTIPLESEL || y!=lphl->PrevFocused )
+   {
+     ListBoxGetItemRect(lphl, y, &rectsel);
+     InvalidateRect(hwnd, &rectsel, TRUE);
+   }
+ if( lphl->PrevFocused!=-1 && y!=lphl->PrevFocused ) 
+   {
+     ListBoxGetItemRect(lphl, lphl->PrevFocused, &rectsel);
+     InvalidateRect(hwnd, &rectsel, TRUE);
+   }
+
 #ifndef WINELIB
   if (GetWindowLong(lphl->hSelf,GWL_EXSTYLE) & WS_EX_DRAGDETECT)
      if( DragDetect(lphl->hSelf,tmpPOINT) )
@@ -987,8 +1019,8 @@
 static LONG LBMouseMove(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  int  y;
-  WORD wRet;
+  int  y,redraw_prev = 0;
+  int  iRet;
   LONG  dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
   RECT rect, rectsel;   /* XXX Broken */
 
@@ -1014,19 +1046,33 @@
     }
     if ((y > 0) && (y < (rect.bottom - 4))) {
       if ((y < rectsel.top) || (y > rectsel.bottom)) {
-	wRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
-	if (wRet == lphl->ItemFocused)  {
+        iRet = ListBoxFindMouse(lphl, LOWORD(lParam), HIWORD(lParam));
+        if (iRet == lphl->ItemFocused || iRet == -1)  {
 	  return 0;
 	}
 	if (dwStyle & LBS_MULTIPLESEL) {
-	  lphl->ItemFocused = wRet;
+          lphl->ItemFocused = iRet;
 	  ListBoxSendNotification(lphl, LBN_SELCHANGE);
-	} else {
-	  ListBoxSetCurSel(lphl, wRet);
-	  if(dwStyle & LBS_EXTENDEDSEL)
-	     ListBoxSendNotification(lphl, LBN_SELCHANGE);
-	}
-	ListBoxGetItemRect(lphl, wRet, &rectsel);
+        } else if ( dwStyle & LBS_EXTENDEDSEL )
+                  {
+                     /* Fixme: extended selection mode */
+                     ListBoxSetSel( lphl, lphl->ItemFocused, 0);
+                     lphl->PrevFocused = lphl->ItemFocused;
+                     lphl->ItemFocused = iRet;
+                     ListBoxSetSel( lphl, iRet, TRUE);
+                     redraw_prev = 1;
+                  }
+               else
+                  {
+                     ListBoxSetCurSel(lphl, (WORD)iRet);
+                     redraw_prev = 1; 
+                  }
+        if( lphl->PrevFocused!=-1 && redraw_prev )
+          {
+            ListBoxGetItemRect(lphl, lphl->PrevFocused, &rectsel);
+            InvalidateRect(hwnd, &rectsel, TRUE);
+          }
+        ListBoxGetItemRect(lphl, iRet, &rectsel);
 	InvalidateRect(hwnd, &rectsel, TRUE);
       }
     }
@@ -1050,8 +1096,6 @@
   ListBoxGetItemRect(lphl,lphl->ItemFocused,&rect);
   switch(wParam) 
     {
-	/* ugly kludge that belongs in TranslateMessage */
-
 	case VK_HOME:
 	case VK_END:
 	case VK_LEFT:
@@ -1065,7 +1109,7 @@
 		  newFocused = (WORD)(INT)SendMessage(lphl->hParent,WM_VKEYTOITEM,
 					              wParam,MAKELPARAM(lphl->ItemFocused,hwnd));
 	          if ( newFocused == 0xFFFE ) return 0L;
-  }
+                }
 	     if ( newFocused == 0xFFFF ) 
 		{
 		  newFocused = lphl->ItemFocused;
@@ -1073,42 +1117,42 @@
 		  /* nested switch */
 		  switch(wParam)
 		    {
-  case VK_HOME:
-    newFocused = 0;
-    break;
-  case VK_END:
-    newFocused = lphl->ItemsCount - 1;
-    break;
-  case VK_LEFT:
+                        case VK_HOME:
+                          newFocused = 0;
+                          break;
+                        case VK_END:
+                          newFocused = lphl->ItemsCount - 1;
+                          break;
+                        case VK_LEFT:
   			  if (dwStyle & LBS_MULTICOLUMN) {
-      if (newFocused >= lphl->ItemsPerColumn) {
-	newFocused -= lphl->ItemsPerColumn;
-      } else {
-	newFocused = 0;
-      }
-    }
-    break;
-  case VK_UP:
-    if (newFocused > 0) newFocused--;
-    break;
-  case VK_RIGHT:
-			    if (dwStyle & LBS_MULTICOLUMN) 
-      newFocused += lphl->ItemsPerColumn;
-    break;
-  case VK_DOWN:
-    newFocused++;
-    break;
-  case VK_PRIOR:
-			    if (newFocused > lphl->ItemsVisible)
-      newFocused -= lphl->ItemsVisible;
+                            if (newFocused >= lphl->ItemsPerColumn) {
+                                newFocused -= lphl->ItemsPerColumn;
+                            } else {
+                                newFocused = 0;
+                            }
+                          }
+                          break;
+                        case VK_UP:
+                          if (newFocused > 0) newFocused--;
+                          break;
+                        case VK_RIGHT:
+                          if (dwStyle & LBS_MULTICOLUMN) 
+                             newFocused += lphl->ItemsPerColumn;
+                          break;
+                        case VK_DOWN:
+                          newFocused++;
+                          break;
+                        case VK_PRIOR:
+                          if (newFocused > lphl->ItemsVisible)
+                              newFocused -= lphl->ItemsVisible;
 			    else  newFocused = 0;
-    break;
-  case VK_NEXT:
-    newFocused += lphl->ItemsVisible;
-    break;
-  default:
-    return 0;
-  }
+                            break;
+                        case VK_NEXT:
+                          newFocused += lphl->ItemsVisible;
+                          break;
+                        default:
+                          return 0;
+                    }
 		  /* end of nested switch */
 		}
 	     break;   
@@ -1132,9 +1176,9 @@
   
   if (!(dwStyle & LBS_MULTIPLESEL)) 
      {
-    ListBoxSetCurSel(lphl, newFocused);
+        ListBoxSetCurSel(lphl, newFocused);
 	ListBoxSendNotification(lphl, LBN_SELCHANGE);
-  }
+     }
 
   lphl->ItemFocused = newFocused;
 
@@ -1235,18 +1279,23 @@
   PAINTSTRUCT  ps;
   HBRUSH       hBrush;
   HFONT        hOldFont;
-  HDC 	hdc;
-  RECT 	rect;
+  HDC   hdc    = BeginPaint( hwnd, &ps );
+  DC    *dc    = (DC *)GDI_GetObjPtr(hdc, DC_MAGIC);
+  RECT  rect, paintRect, scratchRect;
   int   i, top, height, maxwidth, ipc;
 
+
   top = 0;
-  hdc = BeginPaint( hwnd, &ps );
 
   if (!IsWindowVisible(hwnd) || !lphl->bRedrawFlag) {
     EndPaint(hwnd, &ps);
     return 0;
   }
 
+  GetRgnBox(dc->w.hGCClipRgn,&paintRect);
+  GetClientRect(hwnd, &rect);
+  IntersectRect(&paintRect,&rect,&paintRect);
+
   hOldFont = SelectObject(hdc, lphl->hFont);
 
 #ifdef WINELIB32
@@ -1259,7 +1308,6 @@
 
   if (hBrush == 0) hBrush = GetStockObject(WHITE_BRUSH);
 
-  GetClientRect(hwnd, &rect);
   FillRect(hdc, &rect, hBrush);
 
   maxwidth = rect.right;
@@ -1295,17 +1343,23 @@
       lpls->itemRect.left   = rect.left;
       lpls->itemRect.right  = rect.right;
 
-      dprintf_listbox(stddeb,"drawing item: %ld %d %ld %d %d\n",(LONG)rect.left,top,(LONG)rect.right,top+height,lpls->itemState);
-      if (lphl->OwnerDrawn) {
-	ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 0);
-	if (lpls->itemState)
-	  ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_SELECT, ODS_SELECTED);
-      } else {
-	ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 
-			 lpls->itemState);
-      }
-      if ((lphl->ItemFocused == i) && GetFocus() == hwnd)
-	ListBoxDrawItem (hwnd,lphl, hdc, lpls, &lpls->itemRect, ODA_FOCUS, ODS_FOCUS);
+      if( IntersectRect(&scratchRect,&paintRect,&lpls->itemRect) )
+       {
+        dprintf_listbox(stddeb,"drawing item: %ld %d %ld %d %d\n",(LONG)rect.left,top,
+                            (LONG)rect.right,top+height,lpls->itemState);
+
+        if (lphl->OwnerDrawn && (lphl->ItemFocused == i) && GetFocus() == hwnd)
+           {
+             ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_FOCUS, 
+                                                      lpls->itemState & ~ODS_FOCUS);
+             ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE, 
+                                                      lpls->itemState & ~ODS_FOCUS);
+             ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_FOCUS, lpls->itemState);
+           }
+        else
+            ListBoxDrawItem (hwnd, lphl, hdc, lpls, &lpls->itemRect, ODA_DRAWENTIRE,
+                                                     lpls->itemState);
+       }
 
       top += height;
       lphl->ItemsVisible++;
@@ -1325,7 +1379,29 @@
  */
 static LONG LBSetFocus(HWND hwnd, WORD wParam, LONG lParam)
 {
-  dprintf_listbox(stddeb,"ListBox WM_SETFOCUS !\n");
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  LONG       dwStyle;
+
+  dprintf_listbox(stddeb,"ListBox WM_SETFOCUS for "NPFMT"\n",hwnd);
+
+  dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
+
+  if(!(dwStyle & LBS_MULTIPLESEL) )
+       if( lphl->ItemsCount && lphl->ItemFocused != -1)
+         {
+           HDC          hDC = GetDC(hwnd);
+           HFONT        hOldFont = SelectObject(hDC, lphl->hFont);
+           LPLISTSTRUCT lpls;
+
+           lpls = ListBoxGetItem(lphl,lphl->ItemFocused);
+           lpls->itemState |= ODS_FOCUS;
+
+           ListBoxDrawItem(hwnd,lphl,hDC,lpls,&lpls->itemRect, ODA_FOCUS, lpls->itemState);
+           SelectObject(hDC, hOldFont);
+           ReleaseDC(hwnd,hDC);
+         }
+
+  ListBoxSendNotification(lphl, LBN_SETFOCUS);
 
   return 0;
 }
@@ -1335,10 +1411,37 @@
  */
 static LONG LBKillFocus(HWND hwnd, WORD wParam, LONG lParam)
 {
-  dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS !\n");
+  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  LONG       dwStyle;
 
-  InvalidateRect(hwnd, NULL, TRUE);
-  
+  dprintf_listbox(stddeb,"ListBox WM_KILLFOCUS for "NPFMT"\n",hwnd);
+
+  dwStyle = GetWindowLong(lphl->hSelf,GWL_STYLE);
+
+  if (!(dwStyle & LBS_MULTIPLESEL))
+     {
+       if( lphl->ItemsCount )
+           if( lphl->ItemFocused != -1 )
+             {
+              HDC          hDC = GetDC(hwnd);
+              HFONT        hOldFont = SelectObject(hDC, lphl->hFont);
+              LPLISTSTRUCT lpls;
+
+              lpls = ListBoxGetItem(lphl,lphl->ItemFocused);
+              lpls->itemState &= ~ODS_FOCUS;
+
+              ListBoxDrawItem(hwnd,lphl,hDC,lpls,&lpls->itemRect, ODA_FOCUS, lpls->itemState);
+              SelectObject(hDC, hOldFont);
+              ReleaseDC(hwnd,hDC);
+             }
+           else
+             dprintf_listbox(stddeb,"LBKillFocus: no focused item!\n");
+     }
+  else
+     InvalidateRect(hwnd, NULL, TRUE);
+
+  ListBoxSendNotification(lphl, LBN_KILLFOCUS);
+
   return 0;
 }
 
@@ -1466,7 +1569,7 @@
   LPHEADLIST  lphl;
 
   lphl = ListBoxGetStorageHeader(hwnd);
-  dprintf_listbox(stddeb,"ListBox LB_GETCURSEL %u !\n", 
+  dprintf_listbox(stddeb,"ListBox LB_GETCURSEL %i !\n", 
 		  lphl->ItemFocused);
   return lphl->ItemFocused;
 }
@@ -1506,7 +1609,11 @@
 static LONG LBGetSel(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  return (ListBoxGetSel(lphl, wParam) )? 1 : 0;
+  int        iSel = ListBoxGetSel(lphl, wParam);
+
+  dprintf_listbox(stdnimp,"LBGetSel: item %u - %i\n",wParam,iSel);
+
+  return (iSel)? 1 : 0;
 }
 
 /***********************************************************************
@@ -1602,13 +1709,22 @@
 static LONG LBSelectString(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  WORD  wRet;
+  INT  iRet;
 
-  wRet = ListBoxFindString(lphl, wParam, (SEGPTR)lParam);
+  iRet = ListBoxFindString(lphl, wParam, (SEGPTR)lParam);
 
-  /* XXX add functionality here */
+  if( iRet != LB_ERR)
+    {
+      if( GetWindowLong(hwnd, GWL_STYLE) &
+         (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )
+         ListBoxSetSel(lphl,iRet,TRUE);
+      else
+         ListBoxSetCurSel(lphl,iRet);
 
-  return 0;
+      lphl->ItemFocused = iRet;
+      InvalidateRect(hwnd,0,TRUE);
+    }
+  return iRet;
 }
 
 /***********************************************************************
@@ -1635,7 +1751,7 @@
 
   while (lpls != NULL) {
     if (cnt++ >= first)
-      lpls->itemState = select ? ODS_SELECTED : 0;
+      lpls->itemState = select ? lpls->itemState | ODS_SELECTED : 0;
 
     if (cnt > last)
       break;
@@ -1651,17 +1767,24 @@
  */
 static LONG LBSetCaretIndex(HWND hwnd, WORD wParam, LONG lParam)
 {
-  LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
+  LPHEADLIST   lphl = ListBoxGetStorageHeader(hwnd);
+  int          i;
 
-  if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & LBS_MULTIPLESEL)) return 0;
+  if (!(GetWindowLong(lphl->hSelf,GWL_STYLE) & 
+       (LBS_MULTIPLESEL | LBS_EXTENDEDSEL) )) return 0;
+
+  dprintf_listbox(stddeb,"LBSetCaretIndex: hwnd "NPFMT" n=%i\n",hwnd,wParam);  
+
   if (wParam >= lphl->ItemsCount) return LB_ERR;
 
   lphl->ItemFocused = wParam;
-  ListBoxScrollToFocus (lphl);
+  i = ListBoxScrollToFocus (lphl);
 
   SetScrollPos(hwnd, SB_VERT, lphl->FirstVisible, TRUE);
-  InvalidateRect(hwnd, NULL, TRUE);
-  return 0;
+  if(i)
+    InvalidateRect(hwnd, NULL, TRUE);
+ 
+  return 1;
 }
 
 /***********************************************************************
@@ -1752,14 +1875,29 @@
 static LONG LBSetSel(HWND hwnd, WORD wParam, LONG lParam)
 {
   LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
-  WORD wRet;
+  RECT rect;
+  int iRet;
 
   dprintf_listbox(stddeb,"ListBox LB_SETSEL wParam=%x lParam=%lX !\n", wParam, lParam);
 
-  wRet = ListBoxSetSel(lphl, LOWORD(lParam), wParam);
-  InvalidateRect(hwnd, NULL, TRUE);
+  iRet = ListBoxSetSel(lphl, LOWORD(lParam), wParam);
 
-  return wRet;
+  if( iRet > 1 )   
+      InvalidateRect(hwnd, NULL, TRUE);
+  else if( iRet != LB_ERR )
+      {
+        if( GetWindowLong(hwnd,GWL_STYLE) & LBS_EXTENDEDSEL &&
+            lphl->ItemFocused != LOWORD(lParam) )
+          {
+            ListBoxGetItemRect(lphl, lphl->ItemFocused , &rect);
+            InvalidateRect(hwnd,&rect,TRUE);
+            lphl->ItemFocused = LOWORD(lParam);
+          }
+        ListBoxGetItemRect(lphl,LOWORD(lParam),&rect);
+        InvalidateRect(hwnd,&rect,TRUE);
+      }
+
+  return (iRet == (WORD)LB_ERR)? LB_ERR: 0;
 }
 
 /***********************************************************************
@@ -1863,6 +2001,15 @@
 
      case WM_DROPFILES: return LBPassToParent(hwnd, message, wParam, lParam);
 
+     /* these will have to be implemented for proper LBS_EXTENDEDSEL -
+      *
+      * anchor item is an item that with caret (focused) item defines a 
+      * range of currently selected items when listbox is in the extended 
+      * selection mode.
+      */
+     case LB_SETANCHORINDEX: return LB_SETANCHORINDEX; /* that's what Windows returns */
+     case LB_GETANCHORINDEX: return 0;
+
 	case WM_DROPOBJECT:
 	case WM_QUERYDROPOBJECT:
 	case WM_DRAGSELECT:
@@ -1871,8 +2018,6 @@
 		 LPDRAGINFO lpDragInfo = (LPDRAGINFO) PTR_SEG_TO_LIN((SEGPTR)lParam);
 		 LPHEADLIST lphl = ListBoxGetStorageHeader(hwnd);
 
-	         /* more undocumented Microsoft crap - drag&drop depends on it - AK */
-
 		 lpDragInfo->l = ListBoxFindMouse(lphl,lpDragInfo->pt.x,
 						       lpDragInfo->pt.y);
 	        
diff --git a/controls/menu.c b/controls/menu.c
index b467450..00c2129 100644
--- a/controls/menu.c
+++ b/controls/menu.c
@@ -1609,11 +1609,13 @@
 void MENU_TrackMouseMenuBar( HWND hwnd, POINT pt )
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
+    HideCaret(0);
     SendMessage( hwnd, WM_ENTERMENULOOP, 0, 0 );
     SendMessage( hwnd, WM_INITMENU, wndPtr->wIDmenu, 0 );
     MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
 		    pt.x, pt.y, hwnd, NULL );
     SendMessage( hwnd, WM_EXITMENULOOP, 0, 0 );
+    ShowCaret(0);
 }
 
 
@@ -1626,6 +1628,7 @@
 {
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     if (!wndPtr->wIDmenu) return;
+    HideCaret(0);
     SendMessage( hwnd, WM_ENTERMENULOOP, 0, 0 );
     SendMessage( hwnd, WM_INITMENU, wndPtr->wIDmenu, 0 );
       /* Select first selectable item */
@@ -1634,6 +1637,7 @@
     MENU_TrackMenu( (HMENU)wndPtr->wIDmenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
 		    0, 0, hwnd, NULL );
     SendMessage( hwnd, WM_EXITMENULOOP, 0, 0 );
+    ShowCaret(0);
 }
 
 
@@ -1643,8 +1647,14 @@
 BOOL TrackPopupMenu( HMENU hMenu, UINT wFlags, short x, short y,
 		     short nReserved, HWND hWnd, LPRECT lpRect )
 {
-    if (!MENU_ShowPopup( hWnd, hMenu, 0, x, y )) return FALSE;
-    return MENU_TrackMenu( hMenu, wFlags, 0, 0, hWnd, lpRect );
+    BOOL ret;
+    HideCaret(0);
+    if (!MENU_ShowPopup( hWnd, hMenu, 0, x, y )) 
+	ret = FALSE;
+    else
+	ret = MENU_TrackMenu( hMenu, wFlags, 0, 0, hWnd, lpRect );
+    ShowCaret(0);
+    return ret;
 }
 
 
diff --git a/controls/scroll.c b/controls/scroll.c
index d18c175..aac0ecf 100644
--- a/controls/scroll.c
+++ b/controls/scroll.c
@@ -812,7 +812,10 @@
         break;
 
     case WM_ERASEBKGND:
-        break;
+         return 1;
+
+    case WM_GETDLGCODE:
+         return DLGC_WANTARROWS; /* Windows returns this value */
 
     case WM_PAINT:
         {
@@ -823,6 +826,13 @@
         }
         break;
 
+    case 0x400: /* SB_SETSCROLLPOS */
+    case 0x401: /* SB_GETSCROLLPOS */
+    case 0x402: /* SB_GETSCROLLRANGE */
+    case 0x403: /* SB_ENABLE */
+    case 0x404: /* SB_REDRAW */
+        fprintf(stdnimp,"ScrollBarWndProc: undocumented message %04x, please report\n", message );
+
     default:
         return DefWindowProc( hwnd, message, wParam, lParam );
     }
diff --git a/controls/static.c b/controls/static.c
index 0e9cf1a..11adb0d 100644
--- a/controls/static.c
+++ b/controls/static.c
@@ -49,14 +49,14 @@
  *
  * Set the icon for an SS_ICON control.
  */
-static void STATIC_SetIcon( HWND hwnd, HICON hicon )
+static HICON STATIC_SetIcon( HWND hwnd, HICON hicon )
 {
+    HICON prevIcon;
     WND *wndPtr = WIN_FindWndPtr( hwnd );
     STATICINFO *infoPtr = (STATICINFO *)wndPtr->wExtra;
 
-    if ((wndPtr->dwStyle & 0x0f) != SS_ICON) return;
-/*  FIXME: is this OK?
-    if (infoPtr->hIcon) DestroyIcon( infoPtr->hIcon ); */
+    if ((wndPtr->dwStyle & 0x0f) != SS_ICON) return 0;
+    prevIcon = infoPtr->hIcon;
     infoPtr->hIcon = hicon;
     if (hicon)
     {
@@ -65,6 +65,7 @@
                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER );
         GlobalUnlock( hicon );
     }
+    return prevIcon;
 }
 
 
@@ -114,7 +115,7 @@
 
         case WM_NCDESTROY:
             if (style == SS_ICON)
-                STATIC_SetIcon( hWnd, 0 );  /* Destroy the current icon */
+                DestroyIcon( STATIC_SetIcon( hWnd, 0 ) );
             else 
                 lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
             break;
@@ -138,6 +139,7 @@
 
 	case WM_SETTEXT:
 	    if (style == SS_ICON)
+	        /* FIXME : should we also return the previous hIcon here ??? */
                 STATIC_SetIcon( hWnd, LoadIcon( wndPtr->hInstance,
                                                 (SEGPTR)lParam ));
             else
@@ -169,10 +171,10 @@
 	    return (LONG)infoPtr->hIcon;
 
 	case STM_SETICON:
-            STATIC_SetIcon( hWnd, (HICON)wParam );
+            lResult = (LONG)STATIC_SetIcon( hWnd, (HICON)wParam );
             InvalidateRect( hWnd, NULL, FALSE );
             UpdateWindow( hWnd );
-	    return 0;
+	    break;
 
 	default:
 		lResult = DefWindowProc(hWnd, uMsg, wParam, lParam);
diff --git a/files/profile.c b/files/profile.c
index 61a916a..9516811 100644
--- a/files/profile.c
+++ b/files/profile.c
@@ -110,12 +110,12 @@
 
     for ( ; section; section = section->next)
     {
-        if (section->name) fprintf( file, "[%s]\n", section->name );
+        if (section->name) fprintf( file, "[%s]\r\n", section->name );
         for (key = section->key; key; key = key->next)
         {
             fprintf( file, "%s", key->name );
             if (key->value) fprintf( file, "=%s", key->value );
-            fprintf( file, "\n" );
+            fprintf( file, "\r\n" );
         }
     }
 }
diff --git a/if1632/gdi.spec b/if1632/gdi.spec
index cd60272..a01f1b1 100644
--- a/if1632/gdi.spec
+++ b/if1632/gdi.spec
@@ -215,7 +215,7 @@
 304 stub ENGINESETFONTCONTEXT
 305 stub ENGINEGETGLYPHBMP
 306 stub ENGINEMAKEFONTDIR
-307 stub GetCharABCWidths
+307 pascal16 GetCharABCWidths(word word word ptr) GetCharABCWidths
 308 stub GetOutLineTextMetrics
 309 pascal   GetGlyphOutLine(word word word ptr long ptr ptr) GetGlyphOutLine
 310 pascal16 CreateScalableFontResource(word ptr ptr ptr) CreateScalableFontResource
diff --git a/if1632/gdi32.spec b/if1632/gdi32.spec
index 9899d0e..5b6d3c0 100644
--- a/if1632/gdi32.spec
+++ b/if1632/gdi32.spec
@@ -233,7 +233,7 @@
 0229 stub GetTextExtentExPointW
 0230 stub GetTextExtentPoint32A
 0231 stub GetTextExtentPoint32W
-0232 stdcall GetTextExtentPointA(long ptr long ptr) GetTextExtentPoint
+0232 stdcall GetTextExtentPointA(long ptr long ptr) WIN32_GetTextExtentPointA
 0233 stub GetTextExtentPointW
 0234 stub GetTextFaceA
 0235 stub GetTextFaceW
diff --git a/include/options.h b/include/options.h
index a646908..9c89b37 100644
--- a/include/options.h
+++ b/include/options.h
@@ -20,6 +20,13 @@
     LANG_Cz   /* Czech */
 } WINE_LANGUAGE;
 
+/* Supported modes */
+typedef enum
+{
+    MODE_STANDARD,
+    MODE_ENHANCED
+} WINE_MODE;
+
 struct options
 {
     char * desktopGeometry; /* NULL when no desktop */
@@ -32,7 +39,8 @@
     int    debug;
     int    allowReadOnly;   /* Opening a read only file will succeed even
 			       if write access is requested */
-    int    enhanced;        /* Start Wine in enhanced mode */
+    WINE_MODE mode;         /* Start Wine in selected mode
+			       (standard/enhanced) */
     int    ipc;             /* Use IPC mechanisms */
     WINE_LANGUAGE language; /* Current language */
     int    managed;	    /* Managed windows */
diff --git a/include/struct32.h b/include/struct32.h
index a7d4dfa..37c1fd0 100644
--- a/include/struct32.h
+++ b/include/struct32.h
@@ -19,8 +19,15 @@
 	LONG y;
 } POINT32;
 
+typedef struct tagSIZE32
+{
+        LONG cx;
+        LONG cy;
+} SIZE32;
+  
 void PARAM32_POINT32to16(const POINT32*,POINT*);
 void PARAM32_POINT16to32(const POINT*,POINT32*);
+void PARAM32_SIZE16to32(const SIZE* p16, SIZE32* p32);
 
 typedef struct {
 	DWORD style;
diff --git a/include/toolhelp.h b/include/toolhelp.h
index 722d735..11e0e54 100644
--- a/include/toolhelp.h
+++ b/include/toolhelp.h
@@ -240,7 +240,7 @@
 	DWORD dwmsThisVM;
 } TIMERINFO;
 
-BOOL TimerInfo( TIMERINFO *pTimerInfo );
+BOOL TimerCount( TIMERINFO *pTimerInfo );
 
 /* Window classes */
 
diff --git a/include/windows.h b/include/windows.h
index 22a0cd2..3d7c7b0 100644
--- a/include/windows.h
+++ b/include/windows.h
@@ -689,6 +689,14 @@
 #define ETO_OPAQUE          0x02
 #define ETO_CLIPPED         0x04
 
+  /* for GetCharABCWidths() */
+typedef struct tagABC
+{
+    INT   abcA;
+    UINT  abcB;
+    INT   abcC;
+} ABC, *LPABC;
+
   /* Rasterizer status */
 typedef struct
 {
@@ -1999,6 +2007,8 @@
 #define LB_GETITEMDATA         (WM_USER+26)
 #define LB_SETITEMDATA         (WM_USER+27)
 #define LB_SELITEMRANGE        (WM_USER+28)
+#define LB_SETANCHORINDEX      (WM_USER+29) /* undoc. - for LBS_EXTENDEDSEL */
+#define LB_GETANCHORINDEX      (WM_USER+30) /* - * - */
 #define LB_SETCARETINDEX       (WM_USER+31)
 #define LB_GETCARETINDEX       (WM_USER+32)
 #define LB_SETITEMHEIGHT       (WM_USER+33)
@@ -2794,6 +2804,7 @@
 HWND       GetCapture(void);
 WORD       GetCaretBlinkTime(void);
 void       GetCaretPos(LPPOINT);
+BOOL       GetCharABCWidths(HDC,UINT,UINT,LPABC);
 BOOL       GetCharWidth(HDC,WORD,WORD,LPINT);
 BOOL       GetClassInfo(HANDLE,SEGPTR,LPWNDCLASS);
 LONG       GetClassLong(HWND,short);
diff --git a/include/winsock.h b/include/winsock.h
index 56a8fad..4fbfb1d 100644
--- a/include/winsock.h
+++ b/include/winsock.h
@@ -7,12 +7,12 @@
 #ifndef _WINSOCKAPI_
 #define _WINSOCKAPI_
 
+#include <netinet/in.h>
 #include <arpa/inet.h>
 #include <sys/types.h>
 #include <sys/time.h>
 #include <fcntl.h>
 #include <netdb.h>
-#include <netinet/in.h>
 #include <sys/socket.h>
 #include "windows.h"
 
diff --git a/libtest/Makefile.in b/libtest/Makefile.in
index 437a6dd..ae201ae 100644
--- a/libtest/Makefile.in
+++ b/libtest/Makefile.in
@@ -35,7 +35,7 @@
 	$(CC) -o rolex rolex.o $(LDOPTIONS) $(ALL_LIBS)
 
 clean::
-	$(RM) hello hello2 hello3 hello3res.c hello3res.h hello4 new rolex
+	$(RM) $(PROGRAMS) hello3res.c hello3res.h
 
 hello3res.c hello3res.h: $(WINERC)
 
diff --git a/memory/global.c b/memory/global.c
index 4b5c4e6..3f06b43 100644
--- a/memory/global.c
+++ b/memory/global.c
@@ -333,7 +333,7 @@
     ptr = (void *)pArena->base;
     oldsize = pArena->size;
     dprintf_global(stddeb,"oldsize %08lx\n",oldsize);
-    if (size == oldsize) return handle;  /* Nothing to do */
+    if (ptr && (size == oldsize)) return handle;  /* Nothing to do */
 
     ptr = realloc( ptr, size );
     if (!ptr)
diff --git a/memory/selector.c b/memory/selector.c
index 20c7bd1..26afe79 100644
--- a/memory/selector.c
+++ b/memory/selector.c
@@ -105,8 +105,8 @@
     ldt_entry entry;
     WORD i, count;
 
-      /* The limit for the first selector is the whole */
-      /* block. The next selectors get a 64k limit.    */
+    /* The limit for the first selector is the whole */
+    /* block. The next selectors get a 64k limit.    */
     entry.base           = (unsigned long)base;
     entry.type           = type;
     entry.seg_32bit      = is32bit;
@@ -114,6 +114,8 @@
     entry.limit_in_pages = (size > 0x100000);
     if (entry.limit_in_pages) entry.limit = ((size + 0xfff) >> 12) - 1;
     else entry.limit = size - 1;
+    /* Make sure base and limit are not 0 together if the size is not 0 */
+    if (!base && !entry.limit && size) entry.limit = 1;
     count = (size + 0xffff) / 0x10000;
     for (i = 0; i < count; i++)
     {
diff --git a/misc/commdlg.c b/misc/commdlg.c
index 90c3705..9e76ac0 100644
--- a/misc/commdlg.c
+++ b/misc/commdlg.c
@@ -669,12 +669,23 @@
 {
     HANDLE hInst, hDlgTmpl;
     BOOL bRet;
+    SEGPTR ptr;
 
+    /*
+     * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
+     * For now, only the standard dialog works.
+     */
+    /*
+     * FIXME : We should do error checking on the lpFind structure here
+     * and make CommDlgExtendedError() return the error condition.
+     */
     hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_FIND_TEXT );
     hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
-    bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpFind->hwndOwner,
-                                   GetWndProcEntry16("FindTextDlgProc"), 
-                                   (DWORD)lpFind );
+    if (!(ptr = (SEGPTR)WIN16_GlobalLock( hDlgTmpl ))) return -1;
+    bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner,
+                                      GetWndProcEntry16("FindTextDlgProc"),
+                                      (DWORD)lpFind );
+    GlobalUnlock( hDlgTmpl );
     SYSRES_FreeResource( hDlgTmpl );
     return bRet;
 }
@@ -687,68 +698,242 @@
 {
     HANDLE hInst, hDlgTmpl;
     BOOL bRet;
+    SEGPTR ptr;
 
+    /*
+     * FIXME : Should respond to FR_ENABLETEMPLATE and FR_ENABLEHOOK here
+     * For now, only the standard dialog works.
+     */
+    /*
+     * FIXME : We should do error checking on the lpFind structure here
+     * and make CommDlgExtendedError() return the error condition.
+     */
     hDlgTmpl = SYSRES_LoadResource( SYSRES_DIALOG_REPLACE_TEXT );
     hInst = WIN_GetWindowInstance( lpFind->hwndOwner );
-    bRet = DialogBoxIndirectParam( hInst, hDlgTmpl, lpFind->hwndOwner,
-                                   GetWndProcEntry16("ReplaceTextDlgProc"), 
-                                   (DWORD)lpFind );
+    if (!(ptr = (SEGPTR)WIN16_GlobalLock( hDlgTmpl ))) return -1;
+    bRet = CreateDialogIndirectParam( hInst, ptr, lpFind->hwndOwner,
+                                      GetWndProcEntry16("ReplaceTextDlgProc"),
+                                      (DWORD)lpFind );
+    GlobalUnlock( hDlgTmpl );
     SYSRES_FreeResource( hDlgTmpl );
     return bRet;
 }
 
 
 /***********************************************************************
+ *                              FINDDLG_WMInitDialog            [internal]
+ */
+static LRESULT FINDDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    LPFINDREPLACE lpfr;
+
+    SetWindowLong(hWnd, DWL_USER, lParam);
+    lpfr = (LPFINDREPLACE)lParam;
+    lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
+    /*
+     * FIXME : If the initial FindWhat string is empty, we should disable the
+     * FindNext (IDOK) button.  Only after typing some text, the button should be
+     * enabled.
+     */
+    SetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat);
+    CheckRadioButton(hWnd, rad1, rad2, (lpfr->Flags & FR_DOWN) ? rad2 : rad1);
+    if (lpfr->Flags & (FR_HIDEUPDOWN | FR_NOUPDOWN)) {
+	EnableWindow(GetDlgItem(hWnd, rad1), FALSE);
+	EnableWindow(GetDlgItem(hWnd, rad2), FALSE);
+    }
+    if (lpfr->Flags & FR_HIDEUPDOWN) {
+	ShowWindow(GetDlgItem(hWnd, rad1), SW_HIDE);
+	ShowWindow(GetDlgItem(hWnd, rad2), SW_HIDE);
+	ShowWindow(GetDlgItem(hWnd, grp1), SW_HIDE);
+    }
+    CheckDlgButton(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
+    if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
+	EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
+    if (lpfr->Flags & FR_HIDEWHOLEWORD)
+	ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
+    CheckDlgButton(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
+    if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
+	EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
+    if (lpfr->Flags & FR_HIDEMATCHCASE)
+	ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
+    if (!(lpfr->Flags & FR_SHOWHELP)) {
+	EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
+	ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
+    }
+    ShowWindow(hWnd, SW_SHOWNORMAL);
+    return TRUE;
+}    
+
+
+/***********************************************************************
+ *                              FINDDLG_WMCommand               [internal]
+ */
+static LRESULT FINDDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    LPFINDREPLACE lpfr;
+    int uFindReplaceMessage = RegisterWindowMessage(MAKE_SEGPTR(FINDMSGSTRING));
+    int uHelpMessage = RegisterWindowMessage(MAKE_SEGPTR(HELPMSGSTRING));
+
+    lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
+    switch (wParam) {
+	case IDOK:
+	    GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
+	    if (IsDlgButtonChecked(hWnd, rad2))
+		lpfr->Flags |= FR_DOWN;
+		else lpfr->Flags &= ~FR_DOWN;
+	    if (IsDlgButtonChecked(hWnd, chx1))
+		lpfr->Flags |= FR_WHOLEWORD; 
+		else lpfr->Flags &= ~FR_WHOLEWORD;
+	    if (IsDlgButtonChecked(hWnd, chx2))
+		lpfr->Flags |= FR_MATCHCASE; 
+		else lpfr->Flags &= ~FR_MATCHCASE;
+            lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
+	    lpfr->Flags |= FR_FINDNEXT;
+	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    return TRUE;
+	case IDCANCEL:
+            lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
+	    lpfr->Flags |= FR_DIALOGTERM;
+	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    DestroyWindow(hWnd);
+	    return TRUE;
+	case pshHelp:
+	    /* FIXME : should lpfr structure be passed as an argument ??? */
+	    SendMessage(lpfr->hwndOwner, uHelpMessage, 0, 0);
+	    return TRUE;
+    }
+    return FALSE;
+}    
+
+
+/***********************************************************************
  *           FindTextDlgProc   (COMMDLG.13)
  */
 LRESULT FindTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {
-  switch (wMsg)
-    {
-    case WM_INITDIALOG:
-      dprintf_commdlg(stddeb,"FindTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-      ShowWindow(hWnd, SW_SHOWNORMAL);
-      return (TRUE);
-    case WM_COMMAND:
-      switch (wParam)
-	{
-	case IDOK:
-	  EndDialog(hWnd, TRUE);
-	  return(TRUE);
-	case IDCANCEL:
-	  EndDialog(hWnd, FALSE);
-	  return(TRUE);
-	}
-      return(FALSE);
+    switch (wMsg) {
+	case WM_INITDIALOG:
+	    return FINDDLG_WMInitDialog(hWnd, wParam, lParam);
+	case WM_COMMAND:
+	    return FINDDLG_WMCommand(hWnd, wParam, lParam);
     }
-  return FALSE;
+    return FALSE;
 }
 
 
 /***********************************************************************
+ *                              REPLACEDLG_WMInitDialog         [internal]
+ */
+static LRESULT REPLACEDLG_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    LPFINDREPLACE lpfr;
+
+    SetWindowLong(hWnd, DWL_USER, lParam);
+    lpfr = (LPFINDREPLACE)lParam;
+    lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
+    /*
+     * FIXME : If the initial FindWhat string is empty, we should disable the FinNext /
+     * Replace / ReplaceAll buttons.  Only after typing some text, the buttons should be
+     * enabled.
+     */
+    SetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat);
+    SetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith);
+    CheckDlgButton(hWnd, chx1, (lpfr->Flags & FR_WHOLEWORD) ? 1 : 0);
+    if (lpfr->Flags & (FR_HIDEWHOLEWORD | FR_NOWHOLEWORD))
+	EnableWindow(GetDlgItem(hWnd, chx1), FALSE);
+    if (lpfr->Flags & FR_HIDEWHOLEWORD)
+	ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE);
+    CheckDlgButton(hWnd, chx2, (lpfr->Flags & FR_MATCHCASE) ? 1 : 0);
+    if (lpfr->Flags & (FR_HIDEMATCHCASE | FR_NOMATCHCASE))
+	EnableWindow(GetDlgItem(hWnd, chx2), FALSE);
+    if (lpfr->Flags & FR_HIDEMATCHCASE)
+	ShowWindow(GetDlgItem(hWnd, chx2), SW_HIDE);
+    if (!(lpfr->Flags & FR_SHOWHELP)) {
+	EnableWindow(GetDlgItem(hWnd, pshHelp), FALSE);
+	ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE);
+    }
+    ShowWindow(hWnd, SW_SHOWNORMAL);
+    return TRUE;
+}    
+
+
+/***********************************************************************
+ *                              REPLACEDLG_WMCommand            [internal]
+ */
+static LRESULT REPLACEDLG_WMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
+{
+    LPFINDREPLACE lpfr;
+    int uFindReplaceMessage = RegisterWindowMessage(MAKE_SEGPTR(FINDMSGSTRING));
+    int uHelpMessage = RegisterWindowMessage(MAKE_SEGPTR(HELPMSGSTRING));
+
+    lpfr = (LPFINDREPLACE)GetWindowLong(hWnd, DWL_USER);
+    switch (wParam) {
+	case IDOK:
+	    GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
+	    GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
+	    if (IsDlgButtonChecked(hWnd, chx1))
+		lpfr->Flags |= FR_WHOLEWORD; 
+		else lpfr->Flags &= ~FR_WHOLEWORD;
+	    if (IsDlgButtonChecked(hWnd, chx2))
+		lpfr->Flags |= FR_MATCHCASE; 
+		else lpfr->Flags &= ~FR_MATCHCASE;
+            lpfr->Flags &= ~(FR_REPLACE | FR_REPLACEALL | FR_DIALOGTERM);
+	    lpfr->Flags |= FR_FINDNEXT;
+	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    return TRUE;
+	case IDCANCEL:
+            lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL);
+	    lpfr->Flags |= FR_DIALOGTERM;
+	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    DestroyWindow(hWnd);
+	    return TRUE;
+	case psh1:
+	    GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
+	    GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
+	    if (IsDlgButtonChecked(hWnd, chx1))
+		lpfr->Flags |= FR_WHOLEWORD; 
+		else lpfr->Flags &= ~FR_WHOLEWORD;
+	    if (IsDlgButtonChecked(hWnd, chx2))
+		lpfr->Flags |= FR_MATCHCASE; 
+		else lpfr->Flags &= ~FR_MATCHCASE;
+            lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACEALL | FR_DIALOGTERM);
+	    lpfr->Flags |= FR_REPLACE;
+	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    return TRUE;
+	case psh2:
+	    GetDlgItemText(hWnd, edt1, lpfr->lpstrFindWhat, lpfr->wFindWhatLen);
+	    GetDlgItemText(hWnd, edt2, lpfr->lpstrReplaceWith, lpfr->wReplaceWithLen);
+	    if (IsDlgButtonChecked(hWnd, chx1))
+		lpfr->Flags |= FR_WHOLEWORD; 
+		else lpfr->Flags &= ~FR_WHOLEWORD;
+	    if (IsDlgButtonChecked(hWnd, chx2))
+		lpfr->Flags |= FR_MATCHCASE; 
+		else lpfr->Flags &= ~FR_MATCHCASE;
+            lpfr->Flags &= ~(FR_FINDNEXT | FR_REPLACE | FR_DIALOGTERM);
+	    lpfr->Flags |= FR_REPLACEALL;
+	    SendMessage(lpfr->hwndOwner, uFindReplaceMessage, 0, (LPARAM)MAKE_SEGPTR(lpfr));
+	    return TRUE;
+	case pshHelp:
+	    /* FIXME : should lpfr structure be passed as an argument ??? */
+	    SendMessage(lpfr->hwndOwner, uHelpMessage, 0, 0);
+	    return TRUE;
+    }
+    return FALSE;
+}    
+
+
+/***********************************************************************
  *           ReplaceTextDlgProc   (COMMDLG.14)
  */
 LRESULT ReplaceTextDlgProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
 {
-  switch (wMsg)
-    {
-    case WM_INITDIALOG:
-      dprintf_commdlg(stddeb,"ReplaceTextDlgProc // WM_INITDIALOG lParam=%08lX\n", lParam);
-      ShowWindow(hWnd, SW_SHOWNORMAL);
-      return (TRUE);
-    case WM_COMMAND:
-      switch (wParam)
-	{
-	case IDOK:
-	  EndDialog(hWnd, TRUE);
-	  return(TRUE);
-	case IDCANCEL:
-	  EndDialog(hWnd, FALSE);
-	  return(TRUE);
-	}
-      return(FALSE);
+    switch (wMsg) {
+	case WM_INITDIALOG:
+	    return REPLACEDLG_WMInitDialog(hWnd, wParam, lParam);
+	case WM_COMMAND:
+	    return REPLACEDLG_WMCommand(hWnd, wParam, lParam);
     }
-  return FALSE;
+    return FALSE;
 }
 
 
diff --git a/misc/main.c b/misc/main.c
index 762274e..c7a6afa 100644
--- a/misc/main.c
+++ b/misc/main.c
@@ -89,7 +89,7 @@
     SW_SHOWNORMAL,  /* cmdShow */
     FALSE,
     FALSE,          /* AllowReadOnly */
-    FALSE,          /* Enhanced mode */
+    MODE_ENHANCED,  /* Enhanced mode */
     FALSE,          /* IPC enabled */
 #ifdef DEFAULT_LANG
     DEFAULT_LANG,   /* Default language */
@@ -117,7 +117,7 @@
     { "-debugmsg",      ".debugmsg",        XrmoptionSepArg, (caddr_t)NULL },
     { "-dll",           ".dll",             XrmoptionSepArg, (caddr_t)NULL },
     { "-allowreadonly", ".allowreadonly",   XrmoptionNoArg,  (caddr_t)"on" },
-    { "-enhanced",      ".enhanced",        XrmoptionNoArg,  (caddr_t)"off"},
+    { "-mode",          ".mode",            XrmoptionSepArg, (caddr_t)NULL },
     { "-managed",       ".managed",         XrmoptionNoArg,  (caddr_t)"off"}
 };
 
@@ -127,24 +127,23 @@
   "Usage:  %s [options] program_name [arguments]\n" \
   "\n" \
   "Options:\n" \
+  "    -allowreadonly  Read only files may be opened in write mode\n" \
+  "    -backingstore   Turn on backing store\n" \
+  "    -debug          Enter debugger before starting application\n" \
+  "    -debugmsg name  Turn debugging-messages on or off\n" \
   "    -depth n        Change the depth to use for multiple-depth screens\n" \
   "    -desktop geom   Use a desktop window of the given geometry\n" \
   "    -display name   Use the specified display\n" \
+  "    -dll name       Enable or disable built-in DLLs\n" \
+  "    -fixedmap       Use a \"standard\" color map\n" \
   "    -iconic         Start as an icon\n" \
   "    -ipc            Enable IPC facilities\n" \
-  "    -debug          Enter debugger before starting application\n" \
   "    -language xx    Set the language (one of En,Es,De,No,Fr,Fi,Da,Cz)\n" \
   "    -managed        Allow the window manager to manage created windows\n" \
+  "    -mode mode      Start Wine in a particular mode (standard or enhanced)\n" \
   "    -name name      Set the application name\n" \
   "    -privatemap     Use a private color map\n" \
-  "    -fixedmap       Use a \"standard\" color map\n" \
-  "    -synchronous    Turn on synchronous display mode\n" \
-  "    -backingstore   Turn on backing store\n" \
-  "    -spy file       Obsolete. Use -debugmsg +message for messages\n" \
-  "    -debugmsg name  Turn debugging-messages on or off\n" \
-  "    -dll name       Enable or disable built-in DLLs\n" \
-  "    -allowreadonly  Read only files may be opened in write mode\n" \
-  "    -enhanced       Start wine in enhanced mode (like 'win /3') \n"
+  "    -synchronous    Turn on synchronous display mode\n"
 
 
 
@@ -319,6 +318,24 @@
 
 
 /***********************************************************************
+ *           MAIN_ParseModeOption
+ *
+ * Parse -mode option.
+ */
+static void MAIN_ParseModeOption( char *arg )
+{
+    if (!lstrcmpi("enhanced", arg)) Options.mode = MODE_ENHANCED;
+    else if (!lstrcmpi("standard", arg)) Options.mode = MODE_STANDARD;
+    else
+    {
+        fprintf(stderr, "Invalid mode '%s' specified.\n", arg);
+        fprintf(stderr, "Valid modes are: 'standard', 'enhanced' (default).\n");
+	exit(1);
+    }
+}
+
+
+/***********************************************************************
  *           MAIN_ParseOptions
  *
  * Parse command line options and open display.
@@ -368,8 +385,6 @@
 	Options.debug = TRUE;
     if (MAIN_GetResource( db, ".allowreadonly", &value ))
         Options.allowReadOnly = TRUE;
-    if (MAIN_GetResource( db, ".enhanced", &value ))
-        Options.enhanced = TRUE;
     if (MAIN_GetResource( db, ".ipc", &value ))
         Options.ipc = TRUE;
     if (MAIN_GetResource( db, ".depth", &value))
@@ -380,6 +395,9 @@
         MAIN_ParseLanguageOption( (char *)value.addr );
     if (MAIN_GetResource( db, ".managed", &value))
         Options.managed = TRUE;
+    if (MAIN_GetResource( db, ".mode", &value))
+        MAIN_ParseModeOption( (char *)value.addr );
+
 #ifdef DEBUG_RUNTIME
     if (MAIN_GetResource( db, ".debugoptions", &value))
 	ParseDebugOptions((char*)value.addr);
@@ -629,6 +647,8 @@
   static const long cpuflags[5] =
     { WF_CPU086, WF_CPU186, WF_CPU286, WF_CPU386, WF_CPU486 };
 
+  long result = 0;
+
   /* There doesn't seem to be any Pentium flag.  */
 #ifndef WINELIB
   long cpuflag = cpuflags[MIN (runtime_cpu (), 4)];
@@ -636,10 +656,21 @@
   long cpuflag = cpuflags[4];
 #endif
 
-  if (Options.enhanced)
-    return (WF_ENHANCED | cpuflag | WF_PMODE | WF_80x87 | WF_PAGING);
-  else
-    return (WF_STANDARD | cpuflag | WF_PMODE | WF_80x87);
+  switch(Options.mode) {
+  case MODE_STANDARD:
+    result = (WF_STANDARD | cpuflag | WF_PMODE | WF_80x87);
+    break;
+
+  case MODE_ENHANCED:
+    result = (WF_ENHANCED | cpuflag | WF_PMODE | WF_80x87 | WF_PAGING);
+    break;
+
+  default:
+    fprintf(stderr, "Unknown mode set? This shouldn't happen. Check GetWinFlags()!\n");
+    break;
+  }
+
+  return result;
 }
 
 /***********************************************************************
diff --git a/miscemu/int2f.c b/miscemu/int2f.c
index f3fd665..86ff140 100644
--- a/miscemu/int2f.c
+++ b/miscemu/int2f.c
@@ -71,13 +71,13 @@
     switch(AL_reg(context))
     {
     case 0x00:  /* Windows enhanced mode installation check */
-        AX_reg(context) = Options.enhanced ? WINVERSION : 0;
+        AX_reg(context) = (Options.mode == MODE_ENHANCED) ? WINVERSION : 0;
         break;
 	
     case 0x0a:  /* Get Windows version and type */
         AX_reg(context) = 0;
         BX_reg(context) = (WINVERSION >> 8) | ((WINVERSION << 8) & 0xff00);
-        CX_reg(context) = Options.enhanced ? 3 : 2;
+        CX_reg(context) = (Options.mode == MODE_ENHANCED) ? 3 : 2;
         break;
 
     case 0x80:  /* Release time-slice */
diff --git a/objects/font.c b/objects/font.c
index c05ba02..bbef8f6 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -594,7 +594,14 @@
 }
 
  
-/***********************************************************************/
+/***********************************************************************
+ *           GetCharABCWidths   (GDI.307)
+ */
+BOOL GetCharABCWidths(HDC hdc, UINT wFirstChar, UINT wLastChar, LPABC lpABC)
+{
+    /* No TrueType fonts in Wine */
+    return FALSE;
+}
 
 
 /***********************************************************************
diff --git a/objects/metafile.c b/objects/metafile.c
index 20d2235..e93c1a7 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -117,12 +117,7 @@
     {
 	mh->mtType = 1;
 	strcpy(mf->Filename, lpFilename);
-#ifndef WINELIB
 	mf->hFile = _lcreat(lpFilename, 0);
-#else
-        /* temporary fix until _lcreate works under WINELIB */
-	mf->hFile = creat(lpFilename, 0666);
-#endif
 	if (_lwrite(mf->hFile, (char *)mh, MFHEADERSIZE) == -1)
 	{
 	    GlobalFree(mf->hMetaHdr);
diff --git a/resources/TODO b/resources/TODO
new file mode 100644
index 0000000..28e4df9
--- /dev/null
+++ b/resources/TODO
@@ -0,0 +1,17 @@
+Due to the implementation of FindText() and ReplaceText() in /misc/commdlg.c
+I had to change the definition in sysres_En.rc of the dialogs FIND_TEXT and
+REPLACE_TEXT.  These changes should also be made for the other languages.
+Not only should the definitions in sysres_??.rc made up to date with the
+Enlish version, but also the dimensions of the controls should be changed so
+that they will be big enough to contain the text for every individual
+language.
+
+Therefore:
+
+- Definitions of FIND_TEXT and REPLACE_TEXT in sysres_??.rc should match
+  those in sysres_En.rc
+- Dimensions of controls are based on sysres_En.rc.  Other languages should
+  change these dimensions in order to make the text fit.
+
+Frans van Dorsselaer
+dorssel@rulhm1.LeidenUniv.nl
diff --git a/resources/sysres_En.rc b/resources/sysres_En.rc
index b90b9b8..b918771 100644
--- a/resources/sysres_En.rc
+++ b/resources/sysres_En.rc
@@ -165,36 +165,38 @@
 }
 
 
-FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 84
+FIND_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 236, 62
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Find"
 FONT 8, "Helv"
 {
- LTEXT "Fi&nd What:", 1088, 6, 6, 40, 9
- LTEXT "", 1089, 60, 6, 150, 9
- CHECKBOX "Match &Whole Word Only", 1040, 20, 30, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- CHECKBOX "Match &Case", 1041, 20, 50, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- GROUPBOX "Direction", 1072, 90, 40, 80, 40, BS_GROUPBOX
- RADIOBUTTON "&Up", 1056, 100, 50, 50, 12
- RADIOBUTTON "&Down", 1057, 150, 50, 50, 12
- DEFPUSHBUTTON "&Find Next", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "Cancel", 2, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
+ LTEXT "Fi&nd What:", -1, 4, 8, 42, 8
+ EDITTEXT 1152, 47, 7, 128, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Match &Whole Word Only", 1040, 4, 26, 100, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Match &Case", 1041, 4, 42, 64, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ GROUPBOX "Direction", 1072, 107, 26, 68, 28
+ CONTROL "&Up", 1056, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_GROUP | WS_TABSTOP, 111, 38, 20, 12
+ CONTROL "&Down", 1057, "BUTTON", BS_AUTORADIOBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 138, 38, 30, 12
+ DEFPUSHBUTTON "&Find Next", 1, 182, 5, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Cancel", 2, 182, 23, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Help", 1038, 182, 45, 50, 14, WS_GROUP | WS_TABSTOP
 }
 
 
-REPLACE_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 264, 114
+REPLACE_TEXT DIALOG LOADONCALL MOVEABLE DISCARDABLE 36, 24, 230, 94
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Replace"
 FONT 8, "Helv"
 {
- LTEXT "Fi&nd What:", 1088, 6, 6, 40, 9
- LTEXT "", 1089, 60, 6, 150, 9
- LTEXT "Re&place With:", 1090, 6, 26, 40, 9
- LTEXT "", 1091, 60, 26, 150, 9
- CHECKBOX "Match &Whole Word Only", 1040, 20, 40, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- CHECKBOX "Match &Case", 1041, 20, 60, 50, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
- DEFPUSHBUTTON "&Find Next", 1, 206, 6, 56, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
- PUSHBUTTON "&Replace", 1024, 206, 24, 56, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "Replace &All", 1025, 206, 44, 56, 14, WS_GROUP | WS_TABSTOP
- PUSHBUTTON "Cancel", 2, 206, 64, 56, 14, WS_GROUP | WS_TABSTOP
+ LTEXT "Fi&nd What:", -1, 4, 9, 48, 8
+ EDITTEXT 1152, 54, 7, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ LTEXT "Re&place With:", -1, 4, 26, 48, 8
+ EDITTEXT 1153, 54, 24, 114, 12, ES_AUTOHSCROLL | WS_BORDER | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Match &Whole Word Only", 1040, 5, 46, 104, 12, BS_AUTOCHECKBOX | WS_GROUP | WS_TABSTOP
+ CHECKBOX "Match &Case", 1041, 5, 62, 59, 12, BS_AUTOCHECKBOX | WS_TABSTOP
+ DEFPUSHBUTTON "&Find Next", 1, 174, 4, 50, 14, BS_DEFPUSHBUTTON | WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Replace", 1024, 174, 21, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Replace &All", 1025, 174, 38, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "Cancel", 2, 174, 55, 50, 14, WS_GROUP | WS_TABSTOP
+ PUSHBUTTON "&Help", 1038, 174, 75, 50, 14, WS_GROUP | WS_TABSTOP
 }
diff --git a/win32/memory.c b/win32/memory.c
index 0227222..ba58f6f 100644
--- a/win32/memory.c
+++ b/win32/memory.c
@@ -108,7 +108,7 @@
 	static int warned=0;
 	if(!warned)
 	{
-		fprintf("Don't know how to perform MEMORY_IsVrangeFree on "
+		fprintf(stdnimp, "Don't know how to perform MEMORY_IsVrangeFree on "
 			"this system.\n Please fix\n");
 		warned=0;
 	}
diff --git a/win32/param32.c b/win32/param32.c
index 1219725..523c265 100644
--- a/win32/param32.c
+++ b/win32/param32.c
@@ -19,6 +19,13 @@
 	p16->y = p32->y;
 }
 
+void PARAM32_SIZE16to32(const SIZE* p16, SIZE32* p32) 
+  
+{
+        p32->cx = p16->cx;
+        p32->cy = p16->cy;
+}
+
 /****************************************************************
  *           MoveToEx          (GDI32.254)
  */
@@ -32,3 +39,15 @@
 		return MoveToEx(hdc,x,y,&p);
 	}
 }
+
+BOOL WIN32_GetTextExtentPointA(HDC hdc, LPCTSTR str, int length, SIZE32* lpsize)
+
+{
+        SIZE s;
+        BOOL retval;
+
+        retval = GetTextExtentPoint(hdc, str, length, &s);
+        PARAM32_SIZE16to32(&s, lpsize);
+
+        return retval;
+}
diff --git a/windows/caret.c b/windows/caret.c
index 12e9e00..863a75c 100644
--- a/windows/caret.c
+++ b/windows/caret.c
@@ -28,72 +28,109 @@
     WORD          timerid;
 } CARET;
 
-static CARET Caret;
-static BOOL LockCaret;
+typedef enum
+{
+    CARET_OFF = 0,
+    CARET_ON,
+    CARET_TOGGLE,
+} DISPLAY_CARET;
 
-static void CARET_HideCaret();
+static CARET Caret = { (HWND)0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 
 
 /*****************************************************************
- *               CARET_Callback
+ *              CARET_GetHwnd
  */
-WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime)
+HWND CARET_GetHwnd()
 {
-    HDC hdc;
-    HBRUSH hBrush;
-    HRGN rgn;
-
-    dprintf_caret(stddeb,"CARET_Callback: id=%d: LockCaret=%d, hidden=%d, on=%d\n",
-	   timerid, LockCaret, Caret.hidden, Caret.on);
-    if (!LockCaret && (!Caret.hidden || Caret.on))
-    {
-	Caret.on = (Caret.on ? FALSE : TRUE);
-	hdc = GetDC(Caret.hwnd);
-	if (Caret.bitmap == (HBITMAP)0 || Caret.bitmap == (HBITMAP)1)
-	    hBrush = CreateSolidBrush(Caret.color);
-	else
-	    hBrush = CreatePatternBrush(Caret.bitmap);
-	SelectObject(hdc, (HANDLE)hBrush);
-	SetROP2(hdc, R2_NOTXORPEN);
-	rgn = CreateRectRgn(Caret.x, Caret.y, 
-			    Caret.x + Caret.width,
-			    Caret.y + Caret.height);
-	FillRgn(hdc, rgn, hBrush);
-	DeleteObject((HANDLE)rgn);
-	DeleteObject((HANDLE)hBrush);
-	ReleaseDC(Caret.hwnd, hdc);
-    }
-    return 0;
+    return Caret.hwnd;
 }
 
-
 /*****************************************************************
- *               CARET_HideCaret
+ *               CARET_DisplayCaret
  */
-
-static void CARET_HideCaret()
+void CARET_DisplayCaret(DISPLAY_CARET status)
 {
     HDC hdc;
     HBRUSH hBrush;
+    HBRUSH hPrevBrush;
     HRGN rgn;
 
-    Caret.on = FALSE;
+    if (Caret.on && (status == CARET_ON)) return;
+    if (!Caret.on && (status == CARET_OFF)) return;
+
+    /* So now it's always a toggle */
+
+    Caret.on = !Caret.on;
     hdc = GetDC(Caret.hwnd);
     if (Caret.bitmap == (HBITMAP)0 || Caret.bitmap == (HBITMAP)1)
 	hBrush = CreateSolidBrush(Caret.color);
     else
 	hBrush = CreatePatternBrush(Caret.bitmap);
-    SelectObject(hdc, (HANDLE)hBrush);
-    SetROP2(hdc, R2_NOTXORPEN);
+    hPrevBrush = SelectObject(hdc, (HANDLE)hBrush);
+    SetROP2(hdc, R2_XORPEN);
     rgn = CreateRectRgn(Caret.x, Caret.y, 
 			Caret.x + Caret.width,
 			Caret.y + Caret.height);
     FillRgn(hdc, rgn, hBrush);
-    DeleteObject((HANDLE)rgn);
-    DeleteObject((HANDLE)hBrush);
+    DeleteObject( rgn );
+    SelectObject( hdc, hPrevBrush );
+    DeleteObject( hBrush );
     ReleaseDC(Caret.hwnd, hdc);
 }
 
+  
+/*****************************************************************
+ *               CARET_Callback
+ */
+WORD CARET_Callback(HWND hwnd, WORD msg, WORD timerid, LONG ctime)
+{
+    dprintf_caret(stddeb,"CARET_Callback: hwnd="NPFMT", timerid=%d, "
+		"caret=%d\n", hwnd, timerid, Caret.on);
+	
+    CARET_DisplayCaret(CARET_TOGGLE);
+    return 0;
+}
+
+
+/*****************************************************************
+ *               CARET_SetTimer
+ */
+void CARET_SetTimer(void)
+{
+    if (Caret.timerid) KillSystemTimer((HWND)0, Caret.timerid);
+    Caret.timerid = SetSystemTimer((HWND)0, 0, Caret.timeout,
+			(FARPROC)GetWndProcEntry16("CARET_Callback"));
+}
+
+
+/*****************************************************************
+ *               CARET_ResetTimer
+ */
+void CARET_ResetTimer(void)
+{
+    if (Caret.timerid) 
+    {
+	KillSystemTimer((HWND)0, Caret.timerid);
+	Caret.timerid = SetSystemTimer((HWND)0, 0, Caret.timeout,
+			(FARPROC)GetWndProcEntry16("CARET_Callback"));
+    }
+}
+
+
+/*****************************************************************
+ *               CARET_KillTimer
+ */
+void CARET_KillTimer(void)
+{
+    if (Caret.timerid) 
+    {
+	KillSystemTimer((HWND)0, Caret.timerid);
+	Caret.timerid = 0;
+    }
+}
+
+
 /*****************************************************************
  *               CARET_Initialize
  */
@@ -101,14 +138,16 @@
 {
     DWORD WineProc,Win16Proc,Win32Proc;
     static int initialized=0;
+
     if(!initialized)
     {
-      WineProc=(DWORD)CARET_Callback;
-      Win16Proc=(DWORD)GetWndProcEntry16("CARET_Callback");
-      Win32Proc=(DWORD)RELAY32_GetEntryPoint(
-	  	RELAY32_GetBuiltinDLL("WINPROCS32"),"CARET_Callback",0);
-      ALIAS_RegisterAlias(WineProc,Win16Proc,Win32Proc);
-      initialized=1;
+	WineProc = (DWORD)CARET_Callback;
+	Win16Proc = (DWORD)GetWndProcEntry16("CARET_Callback");
+	Win32Proc = (DWORD)RELAY32_GetEntryPoint(
+				RELAY32_GetBuiltinDLL("WINPROCS32"),
+				"CARET_Callback", 0);
+	ALIAS_RegisterAlias(WineProc, Win16Proc, Win32Proc);
+	initialized=1;
     }
 }
 
@@ -119,18 +158,17 @@
 
 BOOL CreateCaret(HWND hwnd, HBITMAP bitmap, INT width, INT height)
 {
+    dprintf_caret(stddeb,"CreateCaret: hwnd="NPFMT"\n", hwnd);
+
     if (!hwnd) return FALSE;
 
-
     /* if cursor already exists, destroy it */
-/*    if (Caret.hwnd)
-	DestroyCaret();
-*/
-    if (bitmap && bitmap != (HBITMAP)1)
-	Caret.bitmap = bitmap;
+    if (Caret.hwnd) DestroyCaret();
+
+    if (bitmap && bitmap != (HBITMAP)1) Caret.bitmap = bitmap;
 
     if (width)
-	Caret.width = width;
+        Caret.width = width;
     else
 	Caret.width = GetSystemMetrics(SM_CXBORDER);
 
@@ -147,17 +185,11 @@
     if (bitmap == (HBITMAP)1)
 	Caret.color = GetSysColor(COLOR_GRAYTEXT);
     else
-	Caret.color = GetSysColor(COLOR_WINDOWTEXT);
+	Caret.color = GetSysColor(COLOR_WINDOW);
     Caret.timeout = 750;
-    LockCaret = FALSE;
 
     CARET_Initialize();
 
-    Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
-                                (FARPROC)GetWndProcEntry16("CARET_Callback"));
-
-    dprintf_caret(stddeb,"CreateCaret: hwnd="NPFMT", timerid=%d\n", 
-		  hwnd, Caret.timerid);
     return TRUE;
 }
    
@@ -168,16 +200,15 @@
 
 BOOL DestroyCaret()
 {
-/*    if (!Caret.hwnd) return;
-*/
-    dprintf_caret(stddeb,"DestroyCaret: timerid=%d\n", Caret.timerid);
+    if (!Caret.hwnd) return FALSE;
 
-    KillSystemTimer( (HWND)0, Caret.timerid);
+    dprintf_caret(stddeb,"DestroyCaret: hwnd="NPFMT", timerid=%d\n",
+		Caret.hwnd, Caret.timerid);
 
-    if (Caret.on)
-	CARET_HideCaret();
+    CARET_KillTimer();
+    CARET_DisplayCaret(CARET_OFF);
 
-    Caret.hwnd = 0;          /* cursor marked as not existing */
+    Caret.hwnd = 0;
     return TRUE;
 }
 
@@ -192,13 +223,15 @@
 
     dprintf_caret(stddeb,"SetCaretPos: x=%d, y=%d\n", x, y);
 
-    LockCaret = TRUE;
-    if (Caret.on)
-	CARET_HideCaret();
-
+    CARET_KillTimer();
+    CARET_DisplayCaret(CARET_OFF);
     Caret.x = x;
     Caret.y = y;
-    LockCaret = FALSE;
+    if (!Caret.hidden)
+    {
+	CARET_DisplayCaret(CARET_ON);
+	CARET_SetTimer();
+    }
 }
 
 /*****************************************************************
@@ -210,12 +243,12 @@
     if (!Caret.hwnd) return;
     if (hwnd && (Caret.hwnd != hwnd)) return;
 
-    LockCaret = TRUE;
-    if (Caret.on)
-	CARET_HideCaret();
+    dprintf_caret(stddeb,"HideCaret: hwnd="NPFMT", hidden=%d\n",
+		hwnd, Caret.hidden);
 
-    ++Caret.hidden;
-    LockCaret = FALSE;
+    CARET_KillTimer();
+    CARET_DisplayCaret(CARET_OFF);
+    Caret.hidden++;
 }
 
 
@@ -228,9 +261,18 @@
     if (!Caret.hwnd) return;
     if (hwnd && (Caret.hwnd != hwnd)) return;
 
-    dprintf_caret(stddeb,"ShowCaret: hidden=%d\n", Caret.hidden);
+    dprintf_caret(stddeb,"ShowCaret: hwnd="NPFMT", hidden=%d\n",
+		hwnd, Caret.hidden);
+
     if (Caret.hidden)
-	--Caret.hidden;
+    {
+	Caret.hidden--;
+	if (!Caret.hidden)
+	{
+	    CARET_DisplayCaret(CARET_ON);
+	    CARET_SetTimer();
+	}
+    }
 }
 
 
@@ -242,12 +284,11 @@
 {
     if (!Caret.hwnd) return;
 
-    CARET_Initialize();
+    dprintf_caret(stddeb,"SetCaretBlinkTime: hwnd="NPFMT", msecs=%d\n",
+		Caret.hwnd, msecs);
 
-    KillSystemTimer( (HWND)0, Caret.timerid);
     Caret.timeout = msecs;
-    Caret.timerid = SetSystemTimer( (HWND)0, 0, Caret.timeout,
-                                 (FARPROC)GetWndProcEntry16("CARET_Callback"));
+    CARET_ResetTimer();
 }
 
 
@@ -258,6 +299,10 @@
 WORD GetCaretBlinkTime()
 {
     if (!Caret.hwnd) return 0;
+
+    dprintf_caret(stddeb,"GetCaretBlinkTime: hwnd="NPFMT", msecs=%d\n",
+		Caret.hwnd, Caret.timeout);
+
     return Caret.timeout;
 }
 
@@ -270,6 +315,9 @@
 {
     if (!Caret.hwnd || !pt) return;
 
+    dprintf_caret(stddeb,"GetCaretPos: hwnd="NPFMT", pt=%p, x=%d, y=%d\n",
+		Caret.hwnd, pt, Caret.x, Caret.y);
+
     pt->x = Caret.x;
     pt->y = Caret.y;
 }
diff --git a/windows/nonclient.c b/windows/nonclient.c
index 976cfb6..15fbcf7 100644
--- a/windows/nonclient.c
+++ b/windows/nonclient.c
@@ -807,6 +807,37 @@
 
 
 /***********************************************************************
+ *           NC_TrackSysMenu
+ *
+ * Track a mouse button press on the system menu.
+ */
+static void NC_TrackSysMenu( HWND hwnd, HDC hdc, POINT pt )
+{
+    RECT rect;
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    int iconic = wndPtr->dwStyle & WS_MINIMIZE;
+
+    if (!(wndPtr->dwStyle & WS_SYSMENU)) return;
+    /* If window has a menu, track the menu bar normally if it not minimized */
+    if (HAS_MENU(wndPtr) && !iconic) MENU_TrackMouseMenuBar( hwnd, pt );
+    else
+    {
+	  /* Otherwise track the system menu like a normal popup menu */
+	NC_GetInsideRect( hwnd, &rect );
+	OffsetRect( &rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top );
+	if (wndPtr->dwStyle & WS_CHILD)
+	    ClientToScreen( wndPtr->hwndParent, (POINT *)&rect );
+	rect.right = rect.left + SYSMETRICS_CXSIZE;
+	rect.bottom = rect.top + SYSMETRICS_CYSIZE;
+	if (!iconic) NC_DrawSysButton( hwnd, hdc, TRUE );
+	TrackPopupMenu( wndPtr->hSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
+		        rect.left, rect.bottom, 0, hwnd, &rect );
+	if (!iconic) NC_DrawSysButton( hwnd, hdc, FALSE );
+    }
+}
+
+
+/***********************************************************************
  *           NC_StartSizeMove
  *
  * Initialisation of a move or resize, when initiatied from a menu choice.
@@ -904,6 +935,7 @@
     BOOL thickframe;
     POINT minTrack, maxTrack, capturePoint = pt;
     WND * wndPtr = WIN_FindWndPtr( hwnd );
+    int moved = 0;
 
     if (IsZoomed(hwnd) || !IsWindowVisible(hwnd) ||
         (wndPtr->flags & WIN_MANAGED)) return;
@@ -977,7 +1009,7 @@
 
     while(1)
     {
-	int dx = 0, dy = 0;
+        int dx = 0, dy = 0;
 
 	MSG_GetHardwareMessage( &msg );
 
@@ -1012,6 +1044,7 @@
 
 	if (dx || dy)
 	{
+            moved = 1;
 	    if (msg.message == WM_KEYDOWN) SetCursorPos( pt.x, pt.y );
 	    else
 	    {
@@ -1032,6 +1065,7 @@
 
     NC_DrawMovingFrame( hdc, &sizingRect, thickframe );
     ReleaseCapture();
+
     if (wndPtr->dwStyle & WS_CHILD) ReleaseDC( wndPtr->hwndParent, hdc );
     else
     {
@@ -1041,6 +1075,14 @@
     SendMessage( hwnd, WM_EXITSIZEMOVE, 0, 0 );
     SendMessage( hwnd, WM_SETVISIBLE, !IsIconic(hwnd), 0L);
 
+    /* Single click brings up the system menu */
+
+    if (!moved)
+    {
+        NC_TrackSysMenu( hwnd, hdc, pt );
+        return;
+    }
+
       /* If Esc key, don't move the window */
     if ((msg.message == WM_KEYDOWN) && (msg.wParam == VK_ESCAPE)) return;
 
@@ -1152,36 +1194,6 @@
 }
 
 /***********************************************************************
- *           NC_TrackSysMenu
- *
- * Track a mouse button press on the system menu.
- */
-static void NC_TrackSysMenu( HWND hwnd, HDC hdc, POINT pt )
-{
-    RECT rect;
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-
-    if (!(wndPtr->dwStyle & WS_SYSMENU)) return;
-      /* If window has a menu, track the menu bar normally */
-    if (HAS_MENU(wndPtr)) MENU_TrackMouseMenuBar( hwnd, pt );
-    else
-    {
-	  /* Otherwise track the system menu like a normal popup menu */
-	NC_GetInsideRect( hwnd, &rect );
-	OffsetRect( &rect, wndPtr->rectWindow.left, wndPtr->rectWindow.top );
-	if (wndPtr->dwStyle & WS_CHILD)
-	    ClientToScreen( wndPtr->hwndParent, (POINT *)&rect );
-	rect.right = rect.left + SYSMETRICS_CXSIZE;
-	rect.bottom = rect.top + SYSMETRICS_CYSIZE;
-	NC_DrawSysButton( hwnd, hdc, TRUE );
-	TrackPopupMenu( wndPtr->hSysMenu, TPM_LEFTALIGN | TPM_LEFTBUTTON,
-		        rect.left, rect.bottom, 0, hwnd, &rect );
-	NC_DrawSysButton( hwnd, hdc, FALSE );
-    }
-}
-
-
-/***********************************************************************
  *           NC_HandleNCLButtonDown
  *
  * Handle a WM_NCLBUTTONDOWN message. Called from DefWindowProc().
diff --git a/windows/painting.c b/windows/painting.c
index 18d6e3c..2e4c2b4 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -30,13 +30,15 @@
     hrgnUpdate = wndPtr->hrgnUpdate;  /* Save update region */
     if (!hrgnUpdate)    /* Create an empty region */
 	if (!(hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ))) return 0;
-    
+
     if (wndPtr->hrgnUpdate || (wndPtr->flags & WIN_INTERNAL_PAINT))
 	MSG_DecPaintCount( wndPtr->hmemTaskQ );
 
     wndPtr->hrgnUpdate = 0;
     wndPtr->flags &= ~(WIN_NEEDS_BEGINPAINT | WIN_INTERNAL_PAINT);
 
+    HideCaret( hwnd );
+
     if (wndPtr->flags & WIN_NEEDS_NCPAINT)
     {
         wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
@@ -71,6 +73,7 @@
 BOOL EndPaint( HWND hwnd, const PAINTSTRUCT* lps )
 {
     ReleaseDC( hwnd, lps->hdc );
+    ShowCaret( hwnd );
     return TRUE;
 }
 
diff --git a/windows/scroll.c b/windows/scroll.c
index d69f5b7..4aa0fce 100644
--- a/windows/scroll.c
+++ b/windows/scroll.c
@@ -20,6 +20,7 @@
 
 
 extern HRGN DCE_GetVisRgn(HWND, WORD);
+extern HWND CARET_GetHwnd();
 
 static int RgnType;
 
@@ -122,9 +123,10 @@
 
 void ScrollWindow(HWND hwnd, short dx, short dy, LPRECT rect, LPRECT clipRect)
 {
-    HDC hdc;
+    HDC  hdc;
     HRGN hrgnUpdate,hrgnClip;
     RECT rc, cliprc;
+    HWND hCaretWnd = CARET_GetHwnd();
 
     dprintf_scroll(stddeb,"ScrollWindow: dx=%d, dy=%d, lpRect =%08lx clipRect=%i,%i,%i,%i\n", 
 	    dx, dy, (LONG)rect, (int)((clipRect)?clipRect->left:0),
@@ -138,6 +140,10 @@
 	GetClientRect(hwnd, &rc);
 	  hrgnClip = CreateRectRgnIndirect( &rc );
 
+          if ((hCaretWnd == hwnd) || IsChild(hwnd,hCaretWnd))
+              HideCaret(hCaretWnd);
+          else hCaretWnd = 0;
+ 
 	  /* children will be Blt'ed too */
 	  hdc      = GetDCEx(hwnd, hrgnClip, DCX_CACHE | DCX_CLIPSIBLINGS);
           DeleteObject(hrgnClip);
@@ -150,7 +156,9 @@
 			 (int)rect->bottom,(int)rc.left,(int)rc.top,
 			 (int)rc.right,(int)rc.bottom);
 
-	CopyRect(&rc, rect);
+          if (hCaretWnd == hwnd) HideCaret(hCaretWnd);
+          else hCaretWnd = 0;
+          CopyRect(&rc, rect);
 	  hdc = GetDC(hwnd);
        }
 
@@ -189,6 +197,7 @@
       }
 
     DeleteObject(hrgnUpdate);
+    if( hCaretWnd ) ShowCaret(hCaretWnd);
 }
 
 
diff --git a/windows/win.c b/windows/win.c
index 456b762..81133a4 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -1240,8 +1240,41 @@
  */
 BOOL FlashWindow(HWND hWnd, BOOL bInvert)
 {
-	dprintf_win(stdnimp,"EMPTY STUB !! FlashWindow !\n");
-	return FALSE;
+    WND *wndPtr = WIN_FindWndPtr(hWnd);
+
+    dprintf_win(stddeb,"FlashWindow: "NPFMT"\n", hWnd);
+
+    if (!wndPtr) return FALSE;
+
+    if (wndPtr->dwStyle & WS_MINIMIZE)
+    {
+        if (bInvert && !(wndPtr->flags & WIN_NCACTIVATED))
+        {
+            HDC hDC = GetDC(hWnd);
+            
+            if (!SendMessage( hWnd, WM_ERASEBKGND, (WPARAM)hDC, (LPARAM)0 ))
+                wndPtr->flags |= WIN_NEEDS_ERASEBKGND;
+            
+            ReleaseDC( hWnd, hDC );
+            wndPtr->flags |= WIN_NCACTIVATED;
+        }
+        else
+        {
+            RedrawWindow( hWnd, 0, 0, RDW_INVALIDATE | RDW_ERASE |
+                          RDW_UPDATENOW | RDW_FRAME );
+            wndPtr->flags &= ~WIN_NCACTIVATED;
+        }
+        return TRUE;
+    }
+    else
+    {
+        WPARAM wparam;
+        if (bInvert) wparam = !(wndPtr->flags & WIN_NCACTIVATED);
+        else wparam = (hWnd == GetActiveWindow());
+
+        SendMessage( hWnd, WM_NCACTIVATE, wparam, (LPARAM)0 );
+        return wparam;
+    }
 }
 
 
diff --git a/wine.man b/wine.man
index 6ac8629..5e79214 100644
--- a/wine.man
+++ b/wine.man
@@ -56,43 +56,14 @@
 .B configure.
 .SH OPTIONS
 .TP
-.I -depth n
-Change the depth to use for multiple-depth screens
-.TP
-.I -desktop geom
-Use a desktop window of the given geometry
-.TP
-.I -display name
-Use the specified display
-.TP
-.I -iconic
-Start as an icon
-.TP
-.I -debug
-Enter the debugger before starting application
-.TP
-.I -language xx
-Set the language to
-.I xx
-(one of En, Es, De, No, Fr, Fi, Da Cz)
-.TP
-.I -managed
-Create each top-level window as a properly managed X window
-.TP
-.I -name name
-Set the application name
-.TP
-.I -privatemap
-Use a private color map
-.TP
-.I -synchronous
-Turn on synchronous display mode
+.I -allowreadonly
+Read only files may be opened in write mode
 .TP
 .I -backingstore
 Turn on backing store
 .TP
-.I -spy file
-Turn on message spying to the specified file
+.I -debug
+Enter the debugger before starting application
 .TP
 .I -debugmsg name[,name]
 Turn debugging messages on or off - for instance, 
@@ -106,6 +77,15 @@
 profile, prop, reg, region, relay, resource, scroll, selector, selectors, 
 stress, syscolor, task, text, timer, toolhelp, utility, win, winsock.
 .TP
+.I -depth n
+Change the depth to use for multiple-depth screens
+.TP
+.I -desktop geom
+Use a desktop window of the given geometry
+.TP
+.I -display name
+Use the specified display
+.TP
 .I -dll name
 Enables/disables built-in DLL's - starting wine with
 .I -dll -commdlg
@@ -115,11 +95,37 @@
 SYSTEM, TOOLHELP, MOUSE, COMMDLG, OLE2, OLE2CONV, OLE2DISP, OLE2NLS, OLE2PROX,
 OLECLI, OLESVR, COMPOBJ, STORAGE, WINPROCS, DDEML
 .TP
-.I -allowreadonly
-Read only files may be opened in write mode
+.I -fixedmap
+Use a "standard" color map.
 .TP
-.I -enhanced
-Starts wine in Enhanced mode
+.I -iconic
+Start as an icon
+.TP
+.I -language xx
+Set the language to
+.I xx
+(one of En, Es, De, No, Fr, Fi, Da, Cz)
+.TP
+.I -managed
+Create each top-level window as a properly managed X window
+.TP
+.I -mode modename
+Determines the mode in which
+.B wine
+is started. Possible mode names are
+.I standard
+and
+.I enhanced.
+Enhanced mode is the default (when no -mode option is specified).
+.TP
+.I -name name
+Set the application name
+.TP
+.I -privatemap
+Use a private color map
+.TP
+.I -synchronous
+Turn on synchronous display mode
 .PD 1
 .SH PROGRAM/ARGUMENTS
 The program name may be specified in DOS format (C:\\WINDOWS\\SOL.EXE) or in