Release 970914

Thu Sep 11 18:24:56 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>

	* [objects/dc.c]
	In DC_SetupGCForPatBlt, replace R2_NOT by GXxor with (black xor white).

Tue Sep  9 23:04:02 1997  U. Bonnes <bon@elektron.ikp.physik.th-darmstadt.de>

	* [memory/virtual.c] 
	Do not write debugging info unconditionally to stderr.

	* [files/profile.c]
	Call PROFILE_GetSection in PROFILE_GetString for key_name "" too.

	* [misc/crtdll.c]
	Many new functions.

	* [include/windows.h] [windows/winpos.c]
	ClientToScreen16 doesn't have a return value.

Sun Sep  7 10:06:39 1997  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [misc/main.c] [AUTHORS]
	Update the list of contributors. Please let me know if I forgot
	someone.

	* [if1632/*.spec] [if1632/builtin.c] [tools/build.c]
	Ordinal base for Win32 DLLs is now computed automatically from the
	lowest ordinal found.

	* [include/wintypes.h]
	WINAPI is now defined as attribute((stdcall)). This will require
	gcc to compile.

	* [if1632/thunk.c]
	Removed Win32 thunks (no longer needed with stdcall).

	* [if1632/crtdll.spec] [misc/crtdll.c]
	Make sure we only reference cdecl functions in the spec file.

	* [objects/dc.c]
	Use CapNotLast drawing style for 1-pixel wide lines.

	* [tools/build.c]
	Added 'double' argument type.
	Added 'varargs' function type for Win32.
	Made CallTo16_xxx functions stdcall.

Fri Sep  5 14:50:49 1997  Alex Korobka <alex@trantor.pharm.sunysb.edu>

	* [tools/build.c] [windows/win.c] [windows/event.c] [windows/message.c]
	More fixes to get message exchange closer to the original.

	* [misc/spy.c]
	Message logs now contain window names.

	* [loader/resource.c] [loader/ne_resource.c] [loader/task.c]
	  [objects/cursoricon.c] [windows/user.c]
	Added some obscure features to fix memory leaks.

Fri Sep  5 00:46:28 1997  Jan Willamowius <jan@janhh.shnet.org>

	* [if1632/kernel32.spec] [win32/newfns.c]
	Added stub for UTRegister() and UTUnRegister().

Thu Sep  4 12:03:12 1997  Frans van Dorsselaer <dorssel@rulhmpc49.LeidenUniv.nl>
	* [controls/edit.c]
	Allow ASCII codes > 127 in WM_CHAR.

Mon Sep  1 17:23:24 1997  Dimitrie O. Paun  <dimi@mail.cs.toronto.edu>

	* [controls/widgets.c]
	In InitCommonControls, remember the name of the class
	because lpszClassName was made to point to a local array
	Added the ProgressBar to the list of implemented controls.
	Call InitCommonControls from WIDGETS_Init to register all
	implemented Common Controls.
	
	* [include/commctrl.h]
	Added misc decl for the Progress Bar.

	* [controls/progress.c] [include/progress.h]
	First attempt at implementiong the Progress Bar class.

	* [objects/brush.h]
	Implementation for GetSysColorBrush[16|32]

	* [controls/status.c]
	Use DrawEdge to draw the borders and fill the background

	* [controls/uitools.c]
	Added DrawDiagEdge32 and DrawRectEdge32

	* [graphics/painting.c]
	Implement DrawEdge[16|32]
	Started DrawFrameControl32

Mon Sep  1 10:07:09 1997  Lawson Whitney <lawson_whitney@juno.com>

	* [misc/comm.c] [include/windows.h]
	SetCommEventMask returns a SEGPTR.

Sun Aug 31 23:28:32 1997  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [loader/pe_image.c][loader/module.c][include/pe_image.h]
	  [include/module.h]
	Cleaned up the whole Win32 library mess (a bit).

	* [debugger/stabs.c]
	If 'wine' has no absolute path and isn't found, check $PATH too.

	* [misc/ole2nls.c]
	Some fixes.

	* [misc/ver.c]
	Added support for PE style version resources.

	* [memory/string.c]
	Check for NULL pointers to _lstr* functions, just as Windows95 does.

	* [multimedia/time.c]
	Made list of timers a simple linked list.

	* [loader/resource.c]
	Netscape 3 seems to pass NEGATIVE resource Ids (in an
	unsigned int, yes). Don't know why, fixed it anyway.

	* [objects/bitmap.c]
	LoadImageW added.

	* [include/win.h][windows/win.c]
	Change wIDmenu from UINT16 to UINT32 and changed the
	SetWindow(Long|Word) accordingly.

Thu Aug 28 19:30:08 1997  Morten Welinder  <terra@diku.dk>

	* [include/windows.h]
	Add a few more colors defined for Win95.
	Add a few more brush styles.

	* [windows/syscolor.c]
 	Add error checks for SYSCOLOR_SetColor, SYSCOLOR_Init,
	GetSysColor16, GetSysColor32.  Add support for above colors.

Sun Aug 24 16:22:57 1997  Andrew Taylor <andrew@riscan.com>

	* [multimedia/mmsystem.c]
	Changed mmioDescend to use mmio functions for file I/O, neccessary
	for memory files.
diff --git a/objects/bitmap.c b/objects/bitmap.c
index 6fe7a98..18df983 100644
--- a/objects/bitmap.c
+++ b/objects/bitmap.c
@@ -49,6 +49,80 @@
                       descr->image, 0, 0, 0, 0, descr->width, descr->height );
 }
 
+/***********************************************************************
+ *           BITMAP_GetBitsPadding
+ *
+ * Return number of bytes to pad a scanline of 16-bit aligned Windows DDB data.
+ */
+INT32 BITMAP_GetBitsPadding( int bmWidth, int bpp )
+{
+    INT32 pad;
+
+    switch (bpp) 
+    {
+    case 1:
+	if (!(bmWidth & 15)) pad = 0;
+	else pad = ((16 - (bmWidth & 15)) + 7) / 8;
+	break;
+
+    case 8:
+	pad = (2 - (bmWidth & 1)) & 1;
+	break;
+
+    case 24:
+	pad = (bmWidth*3) & 1;
+	break;
+
+    case 32:
+    case 16:
+    case 15:
+	pad = 0; /* we have 16bit alignment already */
+	break;
+
+    case 4:
+	if (!(bmWidth & 3)) pad = 0;
+	else pad = ((4 - (bmWidth & 3)) + 1) / 2;
+	break;
+
+    default:
+	fprintf(stderr,"GetBitsPadding: unknown depth %d, please report.\n", bpp );
+        return -1;
+    }
+    return pad;
+}
+
+/***********************************************************************
+ *           BITMAP_GetBitsWidth
+ *
+ * Return number of bytes taken by a scanline of 16-bit aligned Windows DDB data.
+ */
+INT32 BITMAP_GetBitsWidth( int bmWidth, int bpp )
+{
+    switch(bpp)
+    {
+    case 1:
+	return 2 * ((bmWidth+15) >> 4);
+
+    case 24:
+	bmWidth *= 3; /* fall through */
+    case 8:
+	return bmWidth + (bmWidth & 1);
+
+    case 32:
+	return bmWidth * 4;
+
+    case 16:
+    case 15:
+	return bmWidth * 2;
+
+    case 4:
+	return 2 * ((bmWidth+3) >> 2);
+
+    default:
+	fprintf(stderr,"GetBitsPadding: unknown depth %d, please report.\n", bpp );
+    }
+    return -1;
+}
 
 /***********************************************************************
  *           CreateBitmap16    (GDI.48)
@@ -200,46 +274,19 @@
       /* Only get entire lines */
     height = count / bmp->bitmap.bmWidthBytes;
     if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
+
     dprintf_bitmap(stddeb, "GetBitmapBits: %dx%d %d colors %p fetched height: %ld\n",
 	    bmp->bitmap.bmWidth, bmp->bitmap.bmHeight,
 	    1 << bmp->bitmap.bmBitsPixel, buffer, height );
-    if (!height) 
+
+    pad = BITMAP_GetBitsPadding( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel );
+
+    if (!height || (pad == -1))
     {
       GDI_HEAP_UNLOCK( hbitmap );
       return 0;
     }
 
-    switch (bmp->bitmap.bmBitsPixel) {
-    case 1:
-	if (!(bmp->bitmap.bmWidth & 15))
-		pad = 0;
-	else
-		pad = ((16 - (bmp->bitmap.bmWidth & 15)) + 7) / 8;
-    	break;
-    case 4:
-	if (!(bmp->bitmap.bmWidth & 3))
-	    pad = 0;
-	else
-	    pad = ((4 - (bmp->bitmap.bmWidth & 3)) + 1) / 2;
-	break;
-    case 8:
-    	pad = (2 - (bmp->bitmap.bmWidth & 1)) & 1;
-    	break;
-    case 15:
-    case 16:
-    	pad = 0; /* we have 16bit alignment already */
-	break;
-    case 24:
-    	pad = (bmp->bitmap.bmWidth*3) & 1;
-    	break;
-    default:
-	fprintf(stderr,"GetBitMapBits32: unknown depth %d, please report.\n",
-		bmp->bitmap.bmBitsPixel
-	);
-	GDI_HEAP_UNLOCK( hbitmap );
-	return 0;
-    }
-
     /* Hack: change the bitmap height temporarily to avoid */
     /*       getting unnecessary bitmap rows. */
     old_height = bmp->bitmap.bmHeight;
@@ -354,41 +401,15 @@
       /* Only set entire lines */
     height = count / bmp->bitmap.bmWidthBytes;
     if (height > bmp->bitmap.bmHeight) height = bmp->bitmap.bmHeight;
-    if (!height) 
+
+    pad = BITMAP_GetBitsPadding( bmp->bitmap.bmWidth, bmp->bitmap.bmBitsPixel );
+
+    if (!height || (pad == -1)) 
     {
       GDI_HEAP_UNLOCK( hbitmap );
       return 0;
     }
 	
-    switch (bmp->bitmap.bmBitsPixel) {
-    case 1:
-	if (!(bmp->bitmap.bmWidth & 15))
-		pad = 0;
-	else
-		pad = ((16 - (bmp->bitmap.bmWidth & 15)) + 7) / 8;
-    	break;
-    case 4:
-	if (!(bmp->bitmap.bmWidth & 3))
-	    pad = 0;
-	else
-	    pad = ((4 - (bmp->bitmap.bmWidth & 3)) + 1) / 2;
-	break;
-    case 8:
-    	pad = (2 - (bmp->bitmap.bmWidth & 1)) & 1;
-    	break;
-    case 15:
-    case 16:
-    	pad = 0; /* we have 16bit alignment already */
-	break;
-    case 24:
-    	pad = (bmp->bitmap.bmWidth*3) & 1;
-    	break;
-    default:
-	fprintf(stderr,"SetBitMapBits32: unknown depth %d, please report.\n",
-		bmp->bitmap.bmBitsPixel
-	);
-	return 0;
-    }
     sbuf = (LPBYTE)buffer;
 
     widthbytes	= DIB_GetXImageWidthBytes(bmp->bitmap.bmWidth,bmp->bitmap.bmBitsPixel);
@@ -497,6 +518,29 @@
 	return 0;
 }
 
+HANDLE32 WINAPI LoadImage32W( HINSTANCE32 hinst, LPCWSTR name, UINT32 type,
+                              INT32 desiredx, INT32 desiredy, UINT32 loadflags)
+{
+	if (HIWORD(name)) {
+		dprintf_resource(stddeb,"LoadImage32W(0x%04x,%p,%d,%d,%d,0x%08x)\n",
+			hinst,name,type,desiredx,desiredy,loadflags
+		);
+	} else {
+		dprintf_resource(stddeb,"LoadImage32W(0x%04x,%p,%d,%d,%d,0x%08x)\n",
+			hinst,name,type,desiredx,desiredy,loadflags
+		);
+	}
+	switch (type) {
+	case IMAGE_BITMAP:
+		return LoadBitmap32W(hinst,name);
+	case IMAGE_ICON:
+		return LoadIcon32W(hinst,name);
+	case IMAGE_CURSOR:
+		return LoadCursor32W(hinst,name);
+	}
+	return 0;
+}
+
 /**********************************************************************
  *	    CopyImage32    (USER32.60)
  *
diff --git a/objects/brush.c b/objects/brush.c
index 5f216f2..b3fdb31 100644
--- a/objects/brush.c
+++ b/objects/brush.c
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include "brush.h"
 #include "bitmap.h"
+#include "syscolor.h"
 #include "metafile.h"
 #include "color.h"
 #include "stddebug.h"
@@ -241,18 +242,80 @@
  */
 HBRUSH16 WINAPI GetSysColorBrush16( INT16 index )
 {
-    fprintf( stderr, "Unimplemented stub: GetSysColorBrush16(%d)\n", index );
-    return GetStockObject32(LTGRAY_BRUSH);
+    return (HBRUSH16)GetSysColorBrush32(index);
 }
 
 
 /***********************************************************************
  *           GetSysColorBrush32    (USER32.289)
  */
-HBRUSH32 WINAPI GetSysColorBrush32( INT32 index)
+HBRUSH32 WINAPI GetSysColorBrush32( INT32 index )
 {
-    fprintf( stderr, "Unimplemented stub: GetSysColorBrush32(%d)\n", index );
-    return GetStockObject32(LTGRAY_BRUSH);
+  switch(index){
+  case COLOR_SCROLLBAR:
+    return sysColorObjects.hbrushScrollbar;
+  case COLOR_BACKGROUND: /* same as COLOR_DESKTOP */
+    return sysColorObjects.hbrushScrollbar; /*FIXME*/
+  case COLOR_ACTIVECAPTION:
+    return sysColorObjects.hbrushActiveCaption;
+  case COLOR_INACTIVECAPTION:
+    return sysColorObjects.hbrushInactiveCaption;
+  case COLOR_MENU:
+    return sysColorObjects.hbrushMenu;
+  case COLOR_WINDOW:
+    return sysColorObjects.hbrushWindow;
+  case COLOR_WINDOWFRAME:
+    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
+    break;
+  case COLOR_MENUTEXT:
+    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
+    break;
+  case COLOR_WINDOWTEXT:
+    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
+    break;
+  case COLOR_CAPTIONTEXT:
+    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
+    break;
+  case COLOR_ACTIVEBORDER:
+    return sysColorObjects.hbrushActiveBorder;
+  case COLOR_INACTIVEBORDER:
+    return sysColorObjects.hbrushInactiveBorder;
+  case COLOR_APPWORKSPACE:
+    return sysColorObjects.hbrushActiveBorder; /*FIXME*/
+  case COLOR_HIGHLIGHT:
+    return sysColorObjects.hbrushHighlight;
+  case COLOR_HIGHLIGHTTEXT:
+    return sysColorObjects.hbrushHighlight; /*FIXME*/
+  case COLOR_BTNFACE: /* same as COLOR_3DFACE */
+    return sysColorObjects.hbrushBtnFace;
+  case COLOR_BTNSHADOW: /* same as COLOR_3DSHADOW */
+    return sysColorObjects.hbrushBtnShadow;
+  case COLOR_GRAYTEXT:
+    return sysColorObjects.hbrushBtnShadow; /*FIXME*/
+  case COLOR_BTNTEXT:
+    return sysColorObjects.hbrushBtnShadow; /*FIXME*/
+  case COLOR_INACTIVECAPTIONTEXT:
+    return sysColorObjects.hbrushBtnShadow; /*FIXME*/
+  case COLOR_BTNHIGHLIGHT: /* same as COLOR_(3DHIGH|3DHI|BTNHI)LIGHT */
+    return sysColorObjects.hbrushBtnHighlight;
+    /*  case COLOR_3DDKSHADOW: FIXME
+    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
+    break;
+  case COLOR_3DLIGHT:
+    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
+    break;
+  case COLOR_INFOTEXT:
+    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
+    break;
+  case COLOR_INFOBK:
+    fprintf( stderr, "GetSysColorBrush32: Unimplemented index(%d)\n", index );
+    break;*/
+  default:
+    fprintf( stderr, "GetSysColorBrush32: Unknown index(%d)\n", index );
+  }
+
+  return GetStockObject32(LTGRAY_BRUSH);
+
 }
 
 
@@ -299,5 +362,3 @@
     memcpy( buffer, &brush->logbrush, count );
     return count;
 }
-
-
diff --git a/objects/cursoricon.c b/objects/cursoricon.c
index 317f163..fb02109 100644
--- a/objects/cursoricon.c
+++ b/objects/cursoricon.c
@@ -2,6 +2,8 @@
  * Cursor and icon support
  *
  * Copyright 1995 Alexandre Julliard
+ *           1996 Martin Von Loewis
+ *           1997 Alex Korobka
  */
 
 /*
@@ -26,18 +28,22 @@
 
 #include <string.h>
 #include <stdlib.h>
+#include "heap.h"
 #include "windows.h"
+#include "peexe.h"
 #include "color.h"
 #include "bitmap.h"
 #include "callback.h"
 #include "cursoricon.h"
 #include "sysmetrics.h"
+#include "module.h"
 #include "win.h"
 #include "stddebug.h"
 #include "debug.h"
 #include "task.h"
 
 extern UINT16 COLOR_GetSystemPaletteSize();
+extern HGLOBAL16 USER_CallDefaultRsrcHandler( HGLOBAL16, HMODULE16, HRSRC16 );
 
 Cursor CURSORICON_XCursor = None;    /* Current X cursor */
 static HCURSOR32 hActiveCursor = 0;  /* Active cursor */
@@ -196,15 +202,14 @@
 
 
 /**********************************************************************
- *	    CURSORICON_LoadDirEntry
+ *	    CURSORICON_LoadDirEntry16
  *
  * Load the icon/cursor directory for a given resource name and find the
  * best matching entry.
  */
-static BOOL32 CURSORICON_LoadDirEntry( HINSTANCE32 hInstance, SEGPTR name,
-                                       INT32 width, INT32 height,
-                                       INT32 colors, BOOL32 fCursor,
-                                       CURSORICONDIRENTRY *dirEntry )
+static BOOL32 CURSORICON_LoadDirEntry16( HINSTANCE32 hInstance, SEGPTR name,
+                                         INT32 width, INT32 height, INT32 colors, 
+					 BOOL32 fCursor, CURSORICONDIRENTRY *dirEntry )
 {
     HRSRC16 hRsrc;
     HGLOBAL16 hMem;
@@ -231,30 +236,76 @@
 
 
 /**********************************************************************
- *	    CURSORICON_LoadHandler 
+ *          CURSORICON_LoadDirEntry32
  *
- * Create a cursor or icon from a resource.
+ * Load the icon/cursor directory for a given resource name and find the
+ * best matching entry.
  */
-HGLOBAL16 CURSORICON_LoadHandler( HGLOBAL16 handle, HINSTANCE16 hInstance,
-                                  BOOL32 fCursor )
+static BOOL32 CURSORICON_LoadDirEntry32( HINSTANCE32 hInstance, LPCWSTR name,
+                                         INT32 width, INT32 height, INT32 colors,
+                                         BOOL32 fCursor, CURSORICONDIRENTRY *dirEntry )
 {
-    static char* __loadhandlerStr = "CURSORICON_LoadHandler";
+    HANDLE32 hRsrc;
+    HANDLE32 hMem;
+    CURSORICONDIR *dir;
+    CURSORICONDIRENTRY *entry = NULL;
 
+    if (!(hRsrc = FindResource32W( hInstance, name,
+                (LPCWSTR)(fCursor ? RT_GROUP_CURSOR : RT_GROUP_ICON) )))
+        return FALSE;
+    if (!(hMem = LoadResource32( hInstance, hRsrc ))) return FALSE;
+    if ((dir = (CURSORICONDIR*)LockResource32( hMem )))
+    {
+        if (fCursor)
+            entry = (CURSORICONDIRENTRY *)CURSORICON_FindBestCursor( dir,
+                                                               width, height );
+        else
+            entry = (CURSORICONDIRENTRY *)CURSORICON_FindBestIcon( dir,
+                                                       width, height, colors );
+        if (entry) *dirEntry = *entry;
+    }
+    FreeResource32( hMem );
+    return (entry != NULL);
+}
+
+
+/**********************************************************************
+ *	    CURSORICON_CreateFromResource
+ *
+ * Create a cursor or icon from in-memory resource template. 
+ *
+ * FIXME: Adjust icon size when width and height are nonzero (stretchblt).
+ *        Convert to mono when cFlag is LR_MONOCHROME. Do something
+ *        with cbSize parameter as well.
+ */
+static HGLOBAL16 CURSORICON_CreateFromResource( HINSTANCE32 hInstance, HGLOBAL16 hObj, LPBYTE bits,
+	 					UINT32 cbSize, BOOL32 bIcon, DWORD dwVersion, 
+						INT32 width, INT32 height, UINT32 cFlag )
+{
     int sizeAnd, sizeXor;
     HBITMAP32 hAndBits = 0, hXorBits = 0; /* error condition for later */
     BITMAPOBJ *bmpXor, *bmpAnd;
     POINT16 hotspot = { 0 ,0 };
-    CURSORICONINFO *info;
     BITMAPINFO *bmi;
     HDC32 hdc;
 
-    if (fCursor)  /* If cursor, get the hotspot */
+    dprintf_cursor(stddeb,"CreateFromResource: %08x (%u bytes), ver %08x, %ix%i %s %s\n",
+                        (unsigned)bits, cbSize, (unsigned)dwVersion, width, height,
+                                  bIcon ? "icon" : "cursor", cFlag ? "mono" : "" );
+    if (dwVersion == 0x00020000)
     {
-        POINT16 *pt = (POINT16 *)LockResource16( handle );
+	fprintf(stdnimp,"\t2.xx resources are not supported\n");
+	return 0;
+    }
+
+    if (bIcon)
+	bmi = (BITMAPINFO *)bits;
+    else /* get the hotspot */
+    {
+        POINT16 *pt = (POINT16 *)bits;
         hotspot = *pt;
         bmi = (BITMAPINFO *)(pt + 1);
     }
-    else bmi = (BITMAPINFO *)LockResource16( handle );
 
     /* Check bitmap header */
 
@@ -262,7 +313,7 @@
 	 (bmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)  ||
 	  bmi->bmiHeader.biCompression != BI_RGB) )
     {
-          fprintf(stderr,"%s: invalid bitmap header.\n", __loadhandlerStr);
+          fprintf(stderr,"\tinvalid resource bitmap header.\n");
           return 0;
     }
 
@@ -329,7 +380,7 @@
 
     if( !hXorBits || !hAndBits ) 
     {
-	fprintf(stderr,"%s: unable to create a bitmap.\n", __loadhandlerStr );
+	fprintf(stderr,"\tunable to create an icon bitmap.\n");
 	return 0;
     }
 
@@ -340,46 +391,77 @@
     sizeXor = bmpXor->bitmap.bmHeight * bmpXor->bitmap.bmWidthBytes;
     sizeAnd = bmpAnd->bitmap.bmHeight * bmpAnd->bitmap.bmWidthBytes;
 
-    if (!(handle = GlobalAlloc16( GMEM_MOVEABLE,
-                                  sizeof(CURSORICONINFO) + sizeXor + sizeAnd)))
+    if (hObj) hObj = GlobalReAlloc16( hObj, 
+		     sizeof(CURSORICONINFO) + sizeXor + sizeAnd, GMEM_MOVEABLE );
+    if (!hObj) hObj = GlobalAlloc16( GMEM_MOVEABLE, 
+		     sizeof(CURSORICONINFO) + sizeXor + sizeAnd );
+    if (hObj)
     {
-        DeleteObject32( hXorBits );
-        DeleteObject32( hAndBits );
-        return 0;
+	CURSORICONINFO *info;
+
+	/* Make it owned by the module */
+	if (hInstance) FarSetOwner( hObj, MODULE_HANDLEtoHMODULE16(hInstance));
+
+	info = (CURSORICONINFO *)GlobalLock16( hObj );
+	info->ptHotSpot.x   = hotspot.x;
+	info->ptHotSpot.y   = hotspot.y;
+	info->nWidth        = bmpXor->bitmap.bmWidth;
+	info->nHeight       = bmpXor->bitmap.bmHeight;
+	info->nWidthBytes   = bmpXor->bitmap.bmWidthBytes;
+	info->bPlanes       = bmpXor->bitmap.bmPlanes;
+	info->bBitsPerPixel = bmpXor->bitmap.bmBitsPixel;
+
+	/* Transfer the bitmap bits to the CURSORICONINFO structure */
+
+	GetBitmapBits32( hAndBits, sizeAnd, (char *)(info + 1) );
+	GetBitmapBits32( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd );
+	GlobalUnlock16( hObj );
     }
 
-    /* Make it owned by the module */
-    if (hInstance) FarSetOwner( handle, GetExePtr(hInstance) );
-
-    info = (CURSORICONINFO *)GlobalLock16( handle );
-    info->ptHotSpot.x   = hotspot.x;
-    info->ptHotSpot.y   = hotspot.y;
-    info->nWidth        = bmpXor->bitmap.bmWidth;
-    info->nHeight       = bmpXor->bitmap.bmHeight;
-    info->nWidthBytes   = bmpXor->bitmap.bmWidthBytes;
-    info->bPlanes       = bmpXor->bitmap.bmPlanes;
-    info->bBitsPerPixel = bmpXor->bitmap.bmBitsPixel;
-
-    /* Transfer the bitmap bits to the CURSORICONINFO structure */
-
-    GetBitmapBits32( hAndBits, sizeAnd, (char *)(info + 1) );
-    GetBitmapBits32( hXorBits, sizeXor, (char *)(info + 1) + sizeAnd );
     DeleteObject32( hXorBits );
     DeleteObject32( hAndBits );
-    GlobalUnlock16( handle );
-    return handle;
+    return hObj;
 }
 
+
 /**********************************************************************
- *	    CURSORICON_Load
+ *          CreateIconFromResourceEx16          (USER.450)
  *
- * Load a cursor or icon.
+ * FIXME: not sure about exact parameter types
  */
-static HGLOBAL16 CURSORICON_Load( HINSTANCE16 hInstance, SEGPTR name,
-                                  INT32 width, INT32 height, INT32 colors,
-                                  BOOL32 fCursor )
+HICON16 WINAPI CreateIconFromResourceEx16( LPBYTE bits, UINT16 cbSize, BOOL16 bIcon,
+                                    DWORD dwVersion, INT16 width, INT16 height, UINT16 cFlag )
 {
-    HGLOBAL16 handle, hRet;
+    TDB* pTask = (TDB*)GlobalLock16( GetCurrentTask() );
+    if( pTask )
+	return CURSORICON_CreateFromResource( pTask->hInstance, 0, bits, cbSize, bIcon, dwVersion,
+					      width, height, cFlag );
+    return 0;
+}
+
+
+/**********************************************************************
+ *          CreateIconFromResourceEx32          (USER32.76)
+ */
+HICON32 WINAPI CreateIconFromResourceEx32( LPBYTE bits, UINT32 cbSize,
+                                           BOOL32 bIcon, DWORD dwVersion,
+                                           INT32 width, INT32 height,
+                                           UINT32 cFlag )
+{
+    return CreateIconFromResourceEx16( bits, cbSize, bIcon, dwVersion, width, height, cFlag );
+}
+
+
+/**********************************************************************
+ *	    CURSORICON_Load16
+ *
+ * Load a cursor or icon from a 16-bit resource.
+ */
+static HGLOBAL16 CURSORICON_Load16( HINSTANCE16 hInstance, SEGPTR name,
+                                    INT32 width, INT32 height, INT32 colors,
+                                    BOOL32 fCursor )
+{
+    HGLOBAL16 handle;
     HRSRC16 hRsrc;
     CURSORICONDIRENTRY dirEntry;
 
@@ -396,19 +478,89 @@
 
     /* Find the best entry in the directory */
 
-    if (!CURSORICON_LoadDirEntry( hInstance, name, width, height,
-                                  colors, fCursor, &dirEntry )) return 0;
-
+    if ( !CURSORICON_LoadDirEntry16( hInstance, name, width, height,
+                                    colors, fCursor, &dirEntry ) )  return 0;
     /* Load the resource */
 
-    if (!(hRsrc = FindResource16( hInstance,
+    if ( (hRsrc = FindResource16( hInstance,
                                 MAKEINTRESOURCE( dirEntry.icon.wResId ),
-                                fCursor ? RT_CURSOR : RT_ICON ))) return 0;
-    if (!(handle = LoadResource16( hInstance, hRsrc ))) return 0;
+                                fCursor ? RT_CURSOR : RT_ICON )) )
+    {
+	/* 16-bit icon or cursor resources are processed
+	 * transparently by the LoadResource16() via custom
+	 * resource handlers set by SetResourceHandler().
+	 */
 
-    hRet = CURSORICON_LoadHandler( handle, hInstance, fCursor );
-    FreeResource16(handle);
-    return hRet;
+	if ( (handle = LoadResource16( hInstance, hRsrc )) )
+	    return handle;
+    }
+    return 0;
+}
+
+/**********************************************************************
+ *          CURSORICON_Load32
+ *
+ * Load a cursor or icon from a 32-bit resource.
+ */
+static HGLOBAL32 CURSORICON_Load32( HINSTANCE32 hInstance, LPCWSTR name,
+                                    int width, int height, int colors,
+                                    BOOL32 fCursor )
+{
+    HANDLE32 handle;
+    HANDLE32 hRsrc;
+    CURSORICONDIRENTRY dirEntry;
+
+    if(!hInstance)  /* OEM cursor/icon */
+    {
+	WORD resid;
+	if(HIWORD(name))
+	{
+            LPSTR ansi = HEAP_strdupWtoA(GetProcessHeap(),0,name);
+            if( ansi[0]=='#')        /*Check for '#xxx' name */
+            {
+                resid = atoi(ansi+1);
+                HeapFree( GetProcessHeap(), 0, ansi );
+            }
+            else
+            {
+                HeapFree( GetProcessHeap(), 0, ansi );
+                return 0;
+            }
+        }
+        else resid = LOWORD(name);
+        return OBM_LoadCursorIcon(resid, fCursor);
+    }
+
+    /* Find the best entry in the directory */
+ 
+    if ( !CURSORICON_LoadDirEntry32( hInstance, name, width, height,
+				    colors, fCursor, &dirEntry ) )  return 0;
+    /* Load the resource */
+
+    if ( (hRsrc = FindResource32W( hInstance,
+                      (LPWSTR) (DWORD) dirEntry.icon.wResId,
+                      (LPWSTR) (fCursor ? RT_CURSOR : RT_ICON ))) )
+    {
+	HANDLE32 h = 0;
+	if ( (handle = LoadResource32( hInstance, hRsrc )) )
+	{
+	    /* Hack to keep LoadCursor/Icon32() from spawning multiple
+	     * copies of the same object.
+	     */
+#define pRsrcEntry ((LPIMAGE_RESOURCE_DATA_ENTRY)hRsrc)
+	    if( !pRsrcEntry->ResourceHandle ) 
+	    {
+		LPBYTE bits = (LPBYTE)LockResource32( handle );
+		h = CURSORICON_CreateFromResource( hInstance, 0, bits, dirEntry.icon.dwBytesInRes, 
+					!fCursor, 0x00030000, width, height, LR_DEFAULTCOLOR );
+		pRsrcEntry->ResourceHandle = h;
+	    }
+	    else h = pRsrcEntry->ResourceHandle;
+#undef  pRsrcEntry
+	}
+	return h;
+    }
+    return 0;
 }
 
 
@@ -438,80 +590,86 @@
 /***********************************************************************
  *           CURSORICON_IconToCursor
  *
- * Converts bitmap to mono and truncates if icon is too large
+ * Converts bitmap to mono and truncates if icon is too large (should
+ * probably do StretchBlt() instead).
  */
 HCURSOR16 CURSORICON_IconToCursor(HICON16 hIcon, BOOL32 bSemiTransparent)
 {
  HCURSOR16       hRet = 0;
- CURSORICONINFO *ptr = NULL;
+ CURSORICONINFO *pIcon = NULL;
  HTASK16 	 hTask = GetCurrentTask();
  TDB*  		 pTask = (TDB *)GlobalLock16(hTask);
 
  if(hIcon && pTask)
-    if (!(ptr = (CURSORICONINFO*)GlobalLock16( hIcon ))) return FALSE;
-       if (ptr->bPlanes * ptr->bBitsPerPixel == 1)
+    if (!(pIcon = (CURSORICONINFO*)GlobalLock16( hIcon ))) return FALSE;
+       if (pIcon->bPlanes * pIcon->bBitsPerPixel == 1)
            hRet = CURSORICON_Copy( pTask->hInstance, hIcon );
        else
        {
            BYTE  pAndBits[128];
            BYTE  pXorBits[128];
-	   int   x, y, ix, iy, shift; 
-	   int   bpp = (ptr->bBitsPerPixel>=24)?32:ptr->bBitsPerPixel; /* this sucks */
-           BYTE* psPtr = (BYTE *)(ptr + 1) +
-                            ptr->nHeight * BITMAP_WIDTH_BYTES(ptr->nWidth,1);
-           BYTE* pxbPtr = pXorBits;
-           unsigned *psc = NULL, val = 0;
-           unsigned val_base = 0xffffffff >> (32 - bpp);
+	   int   maxx, maxy, ix, iy, bpp = pIcon->bBitsPerPixel;
+           BYTE* psPtr, *pxbPtr = pXorBits;
+           unsigned xor_width, and_width, val_base = 0xffffffff >> (32 - bpp);
            BYTE* pbc = NULL;
 
            COLORREF       col;
            CURSORICONINFO cI;
 
+	   dprintf_icon(stddeb, "IconToCursor:[%04x] %ix%i %ibpp (bogus %ibps)\n", 
+		hIcon, pIcon->nWidth, pIcon->nHeight, pIcon->bBitsPerPixel, pIcon->nWidthBytes );
+
+	   xor_width = BITMAP_GetBitsWidth( pIcon->nWidth, bpp );
+	   and_width =  BITMAP_GetBitsWidth( pIcon->nWidth, 1 );
+	   psPtr = (BYTE *)(pIcon + 1) + pIcon->nHeight * and_width;
+
            memset(pXorBits, 0, 128);
            cI.bBitsPerPixel = 1; cI.bPlanes = 1;
            cI.ptHotSpot.x = cI.ptHotSpot.y = 15;
            cI.nWidth = 32; cI.nHeight = 32;
-           cI.nWidthBytes = 4;	/* 1bpp */
+           cI.nWidthBytes = 4;	/* 32x1bpp */
 
-           x = (ptr->nWidth > 32) ? 32 : ptr->nWidth;
-           y = (ptr->nHeight > 32) ? 32 : ptr->nHeight;
+           maxx = (pIcon->nWidth > 32) ? 32 : pIcon->nWidth;
+           maxy = (pIcon->nHeight > 32) ? 32 : pIcon->nHeight;
 
-           for( iy = 0; iy < y; iy++ )
+           for( iy = 0; iy < maxy; iy++ )
            {
-              val = BITMAP_WIDTH_BYTES( ptr->nWidth, 1 );
-              memcpy( pAndBits + iy * 4,
-                     (BYTE *)(ptr + 1) + iy * val, (val>4) ? 4 : val);
-              shift = iy % 2;
+	      unsigned shift = iy % 2; 
 
-              for( ix = 0; ix < x; ix++ )
+              memcpy( pAndBits + iy * 4, (BYTE *)(pIcon + 1) + iy * and_width, 
+					 (and_width > 4) ? 4 : and_width );
+              for( ix = 0; ix < maxx; ix++ )
               {
                 if( bSemiTransparent && ((ix+shift)%2) )
                 {
+		    /* set AND bit, XOR bit stays 0 */
+
                     pbc = pAndBits + iy * 4 + ix/8;
                    *pbc |= 0x80 >> (ix%8);
                 }
                 else
                 {
-                  psc = (unsigned*)(psPtr + (ix * bpp)/8);
-                  val = ((*psc) >> (ix * bpp)%8) & val_base;
+		    /* keep AND bit, set XOR bit */
+
+		  unsigned *psc = (unsigned*)(psPtr + (ix * bpp)/8);
+                  unsigned  val = ((*psc) >> (ix * bpp)%8) & val_base;
                   col = COLOR_ToLogical(val);
-                  if( GetRValue(col) > 0xa0 ||
-                      GetGValue(col) > 0x80 ||
-                      GetBValue(col) > 0xa0 )
+		  if( (GetRValue(col) + GetGValue(col) + GetBValue(col)) > 0x180 )
                   {
                     pbc = pxbPtr + ix/8;
                    *pbc |= 0x80 >> (ix%8);
                   }
                 }
               }
-              psPtr += ptr->nWidthBytes;
+              psPtr += xor_width;
               pxbPtr += 4;
            }
+
            hRet = CreateCursorIconIndirect( pTask->hInstance , &cI, pAndBits, pXorBits);
 
            if( !hRet ) /* fall back on default drag cursor */
                 hRet = CURSORICON_Copy( pTask->hInstance ,
-                              CURSORICON_Load(0,MAKEINTRESOURCE(OCR_DRAGOBJECT),
+                              CURSORICON_Load16(0,MAKEINTRESOURCE(OCR_DRAGOBJECT),
                                          SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, 1, TRUE) );
        }
 
@@ -531,8 +689,8 @@
         dprintf_cursor( stddeb, "LoadCursor16: %04x %04x\n",
                         hInstance, LOWORD(name) );
 
-    return CURSORICON_Load( hInstance, name,
-                            SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, 1, TRUE);
+    return CURSORICON_Load16( hInstance, name,
+                              SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, 1, TRUE);
 }
 
 
@@ -548,9 +706,9 @@
         dprintf_icon( stddeb, "LoadIcon: %04x %04x\n",
                       hInstance, LOWORD(name) );
 
-    return CURSORICON_Load( hInstance, name,
-                            SYSMETRICS_CXICON, SYSMETRICS_CYICON,
-                            MIN( 16, COLOR_GetSystemPaletteSize() ), FALSE );
+    return CURSORICON_Load16( hInstance, name,
+                              SYSMETRICS_CXICON, SYSMETRICS_CYICON,
+                              MIN( 16, COLOR_GetSystemPaletteSize() ), FALSE );
 }
 
 
@@ -691,7 +849,7 @@
 {
     dprintf_icon( stddeb, "DestroyIcon: %04x\n", hIcon );
     /* FIXME: should check for OEM icon here */
-    return (GlobalFree16( hIcon ) == 0);
+    return (FreeResource16( hIcon ) == 0);
 }
 
 
@@ -711,7 +869,7 @@
 {
     dprintf_cursor( stddeb, "DestroyCursor: %04x\n", hCursor );
     /* FIXME: should check for OEM cursor here */
-    return (GlobalFree16( hCursor ) != 0);
+    return (FreeResource16( hCursor ) != 0);
 }
 
 
@@ -1093,6 +1251,53 @@
     if (rect) CopyRect32( rect, &CURSOR_ClipRect );
 }
 
+/**********************************************************************
+ *          LookupIconIdFromDirectoryEx16	(USER.364)
+ *
+ * FIXME: exact parameter sizes
+ */
+UINT16 WINAPI LookupIconIdFromDirectoryEx16( CURSORICONDIR *dir, BOOL16 bIcon,
+	     INT16 width, INT16 height, UINT16 cFlag )
+{
+    UINT16 retVal = 0;
+    if( dir && !dir->idReserved && (dir->idType & 3) )
+    {
+	int colors = (cFlag == LR_MONOCHROME) ? 2 : COLOR_GetSystemPaletteSize();
+	if( bIcon )
+	{
+	    ICONDIRENTRY* entry;
+	    entry = CURSORICON_FindBestIcon( dir, width, height, colors );
+	    if( entry ) retVal = entry->wResId;
+	}
+	else
+	{
+	    CURSORDIRENTRY* entry;
+	    entry = CURSORICON_FindBestCursor( dir, width, height );
+	    if( entry ) retVal = entry->wResId;
+	}
+    }
+    else dprintf_cursor(stddeb,"IconId: invalid resource directory\n");
+    return retVal;
+}
+
+/**********************************************************************
+ *          LookupIconIdFromDirectoryEx32       (USER32.379)
+ */
+INT32 WINAPI LookupIconIdFromDirectoryEx32( CURSORICONDIR *dir, BOOL32 bIcon,
+             INT32 width, INT32 height, UINT32 cFlag )
+{
+    return LookupIconIdFromDirectoryEx16( dir, bIcon, width, height, cFlag );
+}
+
+/**********************************************************************
+ *          LookupIconIdFromDirectory		(USER32.378)
+ */
+INT32 WINAPI LookupIconIdFromDirectory( CURSORICONDIR *dir, BOOL32 bIcon )
+{
+    return LookupIconIdFromDirectoryEx16( dir, bIcon, 
+	   bIcon ? SYSMETRICS_CXICON : SYSMETRICS_CXCURSOR,
+	   bIcon ? SYSMETRICS_CYICON : SYSMETRICS_CYCURSOR, bIcon ? 0 : LR_MONOCHROME );
+}
 
 /**********************************************************************
  *	    GetIconID    (USER.455)
@@ -1100,52 +1305,143 @@
 WORD WINAPI GetIconID( HGLOBAL16 hResource, DWORD resType )
 {
     CURSORICONDIR *lpDir = (CURSORICONDIR *)GlobalLock16(hResource);
-/* LockResource16(hResource); */
-
-    if (!lpDir || lpDir->idReserved ||
-        ((lpDir->idType != 1) && (lpDir->idType != 2)))
-    {
-        dprintf_cursor(stddeb,"GetIconID: invalid resource directory\n");
-        return 0;
-    }
 
     dprintf_cursor( stddeb, "GetIconID: hRes=%04x, entries=%i\n",
-                    hResource, lpDir->idCount );
+                    hResource, lpDir ? lpDir->idCount : 0);
 
     switch(resType)
     {
-    case 1:  /* cursor */
-        {
-            CURSORDIRENTRY *entry = CURSORICON_FindBestCursor( lpDir,
-                                    SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR );
-            return entry ? entry->wResId : 0;
-        }
-    case 3:  /* icon */
-        {
-            ICONDIRENTRY * entry =  CURSORICON_FindBestIcon( lpDir,
-                                    SYSMETRICS_CXICON, SYSMETRICS_CYICON,
-                                    MIN( 16, COLOR_GetSystemPaletteSize() ) );
-            return entry ? entry->wResId : 0;
-        }
+	case RT_CURSOR:
+	     return (WORD)LookupIconIdFromDirectoryEx16( lpDir, FALSE, 
+			  SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, LR_MONOCHROME );
+	case RT_ICON:
+	     return (WORD)LookupIconIdFromDirectoryEx16( lpDir, TRUE,
+			  SYSMETRICS_CXICON, SYSMETRICS_CYICON, 0 );
+	default:
+	     fprintf( stderr, "GetIconID: invalid res type %ld\n", resType );
     }
-    fprintf( stderr, "GetIconID: invalid res type %ld\n", resType );
     return 0;
 }
 
+/**********************************************************************
+ *          LoadCursorIconHandler    (USER.336)
+ *
+ * Supposed to load resources of Windows 2.x applications.
+ */
+HGLOBAL16 WINAPI LoadCursorIconHandler( HGLOBAL16 hResource, HMODULE16 hModule, HRSRC16 hRsrc )
+{
+    fprintf(stderr,"hModule[%04x]: old 2.x resources are not supported!\n", hModule);
+    return (HGLOBAL16)0;
+}
+
+/**********************************************************************
+ *          LoadDIBIconHandler    (USER.357)
+ * 
+ * RT_ICON resource loader, installed by USER_SignalProc when module
+ * is initialized.
+ */
+HGLOBAL16 WINAPI LoadDIBIconHandler( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
+{
+    /* If hResource is zero we must allocate a new memory block, if it's
+     * non-zero but GlobalLock() returns NULL then it was discarded and
+     * we have to recommit some memory, otherwise we just need to check 
+     * the block size. See LoadProc() in 16-bit SDK for more.
+     */
+
+     hMemObj = USER_CallDefaultRsrcHandler( hMemObj, hModule, hRsrc );
+     if( hMemObj )
+     {
+	 LPBYTE bits = (LPBYTE)GlobalLock16( hMemObj );
+	 hMemObj = CURSORICON_CreateFromResource( hModule, hMemObj, bits, 
+		   SizeofResource16(hModule, hRsrc), TRUE, 0x00030000, 
+		   SYSMETRICS_CXICON, SYSMETRICS_CYICON, LR_DEFAULTCOLOR );
+     }
+     return hMemObj;
+}
+
+/**********************************************************************
+ *          LoadDIBCursorHandler    (USER.356)
+ *
+ * RT_CURSOR resource loader. Same as above.
+ */
+HGLOBAL16 WINAPI LoadDIBCursorHandler( HGLOBAL16 hMemObj, HMODULE16 hModule, HRSRC16 hRsrc )
+{
+    hMemObj = USER_CallDefaultRsrcHandler( hMemObj, hModule, hRsrc );
+    if( hMemObj )
+    {
+	LPBYTE bits = (LPBYTE)GlobalLock16( hMemObj );
+	hMemObj = CURSORICON_CreateFromResource( hModule, hMemObj, bits,
+		  SizeofResource16(hModule, hRsrc), FALSE, 0x00030000,
+		  SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, LR_MONOCHROME );
+    }
+    return hMemObj;
+}
 
 /**********************************************************************
  *	    LoadIconHandler    (USER.456)
  */
 HICON16 WINAPI LoadIconHandler( HGLOBAL16 hResource, BOOL16 bNew )
 {
+    LPBYTE bits = (LPBYTE)LockResource16( hResource );
+
     dprintf_cursor(stddeb,"LoadIconHandler: hRes=%04x\n",hResource);
 
-    if( !bNew )
-      {
-	fprintf(stdnimp,"LoadIconHandler: 2.xx resources are not supported\n");
-        return 0;
-      }
-    return CURSORICON_LoadHandler( hResource, 0, FALSE);
+    return CURSORICON_CreateFromResource( 0, 0, bits, 0, TRUE, 
+		      bNew ? 0x00030000 : 0x00020000, 0, 0, LR_DEFAULTCOLOR );
+}
+
+/***********************************************************************
+ *           LoadCursorW                (USER32.361)
+ */
+HCURSOR32 WINAPI LoadCursor32W(HINSTANCE32 hInstance, LPCWSTR name)
+{
+    return CURSORICON_Load32( hInstance, name,
+                              SYSMETRICS_CXCURSOR, SYSMETRICS_CYCURSOR, 1, TRUE);
+}
+
+/***********************************************************************
+ *           LoadCursorA                (USER32.358)
+ */
+HCURSOR32 WINAPI LoadCursor32A(HINSTANCE32 hInstance, LPCSTR name)
+{
+        HCURSOR32 res=0;
+        if(!HIWORD(name))
+                return LoadCursor32W(hInstance,(LPCWSTR)name);
+        else
+        {
+            LPWSTR uni = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
+            res = LoadCursor32W(hInstance, uni);
+            HeapFree( GetProcessHeap(), 0, uni);
+        }
+        return res;
+}
+
+/***********************************************************************
+ *           LoadIconW          (USER32.363)
+ */
+HICON32 WINAPI LoadIcon32W(HINSTANCE32 hInstance, LPCWSTR name)
+{
+    return CURSORICON_Load32( hInstance, name,
+                              SYSMETRICS_CXICON, SYSMETRICS_CYICON,
+                              MIN( 16, COLOR_GetSystemPaletteSize() ), FALSE );
+}
+
+/***********************************************************************
+ *           LoadIconA          (USER32.362)
+ */
+HICON32 WINAPI LoadIcon32A(HINSTANCE32 hInstance, LPCSTR name)
+{
+    HICON32 res=0;
+
+    if( !HIWORD(name) )
+	return LoadIcon32W(hInstance, (LPCWSTR)name);
+    else
+    {
+	LPWSTR uni = HEAP_strdupAtoW( GetProcessHeap(), 0, name );
+	res = LoadIcon32W( hInstance, uni );
+	HeapFree( GetProcessHeap(), 0, uni );
+    }
+    return res;
 }
 
 /**********************************************************************
diff --git a/objects/dc.c b/objects/dc.c
index 77d3996..ed3b3fd 100644
--- a/objects/dc.c
+++ b/objects/dc.c
@@ -232,6 +232,16 @@
     if (dc->w.flags & DC_DIRTY) CLIPPING_UpdateGCRegion(dc);
 
     val.function = DC_XROPfunction[dc->w.ROPmode-1];
+    /*
+    ** Let's replace GXinvert by GXxor with (black xor white)
+    ** This solves the selection color and leak problems in excel
+    ** FIXME : Let's do that only if we work with X-pixels, not with Win-pixels
+    */
+    if (val.function == GXinvert)
+	{
+	val.foreground = BlackPixelOfScreen(screen) ^ WhitePixelOfScreen(screen);
+	val.function = GXxor;
+	}
     val.fill_style = dc->u.x.brush.fillStyle;
     switch(val.fill_style)
     {
@@ -338,7 +348,7 @@
     }
     else val.line_style = LineSolid;
     val.line_width = dc->u.x.pen.width;
-    val.cap_style  = CapRound;
+    val.cap_style  = (val.line_width <= 1) ? CapNotLast : CapRound;
     val.join_style = JoinMiter;
     XChangeGC( display, dc->u.x.gc, 
 	       GCFunction | GCForeground | GCBackground | GCLineWidth |
diff --git a/objects/dib.c b/objects/dib.c
index 9746225..5035ec34 100644
--- a/objects/dib.c
+++ b/objects/dib.c
@@ -299,13 +299,13 @@
 
     while (lines--)
     {
-	for (i = srcwidth/2, x = 0; i > 0; i--)
+	for (i = dstwidth/2, x = 0; i > 0; i--)
 	{
 	    BYTE pix = *bits++;
 	    XPutPixel( bmpImage, x++, lines, colors[pix >> 4] );
 	    XPutPixel( bmpImage, x++, lines, colors[pix & 0x0f] );
 	}
-        if (srcwidth & 1) XPutPixel( bmpImage, x, lines, colors[*bits >> 4] );
+        if (dstwidth & 1) XPutPixel( bmpImage, x, lines, colors[*bits >> 4] );
         srcbits += linebytes;
         bits	 = srcbits;
     }
@@ -1125,3 +1125,15 @@
         SetDIBits32( hdc, handle, 0, height, bits, data, coloruse );
     return handle;
 }
+
+HBITMAP32 CreateDIBSection(
+	HDC32 hdc,BITMAPINFO *bmi,UINT32 usage, LPVOID **bits,HANDLE32 section,
+	DWORD offset
+) {
+	fprintf(stderr,"CreateDIBSection(%d,[w=%ld,h=%ld],%d,%p,0x%08x,%ld),stub\n",
+		hdc,bmi->bmiHeader.biWidth,bmi->bmiHeader.biHeight,usage,bits,section,offset
+	);
+	*bits = 0xCafeBabe;
+	return 0;
+}
+
diff --git a/objects/font.c b/objects/font.c
index 216962f..941881a 100644
--- a/objects/font.c
+++ b/objects/font.c
@@ -804,11 +804,12 @@
     }
 
     if (!dc->funcs->pGetTextMetrics ||
-        !dc->funcs->pGetTextMetrics( dc,metrics ))
+        !dc->funcs->pGetTextMetrics( dc, metrics ))
         return FALSE;
-    /* map them from device to logic coordinatesystem before returning.
-     * FIXME: should this be in the device driver?
-     */
+
+    /* device layer returns values in device units
+     * therefore we have to convert them to logical */
+
 #define WDPTOLP(x) ((x<0)?					\
 		(-abs((x)*dc->wndExtX/dc->vportExtX)):		\
 		(abs((x)*dc->wndExtX/dc->vportExtX)))
diff --git a/objects/metafile.c b/objects/metafile.c
index ad8622a..ba27f44 100644
--- a/objects/metafile.c
+++ b/objects/metafile.c
@@ -727,16 +727,16 @@
     case META_CREATEREGION:
 	 {
 	    int i;
-	    HRGN32 h1,h2,hrgn=CreateRectRgn32(mr->rdParam[7],mr->rdParam[8],
-					      mr->rdParam[9],mr->rdParam[10]);
-	    for (i=0,h1=CreateRectRgn32(0,0,0,0);i<mr->rdParam[5];i++)
+	    HRGN32 h2,hrgn=CreateRectRgn32(mr->rdParam[7],mr->rdParam[8],
+                                           mr->rdParam[9],mr->rdParam[10]);
+	    for (i = 0; i < mr->rdParam[5]; i++)
 	    {
 	     if (mr->rdParam[11+i*6]==2)
 	     { 
 	       h2=CreateRectRgn32(mr->rdParam[14+i*6],mr->rdParam[12+i*6],
 				  mr->rdParam[15+i*6],mr->rdParam[13+i*6]);
-	       CombineRgn32(hrgn,h1,h2,mr->rdParam[16+i*6]);	/* e.g. RGN_OR */
-	       h1=hrgn;
+	       CombineRgn32(hrgn,hrgn,h2,mr->rdParam[16+i*6]);	/* e.g. RGN_OR */
+               DeleteObject32( h2 );
 	     }
 	    }
 	    MF_AddHandle(ht, nHandles,hrgn);
diff --git a/objects/text.c b/objects/text.c
index 1b46830..7e66e56 100644
--- a/objects/text.c
+++ b/objects/text.c
@@ -254,7 +254,7 @@
                 HPEN32 hpen = CreatePen32( PS_SOLID, 1, GetTextColor32(hdc) );
                 HPEN32 oldPen = SelectObject32( hdc, hpen );
                 MoveTo(hdc, x + prefix_x, y + tm.tmAscent + 1 );
-                LineTo32(hdc, x + prefix_end, y + tm.tmAscent + 1 );
+                LineTo32(hdc, x + prefix_end + 1, y + tm.tmAscent + 1 );
                 SelectObject32( hdc, oldPen );
                 DeleteObject32( hpen );
             }
@@ -312,6 +312,31 @@
     return ret;
 }
 
+/***********************************************************************
+ *           DrawTextEx32A    (USER32.164)
+ */
+INT32 DrawTextEx32A( HDC32 hdc, LPCSTR str, INT32 count,
+                     LPRECT32 rect, UINT32 flags, LPDRAWTEXTPARAMS dtp )
+{
+    fprintf(stderr,"DrawTextEx32A(%d,'%s',%d,%p,0x%08x,%p)\n",
+    	hdc,str,count,rect,flags,dtp
+    );
+    /*FIXME: ignores extended functionality ... */
+    return DrawText32A(hdc,str,count,rect,flags);
+}
+
+/***********************************************************************
+ *           DrawTextEx32W    (USER32.165)
+ */
+INT32 DrawTextEx32W( HDC32 hdc, LPCWSTR str, INT32 count,
+                     LPRECT32 rect, UINT32 flags, LPDRAWTEXTPARAMS dtp )
+{
+    fprintf(stderr,"DrawTextEx32A(%d,%p,%d,%p,0x%08x,%p)\n",
+    	hdc,str,count,rect,flags,dtp
+    );
+    /*FIXME: ignores extended functionality ... */
+    return DrawText32W(hdc,str,count,rect,flags);
+}
 
 /***********************************************************************
  *           ExtTextOut16    (GDI.351)