Release 950706

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	* [toolkit/heap.c]
	fixed LocalLock prototype

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

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

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

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

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

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

	* [misc/profile.c]
	Fixed problem parsing empty lines within sections in .ini files.
diff --git a/windows/graphics.c b/windows/graphics.c
index 26ba7b3..bbc674b 100644
--- a/windows/graphics.c
+++ b/windows/graphics.c
@@ -332,9 +332,8 @@
  *           RoundRect    (GDI.28)
  */
 BOOL RoundRect( HDC hDC, short left, short top, short right, short bottom,
-					short ell_width, short ell_height)
+                short ell_width, short ell_height )
 {
-    int		x1, y1, x2, y2;
     DC * dc = (DC *) GDI_GetObjPtr(hDC, DC_MAGIC);
     if (!dc) 
     {
@@ -346,59 +345,103 @@
     }
     dprintf_graphics(stddeb, "RoundRect(%d %d %d %d  %d %d\n", 
     	left, top, right, bottom, ell_width, ell_height);
-    x1 = XLPTODP(dc, left);
-    y1 = YLPTODP(dc, top);
-    x2 = XLPTODP(dc, right - ell_width);
-    y2 = YLPTODP(dc, bottom - ell_height);
+
+    left   = XLPTODP( dc, left );
+    top    = YLPTODP( dc, top );
+    right  = XLPTODP( dc, right );
+    bottom = YLPTODP( dc, bottom );
+    ell_width  = abs( ell_width * dc->w.VportExtX / dc->w.WndExtX );
+    ell_height = abs( ell_height * dc->w.VportExtY / dc->w.WndExtY );
+
+    /* Fix the coordinates */
+
+    if (left > right) { short t = left; left = right; right = t; }
+    if (top > bottom) { short t = top; top = bottom; bottom = t; }
+    if (ell_width > right - left) ell_width = right - left;
+    if (ell_height > bottom - top) ell_height = bottom - top;
+
     if (DC_SetupGCForBrush( dc ))
     {
-	XFillArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x1, dc->w.DCOrgY + y1,
-		        ell_width, ell_height, 90 * 64, 90 * 64);
-	XFillArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x1, dc->w.DCOrgY + y2,
-		        ell_width, ell_height, 180 * 64, 90 * 64);
-	XFillArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x2, dc->w.DCOrgY + y2,
-		        ell_width, ell_height, 270 * 64, 90 * 64);
-	XFillArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x2, dc->w.DCOrgY + y1,
-		        ell_width, ell_height, 0, 90 * 64);
-	ell_width /= 2;  ell_height /= 2;
-	XFillRectangle(display, dc->u.x.drawable, dc->u.x.gc,
-		dc->w.DCOrgX + left + ell_width, dc->w.DCOrgY + top,
-		right - left - 2 * ell_width, bottom - top);
-	XFillRectangle(display, dc->u.x.drawable, dc->u.x.gc,
-		dc->w.DCOrgX + left, dc->w.DCOrgY + top + ell_height,
-		ell_width, bottom - top - 2 * ell_height);
-	XFillRectangle(display, dc->u.x.drawable, dc->u.x.gc,
-		dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top + ell_height,
-		ell_width, bottom - top - 2 * ell_height);
-	ell_width *= 2;  ell_height *= 2;
-	}    	
-    if (DC_SetupGCForPen(dc)) {
-	XDrawArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x1, dc->w.DCOrgY + y1,
-		        ell_width, ell_height, 90 * 64, 90 * 64);
-	XDrawArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x1, dc->w.DCOrgY + y2,
-		        ell_width, ell_height, 180 * 64, 90 * 64);
-	XDrawArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x2, dc->w.DCOrgY + y2,
-		        ell_width, ell_height, 270 * 64, 90 * 64);
-	XDrawArc(display, dc->u.x.drawable, dc->u.x.gc,
-		        dc->w.DCOrgX + x2, dc->w.DCOrgY + y1,
-		        ell_width, ell_height, 0, 90 * 64);
+        if (ell_width && ell_height)
+        {
+            XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+                      ell_width, ell_height, 90 * 64, 90 * 64 );
+            XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + left, dc->w.DCOrgY + bottom - ell_height,
+                      ell_width, ell_height, 180 * 64, 90 * 64 );
+            XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + right - ell_width,
+                      dc->w.DCOrgY + bottom - ell_height,
+                      ell_width, ell_height, 270 * 64, 90 * 64 );
+            XFillArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top,
+                      ell_width, ell_height, 0, 90 * 64 );
+        }
+        if (ell_width < right - left)
+        {
+            XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+                            dc->w.DCOrgX + left + ell_width / 2,
+                            dc->w.DCOrgY + top,
+                            right - left - ell_width, ell_height / 2 );
+            XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+                            dc->w.DCOrgX + left + ell_width / 2,
+                            dc->w.DCOrgY + bottom - (ell_height+1) / 2,
+                            right - left - ell_width, (ell_height+1) / 2 );
+        }
+        if  (ell_height < bottom - top)
+        {
+            XFillRectangle( display, dc->u.x.drawable, dc->u.x.gc,
+                            dc->w.DCOrgX + left,
+                            dc->w.DCOrgY + top + ell_height / 2,
+                            right - left, bottom - top - ell_height );
+        }
+    }
+    if (DC_SetupGCForPen(dc))
+    {
+        if (ell_width && ell_height)
+        {
+            XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + left, dc->w.DCOrgY + top,
+                      ell_width, ell_height, 90 * 64, 90 * 64 );
+            XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + left, dc->w.DCOrgY + bottom - ell_height,
+                      ell_width, ell_height, 180 * 64, 90 * 64 );
+            XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + right - ell_width,
+                      dc->w.DCOrgY + bottom - ell_height,
+                      ell_width, ell_height, 270 * 64, 90 * 64 );
+            XDrawArc( display, dc->u.x.drawable, dc->u.x.gc,
+                      dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top,
+                      ell_width, ell_height, 0, 90 * 64 );
 	}
-    ell_width /= 2;  ell_height /= 2;
-    MoveTo(hDC, left, top + ell_height);
-    LineTo(hDC, left, bottom - ell_height);
-    MoveTo(hDC, left + ell_width, bottom);
-    LineTo(hDC, right - ell_width, bottom);
-    MoveTo(hDC, right, bottom - ell_height);
-    LineTo(hDC, right, top + ell_height);
-    MoveTo(hDC, right - ell_width, top);
-    LineTo(hDC, left + ell_width, top);
+        if (ell_width < right - left)
+        {
+            XDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+                       dc->w.DCOrgX + left + ell_width / 2,
+                       dc->w.DCOrgY + top,
+                       dc->w.DCOrgX + right - ell_width / 2,
+                       dc->w.DCOrgY + top );
+            XDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+                       dc->w.DCOrgX + left + ell_width / 2,
+                       dc->w.DCOrgY + bottom,
+                       dc->w.DCOrgX + right - ell_width / 2,
+                       dc->w.DCOrgY + bottom );
+        }
+        if (ell_height < bottom - top)
+        {
+            XDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+                       dc->w.DCOrgX + right,
+                       dc->w.DCOrgY + top + ell_height / 2,
+                       dc->w.DCOrgX + right,
+                       dc->w.DCOrgY + bottom - ell_height / 2 );
+            XDrawLine( display, dc->u.x.drawable, dc->u.x.gc, 
+                       dc->w.DCOrgX + left,
+                       dc->w.DCOrgY + top + ell_height / 2,
+                       dc->w.DCOrgX + left,
+                       dc->w.DCOrgY + bottom - ell_height / 2 );
+        }
+    }
     return TRUE;
 }
 
diff --git a/windows/hook.c b/windows/hook.c
index 257b754..d4fe2eb 100644
--- a/windows/hook.c
+++ b/windows/hook.c
@@ -152,6 +152,6 @@
 DWORD CallNextHookEx( HHOOK hhook, short code, WPARAM wParam, LPARAM lParam )
 {
     HOOKDATA *data = (HOOKDATA *)PTR_SEG_TO_LIN(hhook);
-    if (!data->next) return 0;
+    if (data == NULL || !data->next) return 0;
     else return INTERNAL_CALL_HOOK( data->next, code, wParam, lParam );
 }
diff --git a/windows/message.c b/windows/message.c
index 8135724..37a869c 100644
--- a/windows/message.c
+++ b/windows/message.c
@@ -183,6 +183,82 @@
 
 
 /***********************************************************************
+ *           MSG_GetWindowForEvent
+ *
+ * Find the window and hittest for a mouse event.
+ */
+static INT MSG_GetWindowForEvent( POINT pt, HWND *phwnd )
+{
+    WND *wndPtr;
+    HWND hwnd;
+    INT hittest, x, y;
+
+    *phwnd = hwnd = GetDesktopWindow();
+    x = pt.x;
+    y = pt.y;
+    while (hwnd)
+    {
+	  /* If point is in window, and window is visible, and it  */
+          /* is enabled (or it's a top-level window), then explore */
+	  /* its children. Otherwise, go to the next window.       */
+
+	wndPtr = WIN_FindWndPtr( hwnd );
+	if ((wndPtr->dwStyle & WS_VISIBLE) &&
+            (!(wndPtr->dwStyle & WS_DISABLED) ||
+             !(wndPtr->dwStyle & WS_CHILD)) &&
+            (x >= wndPtr->rectWindow.left) &&
+            (x < wndPtr->rectWindow.right) &&
+	    (y >= wndPtr->rectWindow.top) &&
+            (y < wndPtr->rectWindow.bottom))
+	{
+	    *phwnd = hwnd;
+              /* If window is minimized or disabled, ignore its children */
+            if ((wndPtr->dwStyle & WS_MINIMIZE) ||
+                (wndPtr->dwStyle & WS_DISABLED)) break;
+	    x -= wndPtr->rectClient.left;
+	    y -= wndPtr->rectClient.top;
+	    hwnd = wndPtr->hwndChild;
+	}
+	else hwnd = wndPtr->hwndNext;
+    }
+
+
+    /* Send the WM_NCHITTEST message */
+
+    while (*phwnd)
+    {
+        wndPtr = WIN_FindWndPtr( *phwnd );
+        if (wndPtr->dwStyle & WS_DISABLED) hittest = HTERROR;
+        else hittest = (INT)SendMessage( *phwnd, WM_NCHITTEST, 0,
+                                         MAKELONG( pt.x, pt.y ) );
+        if (hittest != HTTRANSPARENT) break;  /* Found the window */
+        hwnd = wndPtr->hwndNext;
+        while (hwnd)
+        {
+            wndPtr = WIN_FindWndPtr( hwnd );
+            if ((wndPtr->dwStyle & WS_VISIBLE) &&
+                (x >= wndPtr->rectWindow.left) &&
+                (x < wndPtr->rectWindow.right) &&
+                (y >= wndPtr->rectWindow.top) &&
+                (y < wndPtr->rectWindow.bottom)) break;
+            hwnd = wndPtr->hwndNext;
+        }
+        if (hwnd) *phwnd = hwnd; /* Found a suitable sibling */
+        else  /* Go back to the parent */
+        {
+            *phwnd = WIN_FindWndPtr( *phwnd )->hwndParent;
+            wndPtr = WIN_FindWndPtr( *phwnd );
+            x += wndPtr->rectClient.left;
+            y += wndPtr->rectClient.top;
+        }
+    }
+
+    if (!*phwnd) *phwnd = GetDesktopWindow();
+    return hittest;
+}
+
+
+/***********************************************************************
  *           MSG_TranslateMouseMsg
  *
  * Translate an mouse hardware event into a real mouse message.
@@ -218,20 +294,7 @@
 	ScreenToClient( msg->hwnd, (LPPOINT)&msg->lParam );
 	return TRUE;  /* No need to further process the message */
     }
-    else msg->hwnd = WindowFromPoint( msg->pt );
-
-      /* Send the WM_NCHITTEST message */
-
-    hittest_result = (INT)SendMessage( msg->hwnd, WM_NCHITTEST, 0,
-                                       MAKELONG( msg->pt.x, msg->pt.y ) );
-    while ((hittest_result == HTTRANSPARENT) && (msg->hwnd))
-    {
-	msg->hwnd = WINPOS_NextWindowFromPoint( msg->hwnd, msg->pt );
-	if (msg->hwnd)
-	    hittest_result = (INT)SendMessage( msg->hwnd, WM_NCHITTEST, 0,
-                                             MAKELONG( msg->pt.x, msg->pt.y ));
-    }
-    if (!msg->hwnd) msg->hwnd = GetDesktopWindow();
+    else hittest_result = MSG_GetWindowForEvent( msg->pt, &msg->hwnd );
 
       /* Send the WM_PARENTNOTIFY message */
 
diff --git a/windows/painting.c b/windows/painting.c
index 774081a..e29056e 100644
--- a/windows/painting.c
+++ b/windows/painting.c
@@ -39,8 +39,8 @@
 
     if (wndPtr->flags & WIN_NEEDS_NCPAINT)
     {
-        SendMessage( hwnd, WM_NCPAINT, 0, 0 );
         wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
+        SendMessage( hwnd, WM_NCPAINT, 0, 0 );
     }
 
     lps->hdc = GetDCEx( hwnd, hrgnUpdate, DCX_INTERSECTRGN | DCX_USESTYLE );
@@ -56,8 +56,8 @@
 
     if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
     {
-        lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
         wndPtr->flags &= ~WIN_NEEDS_ERASEBKGND;
+        lps->fErase = !SendMessage( hwnd, WM_ERASEBKGND, lps->hdc, 0 );
     }
     else lps->fErase = TRUE;
 
@@ -225,8 +225,8 @@
     {
         if (wndPtr->flags & WIN_NEEDS_NCPAINT)
         {
-            SendMessage( hwnd, WM_NCPAINT, 0, 0 );
             wndPtr->flags &= ~WIN_NEEDS_NCPAINT;
+            SendMessage( hwnd, WM_NCPAINT, 0, 0 );
         }
         if (wndPtr->flags & WIN_NEEDS_ERASEBKGND)
         {
diff --git a/windows/win.c b/windows/win.c
index 6add88a..aad3546 100644
--- a/windows/win.c
+++ b/windows/win.c
@@ -892,11 +892,15 @@
 /***********************************************************************
  *           IsWindowVisible   (USER.49)
  */
-BOOL IsWindowVisible(HWND hWnd)
+BOOL IsWindowVisible( HWND hwnd )
 {
-    WND * wndPtr = WIN_FindWndPtr(hWnd);
-    if (wndPtr == 0) return(FALSE);
-    else return ((wndPtr->dwStyle & WS_VISIBLE) != 0);
+    WND *wndPtr = WIN_FindWndPtr( hwnd );
+    while (wndPtr && (wndPtr->dwStyle & WS_CHILD))
+    {
+        if (!(wndPtr->dwStyle & WS_VISIBLE)) return FALSE;
+        wndPtr = WIN_FindWndPtr( wndPtr->hwndParent );
+    }
+    return (wndPtr && (wndPtr->dwStyle & WS_VISIBLE));
 }
 
  
diff --git a/windows/winpos.c b/windows/winpos.c
index bab8113..b241afc 100644
--- a/windows/winpos.c
+++ b/windows/winpos.c
@@ -531,32 +531,6 @@
 
 
 /*******************************************************************
- *         WINPOS_NextWindowFromPoint
- *
- *  Looks for next enabled window that is
- *  a) sibling of hwnd, later in Z-order and encloses pt, or
- *  b) parent of hwnd
- */
-HWND WINPOS_NextWindowFromPoint( HWND hwnd, POINT pt )
-{
-    WND *wndPtr = WIN_FindWndPtr( hwnd );
-
-    if (!wndPtr->hwndParent) return hwnd;  /* desktop window */
-    ScreenToClient( wndPtr->hwndParent, &pt ); /* make pt relative to parent */
-    for (;;)
-    {
-        if (!wndPtr->hwndNext) break;  /* No more children */
-        hwnd = wndPtr->hwndNext;
-        wndPtr = WIN_FindWndPtr( hwnd );
-        if ((wndPtr->dwStyle & WS_VISIBLE) &&
-            !(wndPtr->dwStyle & WS_DISABLED) &&
-            PtInRect( &wndPtr->rectWindow, pt )) return hwnd;
-    }
-    return wndPtr->hwndParent;
-}
-
-
-/*******************************************************************
  *         WINPOS_ChangeActiveWindow
  *
  * Change the active window and send the corresponding messages.