Release 960516

Thu May 16 13:35:31 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [*/*.c]
	Renamed RECT, POINT and SIZE structures to RECT16, POINT16 and
	SIZE16. Implemented Win32 version of most functions that take
	these types as parameters.

	* [configure]
	Patched autoconf to attempt to correctly detect -lnsl and
	-lsocket. Please check this out.
	
	* [controls/button.c]
	Added support for Win32 BM_* messages.

	* [controls/menu.c]
	Avoid sending extra WM_MENUSELECT messages. This avoids crashes
	with Excel.

	* [memory.heap.c] [include/heap.h]
	Added support for SEGPTRs in Win32 heaps. Added a few macros to
 	make using SEGPTRs easier. They are a bit slower than MAKE_SEGPTR,
 	but they work with Win32.

	* [memory/atom.c]
	Implemented Win32 atom functions.

	* [memory/local.c]
	Fixed LocalReAlloc() changes to avoid copying the whole block twice.

	* [win32/memory.c]
	Use /dev/zero instead of MAP_ANON for VirtualAlloc().

	* [windows/class.c]
	Properly implemented the Win32 class functions.

	* [windows/winproc.c] (New file)
	New file handling the message translation between Win16 and Win32.

Mon May 13 18:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [windows/mdi.c] [windows/menu.c]
	Improved WM_MDICREATE and WM_MDICASCADE handling.

	* [windows/event.c] [objects/bitblt.c]
	Handle GraphicsExpose event for BitBlt from screen to screen.

	* [windows/event.c] [windows/win.c] [windows/nonclient.c]
	Bunch of fixes for problems with -managed.

	* [windows/win.c] [windows/winpos.c]
	Changed conditions for WM_SIZE, WM_MOVE, and WM_GETMINMAXINFO
	in CreateWindow.

	* [windows/win.c] [windows/queue.c] [misc/user.c]
	Do not send WM_PARENTNOTIFY when in AppExit and call WH_SHELL
	on window creation/destruction.

	* [objects/palette.c]
	Crude RealizePalette(). At least something is visible in LviewPro.

Sun May 12 02:05:00 1996  Thomas Sandford <t.d.g.sandford@prds-grn.demon.co.uk>

	* [if1632/gdi32.spec]
	Added Rectangle (use win16 version).

	* [if1632/kernel32.spec]
	Added GetWindowsDirectoryA (use win16 GetWindowsDirectory).

	* [if1632/user32.spec]
	Added GetSubMenu, MoveWindow, SetScrollPos, SetScrollRange (use win16
	versions).
	Added SetWindowsHookExA (empty stub for now).

	* [include/handle32.h]
	Changed #include <malloc.h> to #include <stdlib.h> to prevent
	hate message from FreeBSD compiler.

	* [win32/newfns.c]
	Added new function SetWindowsHookEx32A (empty stub for now).

	* [win32/user32.c]
	Removed redundant debugging printf statement.

Sun May 12 01:24:57 1996  Huw D. M. Davies <h.davies1@physics.oxford.ac.uk>

	* [memory/local.c]
	Avoid creating adjacent free blocks.
	Free the block in LocalReAlloc() before allocating a new one.
	Fixed LocalReAlloc() for discarded blocks.
	
Fri May 10 23:05:12 1996  Jukka Iivonen <iivonen@cc.helsinki.fi>

	* [resources/sysres_Fi.rc]
	ChooseFont and ChooseColor dialogs updated.

Fri May 10 17:19:33 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/drive.c,if1632/kernel.spec]
	GetCurrentDirectory(),SetCurrentDirectory() implemented.

	* [if1632/advapi32.spec] [if1632/kernel.spec] [if1632/shell.spec]
	  [include/windows.h] [include/winreg.h] [loader/main.c]
	  [misc/main.c] [misc/shell.c] [misc/registry.c]
	Registry fixes:
	- loads win95 registry databases,
	- save only updated keys on default,
	- now adhers to the new function naming standard,
	- minor cleanups.

Tue May 7 22:36:13 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [combo.c]
	Added WM_COMMAND-handling for interaction between EDIT and COMBOLBOX
        and synchronized mine with Greg Kreider's works.

	* [commdlg.c]
	Bugfix in ChooseFont: font size handling.
diff --git a/memory/heap.c b/memory/heap.c
index 77fded0..8ba60e8 100644
--- a/memory/heap.c
+++ b/memory/heap.c
@@ -10,6 +10,7 @@
 #include "windows.h"
 #include "debugger.h"
 #include "kernel32.h"  /* for CRITICAL_SECTION */
+#include "selectors.h"
 #include "winbase.h"
 #include "winerror.h"
 #include "winnt.h"
@@ -72,6 +73,7 @@
     struct tagSUBHEAP  *next;       /* Next sub-heap */
     struct tagHEAP     *heap;       /* Main heap structure */
     DWORD               magic;      /* Magic number */
+    WORD                selector;   /* Selector for HEAP_WINE_SEGPTR heaps */
 } SUBHEAP;
 
 #define SUBHEAP_MAGIC    ((DWORD)('S' | ('U'<<8) | ('B'<<16) | ('H'<<24)))
@@ -216,7 +218,7 @@
  *
  * Find the sub-heap containing a given address.
  */
-static SUBHEAP *HEAP_FindSubHeap( HEAP *heap, void *ptr )
+static SUBHEAP *HEAP_FindSubHeap( HEAP *heap, LPCVOID ptr )
 {
     SUBHEAP *sub = &heap->subheap;
     while (sub)
@@ -409,16 +411,25 @@
  *
  * Create a sub-heap of the given size.
  */
-static SUBHEAP *HEAP_CreateSubHeap( DWORD commitSize, DWORD totalSize )
+static SUBHEAP *HEAP_CreateSubHeap( DWORD flags, DWORD commitSize,
+                                    DWORD totalSize )
 {
     SUBHEAP *subheap;
+    WORD selector = 0;
 
     /* Round-up sizes on a 64K boundary */
 
-    totalSize  = (totalSize + 0xffff) & 0xffff0000;
-    commitSize = (commitSize + 0xffff) & 0xffff0000;
-    if (!commitSize) commitSize = 0x10000;
-    if (totalSize < commitSize) totalSize = commitSize;
+    if (flags & HEAP_WINE_SEGPTR)
+    {
+        totalSize = commitSize = 0x10000;  /* Only 64K at a time for SEGPTRs */
+    }
+    else
+    {
+        totalSize  = (totalSize + 0xffff) & 0xffff0000;
+        commitSize = (commitSize + 0xffff) & 0xffff0000;
+        if (!commitSize) commitSize = 0x10000;
+        if (totalSize < commitSize) totalSize = commitSize;
+    }
 
     /* Allocate the memory block */
 
@@ -437,6 +448,21 @@
         return NULL;
     }
 
+    /* Allocate a selector if needed */
+
+    if (flags & HEAP_WINE_SEGPTR)
+    {
+        selector = SELECTOR_AllocBlock( subheap, totalSize,
+                     (flags & HEAP_WINE_CODESEG) ? SEGMENT_CODE : SEGMENT_DATA,
+                     (flags & HEAP_WINE_CODESEG) != 0, FALSE );
+        if (!selector)
+        {
+            fprintf( stderr, "HEAP_CreateSubHeap: could not allocate selector\n" );
+            VirtualFree( subheap, 0, MEM_RELEASE );
+            return NULL;
+        }
+    }
+
     /* Fill the sub-heap structure */
 
     subheap->size       = totalSize;
@@ -445,6 +471,7 @@
     subheap->next       = NULL;
     subheap->heap       = NULL;
     subheap->magic      = SUBHEAP_MAGIC;
+    subheap->selector   = selector;
     return subheap;
 }
 
@@ -490,7 +517,8 @@
         return NULL;
     }
     size += sizeof(SUBHEAP) + sizeof(ARENA_FREE);
-    if (!(subheap = HEAP_CreateSubHeap( size, MAX( HEAP_DEF_SIZE, size ) )))
+    if (!(subheap = HEAP_CreateSubHeap( heap->flags, size,
+                                        MAX( HEAP_DEF_SIZE, size ) )))
         return NULL;
 
     /* Insert the new sub-heap in the list */
@@ -675,6 +703,72 @@
 
 
 /***********************************************************************
+ *           HEAP_IsInsideHeap
+ *
+ * Check whether the pointer is to a block inside a given heap.
+ */
+int HEAP_IsInsideHeap( HANDLE32 heap, DWORD flags, LPCVOID ptr )
+{
+    HEAP *heapPtr = HEAP_GetPtr( heap );
+    SUBHEAP *subheap;
+    int ret;
+
+    /* Validate the parameters */
+
+    if (!heapPtr) return 0;
+    flags |= heapPtr->flags;
+    if (!(flags & HEAP_NO_SERIALIZE)) HeapLock( heap );
+    ret = (((subheap = HEAP_FindSubHeap( heapPtr, ptr )) != NULL) &&
+           (((char *)ptr >= (char *)subheap + subheap->headerSize
+                              + sizeof(ARENA_INUSE))));
+    if (!(flags & HEAP_NO_SERIALIZE)) HeapUnlock( heap );
+    return ret;
+}
+
+
+/***********************************************************************
+ *           HEAP_GetSegptr
+ *
+ * Transform a linear pointer into a SEGPTR. The pointer must have been
+ * allocated from a HEAP_WINE_SEGPTR heap.
+ */
+SEGPTR HEAP_GetSegptr( HANDLE32 heap, DWORD flags, LPCVOID ptr )
+{
+    HEAP *heapPtr = HEAP_GetPtr( heap );
+    SUBHEAP *subheap;
+    SEGPTR ret;
+
+    /* Validate the parameters */
+
+    if (!heapPtr) return 0;
+    flags |= heapPtr->flags;
+    if (!(flags & HEAP_WINE_SEGPTR))
+    {
+        fprintf( stderr, "HEAP_GetSegptr: heap %08x is not a SEGPTR heap\n",
+                 heap );
+        return 0;
+    }
+    if (!(flags & HEAP_NO_SERIALIZE)) HeapLock( heap );
+
+    /* Get the subheap */
+
+    if (!(subheap = HEAP_FindSubHeap( heapPtr, ptr )))
+    {
+        fprintf( stderr, "HEAP_GetSegptr: %p is not inside heap %08x\n",
+                 ptr, heap );
+        if (!(flags & HEAP_NO_SERIALIZE)) HeapUnlock( heap );
+        return 0;
+    }
+
+    /* Build the SEGPTR */
+
+    ret = PTR_SEG_OFF_TO_SEGPTR(subheap->selector, (DWORD)ptr-(DWORD)subheap);
+    if (!(flags & HEAP_NO_SERIALIZE)) HeapUnlock( heap );
+    return ret;
+}
+
+
+/***********************************************************************
  *           HeapCreate   (KERNEL32.336)
  */
 HANDLE32 HeapCreate( DWORD flags, DWORD initialSize, DWORD maxSize )
@@ -691,7 +785,7 @@
         maxSize = HEAP_DEF_SIZE;
         flags |= HEAP_GROWABLE;
     }
-    if (!(subheap = HEAP_CreateSubHeap( initialSize, maxSize )))
+    if (!(subheap = HEAP_CreateSubHeap( flags, initialSize, maxSize )))
     {
         SetLastError( ERROR_OUTOFMEMORY );
         return 0;
@@ -1095,5 +1189,18 @@
  */
 BOOL HeapWalk( HANDLE32 heap, void *entry )
 {
+    fprintf( stderr, "HeapWalk(%08x): not implemented\n", heap );
     return FALSE;
 }
+
+
+/***********************************************************************
+ *           HEAP_strdupA
+ */
+LPSTR HEAP_strdupA( HANDLE32 heap, DWORD flags, LPCSTR str )
+{
+    INT32 len = lstrlen(str) + 1;
+    LPSTR p = HeapAlloc( heap, flags, len );
+    if (p) strcpy( p, str );
+    return p;
+}